milestone 19: hygiene sweep - dead ecs surface, single-source constants, tls classification, frontend state hazards, docker smoke network fix
CI / test (push) Successful in 1m46s
CI / test-aarch64 (push) Successful in 5m30s
CI / frontend (push) Successful in 46s
CI / cross (push) Successful in 8m12s
CI / docker (push) Successful in 3m46s

This commit is contained in:
2026-08-07 20:39:27 +02:00
parent 6f67940995
commit 6c507992e4
59 changed files with 1020 additions and 382 deletions
@@ -0,0 +1,29 @@
import { fireEvent, render, screen, waitFor } from "@testing-library/react";
import { ApiError } from "@/lib/api";
import BlocklistForm, { swallowMutationError } from "./BlocklistForm";
test("swallowMutationError drops an ApiError and rethrows anything else", () => {
expect(() => swallowMutationError(new ApiError(400, "bad url"))).not.toThrow();
expect(() => swallowMutationError(new TypeError("cannot read x of undefined"))).toThrow(TypeError);
expect(() => swallowMutationError("not an error at all")).toThrow();
});
test("a rejected submit leaves the typed values in place; a resolved one clears them", async () => {
const rejecting = vi.fn(() => Promise.reject(new ApiError(400, "bad url")));
const { rerender } = render(<BlocklistForm busy={false} error={null} onSubmit={rejecting} onCancel={undefined} />);
const url = screen.getByLabelText("URL") as HTMLInputElement;
const name = screen.getByLabelText("Name") as HTMLInputElement;
fireEvent.change(url, { target: { value: "https://example.com/list.txt" } });
fireEvent.change(name, { target: { value: "Example" } });
fireEvent.click(screen.getByRole("button", { name: "Add source" }));
await waitFor(() => expect(rejecting).toHaveBeenCalledTimes(1));
expect(url.value).toBe("https://example.com/list.txt");
expect(name.value).toBe("Example");
const resolving = vi.fn(() => Promise.resolve());
rerender(<BlocklistForm busy={false} error={null} onSubmit={resolving} onCancel={undefined} />);
fireEvent.click(screen.getByRole("button", { name: "Add source" }));
await waitFor(() => expect(url.value).toBe(""));
expect(name.value).toBe("");
});