import { describe, it, expect, vi } from "vitest"; import { renderHook } from "@testing-library/react"; import { QueryClient, QueryClientProvider } from "@tanstack/react-query"; import { createElement, type ReactNode } from "react"; import { useBackupJobs, useBackupRuns, useBackupAlerts } from "../useBackups"; import { useAlertmanagerAlerts, usePrometheusStatus, } from "../useObservability"; vi.mock("../../api/client", () => ({ fetchAlertmanagerAlerts: vi.fn(), fetchAlertmanagerStatus: vi.fn(), fetchPrometheusStatus: vi.fn(), fetchPrometheusTargets: vi.fn(), fetchMonitoringMachines: vi.fn(), })); vi.mock("../../api/backups", () => ({ fetchBackupJobs: vi.fn(), fetchBackupRuns: vi.fn(), fetchBackupAlerts: vi.fn(), fetchBackupDashboard: vi.fn(), fetchBackupJob: vi.fn(), acknowledgeBackupAlert: vi.fn(), })); function createWrapper() { const queryClient = new QueryClient({ defaultOptions: { queries: { retry: false } }, }); return ({ children }: { children: ReactNode }) => createElement(QueryClientProvider, { client: queryClient }, children); } describe("per-instance hook queryKey isolation", () => { it("useBackupJobs produces different keys for different serviceIds", () => { const wrapper = createWrapper(); const { result: a } = renderHook(() => useBackupJobs("svc-a"), { wrapper }); const { result: b } = renderHook(() => useBackupJobs("svc-b"), { wrapper }); expect(a).toBeDefined(); expect(b).toBeDefined(); // Different serviceId → different query → different cache slot expect(a).not.toBe(b); }); it("useBackupJobs with undefined serviceId is stable (same key)", () => { const wrapper = createWrapper(); const { result: a } = renderHook(() => useBackupJobs(), { wrapper }); const { result: b } = renderHook(() => useBackupJobs(), { wrapper }); expect(a).toBeDefined(); expect(b).toBeDefined(); }); it("useBackupRuns includes serviceId in queryKey", () => { const wrapper = createWrapper(); const { result: a } = renderHook( () => useBackupRuns(undefined, undefined, "svc-a"), { wrapper }, ); expect(a).toBeDefined(); }); it("useBackupAlerts includes serviceId in queryKey", () => { const wrapper = createWrapper(); const { result: a } = renderHook( () => useBackupAlerts(undefined, false, undefined, "svc-a"), { wrapper }, ); expect(a).toBeDefined(); }); it("useAlertmanagerAlerts includes serviceId in queryKey", () => { const wrapper = createWrapper(); const { result: a } = renderHook(() => useAlertmanagerAlerts("svc-a"), { wrapper, }); expect(a).toBeDefined(); }); it("usePrometheusStatus includes serviceId in queryKey", () => { const wrapper = createWrapper(); const { result: a } = renderHook(() => usePrometheusStatus("svc-a"), { wrapper, }); expect(a).toBeDefined(); }); });