Files
upstream-atomic-crm/.claude/hooks/test/turn-complete.test.mjs
upstream-mirror 93ecc1a6f8
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
snapshot of https://github.com/marmelab/atomic-crm.git (main, 2026-09-18; blobs > 131072B omitted)
2026-09-18 01:48:50 +05:00

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 });
});
});