4.3 KiB
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_URLis a parseable URL withprotocol === 'http:'ANDprocess.env.NPM_TOKENhas 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 /-/pingreturns HTTP 200 - THEN
HealthPollerresolves and the fixture is considered ready
Scenario: Ping never succeeds → timeout
- WHEN
/-/pingnever returns 200 within the configuredhealthTimeoutMs - THEN
setup()rejects withINTEGRATION.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
storagefield - 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' }]andpackages: [{ name: '@suaveplan/*', access: '$authenticated', publish: 'ci' }]are supplied - THEN the rendered Verdaccio YAML contains an htpasswd entry for
ciAND apackagesblock 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
usersarray is supplied - THEN the thrown error has
code === 'INTEGRATION.VERDACCIO.CONFIG_INVALID'ANDcauseis the underlyingZodError
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_URLreturns the package metadata AND the tarball digest matches the locally built artefact