test: Extract shared conformance-test scaffolding into a common module #78

Closed
opened 2026-07-03 21:18:52 +00:00 by rosa · 1 comment
Owner

This was generated by AI during triage.

Found during the two-axis reviews of PRs #76 and #77.

Location: crates/infra/tests/
Severity: Code health — test-infrastructure duplication

Problem

The repository-conformance test suites duplicate their scaffolding verbatim. post_repository_conformance.rs established the pattern (generic behaviour functions + a both_adapters! macro that instantiates each behaviour against Postgres via #[sqlx::test] and the in-memory MemoryAppRepo via #[tokio::test], plus create_user_request() / seed_user() helpers). PR #76 (confirmation_repository_conformance.rs) and PR #77 (authorization_code_repository_conformance.rs) each copied the macro and user-seeding helpers wholesale, because integration-test binaries can't share code without a common module. Once both merge there are three verbatim copies.

Both standards reviews flagged the duplication and set the extraction threshold at the third occurrence — which #77 crosses.

Suggested fix

Extract the shared scaffolding into crates/infra/tests/common/mod.rs (the standard Rust pattern for sharing across integration-test binaries): the both_adapters! macro and the user-seeding helpers, parameterised as the confirmation suite already needs (multiple users). Update the three conformance suites to use it; behaviour functions stay in their own files.

This should land after PRs #76 and #77 merge, since it touches the same new files.

> *This was generated by AI during triage.* Found during the two-axis reviews of PRs #76 and #77. **Location:** `crates/infra/tests/` **Severity:** Code health — test-infrastructure duplication ## Problem The repository-conformance test suites duplicate their scaffolding verbatim. `post_repository_conformance.rs` established the pattern (generic behaviour functions + a `both_adapters!` macro that instantiates each behaviour against Postgres via `#[sqlx::test]` and the in-memory `MemoryAppRepo` via `#[tokio::test]`, plus `create_user_request()` / `seed_user()` helpers). PR #76 (`confirmation_repository_conformance.rs`) and PR #77 (`authorization_code_repository_conformance.rs`) each copied the macro and user-seeding helpers wholesale, because integration-test binaries can't share code without a common module. Once both merge there are three verbatim copies. Both standards reviews flagged the duplication and set the extraction threshold at the third occurrence — which #77 crosses. ## Suggested fix Extract the shared scaffolding into `crates/infra/tests/common/mod.rs` (the standard Rust pattern for sharing across integration-test binaries): the `both_adapters!` macro and the user-seeding helpers, parameterised as the confirmation suite already needs (multiple users). Update the three conformance suites to use it; behaviour functions stay in their own files. This should land after PRs #76 and #77 merge, since it touches the same new files.
Author
Owner

Agent Brief

Category: enhancement
Summary: Extract the duplicated conformance-test scaffolding into a module shared by the infra crate's integration-test binaries

Current behavior:
The three repository-conformance suites in the infra crate's integration tests (post, password-reset confirmation, authorization code) each carry their own copy of the same scaffolding, because integration-test binaries cannot share code without a common module:

  • A both_adapters! macro — byte-identical in all three suites — that takes a generic behaviour function over R: AppRepository and emits two wrapper tests: one running it against PostgresAppRepository via #[sqlx::test] with the repo's migrations, one against MemoryAppRepo via #[tokio::test].
  • A create_user_request() helper that builds a valid CreateUserRequest (fixed argon2 hash, generated confirmation id/verifier, day-long expiry). The post and authorization-code suites hardcode the user name and email; the confirmation suite's variant takes them as parameters because its behaviours need multiple distinct users.
  • A seed_user() helper that creates the user and returns its UserId (present in the post and authorization-code suites; the confirmation suite inlines the equivalent because it also needs the confirmation id back).

Desired behavior:
The shared scaffolding lives once, in a common module using the standard Rust pattern for sharing code across integration-test binaries (a common module under the crate's tests/ directory), and all three conformance suites use it. Behaviour functions stay in their own suite files — only the scaffolding moves.

Key interfaces:

  • both_adapters! — moves unchanged; each suite must be able to invoke it after the extraction.
  • create_user_request(name, email) — standardise on the parameterised form the confirmation suite already needs; suites that don't care about the identity can pass fixed values or use a zero-argument convenience wrapper.
  • seed_user() — must support seeding multiple distinct users, and the confirmation suite's need to know the seeded user's email-confirmation id should be satisfiable (whether by returning richer data or by suites composing create_user_request directly is an implementation choice).

Acceptance criteria:

  • Exactly one definition of the both_adapters! macro and the user-seeding helpers remains, in a module shared across the infra integration-test binaries.
  • All three conformance suites use the shared module; their behaviour functions are unchanged and remain in their own files.
  • The set of test names (the pg_*/mem_* pairs) is identical before and after the refactor, and all of them pass.
  • The ci mise task passes with no new warnings (note: each integration-test binary compiles the common module independently, so helpers unused by one binary can trigger dead-code warnings — the extraction must not introduce any).

Out of scope:

  • Changing any behaviour function or test semantics.
  • Adding new conformance behaviours or new adapters.
  • Touching unit tests or any tests outside the three conformance suites.
  • Ordering parity between the adapters (tracked separately in issue #29).
## Agent Brief **Category:** enhancement **Summary:** Extract the duplicated conformance-test scaffolding into a module shared by the infra crate's integration-test binaries **Current behavior:** The three repository-conformance suites in the infra crate's integration tests (post, password-reset confirmation, authorization code) each carry their own copy of the same scaffolding, because integration-test binaries cannot share code without a common module: - A `both_adapters!` macro — byte-identical in all three suites — that takes a generic behaviour function over `R: AppRepository` and emits two wrapper tests: one running it against `PostgresAppRepository` via `#[sqlx::test]` with the repo's migrations, one against `MemoryAppRepo` via `#[tokio::test]`. - A `create_user_request()` helper that builds a valid `CreateUserRequest` (fixed argon2 hash, generated confirmation id/verifier, day-long expiry). The post and authorization-code suites hardcode the user name and email; the confirmation suite's variant takes them as parameters because its behaviours need multiple distinct users. - A `seed_user()` helper that creates the user and returns its `UserId` (present in the post and authorization-code suites; the confirmation suite inlines the equivalent because it also needs the confirmation id back). **Desired behavior:** The shared scaffolding lives once, in a common module using the standard Rust pattern for sharing code across integration-test binaries (a `common` module under the crate's `tests/` directory), and all three conformance suites use it. Behaviour functions stay in their own suite files — only the scaffolding moves. **Key interfaces:** - `both_adapters!` — moves unchanged; each suite must be able to invoke it after the extraction. - `create_user_request(name, email)` — standardise on the parameterised form the confirmation suite already needs; suites that don't care about the identity can pass fixed values or use a zero-argument convenience wrapper. - `seed_user()` — must support seeding multiple distinct users, and the confirmation suite's need to know the seeded user's email-confirmation id should be satisfiable (whether by returning richer data or by suites composing `create_user_request` directly is an implementation choice). **Acceptance criteria:** - [ ] Exactly one definition of the `both_adapters!` macro and the user-seeding helpers remains, in a module shared across the infra integration-test binaries. - [ ] All three conformance suites use the shared module; their behaviour functions are unchanged and remain in their own files. - [ ] The set of test names (the `pg_*`/`mem_*` pairs) is identical before and after the refactor, and all of them pass. - [ ] The `ci` mise task passes with no new warnings (note: each integration-test binary compiles the common module independently, so helpers unused by one binary can trigger dead-code warnings — the extraction must not introduce any). **Out of scope:** - Changing any behaviour function or test semantics. - Adding new conformance behaviours or new adapters. - Touching unit tests or any tests outside the three conformance suites. - Ordering parity between the adapters (tracked separately in issue #29).
rosa closed this issue 2026-07-04 01:56:07 +00:00
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
rosa/vernier#78
No description provided.