import { render, screen } from "@testing-library/react"; import userEvent from "@testing-library/user-event"; import { beforeEach, vi } from "vitest"; import { useSessionStore } from "../store/sessionStore"; import { ModelActivityPanel } from "./ModelActivityPanel"; beforeEach(() => useSessionStore.getState().resetSession()); test("renders the streamed model activity", () => { useSessionStore.getState().applyEvent({ type: "activity_delta", text: "Promoting table dim_patient." }); render(); expect(screen.getByText(/Promoting table dim_patient/)).toBeInTheDocument(); }); test("does not treat final assistant text as model reasoning", () => { useSessionStore.getState().applyEvent({ type: "text_delta", text: "Final answer" }); render(); expect(screen.queryByText("Final answer")).not.toBeInTheDocument(); expect(screen.getByText("No activity yet.")).toBeInTheDocument(); }); test("renders markdown emphasis instead of literal asterisks", () => { useSessionStore.getState().applyEvent({ type: "activity_delta", text: "Chiarimento su **fibrillazione atriale**." }); render(); expect(screen.getByText("fibrillazione atriale").tagName).toBe("STRONG"); }); test("close button calls onClose", async () => { const onClose = vi.fn(); render(); await userEvent.click(screen.getByRole("button", { name: /close/i })); expect(onClose).toHaveBeenCalled(); }); const EIGHT = ["para-01", "para-02", "para-03", "para-04", "para-05", "para-06", "para-07", "para-08"].join("\n\n"); test("collapsed shows only the last 5 paragraphs of the model-stream tail", () => { useSessionStore.getState().applyEvent({ type: "activity_delta", text: EIGHT }); render(); expect(screen.getByText("para-08")).toBeInTheDocument(); expect(screen.getByText("para-04")).toBeInTheDocument(); expect(screen.queryByText("para-03")).not.toBeInTheDocument(); expect(screen.queryByText("para-01")).not.toBeInTheDocument(); }); test("expanding reveals the full stream", async () => { useSessionStore.getState().applyEvent({ type: "activity_delta", text: EIGHT }); render(); await userEvent.click(screen.getByRole("button", { name: /show more/i })); expect(screen.getByText("para-01")).toBeInTheDocument(); }); test("paragraphs stay separated as distinct blocks", () => { useSessionStore .getState() .applyEvent({ type: "activity_delta", text: "Primo paragrafo.\n\nSecondo paragrafo." }); render(); const first = screen.getByText("Primo paragrafo."); const second = screen.getByText("Secondo paragrafo."); expect(first.tagName).toBe("P"); expect(second.tagName).toBe("P"); expect(first).not.toBe(second); }); test("separates activity updates concatenated after sentence punctuation", () => { useSessionStore.getState().applyEvent({ type: "activity_delta", text: "Ambiguità principale risolta.Finestra temporale risolta.Terza ambiguità risolta.", }); render(); const first = screen.getByText("Ambiguità principale risolta."); const second = screen.getByText("Finestra temporale risolta."); const third = screen.getByText("Terza ambiguità risolta."); expect(first.tagName).toBe("P"); expect(second.tagName).toBe("P"); expect(third.tagName).toBe("P"); });