Skip to content
This repository was archived by the owner on Jun 8, 2026. It is now read-only.

Commit 43e08f7

Browse files
committed
FEA-1550: Decouple listener tests from PGlite
- Use an in-memory AgentHookLifecycle fake for listener routing tests. - Keep listener assertions focused on HTTP contract, harness stamping, provider-hint rejection, and malformed/oversized payload handling. Testing: Targeted listener test and full desktop test suite passed. Risks: Low; test-only refactor, PGlite behavior remains covered by dedicated database tests.
1 parent 396cd5a commit 43e08f7

1 file changed

Lines changed: 46 additions & 20 deletions

File tree

apps/desktop/test/agent-monitor-listener.test.ts

Lines changed: 46 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
11
import assert from "node:assert/strict";
22
import http from "node:http";
3-
import { mkdtemp, rm } from "node:fs/promises";
4-
import { tmpdir } from "node:os";
5-
import path from "node:path";
63
import { test } from "node:test";
7-
import { openPgliteAgentDatabase, type PgliteAgentDatabase } from "../src/main/database/pglite.js";
8-
import { AgentHookListener } from "../src/main/agent-monitor-listener.js";
4+
import {
5+
AgentHookListener,
6+
type AgentHookLifecycle,
7+
} from "../src/main/agent-monitor-listener.js";
8+
import type { HookData } from "../src/main/agent-dashboard-db-types.js";
99

1010
interface PostResult {
1111
status: number;
@@ -62,44 +62,70 @@ interface ListenerDiagnostics {
6262
logs: string[];
6363
}
6464

65+
interface CapturedSession {
66+
id: string;
67+
harness: string;
68+
cwd: string | null;
69+
}
70+
71+
class InMemoryHookLifecycle implements AgentHookLifecycle {
72+
readonly sessions = {
73+
getAll: async (): Promise<CapturedSession[]> => [...this.sessionRows.values()],
74+
getById: async (id: string): Promise<CapturedSession | null> =>
75+
this.sessionRows.get(id) ?? null,
76+
};
77+
78+
private readonly sessionRows = new Map<string, CapturedSession>();
79+
80+
constructor(private readonly diagnostics: ListenerDiagnostics) {}
81+
82+
processEvent(hookType: string, data: HookData, harness: string): boolean {
83+
if (hookType !== "SessionStart") {
84+
return false;
85+
}
86+
const sessionId = data.session_id;
87+
if (typeof sessionId !== "string" || sessionId.length === 0) {
88+
return false;
89+
}
90+
this.sessionRows.set(sessionId, {
91+
id: sessionId,
92+
harness,
93+
cwd: typeof data.cwd === "string" ? data.cwd : null,
94+
});
95+
this.diagnostics.emits.push(sessionId);
96+
return true;
97+
}
98+
}
99+
65100
async function withListener(
66101
run: (
67102
url: string,
68-
db: PgliteAgentDatabase,
103+
lifecycle: InMemoryHookLifecycle,
69104
diagnostics: ListenerDiagnostics,
70105
) => Promise<void>,
71106
): Promise<void> {
72-
const dir = await mkdtemp(path.join(tmpdir(), "cl-listener-"));
73107
const diagnostics: ListenerDiagnostics = { emits: [], logs: [] };
74-
const db = await openPgliteAgentDatabase({
75-
dataDir: path.join(dir, "agent-dashboard.pgdata"),
76-
detectBillingMode: () => "api",
77-
extractTranscript: () => null,
78-
emit: (sessionId) => diagnostics.emits.push(sessionId),
79-
log: (message) => diagnostics.logs.push(message),
80-
});
108+
const lifecycle = new InMemoryHookLifecycle(diagnostics);
81109
const listener = new AgentHookListener({
82-
lifecycle: db,
110+
lifecycle,
83111
log: (message) => diagnostics.logs.push(message),
84112
port: 0,
85113
});
86114
await listener.start();
87115
const url = listener.getUrl();
88116
assert.ok(url, "listener bound to an ephemeral port");
89117
try {
90-
await run(url!, db, diagnostics);
118+
await run(url!, lifecycle, diagnostics);
91119
} finally {
92120
await listener.stop();
93-
await db.close();
94-
await rm(dir, { recursive: true, force: true });
95121
}
96122
}
97123

98124
async function assertNoWritesOrEmits(
99-
db: PgliteAgentDatabase,
125+
lifecycle: InMemoryHookLifecycle,
100126
diagnostics: ListenerDiagnostics,
101127
): Promise<void> {
102-
assert.equal((await db.sessions.getAll()).length, 0, "no session rows written");
128+
assert.equal((await lifecycle.sessions.getAll()).length, 0, "no session rows written");
103129
assert.deepEqual(diagnostics.emits, [], "no live DB-change emits");
104130
}
105131

0 commit comments

Comments
 (0)