1import { EnvironmentId, type VcsRef } from "@t3tools/contracts";
2import { describe, expect, it, vi } from "vite-plus/test";
3import { page, userEvent } from "vite-plus/test/browser";
4
5const mocks = vi.hoisted(() => ({ resolvedQueries: new Set<string>() }));
6
7const REFS: VcsRef[] = ["develop", "main", "origin/main", "origin/feature/main-nav"].map(
8 (name) => ({ name, current: false, isDefault: false, worktreePath: null }),
9);
10
11// Like the real hook, a query has no refs until the server answers it.
12vi.mock(import("../state/queries"), async (original) => ({
13 ...(await original()),
14 usePaginatedBranches: (target) => {
15 const query = target.query ?? "";
16 const resolved = mocks.resolvedQueries.has(query);
17 const refs = resolved ? REFS.filter((ref) => ref.name.includes(query)) : [];
18 return {
19 data: resolved
20 ? { refs, isRepo: true, hasPrimaryRemote: true, nextCursor: null, totalCount: refs.length }
21 : null,
22 refs,
23 error: null,
24 isPending: !resolved,
25 isFetchingNextPage: false,
26 refresh: () => {},
27 loadNext: () => {},
28 };
29 },
30}));
31
32import "~/index.css";
33import { render } from "../../test/render";
34import { WorktreeBaseBranchPicker } from "./WorktreeBaseBranchPicker";
35
36function setup() {
37 mocks.resolvedQueries = new Set([""]);
38}
39
40describe("WorktreeBaseBranchPicker", () => {
41 it.each([
42 { keys: "{Enter}", selected: "main" },
43 { keys: "{ArrowDown}{Enter}", selected: "origin/main" },
44 ])(
45 "$keys selects $selected when each keystroke's results arrive before the next",
46 async ({ keys, selected }) => {
47 setup();
48 const onValueChange = vi.fn();
49 const picker = () => (
50 <WorktreeBaseBranchPicker
51 environmentId={EnvironmentId.make("primary")}
52 cwd="/repo"
53 value=""
54 onValueChange={onValueChange}
55 startFromOrigin={false}
56 onStartFromOriginChange={() => {}}
57 />
58 );
59 await using screen = await render(picker());
60
61 await userEvent.click(screen.getByRole("combobox"));
62 let query = "";
63 for (const char of "main") {
64 await userEvent.type(page.getByPlaceholder("Search refs..."), char);
65 query += char;
66 mocks.resolvedQueries.add(query);
67 await screen.rerender(picker());
68 }
69
70 await expect
71 .element(page.getByRole("option", { name: "main", exact: true }))
72 .toHaveAttribute("data-highlighted");
73 await userEvent.keyboard(keys);
74 expect(onValueChange).toHaveBeenCalledExactlyOnceWith(selected);
75 },
76 );
77});