AI_PROJECT / src /hf-space /server.test.mjs
chenchenaoyang's picture
Deploy HF Space with dataset backend
476094d verified
Raw
History Blame Contribute Delete
7.52 kB
import test from "node:test";
import assert from "node:assert/strict";
import fs from "node:fs/promises";
import os from "node:os";
import path from "node:path";
import { createAdminSessionCookie } from "./admin-auth.mjs";
import { EncryptedPoolStore } from "./encrypted-pool-store.mjs";
import { createHfSpaceServer } from "./server.mjs";
async function startServer(server) {
await new Promise((resolve) => server.listen(0, "127.0.0.1", resolve));
const address = server.address();
return `http://127.0.0.1:${address.port}`;
}
async function stopServer(server) {
await new Promise((resolve, reject) => server.close((error) => (error ? reject(error) : resolve())));
}
async function makeEnv() {
const root = await fs.mkdtemp(path.join(os.tmpdir(), "hf-space-server-test-"));
return {
root,
env: {
DATA_DIR: path.join(root, "data"),
POOL_CRYPTO_KEY: "pool-crypto-test",
ADMIN_SESSION_SECRET: "admin-session-secret",
ADMIN_HF_USERNAMES: "alice",
CODEX_ACCOUNT_PROXY_KEY: "acc-proxy-key",
CODEX_API_PROXY_KEY: "codex-api-proxy-key",
CLAUDE_API_PROXY_KEY: "claude-api-proxy-key",
CODEX_PROXY_UPSTREAM_BASE: "https://chatgpt.com/backend-api/codex",
},
};
}
function sessionCookie(env) {
return createAdminSessionCookie(
{
username: "alice",
displayName: "Alice",
},
env.ADMIN_SESSION_SECRET,
).split(";")[0];
}
test("HF server enforces admin and proxy auth boundaries", async () => {
const { env } = await makeEnv();
const { server } = await createHfSpaceServer({
env,
codexApiFetchFn: async () => new Response('{"data":[{"id":"gpt-5.4"}]}', { status: 200 }),
});
const baseUrl = await startServer(server);
try {
const healthRes = await fetch(`${baseUrl}/healthz`);
assert.deepEqual(await healthRes.json(), { ok: true });
const adminRes = await fetch(`${baseUrl}/admin/api/app-config`);
assert.equal(adminRes.status, 401);
const adminWithProxyKey = await fetch(`${baseUrl}/admin/api/app-config`, {
headers: {
authorization: "Bearer acc-proxy-key",
},
});
assert.equal(adminWithProxyKey.status, 401);
const proxyWithSessionOnly = await fetch(`${baseUrl}/proxy/codex-account/v1/models`, {
headers: {
cookie: sessionCookie(env),
},
});
assert.equal(proxyWithSessionOnly.status, 401);
} finally {
await stopServer(server);
}
});
test("HF server imports encrypted pool data, reloads services, and hides public status routes", async () => {
const { env } = await makeEnv();
const { server } = await createHfSpaceServer({
env,
codexApiFetchFn: async () => new Response('{"data":[{"id":"gpt-5.4"}]}', { status: 200 }),
});
const baseUrl = await startServer(server);
const cookie = sessionCookie(env);
try {
const importRes = await fetch(`${baseUrl}/admin/api/pools/codex-api/import`, {
method: "POST",
headers: {
cookie,
"content-type": "application/json",
},
body: JSON.stringify({
items: [
{
name: "main",
type: "codex",
baseUrl: "https://example.com/v1",
apiKey: "sk-import-secret",
model: "gpt-5.4",
disabled: false,
},
],
}),
});
assert.equal(importRes.status, 200);
const encryptedPath = path.join(env.DATA_DIR, "pools", "codex-api.enc");
const encrypted = await fs.readFile(encryptedPath, "utf8");
assert.doesNotMatch(encrypted, /sk-import-secret/);
const reloadRes = await fetch(`${baseUrl}/admin/api/reload`, {
method: "POST",
headers: {
cookie,
},
});
assert.equal(reloadRes.status, 200);
const statusRes = await fetch(`${baseUrl}/admin/api/api-pool/codex/status`, {
headers: {
cookie,
},
});
const status = await statusRes.json();
assert.equal(status.running, true);
assert.equal(status.proxyStatus.body.scheduledSwitchEnabled, true);
assert.equal(typeof status.proxyStatus.body.inflightRequests, "number");
assert.equal(status.proxyStatus.body.scheduledSwitchIntervalMs, 900000);
const proxyRes = await fetch(`${baseUrl}/proxy/codex-api/v1/models`, {
headers: {
authorization: "Bearer codex-api-proxy-key",
},
});
assert.equal(proxyRes.status, 200);
const hiddenStatusRes = await fetch(`${baseUrl}/proxy/codex-api/proxy/status`, {
headers: {
authorization: "Bearer codex-api-proxy-key",
},
});
assert.equal(hiddenStatusRes.status, 404);
} finally {
await stopServer(server);
}
});
test("HF server persists remote api pool runtime config and reloads the targeted service", async () => {
const { env } = await makeEnv();
const { server } = await createHfSpaceServer({
env,
codexApiFetchFn: async () => new Response('{"data":[{"id":"gpt-5.4"}]}', { status: 200 }),
claudeApiFetchFn: async () => new Response('{"data":[{"id":"claude-sonnet-4"}]}', { status: 200 }),
});
const baseUrl = await startServer(server);
const cookie = sessionCookie(env);
try {
await fetch(`${baseUrl}/admin/api/pools/codex-api/import`, {
method: "POST",
headers: {
cookie,
"content-type": "application/json",
},
body: JSON.stringify({
items: [
{
name: "main",
type: "codex",
baseUrl: "https://example.com/v1",
apiKey: "sk-import-secret",
model: "gpt-5.4",
disabled: false,
},
],
}),
});
await fetch(`${baseUrl}/admin/api/pools/claude-code-api/import`, {
method: "POST",
headers: {
cookie,
"content-type": "application/json",
},
body: JSON.stringify({
items: [
{
name: "claude-main",
type: "claude-code",
baseUrl: "https://claude.example.com",
apiKey: "sk-claude-secret",
model: "claude-sonnet-4",
disabled: false,
},
],
}),
});
const saveRes = await fetch(`${baseUrl}/admin/api/api-pool/config`, {
method: "PUT",
headers: {
cookie,
"content-type": "application/json",
},
body: JSON.stringify({
provider: "claude-code",
enableScheduledSwitch: false,
scheduledSwitchIntervalMs: 120000,
}),
});
assert.equal(saveRes.status, 200);
const savePayload = await saveRes.json();
assert.equal(savePayload.config.enableScheduledSwitch, false);
assert.equal(savePayload.config.scheduledSwitchIntervalMs, 120000);
assert.equal(savePayload.status.proxyStatus.body.scheduledSwitchEnabled, false);
assert.equal(savePayload.status.proxyStatus.body.scheduledSwitchIntervalMs, 120000);
const configRes = await fetch(`${baseUrl}/admin/api/api-pool/config`, {
headers: { cookie },
});
assert.equal(configRes.status, 200);
const config = await configRes.json();
assert.equal(config.enableScheduledSwitch, false);
assert.equal(config.scheduledSwitchIntervalMs, 120000);
const configPath = path.join(env.DATA_DIR, "config", "api-pool-runtime.json");
const savedConfig = JSON.parse(await fs.readFile(configPath, "utf8"));
assert.equal(savedConfig.enableScheduledSwitch, false);
assert.equal(savedConfig.scheduledSwitchIntervalMs, 120000);
} finally {
await stopServer(server);
}
});