Files
siftlode/frontend/src/lib/api/adminLogs.dom.test.ts
T
peter 8f6f89832f fix(diagnostics): honest live console after review
- Live stops polling on a failed read and marks the list as possibly
  stale (with Retry), instead of re-raising the error dialog every tick.
- While live, a refetch reads the newest page only, whatever the cache
  holds (a late "Load older", a revisited filter set).
- Copy is disabled and the list dimmed while a filter change loads.
- Dates follow the UI language; the pivot chip uses the shared .chip.
- Tests: query-string wire test, Copy, every facet's skip key.
2026-09-19 03:42:26 +02:00

65 lines
2.2 KiB
TypeScript

// @vitest-environment jsdom
//
// The log console's query strings. The console's DOM tests mock this slice, so nothing else in the
// suite looks at the URL that goes out — and a multi-level group is the case that breaks quietly:
// `levels` must repeat, or FastAPI's list reads only the last one.
import { afterEach, beforeEach, describe, expect, it, vi } from "vitest";
import { adminApi } from "./admin";
const fetchMock = vi.fn();
beforeEach(() => {
fetchMock.mockReset().mockResolvedValue({
ok: true,
status: 200,
headers: new Headers({ "content-type": "application/json" }),
json: async () => ({}),
text: async () => "{}",
});
vi.stubGlobal("fetch", fetchMock);
});
afterEach(() => vi.unstubAllGlobals());
const lastQuery = (): URLSearchParams => {
const calls = fetchMock.mock.calls;
return new URL(String(calls[calls.length - 1]?.[0]), "http://x").searchParams;
};
describe("adminApi log query strings", () => {
it("repeats the list filters and sends every single one it is given", async () => {
await adminApi.adminLogs(
{
levels: ["ERROR", "CRITICAL"],
sources: ["api", "worker"],
user: "none",
event: "sync.rss.failed",
request_id: "req-abcdef12",
job_id: 42,
q: "100% done",
since: "2026-09-19T11:00:00.000Z",
},
"cursor-1",
);
const p = lastQuery();
expect(p.getAll("levels")).toEqual(["ERROR", "CRITICAL"]);
expect(p.getAll("sources")).toEqual(["api", "worker"]);
expect(Object.fromEntries([...p].filter(([k]) => k !== "levels" && k !== "sources"))).toEqual({
user: "none",
event: "sync.rss.failed",
request_id: "req-abcdef12",
job_id: "42",
q: "100% done",
since: "2026-09-19T11:00:00.000Z",
before: "cursor-1",
});
});
it("leaves out what is not set, and the facets carry no cursor", async () => {
await adminApi.adminLogs({ q: "", user: undefined }, null);
expect(String(fetchMock.mock.calls[0]?.[0])).toBe("/api/admin/logs");
await adminApi.adminLogFacets({ levels: ["WARNING"], since: "2026-09-19T11:00:00.000Z" });
expect([...lastQuery().keys()]).toEqual(["levels", "since"]);
});
});