test(frontend): unit tests exercise named SSE events (fidelity) + cleanup
FakeEventSource.addEventListener was a no-op, so emit() only drove onmessage.
Production relies on addEventListener for the backend's NAMED events
(event: ui_request), so the unit tests could pass while prod silently broke.
- fakeEventSource: store named handlers in a Map<string,Set>; add emitNamed()
that dispatches to them; keep emit() for the unnamed/default onmessage path
- useSessionStream.test: ui_request now driven via emitNamed (production path);
add a separate test for the unnamed text_delta path via plain emit
- f1-loop.test: widget emission switched to emitNamed("ui_request", ...)
- verified: tests FAIL if addEventListener wiring is removed from
useSessionStream (then restored)
- cleanup: fake-pi.mjs drops unused execFileSync import, uses static spawnSync
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -10,16 +10,25 @@ beforeEach(() => {
|
||||
useSessionStore.getState().resetSession();
|
||||
});
|
||||
|
||||
test("opens an EventSource for the session and feeds events to the store", () => {
|
||||
test("opens an EventSource and feeds NAMED events to the store", () => {
|
||||
renderHook(() => useSessionStream("s1"));
|
||||
const es = FakeEventSource.instances[0];
|
||||
expect(es.url).toContain("/sessions/s1/events");
|
||||
// Backend sends `event: ui_request` (named) — drive the addEventListener path
|
||||
// that production relies on, not the unnamed onmessage fallback.
|
||||
act(() =>
|
||||
es.emit({ type: "ui_request", ui_request: { id: "u1", widget: "select" } })
|
||||
es.emitNamed("ui_request", { type: "ui_request", ui_request: { id: "u1", widget: "select" } })
|
||||
);
|
||||
expect(useSessionStore.getState().pendingWidget?.id).toBe("u1");
|
||||
});
|
||||
|
||||
test("also feeds UNNAMED (default message) events to the store", () => {
|
||||
renderHook(() => useSessionStream("s1"));
|
||||
const es = FakeEventSource.instances[0];
|
||||
act(() => es.emit({ type: "text_delta", text: "hello" }));
|
||||
expect(useSessionStore.getState().transcript.at(-1)?.text).toBe("hello");
|
||||
});
|
||||
|
||||
test("closes the stream on unmount", () => {
|
||||
const { unmount } = renderHook(() => useSessionStream("s1"));
|
||||
const es = FakeEventSource.instances[0];
|
||||
|
||||
Reference in New Issue
Block a user