Initial Commit
This commit is contained in:
@@ -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
|
||||
Reference in New Issue
Block a user