Backend (Go): - Expanded integration_test.go: health, auth middleware (expired/invalid/wrong-secret JWT), tenant CRUD, case CRUD (create/list/get/update/delete + filters + validation), deadline CRUD (create/list/update/complete/delete), appointment CRUD, dashboard (verifies all sections), deadline calculator (valid/invalid/unknown type), proceeding types & rules, document endpoints, AI extraction (no-key path), and full critical path E2E (auth -> case -> deadline -> appointment -> dashboard -> complete) - New handler unit tests: case (10), appointment (11), dashboard (1), calculate (5), document (10), AI (4) — all testing validation, auth guards, and error paths without DB - Total: ~80 backend tests (unit + integration) Frontend (TypeScript/Vitest): - Installed vitest 2.x, @testing-library/react, @testing-library/jest-dom, jsdom 24, msw - vitest.config.ts with jsdom env, esbuild JSX automatic, path aliases - API client tests (13): URL construction, no double /api/, auth header, tenant header, POST/PUT/PATCH/DELETE methods, error handling, 204 responses - DeadlineTrafficLights tests (5): renders cards, correct counts, zero state, onFilter callback - CaseOverviewGrid tests (4): renders categories, counts, header, zero state - LoginPage tests (8): form rendering, mode toggle, password login, redirect, error display, magic link, registration link - Total: 30 frontend tests Makefile: test-frontend target now runs vitest instead of placeholder echo.
68 lines
2.1 KiB
TypeScript
68 lines
2.1 KiB
TypeScript
import { describe, it, expect, vi } from "vitest";
|
|
import { render, screen, fireEvent } from "@testing-library/react";
|
|
import { DeadlineTrafficLights } from "@/components/dashboard/DeadlineTrafficLights";
|
|
import type { DeadlineSummary } from "@/lib/types";
|
|
|
|
describe("DeadlineTrafficLights", () => {
|
|
const defaultData: DeadlineSummary = {
|
|
overdue_count: 3,
|
|
due_this_week: 5,
|
|
due_next_week: 2,
|
|
ok_count: 10,
|
|
};
|
|
|
|
it("renders all three traffic light cards", () => {
|
|
render(<DeadlineTrafficLights data={defaultData} />);
|
|
|
|
expect(screen.getByText("Überfällig")).toBeInTheDocument();
|
|
expect(screen.getByText("Diese Woche")).toBeInTheDocument();
|
|
expect(screen.getByText("Im Zeitplan")).toBeInTheDocument();
|
|
});
|
|
|
|
it("displays correct counts", () => {
|
|
render(<DeadlineTrafficLights data={defaultData} />);
|
|
|
|
// Overdue: 3
|
|
expect(screen.getByText("3")).toBeInTheDocument();
|
|
// This week: 5
|
|
expect(screen.getByText("5")).toBeInTheDocument();
|
|
// OK: ok_count + due_next_week = 10 + 2 = 12
|
|
expect(screen.getByText("12")).toBeInTheDocument();
|
|
});
|
|
|
|
it("displays zero counts correctly", () => {
|
|
const zeroData: DeadlineSummary = {
|
|
overdue_count: 0,
|
|
due_this_week: 0,
|
|
due_next_week: 0,
|
|
ok_count: 0,
|
|
};
|
|
|
|
render(<DeadlineTrafficLights data={zeroData} />);
|
|
|
|
const zeros = screen.getAllByText("0");
|
|
expect(zeros).toHaveLength(3);
|
|
});
|
|
|
|
it("calls onFilter with correct key when clicked", () => {
|
|
const onFilter = vi.fn();
|
|
render(<DeadlineTrafficLights data={defaultData} onFilter={onFilter} />);
|
|
|
|
fireEvent.click(screen.getByText("Überfällig"));
|
|
expect(onFilter).toHaveBeenCalledWith("overdue");
|
|
|
|
fireEvent.click(screen.getByText("Diese Woche"));
|
|
expect(onFilter).toHaveBeenCalledWith("this_week");
|
|
|
|
fireEvent.click(screen.getByText("Im Zeitplan"));
|
|
expect(onFilter).toHaveBeenCalledWith("ok");
|
|
});
|
|
|
|
it("renders without onFilter prop (no crash)", () => {
|
|
expect(() => {
|
|
render(<DeadlineTrafficLights data={defaultData} />);
|
|
fireEvent.click(screen.getByText("Überfällig"));
|
|
}).not.toThrow();
|
|
});
|
|
});
|