import { beforeEach, describe, expect, it, vi } from "vitest"; import { ApiError, apiFetch } from "@/lib/auth/api-client"; import { createHive, fetchHive, fetchHiveAt, fetchHiveHistory, fetchHiveSystems, fetchHiveTemplate, hiveConflictOf, hiveErrorCode, hiveKeys, postHiveChange, } from "./api"; vi.mock("@/lib/auth/api-client", async (importOriginal) => { const original = await importOriginal(); return { ...original, apiFetch: vi.fn() }; }); describe("hive api", () => { beforeEach(() => { vi.mocked(apiFetch).mockReset(); vi.mocked(apiFetch).mockResolvedValue(undefined); }); it("reads systems, setup, template, history and a day", async () => { await fetchHiveSystems(); await fetchHive("c 1"); await fetchHiveTemplate("s1"); await fetchHiveHistory("c1"); await fetchHiveHistory("c1", "abc_-"); await fetchHiveAt("c1", "2026-10-01"); expect(vi.mocked(apiFetch).mock.calls.map((call) => call[0])).toEqual([ "/hive-systems", "/colonies/c%201/hive", "/hive-systems/s1/template", "/colonies/c1/hive/changes", "/colonies/c1/hive/changes?cursor=abc_-", "/colonies/c1/hive/at?day=2026-10-01", ]); }); it("sends the idempotency key on create and change", async () => { const state = { schemaVersion: 1 as const, stack: [] }; await createHive("c1", { systemId: "s", state, occurredOn: "2026-10-01" }, "key-1"); await postHiveChange("c1", { occurredOn: "2026-10-01", source: "CARD", ops: [] }, "key-2"); const [create, change] = vi.mocked(apiFetch).mock.calls; expect(create[0]).toBe("/colonies/c1/hive"); expect(create[1]).toMatchObject({ method: "POST", headers: { "Idempotency-Key": "key-1" } }); expect(change[0]).toBe("/colonies/c1/hive/changes"); expect(change[1]).toMatchObject({ method: "POST", headers: { "Idempotency-Key": "key-2" } }); }); it("has the query keys of the plan", () => { expect(hiveKeys.systems).toEqual(["hive-systems"]); expect(hiveKeys.detail("c1")).toEqual(["colonies", "c1", "hive"]); expect(hiveKeys.history("c1")).toEqual(["colonies", "c1", "hive", "history"]); }); it("extracts the HIVE_CONFLICT body and error codes", () => { const body = { code: "HIVE_CONFLICT", opIndex: 1, reason: "RULE_ROOF_TOP: x", current: { version: 3, state: {} } }; expect(hiveConflictOf(new ApiError(409, "Conflict", body))).toEqual(body); expect(hiveConflictOf(new ApiError(409, "Conflict", { code: "HIVE_EXISTS" }))).toBeNull(); expect(hiveConflictOf(new Error("x"))).toBeNull(); expect(hiveErrorCode(new ApiError(404, "nf", { code: "HIVE_NOT_FOUND" }))).toBe("HIVE_NOT_FOUND"); expect(hiveErrorCode(new ApiError(500, "x"))).toBeNull(); }); });