Skip to content
Source
Sign inSign up
Open History to see the last commit

ChatView.modelPick.browser.test.tsx

67 lines2.7 KB

1import { createMemoryHistory } from "@tanstack/react-router";
2import { DEFAULT_CLIENT_SETTINGS } from "@t3tools/contracts/settings";
3import type * as Context from "effect/Context";
4import { expect, it, vi } from "vite-plus/test";
5import { page } from "vite-plus/test/browser";
6​
7import { AppRoot } from "~/AppRoot";
8// The route loads ChatView lazily, and its first transform (React Compiler over ~4k lines)
9// takes 6-11s; importing it here keeps that out of the test's timeout.
10import "~/components/ChatView";
11import { __setClientSettingsForTests } from "~/hooks/useSettings";
12import { getRouter } from "~/router";
13import {
14 ENVIRONMENT_ID,
15 dispatchedCommands,
16 installFakeEnvironment,
17 threadWithHistory,
18 type FakeDriver,
19} from "../../test/fakeEnvironment";
20import { render } from "../../test/render";
21​
22// The socket is the only fake layer; see test/appScenarios.renders.tsx.
23vi.mock("../../../../packages/client-runtime/src/connection/driver.ts", async (importOriginal) => {
24 const [actual, { fakeDriver }, Layer] = await Promise.all([
25 importOriginal<{ readonly ConnectionDriver: Context.Key<unknown, FakeDriver> }>(),
26 import("../../test/fakeEnvironment"),
27 import("effect/Layer"),
28 ]);
29 return { ...actual, layer: Layer.succeed(actual.ConnectionDriver, fakeDriver) };
30});
31​
32vi.mock(import("~/rpc/requestLatencyState"), async (original) => ({
33 ...(await original()),
34 trackRpcRequestSent: () => {},
35}));
36​
37// Its own file: the app's shell subscription outlives a test, and it must list this thread.
38it("a model picked for an existing thread reaches the server before any message is sent", async () => {
39 const thread = threadWithHistory("thread-model-pick", 1);
40 using _environment = installFakeEnvironment([thread], { acceptCommands: true });
41 __setClientSettingsForTests({
42 ...DEFAULT_CLIENT_SETTINGS,
43 onboardingCompletedAt: "2026-01-01T00:00:00.000Z",
44 });
45 const router = getRouter(
46 createMemoryHistory({ initialEntries: [`/${ENVIRONMENT_ID}/${thread.id}`] }),
47 );
48 await router.load();
49 await using _app = await render(<AppRoot router={router} />, {
50 // AppRoot brings its own router.
51 router: false,
52 });
53 await expect.element(page.getByText("Answer 0 for thread-model-pick.")).toBeVisible();
54​
55 await page.getByRole("button", { name: "GPT-5.4", exact: true }).click();
56 await page.getByRole("option", { name: /GPT-5\.5/ }).click();
57 await vi.waitFor(() =>
58 expect(
59 dispatchedCommands().filter((command) => command.type === "thread.model-selection.set"),
60 ).toEqual([
61 expect.objectContaining({
62 threadId: thread.id,
63 modelSelection: expect.objectContaining({ instanceId: "codex", model: "gpt-5.5" }),
64 }),
65 ]),
66 );
67});