feat(coverage): L0 unification — close test gaps in nav, media, mp

Closes the per-layer threshold gaps surfaced by the 2026-05-13 PRD
audit. After this commit all five features pass their declared
100%/100%/95%/100% bands on entities + use-cases + controllers.

media (was: missing @vitest/coverage-v8 + missing vitest config block +
  one controller at 86.66% lines / 75% branches)
  - Added @vitest/coverage-v8 dev dep
  - Applied the standard helper-driven vitest config
  - Declared the coverage section in feature.manifest.ts
  - Added 2 tests to list-media.controller.test.ts covering the
    InputParseError branch (unknown fields + invalid limit)
  - Now: 16 files / 80 tests / 97.12% / controllers 100%

marketing-pages (was: get-site-settings.controller at 93.54% lines /
  90.9% branches)
  - Added 1 test to get-site-settings.controller.test.ts covering the
    InputParseError branch on unknown fields
  - Now: 22 files / 68 tests / 95.66% / controllers 100%

navigation (was: entities/errors/common.ts at 50% function hits +
  get-header.controller at 86.66% lines / 80% branches)
  - Root cause: InputParseError class never instantiated in any test
  - Added 2 tests to get-header.controller.test.ts covering the
    InputParseError branch + verifying the Zod cause is preserved.
    One test exercises both gap files at once (controller throws,
    InputParseError class is constructed).
  - Wired navigation/vitest.config.ts through the shared helper
  - Declared the coverage section in feature.manifest.ts
  - Now: 11 files / 45 tests / 98.04% / entities + controllers 100%

All 5 features now drive thresholds from the manifest via the helper.
The duplication problem the keystone eliminates is gone.

Repo-wide via `pnpm coverage:aggregate`:
  - statements 95.87% (lh 2994 / lf 3123)
  - branches   88.91% (brh 433 / brf 487)
  - functions  100%   (fnh 142 / fnf 142)
  - lines      95.87%

`pnpm coverage:diff -- --base HEAD~1` reports status: pass.

coverage/summary.json refreshed in the same commit so the trend
captures the post-unification state.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-05-13 16:39:08 +02:00
parent 6428f10b82
commit bf0b049583
10 changed files with 191 additions and 56 deletions

View File

@@ -2,6 +2,7 @@ import { describe, it, expect } from "vitest";
import { listMediaController } from "@/interface-adapters/controllers/list-media.controller";
import { listMediaUseCase } from "@/application/use-cases/list-media.use-case";
import { MockMediaRepository } from "@/infrastructure/repositories/media.repository.mock";
import { InputParseError } from "@/entities/errors/common";
import { mediaFactory } from "@/__factories__/media.factory";
describe("listMediaController", () => {
@@ -38,4 +39,22 @@ describe("listMediaController", () => {
const result = await controller({ limit: 2, offset: 1 });
expect(result).toHaveLength(2);
});
it("throws InputParseError on unknown fields (strict schema)", async () => {
const repo = new MockMediaRepository();
const useCase = listMediaUseCase(repo);
const controller = listMediaController(useCase);
await expect(controller({ unknownField: 1 })).rejects.toThrow(
InputParseError,
);
});
it("throws InputParseError when limit is not a positive integer", async () => {
const repo = new MockMediaRepository();
const useCase = listMediaUseCase(repo);
const controller = listMediaController(useCase);
await expect(controller({ limit: -1 })).rejects.toThrow(InputParseError);
});
});