140 lines
4.4 KiB
TypeScript
140 lines
4.4 KiB
TypeScript
import { beforeEach, describe, expect, it, vi } from "vitest";
|
|
|
|
vi.mock("@react-native-async-storage/async-storage", () => {
|
|
const storage = new Map<string, string>();
|
|
return {
|
|
default: {
|
|
getItem: vi.fn(async (key: string) => storage.get(key) ?? null),
|
|
setItem: vi.fn(async (key: string, value: string) => {
|
|
storage.set(key, value);
|
|
}),
|
|
removeItem: vi.fn(async (key: string) => {
|
|
storage.delete(key);
|
|
}),
|
|
},
|
|
};
|
|
});
|
|
|
|
const { replaceRoute } = vi.hoisted(() => ({
|
|
replaceRoute: vi.fn(),
|
|
}));
|
|
|
|
vi.mock("expo-router", () => ({
|
|
router: {
|
|
replace: replaceRoute,
|
|
},
|
|
}));
|
|
|
|
import { openProjectDirectly } from "@/hooks/use-open-project";
|
|
import { useSessionStore } from "@/stores/session-store";
|
|
import {
|
|
buildWorkspaceTabPersistenceKey,
|
|
collectAllTabs,
|
|
useWorkspaceLayoutStore,
|
|
} from "@/stores/workspace-layout-store";
|
|
|
|
const SERVER_ID = "server-1";
|
|
const WORKSPACE_ID = "/repo/project";
|
|
|
|
describe("openProjectDirectly", () => {
|
|
beforeEach(() => {
|
|
replaceRoute.mockReset();
|
|
useSessionStore.setState({
|
|
sessions: {},
|
|
});
|
|
useSessionStore.getState().initializeSession(SERVER_ID, {} as never);
|
|
useWorkspaceLayoutStore.setState({
|
|
layoutByWorkspace: {},
|
|
splitSizesByWorkspace: {},
|
|
pinnedAgentIdsByWorkspace: {},
|
|
});
|
|
vi.restoreAllMocks();
|
|
});
|
|
|
|
it("opens the workspace directly, marks workspaces hydrated, and seeds a launcher tab", async () => {
|
|
vi.spyOn(globalThis.crypto, "randomUUID").mockReturnValue(
|
|
"11111111-1111-1111-1111-111111111111",
|
|
);
|
|
|
|
const result = await openProjectDirectly({
|
|
serverId: SERVER_ID,
|
|
projectPath: WORKSPACE_ID,
|
|
isConnected: true,
|
|
client: {
|
|
openProject: vi.fn(async () => ({
|
|
requestId: "request-1",
|
|
error: null,
|
|
workspace: {
|
|
id: 1,
|
|
projectId: 1,
|
|
projectDisplayName: "project",
|
|
projectRootPath: WORKSPACE_ID,
|
|
workspaceDirectory: WORKSPACE_ID,
|
|
projectKind: "git" as const,
|
|
workspaceKind: "checkout" as const,
|
|
name: "project",
|
|
status: "done" as const,
|
|
activityAt: null,
|
|
diffStat: null,
|
|
},
|
|
})),
|
|
},
|
|
mergeWorkspaces: useSessionStore.getState().mergeWorkspaces,
|
|
setHasHydratedWorkspaces: useSessionStore.getState().setHasHydratedWorkspaces,
|
|
openLauncherTab: useWorkspaceLayoutStore.getState().openLauncherTab,
|
|
replaceRoute,
|
|
});
|
|
|
|
expect(result).toBe(true);
|
|
expect(useSessionStore.getState().sessions[SERVER_ID]?.hasHydratedWorkspaces).toBe(true);
|
|
expect(Array.from(useSessionStore.getState().sessions[SERVER_ID]?.workspaces.values() ?? [])).toEqual([
|
|
expect.objectContaining({
|
|
id: "1",
|
|
projectId: "1",
|
|
projectRootPath: WORKSPACE_ID,
|
|
workspaceDirectory: WORKSPACE_ID,
|
|
}),
|
|
]);
|
|
|
|
const workspaceKey = buildWorkspaceTabPersistenceKey({
|
|
serverId: SERVER_ID,
|
|
workspaceId: "1",
|
|
});
|
|
expect(workspaceKey).toBeTruthy();
|
|
const layout = useWorkspaceLayoutStore.getState().layoutByWorkspace[workspaceKey as string];
|
|
expect(layout.root.kind).toBe("pane");
|
|
const tabs = collectAllTabs(layout.root);
|
|
expect(tabs).toHaveLength(1);
|
|
expect(tabs[0]?.target).toEqual({
|
|
kind: "launcher",
|
|
launcherId: "11111111-1111-1111-1111-111111111111",
|
|
});
|
|
expect(replaceRoute).toHaveBeenCalledWith("/h/server-1/workspace/MQ");
|
|
});
|
|
|
|
it("does not navigate or seed tabs when openProject fails", async () => {
|
|
const result = await openProjectDirectly({
|
|
serverId: SERVER_ID,
|
|
projectPath: WORKSPACE_ID,
|
|
isConnected: true,
|
|
client: {
|
|
openProject: vi.fn(async () => ({
|
|
requestId: "request-2",
|
|
error: "Failed to open project",
|
|
workspace: null,
|
|
})),
|
|
},
|
|
mergeWorkspaces: useSessionStore.getState().mergeWorkspaces,
|
|
setHasHydratedWorkspaces: useSessionStore.getState().setHasHydratedWorkspaces,
|
|
openLauncherTab: useWorkspaceLayoutStore.getState().openLauncherTab,
|
|
replaceRoute,
|
|
});
|
|
|
|
expect(result).toBe(false);
|
|
expect(useSessionStore.getState().sessions[SERVER_ID]?.hasHydratedWorkspaces).toBe(false);
|
|
expect(useSessionStore.getState().sessions[SERVER_ID]?.workspaces.size).toBe(0);
|
|
expect(useWorkspaceLayoutStore.getState().layoutByWorkspace).toEqual({});
|
|
expect(replaceRoute).not.toHaveBeenCalled();
|
|
});
|
|
});
|