forked from bai/curriculum-project-hub
75 lines
2.5 KiB
TypeScript
75 lines
2.5 KiB
TypeScript
import { createServer } from "node:net";
|
|
import { once } from "node:events";
|
|
import { mkdtemp, rm, writeFile } from "node:fs/promises";
|
|
import { tmpdir } from "node:os";
|
|
import { join } from "node:path";
|
|
import { afterEach, describe, expect, it } from "vitest";
|
|
import { resetDb, TEST_DATABASE_URL, TEST_SECRET_KEY, TEST_SECRET_KEY_ID } from "./helpers.js";
|
|
|
|
const ENV_KEYS = [
|
|
"DATABASE_URL",
|
|
"ANTHROPIC_AUTH_TOKEN",
|
|
"ANTHROPIC_API_KEY",
|
|
"FEISHU_APP_ID",
|
|
"FEISHU_APP_SECRET",
|
|
"FEISHU_BOT_OPEN_ID",
|
|
"HUB_PROJECT_WORKSPACE_ROOT",
|
|
"HUB_SESSION_SECRET",
|
|
"HUB_PUBLIC_BASE_URL",
|
|
"HUB_FEISHU_LISTENER_ENABLED",
|
|
"HUB_SECRET_KEYRING_FILE",
|
|
"HOST",
|
|
"PORT",
|
|
] as const;
|
|
|
|
describe("Hub startup", () => {
|
|
const previousEnv = new Map(ENV_KEYS.map((key) => [key, process.env[key]]));
|
|
|
|
afterEach(() => {
|
|
for (const [key, value] of previousEnv) {
|
|
if (value === undefined) delete process.env[key];
|
|
else process.env[key] = value;
|
|
}
|
|
});
|
|
|
|
it("rejects startup before the Feishu listener when the HTTP bind fails", async () => {
|
|
await resetDb();
|
|
const blocker = createServer();
|
|
blocker.listen(0, "127.0.0.1");
|
|
await once(blocker, "listening");
|
|
const address = blocker.address();
|
|
if (address === null || typeof address === "string") throw new Error("expected an INET test listener");
|
|
|
|
const keyringDirectory = await mkdtemp(join(tmpdir(), "cph-hub-start-keyring-"));
|
|
const keyringFile = join(keyringDirectory, "keyring.json");
|
|
await writeFile(keyringFile, JSON.stringify({
|
|
version: 1,
|
|
activeKeyId: TEST_SECRET_KEY_ID,
|
|
keys: { [TEST_SECRET_KEY_ID]: TEST_SECRET_KEY.toString("base64") },
|
|
}), { mode: 0o600 });
|
|
|
|
Object.assign(process.env, {
|
|
DATABASE_URL: TEST_DATABASE_URL,
|
|
FEISHU_APP_ID: "test-app",
|
|
FEISHU_APP_SECRET: "test-secret",
|
|
FEISHU_BOT_OPEN_ID: "ou_test_bot",
|
|
HUB_PROJECT_WORKSPACE_ROOT: "/tmp/cph-hub-server-start-test",
|
|
HUB_SESSION_SECRET: "integration-session-secret-with-32-bytes",
|
|
HUB_PUBLIC_BASE_URL: "https://hub.example.test",
|
|
HUB_FEISHU_LISTENER_ENABLED: "false",
|
|
HUB_SECRET_KEYRING_FILE: keyringFile,
|
|
HOST: "127.0.0.1",
|
|
PORT: String(address.port),
|
|
});
|
|
|
|
try {
|
|
const { startHub } = await import("../../src/hub.js");
|
|
await expect(startHub()).rejects.toMatchObject({ code: "EADDRINUSE" });
|
|
} finally {
|
|
blocker.close();
|
|
await once(blocker, "close");
|
|
await rm(keyringDirectory, { recursive: true, force: true });
|
|
}
|
|
});
|
|
});
|