refactor(web): set up component test infra + decompose ProjectWizard

Phase 4a: Add @testing-library/react, user-event, jest-dom, jsdom.
Switch vitest environment to jsdom, add setup file, create test-utils
with QueryClient wrapper.

Phase 4b: Extract ProjectWizard form logic into project-wizard/ subdir:
- types.ts: WizardState, Assignment, constants, factory functions
- useProjectWizardForm.ts: form state hook + canGoNext pure function

Phase 4c: 32 tests for canGoNext validation (all 5 steps), makeDefaultState,
and makeReq factory function.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-04-10 17:00:45 +02:00
parent 2f2fe2631f
commit 63db4a09e6
10 changed files with 1350 additions and 349 deletions
@@ -1,3 +1,4 @@
// @vitest-environment node
import React from "react";
import { renderToStaticMarkup } from "react-dom/server";
import { beforeEach, describe, expect, it, vi } from "vitest";
@@ -75,7 +76,7 @@ describe("AllocationPopover", () => {
/>,
);
expect(html).toContain("data-testid=\"timeline-allocation-popover-error\"");
expect(html).toContain('data-testid="timeline-allocation-popover-error"');
expect(html).toContain("The selected booking could not be loaded right now.");
expect(html).toContain("Assignment not found");
});
@@ -98,8 +99,10 @@ describe("AllocationPopover", () => {
/>,
);
expect(html).toContain("data-testid=\"timeline-allocation-popover-unavailable\"");
expect(html).toContain("The selected booking could not be resolved from the current timeline data.");
expect(html).toContain('data-testid="timeline-allocation-popover-unavailable"');
expect(html).toContain(
"The selected booking could not be resolved from the current timeline data.",
);
});
it("renders a loading skeleton when the allocation is being fetched", () => {
@@ -120,7 +123,7 @@ describe("AllocationPopover", () => {
/>,
);
expect(html).toContain("data-testid=\"timeline-allocation-popover-loading\"");
expect(html).toContain('data-testid="timeline-allocation-popover-loading"');
});
it("renders allocation data when provided as initialAllocation", () => {
@@ -160,8 +163,8 @@ describe("AllocationPopover", () => {
/>,
);
expect(html).not.toContain("data-testid=\"timeline-allocation-popover-error\"");
expect(html).not.toContain("data-testid=\"timeline-allocation-popover-unavailable\"");
expect(html).not.toContain("data-testid=\"timeline-allocation-popover-loading\"");
expect(html).not.toContain('data-testid="timeline-allocation-popover-error"');
expect(html).not.toContain('data-testid="timeline-allocation-popover-unavailable"');
expect(html).not.toContain('data-testid="timeline-allocation-popover-loading"');
});
});