import { beforeEach, describe, expect, it, vi } from "vitest"; import type { StateStorage } from "zustand/middleware"; import { createSidebarViewStorage, migrateSidebarViewState, useSidebarViewStore, } from "./sidebar-view-store"; vi.mock("@react-native-async-storage/async-storage", () => ({ default: { getItem: vi.fn().mockResolvedValue(null), setItem: vi.fn().mockResolvedValue(undefined), removeItem: vi.fn().mockResolvedValue(undefined), }, })); interface MemoryStorage extends StateStorage> { reads: string[]; } function createMemoryStorage(entries: Record): MemoryStorage { const reads: string[] = []; return { reads, getItem: async (name) => { reads.push(name); return entries[name] ?? null; }, setItem: async (name, value) => { entries[name] = value; }, removeItem: async (name) => { entries[name] = null; }, }; } describe("sidebar view store", () => { beforeEach(() => { useSidebarViewStore.setState({ groupMode: "project", hostFilter: null, }); }); it("keeps a host filter that still points at an available host", () => { useSidebarViewStore.getState().setHostFilter("host-a"); useSidebarViewStore.getState().reconcileHostFilter(["host-a", "host-b"]); expect(useSidebarViewStore.getState().hostFilter).toBe("host-a"); }); it("clears a host filter after that host is removed", () => { useSidebarViewStore.getState().setHostFilter("removed-host"); useSidebarViewStore.getState().reconcileHostFilter(["host-a"]); expect(useSidebarViewStore.getState().hostFilter).toBeNull(); }); it("migrates legacy per-host group modes to the new global mode", () => { expect( migrateSidebarViewState({ groupModeByServerId: { "host-a": "project", "host-b": "status", }, }), ).toEqual({ groupMode: "status", hostFilter: null, }); }); it("keeps current persisted sidebar view state during version migration", () => { expect( migrateSidebarViewState({ groupMode: "status", hostFilter: "host-a", }), ).toEqual({ groupMode: "status", hostFilter: "host-a", }); }); it("falls back to the legacy storage key when the new key is empty", async () => { const storage = createMemoryStorage({ "sidebar-view": null, "sidebar-group-mode": JSON.stringify({ state: { groupModeByServerId: { "host-a": "status" } }, version: 0, }), }); const value = await createSidebarViewStorage(storage).getItem("sidebar-view"); expect(value).toBe( JSON.stringify({ state: { groupModeByServerId: { "host-a": "status" } }, version: 0, }), ); expect(storage.reads).toEqual(["sidebar-view", "sidebar-group-mode"]); }); it("uses the new storage key without reading the legacy key when current state exists", async () => { const storage = createMemoryStorage({ "sidebar-view": JSON.stringify({ state: { groupMode: "project", hostFilter: "host-a" }, version: 1, }), "sidebar-group-mode": JSON.stringify({ state: { groupModeByServerId: { "host-b": "status" } }, version: 0, }), }); const value = await createSidebarViewStorage(storage).getItem("sidebar-view"); expect(value).toBe( JSON.stringify({ state: { groupMode: "project", hostFilter: "host-a" }, version: 1, }), ); expect(storage.reads).toEqual(["sidebar-view"]); }); });