From c6a47525e74c674e621d479cc4e8e7c00b69eba7 Mon Sep 17 00:00:00 2001 From: xishell <26227374+xishell@users.noreply.github.com> Date: Tue, 5 May 2026 10:58:17 +0200 Subject: [PATCH 1/2] test(frontend): add vitest sutie with coverage parity to backend --- frontend/.gitignore | 3 + frontend/README.md | 39 ++++- frontend/src/__tests__/App.test.tsx | 22 +++ frontend/src/__tests__/HarborMap.test.tsx | 83 +++++++++ .../__tests__/ActivityLogPanel.test.tsx | 132 +++++++++++++++ .../components/__tests__/AuthDialog.test.tsx | 150 +++++++++++++++++ .../__tests__/BerthDetailPanel.test.tsx | 116 +++++++++++++ .../__tests__/DashboardLayoutContext.test.tsx | 90 ++++++++++ .../src/components/__tests__/Footer.test.tsx | 13 ++ .../__tests__/HarborMasterOverview.test.tsx | 64 +++++++ .../__tests__/HarborOverview.test.tsx | 90 ++++++++++ .../src/components/__tests__/Header.test.tsx | 88 ++++++++++ .../components/__tests__/MainLayout.test.tsx | 88 ++++++++++ .../components/__tests__/MapLegend.test.tsx | 25 +++ .../components/__tests__/NorthArrow.test.tsx | 10 ++ .../__tests__/NotificationSettings.test.tsx | 80 +++++++++ .../components/__tests__/SideMenu.test.tsx | 65 +++++++ .../components/__tests__/sharedUi.test.tsx | 94 +++++++++++ .../hooks/__tests__/useBerthDetail.test.ts | 75 +++++++++ .../hooks/__tests__/useBerthsStream.test.ts | 85 ++++++++++ frontend/src/hooks/__tests__/useNow.test.ts | 48 ++++++ frontend/src/lib/__tests__/freshness.test.ts | 44 +++++ frontend/src/lib/__tests__/marinas.test.ts | 26 +++ frontend/src/lib/__tests__/utils.test.ts | 24 +++ .../src/pages/__tests__/Dashboard.test.tsx | 35 ++++ .../src/pages/__tests__/Settings.test.tsx | 158 ++++++++++++++++++ frontend/src/test/Dashboard.test.tsx | 18 -- frontend/src/test/eventSource.ts | 70 ++++++++ frontend/src/test/helpers.tsx | 154 +++++++++++++++++ frontend/src/test/setup.ts | 67 +++++++- frontend/vitest.config.ts | 24 +++ 31 files changed, 2051 insertions(+), 29 deletions(-) create mode 100644 frontend/src/__tests__/App.test.tsx create mode 100644 frontend/src/__tests__/HarborMap.test.tsx create mode 100644 frontend/src/components/__tests__/ActivityLogPanel.test.tsx create mode 100644 frontend/src/components/__tests__/AuthDialog.test.tsx create mode 100644 frontend/src/components/__tests__/BerthDetailPanel.test.tsx create mode 100644 frontend/src/components/__tests__/DashboardLayoutContext.test.tsx create mode 100644 frontend/src/components/__tests__/Footer.test.tsx create mode 100644 frontend/src/components/__tests__/HarborMasterOverview.test.tsx create mode 100644 frontend/src/components/__tests__/HarborOverview.test.tsx create mode 100644 frontend/src/components/__tests__/Header.test.tsx create mode 100644 frontend/src/components/__tests__/MainLayout.test.tsx create mode 100644 frontend/src/components/__tests__/MapLegend.test.tsx create mode 100644 frontend/src/components/__tests__/NorthArrow.test.tsx create mode 100644 frontend/src/components/__tests__/NotificationSettings.test.tsx create mode 100644 frontend/src/components/__tests__/SideMenu.test.tsx create mode 100644 frontend/src/components/__tests__/sharedUi.test.tsx create mode 100644 frontend/src/hooks/__tests__/useBerthDetail.test.ts create mode 100644 frontend/src/hooks/__tests__/useBerthsStream.test.ts create mode 100644 frontend/src/hooks/__tests__/useNow.test.ts create mode 100644 frontend/src/lib/__tests__/freshness.test.ts create mode 100644 frontend/src/lib/__tests__/marinas.test.ts create mode 100644 frontend/src/lib/__tests__/utils.test.ts create mode 100644 frontend/src/pages/__tests__/Dashboard.test.tsx create mode 100644 frontend/src/pages/__tests__/Settings.test.tsx delete mode 100644 frontend/src/test/Dashboard.test.tsx create mode 100644 frontend/src/test/eventSource.ts create mode 100644 frontend/src/test/helpers.tsx diff --git a/frontend/.gitignore b/frontend/.gitignore index a547bf3..422b0da 100644 --- a/frontend/.gitignore +++ b/frontend/.gitignore @@ -12,6 +12,9 @@ dist dist-ssr *.local +coverage +junit.xml + # Editor directories and files .vscode/* !.vscode/extensions.json diff --git a/frontend/README.md b/frontend/README.md index dd21339..a0f0509 100644 --- a/frontend/README.md +++ b/frontend/README.md @@ -46,14 +46,47 @@ Starts a Prism mock server from the OpenAPI spec and proxies to it automatically ## Frontend Tests -Frontend smoke tests use Vitest, React Testing Library, and Prism. +Frontend tests use Vitest, React Testing Library, and stubbed `fetch`/`EventSource`. +The structure mirrors the backend test suite: shared fixtures and factories live +alongside the test files and exercise the same flows the running app does. -The test command starts a Prism mock API from the OpenAPI specification at `docs/api/openapi.yml`, then runs the frontend test suite. +| Layer | Backend equivalent | Frontend equivalent | +| ------------ | --------------------------------- | --------------------------------------------------------- | +| Test runner | `pytest` | `vitest run` | +| HTTP harness | `httpx.AsyncClient` over ASGI app | `mockFetch` helper + `@testing-library/react` | +| Streams | aiomqtt test stubs | `FakeEventSource` mock with `emit`/`emitOpen`/`emitError` | +| Fixtures | `tests/conftest.py` | `src/test/setup.ts`, `src/test/helpers.tsx` | +| Factories | `tests/_helpers.py` | `makeBerth`, `makeUser`, `makeEvent`, `buildAuthContext` | +| Coverage | `pytest-cov` (`fail_under = 80`) | `@vitest/coverage-v8` (`thresholds.lines = 80`) | + +Tests live next to the source they exercise: + +``` +src/ + __tests__/ app + HarborMap entry tests + components/__tests__/ UI panels + layout chrome + hooks/__tests__/ data hooks (fake timers + mocked fetch/EventSource) + lib/__tests__/ pure helpers + pages/__tests__/ page components (Dashboard, Settings) + test/ shared setup, factories, EventSource mock +``` ### Run tests locally ```bash cd frontend bun install -bun run test +bun run test # full suite (boots Prism alongside vitest, mirrors CI) +bun run test:watch # vitest watch mode, no Prism +bun run test:cov # full suite with v8 coverage report ``` + +### Writing new tests + +- Reach for `renderWithAuthLayout` whenever a component uses `useOutletContext`. +- Use `mockFetch((url, init) => ...)` to replace the network layer; combine with + `jsonResponse` / `errorResponse` from `src/test/helpers.tsx`. +- For SSE-driven hooks, drive the `FakeEventSource` via `getLastEventSource()` + and call `emit("berth.update", payload)`. +- Keep factory builders in sync with `src/api-types.ts` — when a schema changes, + the type checker catches stale fixtures. diff --git a/frontend/src/__tests__/App.test.tsx b/frontend/src/__tests__/App.test.tsx new file mode 100644 index 0000000..b64d9b9 --- /dev/null +++ b/frontend/src/__tests__/App.test.tsx @@ -0,0 +1,22 @@ +import { render, screen } from "@testing-library/react"; +import { describe, expect, test, vi } from "vitest"; +import { App } from "../App"; + +vi.mock("../components/layout/MainLayout", () => ({ + MainLayout: () =>
, +})); + +describe("App", () => { + test("renders MainLayout for a marina route", async () => { + window.history.pushState({}, "", "/saltsjobaden"); + render(
+ const freeBlock = screen.getByText("Free").closest("div")?.parentElement;
+ expect(freeBlock?.textContent).toContain("1");
+ expect(freeBlock?.textContent).toContain("2");
+ });
+
+ test("shows static system status rows", () => {
+ render(