Initial Commit

This commit is contained in:
2026-05-27 23:29:53 +01:00
commit fbc70f96e6
10000 changed files with 1102152 additions and 0 deletions

View File

@@ -0,0 +1,106 @@
## ADDED Requirements
### Requirement: Layer 0 dep-graph isolation
The `@suaveplan/testing-integration-mongodb` package's `dependencies` MUST be exactly `@suaveplan/testing-integration` (`workspace:^`) and `testcontainers` (`catalog:integration`). No other `@suaveplan/*` runtime dep is permitted. `devDependencies` MAY include `@suaveplan/testing` for the package's own tests.
#### Scenario: Runtime closure clean
- **WHEN** `bunx turbo ls --filter=@suaveplan/testing-integration-mongodb...` is run
- **THEN** the only `@suaveplan/*` package in the runtime closure is `@suaveplan/testing-integration`
### Requirement: Image-pinning policy
The default image MUST be `mongo:7.0`. The `constants/index.ts` file MUST carry a `# TODO: replace with sha256:<digest>` comment until the digest is recorded.
#### Scenario: Pinned tag
- **WHEN** the constants file is read
- **THEN** the image string equals `mongo:7.0` AND a sha256 TODO line is present
### Requirement: Env-bridge passthrough
The fixture MUST consult `MONGODB_URL` and `MONGODB_DATABASE`. When both are present and non-empty, `start()` MUST skip container creation and return a handle whose config points at the live MongoDB.
#### Scenario: Live MongoDB present
- **WHEN** both env vars are set
- **THEN** `start()` returns without invoking `containerFactory` AND the returned config's `url` equals `MONGODB_URL`
#### Scenario: Partial env triggers container
- **WHEN** `MONGODB_URL` is set but `MONGODB_DATABASE` is empty
- **THEN** `start()` falls back to container mode
### Requirement: Healthcheck
The fixture MUST run `mongosh --eval "db.runCommand('ping')"` in-container via the injectable `execFn` and treat exit code `0` with stdout containing `ok` as ready. The default `healthTimeoutMs` MUST be `60000`. Callers MAY override.
#### Scenario: Healthcheck succeeds
- **WHEN** the in-container `mongosh` ping returns exit code 0 with `{ ok: 1 }` stdout
- **THEN** `start()` resolves
#### Scenario: Healthcheck times out
- **WHEN** the ping never succeeds within `healthTimeoutMs`
- **THEN** `start()` rejects with code `INTEGRATION.MONGODB.HEALTHCHECK_TIMEOUT`
### Requirement: Replica-set initialisation
When `replicaSet: true` is supplied, the fixture MUST start `mongod` with `--replSet rs0` and run `rs.initiate()` via `execFn` after the ping healthcheck passes. The fixture MUST NOT resolve `start()` until `rs.status().ok === 1`.
#### Scenario: Replica-set ready
- **WHEN** `start({ database: 'app', replicaSet: true })` resolves
- **THEN** a subsequent `rs.status()` call reports `ok: 1` AND a multi-document transaction succeeds against the returned `url`
### Requirement: Authentication mode
When `authentication: { username, password }` is supplied, the fixture MUST start `mongod` with `--auth`, create the supplied user via `execFn` against the `admin` database, and embed the credentials in the returned `url` (`mongodb://user:pass@host:port/database`).
#### Scenario: Auth rejects bad credentials
- **WHEN** the fixture starts in auth mode and a client connects with an incorrect password
- **THEN** the connection fails with a MongoDB authentication error
### Requirement: Config shape
The exported `MongoDbConfig` interface MUST include `database`, optional `replicaSet?: boolean`, optional `authentication?: { username: string; password: string }`, and the resolved `url`. A sibling `mongodb-fixture.schemas.ts` MUST export a Zod `MongoDbConfigSchema` that validates the same shape.
#### Scenario: Schema parity
- **WHEN** `MongoDbConfigSchema.safeParse` is run against a `MongoDbConfig` value
- **THEN** valid configs parse OK AND missing required fields fail with `ZodError`
### Requirement: Error-code prefix
All errors thrown from the fixture MUST carry a `code` matching `^INTEGRATION\.MONGODB\.[A-Z_]+$`.
#### Scenario: Coded error
- **WHEN** any fixture method throws
- **THEN** `code` starts with `INTEGRATION.MONGODB.`
### Requirement: Injectable fakes
The fixture constructor MUST accept `containerFactory?: () => GenericContainer` and `execFn?: (cmd: string[]) => Promise<{ stdout: string; stderr: string; exitCode: number }>`. Unit tests MUST be able to drive 100% Istanbul branch coverage without Docker.
#### Scenario: Fake injection
- **WHEN** the fixture is constructed with both fakes
- **THEN** real Docker is never invoked during the test
### Requirement: Plugin scenarios
The fixture MUST support, end-to-end against a real container, the following flows in its smoke test:
#### Scenario: Plain mode write/read round-trip
- **WHEN** the fixture is started in plain mode and an `insertOne` followed by a `findOne` is performed
- **THEN** the inserted document is read back unchanged
#### Scenario: Replica-set transaction round-trip
- **WHEN** the fixture is started with `replicaSet: true` and a multi-document transaction is committed
- **THEN** all inserts are visible after `commitTransaction()` AND none are visible if `abortTransaction()` is called instead