feat(tests): module-level integration tests for real route groups (F10) #55
Loading…
Reference in a new issue
No description provided.
Delete branch "feat/pms-124-integration-tests"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Closes PMS-124. Subtask of PMS-121 (F10).
Background
PMS-121 F10 calls for a
tests/harness covering every real route group, run in CI. Today the repo has zero integration tests at the workspace root (onlycrates/mokosh-auth/tests/e2e_oidc.rs), and CI runscargo test --libonly.The story-level acceptance permits "testcontainers or the dev compose Postgres". This PR takes the
#[sqlx::test]+ CI service container path, matching the pattern already in use incrates/mokosh-auth/tests/e2e_oidc.rs. testcontainers was rejected as a new heavy dep when an existing in-repo pattern already exists for the same outcome.Change
Harness (
tests/common/mod.rs)boot(pool)builds the PSA router viacreate_api_routerwith a stub Google OAuth client, the host crate'sLogMailer, and the SSO subsystem deliberately disabled (at_jwt = None,bunyip_verifier = None). It then spawns the router on127.0.0.1:0and returns a cookie-aware reqwest client pointed at the assigned URL.seed_admininserts asuper_adminuser under the default tenant (id00000000-0000-0000-0000-000000000001, seeded bymigrations/001_initial_schema.sql) with an Argon2-hashed password produced by the host crate'shash_password. It mirrorsmodules::auth::bootstrap::maybe_bootstrap_adminwithout touching process env vars (so tests stay parallel-safe).loginposts/api/v1/auth/loginso the response'sSet-Cookielands in the jar and authenticates subsequent calls.Tests
tests/auth.rs: login -> GET/mereflects the seeded admin.tests/contacts.rs: create company -> list -> get by id -> delete.tests/tenants.rs: GET/tenantsfor a super_admin contains the seeded default tenant.tests/tickets.rs: seed a company directly, then create ticket -> list -> get -> PUT (title change) -> POST a note.Host-crate additive change
Database::from_pool(PgPool)so the harness can wrap the per-test pool sqlx hands it. Purely additive; the existingDatabase::new(url)path is unchanged.CI (
.forgejo/workflows/check.yml)pg_isreadyhealth probe.DATABASE_URL=postgres://postgres:postgres@localhost:5432/postgresat job scope.cargo test --test auth --test contacts --test tenants --test tickets.SQLX_OFFLINE=truestays in effect for compile (uses.sqlx/cache); runtime sqlx calls in the integration tests still hit the live Postgres service.Out of scope
filter.validate()?helper (was the implicit suggestion in the parent story for PMS-123; the existing inline?pattern is fine).#[tokio::test]per route group". Per-endpoint coverage can grow inside each test file later.Risk notes
just check-docker, but the test code (and the new CI Postgres service config) is validated only by CI. Watch the first run.localhost, the integration step will time out atpg_isready. Fix would be to switchDATABASE_URLhost to the service name (postgres) per Forgejo's container-runner semantics.PMS-124. Stand up a `tests/` harness that uses `#[sqlx::test]` to provision a fresh database per test invocation (matching the existing pattern in `crates/mokosh-auth/tests/e2e_oidc.rs`) and exercises the four real PSA route groups end-to-end through reqwest against a real TCP listener. Harness (`tests/common/mod.rs`): - `boot(pool)` builds the PSA router via `create_api_router` with a stub Google OAuth client, `LogMailer`, and the SSO subsystem deliberately disabled (`at_jwt = None`, `bunyip_verifier = None`); the tests cover the legacy HS256-cookie auth path that the PSA endpoints still take. Spawns the router on `127.0.0.1:0` and returns the assigned URL plus a cookie-aware reqwest client. - `seed_admin` inserts a `super_admin` user under the default tenant (id `00000000-0000-0000-0000-000000000001`, seeded by `001_initial_schema.sql`) with an Argon2-hashed password produced by the host crate's `hash_password`, mirroring `modules::auth::bootstrap::maybe_bootstrap_admin` without depending on process env vars. - `login` posts `/api/v1/auth/login` and lets the cookie jar carry the resulting session cookie into subsequent requests. Tests: - `tests/auth.rs`: login -> GET `/me` reflects the seeded admin. - `tests/contacts.rs`: create company -> list (asserts presence) -> get by id -> delete. - `tests/tenants.rs`: list `/tenants` for a super_admin contains the seeded default tenant. - `tests/tickets.rs`: seed a company directly, then create ticket -> list -> get -> PUT (title change) -> POST a note. Cargo: dev-dep on `reqwest` with the `cookies` feature for cookie-jar handling, and `sqlx` with the `macros` feature for `#[sqlx::test]`. Host crate: add `Database::from_pool(PgPool)` so the harness can wrap the per-test pool sqlx hands it. Purely additive; the existing `Database::new(url)` path stays unchanged. CI (`.forgejo/workflows/check.yml`): add a Postgres 16 service on port 5432, set `DATABASE_URL=postgres://postgres:postgres@localhost:5432/postgres`, and add a new "Integration tests" step that runs `cargo test --test auth --test contacts --test tenants --test tickets`. The existing `cargo test --lib` step stays for the unit tests that need no database. This closes the F10 acceptance criterion on PMS-121 ("A `tests/` harness runs integration tests for all real route groups in CI"). The story-level allowance of "testcontainers or the dev compose Postgres" is taken via `#[sqlx::test]` plus a CI service container, which keeps the test toolchain consistent with the auth crate's existing `e2e_oidc.rs`. #PMS-124 Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>