Files
2026-05-27 23:29:53 +01:00

76 lines
4.3 KiB
Markdown

## ADDED Requirements
### Requirement: Verdaccio image and pinning
`@suaveplan/testing-integration-verdaccio` SHALL ship a `VerdaccioFixture` ServiceFixture backed by `verdaccio/verdaccio:6@sha256:<digest>`. The image MUST be pinned by both tag and sha256 digest and MUST be tracked by `scripts/verify-image-pinning.ts`.
#### Scenario: Image is pinned
- **WHEN** the fixture's image config is read
- **THEN** the value matches `^verdaccio/verdaccio:6@sha256:[a-f0-9]{64}$`
### Requirement: Environment-variable bridge
The fixture SHALL expose its endpoint and credentials to the test environment via the variables `NPM_REGISTRY_URL` and `NPM_TOKEN`. `NPM_REGISTRY_URL` MUST be the fully-qualified `http://<host>:<port>/` form. `NPM_TOKEN` MUST be a Verdaccio-compatible bearer token generated at fixture startup.
#### Scenario: Env-bridge populated after start
- **WHEN** `VerdaccioFixture.setup()` resolves
- **THEN** `process.env.NPM_REGISTRY_URL` is a parseable URL with `protocol === 'http:'` AND `process.env.NPM_TOKEN` has length ≥ 32
### Requirement: Healthcheck via /-/ping
Readiness SHALL be determined by a polling HTTP `GET /-/ping` against the fixture's endpoint. The poller MUST respect `HealthPoller` defaults from `@suaveplan/testing-integration` and SHALL accept an injectable `fetch` implementation for unit tests.
#### Scenario: Ping returns 200 → ready
- **WHEN** `GET /-/ping` returns HTTP 200
- **THEN** `HealthPoller` resolves and the fixture is considered ready
#### Scenario: Ping never succeeds → timeout
- **WHEN** `/-/ping` never returns 200 within the configured `healthTimeoutMs`
- **THEN** `setup()` rejects with `INTEGRATION.VERDACCIO.HEALTH_TIMEOUT`
### Requirement: Configuration shape
The fixture SHALL accept a config object of shape `{ storage?: 'memory'|'tmpfs'; users?: Array<{ username: string; password: string }>; packages?: Array<{ name: string; access?: string; publish?: string }>; uplinks?: Record<string, string> }`. `storage` defaults to `'memory'`. The fixture SHALL translate this object into Verdaccio's native YAML config at startup. Invalid config MUST be rejected via Zod with a `INTEGRATION.VERDACCIO.CONFIG_INVALID` error.
#### Scenario: Memory storage default
- **WHEN** the fixture is started without a `storage` field
- **THEN** Verdaccio runs with in-memory storage AND no host filesystem path is mounted
#### Scenario: tmpfs storage
- **WHEN** the fixture is started with `storage: 'tmpfs'`
- **THEN** the container's storage path is backed by a tmpfs mount AND publish state survives within the fixture lifetime but not across restarts
#### Scenario: User and package config translated
- **WHEN** `users: [{ username: 'ci', password: 'p' }]` and `packages: [{ name: '@suaveplan/*', access: '$authenticated', publish: 'ci' }]` are supplied
- **THEN** the rendered Verdaccio YAML contains an htpasswd entry for `ci` AND a `packages` block matching the input
### Requirement: Error code prefix
Every error thrown by `@suaveplan/testing-integration-verdaccio` SHALL extend the package's structured error class and carry a `code` of the form `INTEGRATION.VERDACCIO.<REASON>` (uppercase ASCII, dots as separators).
#### Scenario: Coded error on health timeout
- **WHEN** the fixture's healthcheck never succeeds
- **THEN** the thrown error has `code === 'INTEGRATION.VERDACCIO.HEALTH_TIMEOUT'`
#### Scenario: Coded error on invalid config
- **WHEN** an invalid `users` array is supplied
- **THEN** the thrown error has `code === 'INTEGRATION.VERDACCIO.CONFIG_INVALID'` AND `cause` is the underlying `ZodError`
### Requirement: Publish flow integration test
The fixture SHALL be exercisable end-to-end against `bun scripts/publish.ts --package @suaveplan/<pkg>` so the genesis publish path is testable in CI before any real publish to the production Verdaccio at `https://npmjs.fq.io/`. A reference integration test SHALL ship in the package demonstrating: fixture startup, env-bridge wiring, `bun scripts/publish.ts` invocation against the fixture, and verification of the published tarball via `npm view --registry $NPM_REGISTRY_URL`.
#### Scenario: Publish round-trip
- **WHEN** the integration test runs `bun scripts/publish.ts --package <probe>` against the fixture
- **THEN** `npm view <probe>@0.0.0 --registry $NPM_REGISTRY_URL` returns the package metadata AND the tarball digest matches the locally built artefact