milestone 30: overview as a dashboard, explicit health contract, period aggregations

This commit is contained in:
2026-08-22 16:45:15 +02:00
parent 0e83477d80
commit 623667e475
89 changed files with 7222 additions and 4239 deletions
@@ -1,4 +1,4 @@
import { render, screen, waitFor, within } from "@testing-library/react";
import { cleanup, render, screen, waitFor, within } from "@testing-library/react";
import { QueryClientProvider } from "@tanstack/react-query";
import { RouterProvider, createMemoryHistory } from "@tanstack/react-router";
import { AuthProvider } from "@/auth/store";
@@ -6,6 +6,7 @@ import { createQueryClient } from "@/lib/queryClient";
import { createAppRouter } from "@/routes";
import type { QueryDetail } from "@/lib/types";
import { provenance } from "@/features/queries/provenanceFixture";
import { health } from "@/lib/healthFixture";
function detail(id: number, sections: Parameters<typeof provenance>[0] = {}): QueryDetail {
return { id, ...provenance(sections) };
@@ -16,6 +17,7 @@ let responses: Record<string, unknown>;
beforeEach(() => {
responses = {
"/api/version": { version: "0.0.0-test", git_commit: "0000000", zig_version: "0.16.0", uptime_seconds: 1 },
"/api/health": health(),
};
vi.stubGlobal(
"fetch",
@@ -310,3 +312,43 @@ test("a row retention has pruned explains the 404 and keeps the way back to the
domain: "gone",
});
});
/**
* The related-actions region of a query detail. Scoped on purpose: the sidebar
* carries a Pause of its own, and this is the one that answers "this query was
* blocked and should not have been".
*/
function related(): HTMLElement {
return screen.getByRole("region", { name: "Related" });
}
test("a blocked query's Related offers Pause; an allowed one has nothing to pause about", async () => {
responses["/api/queries/50"] = detail(50, {
policy: { action: "block", reason: "blocklist_domain", matched: "ads.example" },
route: { kind: "blocked", upstream: "" },
});
renderDetail(50);
await screen.findByRole("heading", { name: "example.com" });
await waitFor(() => expect(within(related()).getByRole("button", { name: "Pause" })).toBeTruthy());
cleanup();
responses["/api/queries/51"] = detail(51, { policy: { action: "allow", reason: "no_match", matched: "" } });
renderDetail(51);
await screen.findByRole("heading", { name: "example.com" });
expect(within(related()).queryByRole("button", { name: "Pause" })).toBeNull();
});
test("the Pause action stays away while protection is unavailable", async () => {
responses["/api/health"] = health({ protection: { state: "unavailable", until: null } });
responses["/api/queries/52"] = detail(52, {
policy: { action: "block", reason: "blocklist_domain", matched: "ads.example" },
route: { kind: "blocked", upstream: "" },
});
renderDetail(52);
await screen.findByRole("heading", { name: "example.com" });
await waitFor(() => expect(screen.getByText("Diagnostics around this query")).toBeTruthy());
expect(within(related()).queryByRole("button", { name: "Pause" })).toBeNull();
});