Some checks failed
✅ Check / 🔬 ESLint (push) Failing after 21s
✅ Check / 🏷️ Typecheck (push) Failing after 11s
✅ Check / 🔎 Test (push) Failing after 11s
✅ Check / e2e-test (push) Failing after 11s
✅ Check / 🔨 Build (push) Failing after 11s
🚀 Deploy / 🚀 Deploy (doc) (push) Failing after 12s
🚀 Deploy / 🚀 Deploy (demo) (push) Failing after 12s
🚀 Deploy / 🚀 Deploy (supabase) (push) Failing after 18s
60 lines
2.3 KiB
JavaScript
60 lines
2.3 KiB
JavaScript
// Tests for turn-complete.mjs — the Stop hook that drops a per-session sentinel
|
|
// (/tmp/pty-sentinels/pty-turn-done-<session_id>) the chat-service PtySession
|
|
// watcher polls. Must always exit 0 (a Stop hook never blocks) and never throw on
|
|
// a missing/malformed payload.
|
|
|
|
import { existsSync, mkdtempSync, rmSync, writeFileSync } from "node:fs";
|
|
import { tmpdir } from "node:os";
|
|
import { dirname, join } from "node:path";
|
|
import { fileURLToPath } from "node:url";
|
|
import { spawnSync } from "node:child_process";
|
|
import { describe, test, expect, afterAll } from "vitest";
|
|
|
|
const HERE = dirname(fileURLToPath(import.meta.url));
|
|
const HOOK = join(HERE, "..", "turn-complete.mjs");
|
|
// A unique id so the test never collides with a real session's sentinel.
|
|
const SID = "turn-complete-test-7e3a9f21";
|
|
const sentinel = join("/tmp/pty-sentinels", `pty-turn-done-${SID}`);
|
|
|
|
const run = (input) => spawnSync("node", [HOOK], { input, encoding: "utf8" });
|
|
|
|
afterAll(() => rmSync(sentinel, { force: true }));
|
|
|
|
describe("turn-complete", () => {
|
|
test("creates the per-session sentinel and exits 0", () => {
|
|
const r = run(JSON.stringify({ session_id: SID }));
|
|
expect(r.status).toBe(0);
|
|
expect(existsSync(sentinel)).toBe(true);
|
|
});
|
|
|
|
test("no session id → no throw, exits 0", () => {
|
|
expect(run(JSON.stringify({})).status).toBe(0);
|
|
});
|
|
|
|
test("malformed payload → no throw, exits 0", () => {
|
|
expect(run("not json").status).toBe(0);
|
|
});
|
|
|
|
test("inert when config.launcher.turnSentinelDir is unset (no launcher)", () => {
|
|
// A repo whose config omits turnSentinelDir: the hook writes no sentinel.
|
|
const repo = mkdtempSync(join(tmpdir(), "turn-complete-repo-"));
|
|
writeFileSync(
|
|
join(repo, "harness.config.json"),
|
|
JSON.stringify({ validation: { steps: [] }, roles: {}, launcher: {} }),
|
|
);
|
|
const otherSid = "turn-complete-inert-9c1d";
|
|
const wouldBe = join("/tmp/pty-sentinels", `pty-turn-done-${otherSid}`);
|
|
rmSync(wouldBe, { force: true });
|
|
const env = { ...process.env, APP_DIR: repo };
|
|
delete env.CLAUDE_PROJECT_DIR;
|
|
const r = spawnSync("node", [HOOK], {
|
|
input: JSON.stringify({ session_id: otherSid }),
|
|
env,
|
|
encoding: "utf8",
|
|
});
|
|
expect(r.status).toBe(0);
|
|
expect(existsSync(wouldBe)).toBe(false);
|
|
rmSync(repo, { recursive: true, force: true });
|
|
});
|
|
});
|