Files
kandev/apps/web/lib/state/slices/workspace/workspace-slice.test.ts
T

79 lines
3.4 KiB
TypeScript

import { describe, expect, it } from "vitest";
import { create } from "zustand";
import { immer } from "zustand/middleware/immer";
import { createWorkspaceSlice } from "./workspace-slice";
import type { WorkspaceSlice } from "./types";
import type { Branch } from "@/lib/types/http";
function makeStore() {
return create<WorkspaceSlice>()(
// eslint-disable-next-line @typescript-eslint/no-explicit-any
immer((...a) => ({ ...(createWorkspaceSlice as any)(...a) })),
);
}
const REPO = "repo-1";
const BRANCHES: Branch[] = [{ name: "main", type: "local" }];
const FETCHED_AT = "2026-04-30T10:00:00Z";
describe("setRepositoryBranches", () => {
it("stores branches and marks loaded without meta", () => {
const s = makeStore();
s.getState().setRepositoryBranches(REPO, BRANCHES);
const state = s.getState().repositoryBranches;
expect(state.itemsByRepositoryId[REPO]).toEqual(BRANCHES);
expect(state.loadedByRepositoryId[REPO]).toBe(true);
expect(state.loadingByRepositoryId[REPO]).toBe(false);
expect(state.fetchedAtByRepositoryId[REPO]).toBeUndefined();
expect(state.fetchErrorByRepositoryId[REPO]).toBeUndefined();
});
it("records fetchedAt + clears prior fetchError on success", () => {
const s = makeStore();
s.getState().setRepositoryBranches(REPO, BRANCHES, { fetchError: "boom" });
expect(s.getState().repositoryBranches.fetchErrorByRepositoryId[REPO]).toBe("boom");
s.getState().setRepositoryBranches(REPO, BRANCHES, { fetchedAt: FETCHED_AT });
const state = s.getState().repositoryBranches;
expect(state.fetchedAtByRepositoryId[REPO]).toBe(FETCHED_AT);
expect(state.fetchErrorByRepositoryId[REPO]).toBeUndefined();
});
it("preserves the prior fetchedAt when meta omits it", () => {
const s = makeStore();
s.getState().setRepositoryBranches(REPO, BRANCHES, { fetchedAt: FETCHED_AT });
s.getState().setRepositoryBranches(REPO, BRANCHES);
expect(s.getState().repositoryBranches.fetchedAtByRepositoryId[REPO]).toBe(FETCHED_AT);
});
});
describe("setRepositoryBranchesLoading", () => {
it("toggles only the loading flag", () => {
const s = makeStore();
s.getState().setRepositoryBranchesLoading(REPO, true);
expect(s.getState().repositoryBranches.loadingByRepositoryId[REPO]).toBe(true);
s.getState().setRepositoryBranchesLoading(REPO, false);
expect(s.getState().repositoryBranches.loadingByRepositoryId[REPO]).toBe(false);
});
});
describe("setRepositoryBranchesFetchError", () => {
it("records the error without touching cached branches", () => {
const s = makeStore();
s.getState().setRepositoryBranches(REPO, BRANCHES, { fetchedAt: FETCHED_AT });
s.getState().setRepositoryBranchesFetchError(REPO, "network down");
const state = s.getState().repositoryBranches;
expect(state.fetchErrorByRepositoryId[REPO]).toBe("network down");
// Cached branches and fetchedAt are preserved so the dropdown stays usable
// (stale-while-revalidate semantics).
expect(state.itemsByRepositoryId[REPO]).toEqual(BRANCHES);
expect(state.fetchedAtByRepositoryId[REPO]).toBe(FETCHED_AT);
});
it("clears the error when called with undefined", () => {
const s = makeStore();
s.getState().setRepositoryBranchesFetchError(REPO, "boom");
s.getState().setRepositoryBranchesFetchError(REPO, undefined);
expect(s.getState().repositoryBranches.fetchErrorByRepositoryId[REPO]).toBeUndefined();
});
});