feat(per-instance-hook-scoping): scope observability + backup hooks by instance

This commit is contained in:
Developer
2026-07-09 23:54:31 +00:00
parent ad61d92b32
commit 3bc7ce5269
12 changed files with 268 additions and 73 deletions
@@ -0,0 +1,85 @@
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();
});
});