W / test /account-add-proxy-ordering.test.js
Ac66's picture
Upload folder using huggingface_hub
2b64d42 verified
import { afterEach, describe, it } from 'node:test';
import assert from 'node:assert/strict';
import { config } from '../src/config.js';
import { configureBindHost, getAccountList, removeAccount } from '../src/auth.js';
import { handleDashboardApi } from '../src/dashboard/api.js';
import { getEffectiveProxy, removeProxy } from '../src/dashboard/proxy-config.js';
const originalAllowPrivate = config.allowPrivateProxyHosts;
const originalDashboardPassword = config.dashboardPassword;
const originalApiKey = config.apiKey;
const createdAccountIds = new Set();
function fakeRes() {
return {
statusCode: 0,
body: '',
writeHead(status) { this.statusCode = status; },
end(chunk) { this.body += chunk ? String(chunk) : ''; },
json() { return this.body ? JSON.parse(this.body) : null; },
};
}
function snapshotAccountIds() {
return getAccountList().map(a => a.id);
}
afterEach(() => {
config.allowPrivateProxyHosts = originalAllowPrivate;
config.dashboardPassword = originalDashboardPassword;
config.apiKey = originalApiKey;
configureBindHost('127.0.0.1');
for (const a of getAccountList()) {
if (typeof a.email === 'string' && a.email.startsWith('test-proxy-ordering-')) {
removeAccount(a.id);
}
}
for (const id of createdAccountIds) {
removeProxy('account', id);
createdAccountIds.delete(id);
}
});
describe('POST /accounts proxy ordering (regression for PR #90 follow-up)', () => {
it('does NOT create account when proxy format is invalid', async () => {
config.dashboardPassword = '';
config.apiKey = '';
configureBindHost('127.0.0.1');
const before = snapshotAccountIds();
const res = fakeRes();
await handleDashboardApi(
'POST',
'/accounts',
{ api_key: `test-proxy-ordering-bad-${Date.now()}`, label: `test-proxy-ordering-bad-${Date.now()}`, proxy: 'not-a-valid-proxy-url' },
{ headers: {}, socket: { remoteAddress: '127.0.0.1' } },
res
);
const after = snapshotAccountIds();
assert.equal(res.statusCode, 400);
assert.equal(res.json().error, 'ERR_PROXY_FORMAT_INVALID');
assert.deepEqual(after, before, 'no account should be created when proxy format is invalid');
});
it('does NOT create account when proxy host is private and ALLOW_PRIVATE_PROXY_HOSTS is off', async () => {
config.dashboardPassword = '';
config.apiKey = '';
config.allowPrivateProxyHosts = false;
configureBindHost('127.0.0.1');
const before = snapshotAccountIds();
const res = fakeRes();
await handleDashboardApi(
'POST',
'/accounts',
{ api_key: `test-proxy-ordering-priv-${Date.now()}`, label: `test-proxy-ordering-priv-${Date.now()}`, proxy: 'http://192.168.1.100:8080' },
{ headers: {}, socket: { remoteAddress: '127.0.0.1' } },
res
);
const after = snapshotAccountIds();
assert.equal(res.statusCode, 400, `expected 400, got ${res.statusCode}: ${res.body}`);
assert.ok(/PRIVATE|private|local/i.test(res.json().error || ''), `expected private-host error, got ${res.json().error}`);
assert.deepEqual(after, before, 'no account should be created when private proxy is rejected');
});
it('creates account with valid public proxy and binds account-level proxy', async () => {
config.dashboardPassword = '';
config.apiKey = '';
configureBindHost('127.0.0.1');
const before = snapshotAccountIds();
const label = `test-proxy-ordering-public-${Date.now()}`;
const key = `test-key-${Date.now()}`;
const proxy = 'http://1.1.1.1:8080';
const res = fakeRes();
await handleDashboardApi(
'POST',
'/accounts',
{ api_key: key, label, proxy },
{ headers: {}, socket: { remoteAddress: '127.0.0.1' } },
res
);
const after = snapshotAccountIds();
const body = res.json();
assert.equal(res.statusCode, 200, `expected 200, got ${res.statusCode}: ${res.body}`);
assert.equal(body.success, true);
assert.equal(after.length, before.length + 1, 'should create exactly one account');
const accountId = body.account.id;
createdAccountIds.add(accountId);
const proxyCfg = getEffectiveProxy(accountId);
assert.deepEqual(proxyCfg, {
type: 'http',
host: '1.1.1.1',
port: 8080,
username: '',
password: '',
});
});
it('prefers api_key when api_key + token are both provided', async () => {
config.dashboardPassword = '';
config.apiKey = '';
configureBindHost('127.0.0.1');
const label = `test-proxy-ordering-both-${Date.now()}`;
const key = `test-key-both-${Date.now()}`;
const res = fakeRes();
await handleDashboardApi(
'POST',
'/accounts',
{
api_key: key,
token: 'definitely-not-a-valid-token',
label,
proxy: 'http://1.1.1.1:8080',
},
{ headers: {}, socket: { remoteAddress: '127.0.0.1' } },
res
);
const body = res.json();
assert.equal(res.statusCode, 200, `expected 200, got ${res.statusCode}: ${res.body}`);
assert.equal(body.success, true);
assert.equal(body.account.method, 'api_key', 'api_key should win when both fields are present');
createdAccountIds.add(body.account.id);
});
it('returns non-ERR_* proxy validation errors when host validation throws generic errors', async () => {
config.dashboardPassword = '';
config.apiKey = '';
configureBindHost('127.0.0.1');
const before = snapshotAccountIds();
const label = `test-proxy-ordering-non-err-${Date.now()}`;
const key = `test-key-non-err-${Date.now()}`;
const res = fakeRes();
await handleDashboardApi(
'POST',
'/accounts',
{ api_key: key, label, proxy: 'http://does-not-exist.invalid:8080' },
{ headers: {}, socket: { remoteAddress: '127.0.0.1' } },
res
);
const after = snapshotAccountIds();
const body = res.json();
assert.equal(res.statusCode, 400);
assert.ok(body.error && !/^ERR_/.test(body.error), `expected non-ERR_* error, got ${body.error}`);
assert.deepEqual(after, before);
});
it('rejects request with no api_key/token before doing any work', async () => {
config.dashboardPassword = '';
config.apiKey = '';
configureBindHost('127.0.0.1');
const before = snapshotAccountIds();
const res = fakeRes();
await handleDashboardApi(
'POST',
'/accounts',
{ proxy: 'http://example.com:8080', label: 'no-key' },
{ headers: {}, socket: { remoteAddress: '127.0.0.1' } },
res
);
const after = snapshotAccountIds();
assert.equal(res.statusCode, 400);
assert.match(res.json().error, /Provide api_key or token/);
assert.deepEqual(after, before);
});
it('creates account with no proxy when none provided', async () => {
config.dashboardPassword = '';
config.apiKey = '';
configureBindHost('127.0.0.1');
const before = snapshotAccountIds().length;
const label = `test-proxy-ordering-noproxy-${Date.now()}`;
const res = fakeRes();
await handleDashboardApi(
'POST',
'/accounts',
{ api_key: `key-${label}`, label },
{ headers: {}, socket: { remoteAddress: '127.0.0.1' } },
res
);
const after = snapshotAccountIds().length;
assert.equal(res.statusCode, 200, `expected 200, got ${res.statusCode}: ${res.body}`);
assert.equal(res.json().success, true);
assert.equal(after, before + 1, 'exactly one account should be created');
});
});