From 15da838fb654832f7ee572faee0591c73853da4b Mon Sep 17 00:00:00 2001 From: alejandrobailo Date: Thu, 25 Jun 2026 13:58:14 +0200 Subject: [PATCH] fix(ui): reset Lighthouse chat from sidebar --- ui/app/(prowler)/lighthouse/page.test.ts | 19 ++++++++ ui/app/(prowler)/lighthouse/page.tsx | 2 + .../chat/lighthouse-v2-chat-page.test.tsx | 43 ++++++++++++++++++- .../chat/lighthouse-v2-chat-page.tsx | 4 ++ 4 files changed, 67 insertions(+), 1 deletion(-) create mode 100644 ui/app/(prowler)/lighthouse/page.test.ts diff --git a/ui/app/(prowler)/lighthouse/page.test.ts b/ui/app/(prowler)/lighthouse/page.test.ts new file mode 100644 index 0000000000..e7260e2506 --- /dev/null +++ b/ui/app/(prowler)/lighthouse/page.test.ts @@ -0,0 +1,19 @@ +import { readFileSync } from "node:fs"; +import path from "node:path"; +import { fileURLToPath } from "node:url"; + +import { describe, expect, it } from "vitest"; + +describe("Lighthouse page", () => { + const currentDir = path.dirname(fileURLToPath(import.meta.url)); + const pagePath = path.join(currentDir, "page.tsx"); + const source = readFileSync(pagePath, "utf8"); + + it("keys the Cloud chat by the active route conversation", () => { + // Given / When / Then + expect(source).toContain( + 'const chatRouteKey = activeSessionId ?? initialPrompt ?? "new";', + ); + expect(source).toContain("key={chatRouteKey}"); + }); +}); diff --git a/ui/app/(prowler)/lighthouse/page.tsx b/ui/app/(prowler)/lighthouse/page.tsx index 2860776ca1..396b9c243f 100644 --- a/ui/app/(prowler)/lighthouse/page.tsx +++ b/ui/app/(prowler)/lighthouse/page.tsx @@ -66,11 +66,13 @@ export default async function AIChatbot({ const initialMessages = activeSessionId ? await getLighthouseV2Messages(activeSessionId) : { data: [] }; + const chatRouteKey = activeSessionId ?? initialPrompt ?? "new"; return (
{ }); }); + afterEach(() => { + vi.unstubAllGlobals(); + }); + it("uses the neutral page background instead of the global app background token", () => { // Given / When const { container } = renderPage(); @@ -148,6 +152,43 @@ describe("LighthouseV2ChatPage", () => { expect(createSessionMock).toHaveBeenCalledWith("Summarize findings"); expect(pushMock).toHaveBeenCalledWith("/lighthouse?session=session-1"); }); + + it("closes an active stream when the chat unmounts", async () => { + // Given + const user = userEvent.setup(); + const closeMock = vi.fn(); + const eventSourceMock = vi.fn(function MockEventSource( + this: Record, + ) { + this.addEventListener = vi.fn(); + this.close = closeMock; + }); + vi.stubGlobal("EventSource", eventSourceMock); + sendMessageMock.mockResolvedValue({ + data: { + task: { + id: "task-1", + name: "lighthouse-run", + state: "executing", + }, + streamUrl: "/api/stream", + }, + }); + const { unmount } = renderPage({ initialSessionId: "session-1" }); + + // When + await user.type( + screen.getByRole("textbox", { name: "Message" }), + ["Summarize findings", "{Enter}"].join(""), + ); + await waitFor(() => + expect(eventSourceMock).toHaveBeenCalledWith("/api/stream"), + ); + unmount(); + + // Then + expect(closeMock).toHaveBeenCalledTimes(1); + }); }); function renderPage( diff --git a/ui/components/lighthouse-v2/chat/lighthouse-v2-chat-page.tsx b/ui/components/lighthouse-v2/chat/lighthouse-v2-chat-page.tsx index dbb2b211b7..dca6f11f3b 100644 --- a/ui/components/lighthouse-v2/chat/lighthouse-v2-chat-page.tsx +++ b/ui/components/lighthouse-v2/chat/lighthouse-v2-chat-page.tsx @@ -280,6 +280,10 @@ export function LighthouseV2ChatPage({ } }; + useMountEffect(() => { + return () => closeStream(); + }); + useMountEffect(() => { if (initialPrompt && !initialPromptSentRef.current) { initialPromptSentRef.current = true;