1import { describe, expect, it } from "vite-plus/test";
2import {
3 initialWorkspaceTabsState,
4 workspaceTabsReducer,
5 workspaceToolbarHeight,
6} from "./workspace-tabs-state";
7
8describe("workspace root navigation", () => {
9 it("retains separate queries and positions across tabs, and cancels only the current search", () => {
10 let state = initialWorkspaceTabsState();
11 state = workspaceTabsReducer(state, { type: "scroll", tab: "threads", offset: 640 });
12 state = workspaceTabsReducer(state, { type: "search" });
13 state = workspaceTabsReducer(state, { type: "query", query: "keyboard" });
14 state = workspaceTabsReducer(state, { type: "scroll", tab: "threads", offset: 160 });
15 state = workspaceTabsReducer(state, { type: "expand" });
16 state = workspaceTabsReducer(state, { type: "select", tab: "pullRequests" });
17 expect(state.tabs.pullRequests.query).toBe("");
18 state = workspaceTabsReducer(state, { type: "scroll", tab: "pullRequests", offset: 240 });
19 state = workspaceTabsReducer(state, { type: "search" });
20 state = workspaceTabsReducer(state, { type: "query", query: "navigation" });
21 state = workspaceTabsReducer(state, { type: "select", tab: "threads" });
22 expect(state.tabs.threads).toMatchObject({
23 query: "keyboard",
24 scrollOffset: 160,
25 searchMode: "expanded",
26 });
27 state = workspaceTabsReducer(state, { type: "cancel" });
28 expect(state.tabs.threads).toMatchObject({
29 query: "",
30 scrollOffset: 640,
31 searchMode: "resting",
32 });
33 expect(state.tabs.pullRequests).toMatchObject({
34 query: "navigation",
35 scrollOffset: 240,
36 searchMode: "active",
37 });
38 });
39
40 it("clear keeps search active without losing the position cancel restores", () => {
41 let state = initialWorkspaceTabsState();
42 state = workspaceTabsReducer(state, { type: "scroll", tab: "threads", offset: 500 });
43 state = workspaceTabsReducer(state, { type: "search" });
44 state = workspaceTabsReducer(state, { type: "query", query: "diff" });
45 state = workspaceTabsReducer(state, { type: "scroll", tab: "threads", offset: 80 });
46 state = workspaceTabsReducer(state, { type: "query", query: "" });
47 state = workspaceTabsReducer(state, { type: "search" });
48 expect(state.tabs.threads).toMatchObject({
49 query: "",
50 searchMode: "active",
51 searchEntryOffset: 500,
52 });
53 expect(workspaceTabsReducer(state, { type: "cancel" }).tabs.threads.scrollOffset).toBe(500);
54 });
55
56 it("reserves space for both Android toolbar rows when expanded", () => {
57 expect(workspaceToolbarHeight("expanded")).toBeGreaterThan(
58 workspaceToolbarHeight("resting") * 2,
59 );
60 });
61
62 it("a late native blur cannot reopen a cancelled search", () => {
63 let state = workspaceTabsReducer(initialWorkspaceTabsState(), { type: "search" });
64 state = workspaceTabsReducer(state, { type: "cancel" });
65 expect(workspaceTabsReducer(state, { type: "expand" })).toBe(state);
66 });
67
68 it("a blur from the previous native tab cannot open search in the selected tab", () => {
69 let state = workspaceTabsReducer(initialWorkspaceTabsState(), { type: "search" });
70 state = workspaceTabsReducer(state, { type: "query", query: "keyboard" });
71 state = workspaceTabsReducer(state, { type: "select", tab: "pullRequests" });
72 state = workspaceTabsReducer(state, { type: "expand", tab: "threads" });
73 expect(state.tabs.threads).toMatchObject({ query: "keyboard", searchMode: "expanded" });
74 expect(state.tabs.pullRequests.searchMode).toBe("resting");
75 expect(workspaceTabsReducer(state, { type: "select", tab: "pullRequests" })).toBe(state);
76 });
77});