test(auth): end-to-end placement tests for the bunyip login path (PMS-249) #182

Merged
longjacksonle merged 1 commit from feat/mapps-249-bunyip-login-e2e into main 2026-06-11 19:29:53 +02:00

What

Closes the last gap from the org-membership work: the full "authenticate via Bunyip -> land in the right tenant" path was only unit/service-tested because it ran through a live OIDC verifier.

How

Extracts the verifier-free core of ensure_user_from_bunyip into pub place_bunyip_user(auth, tenants, invitations, sub, email, email_verified, claims) - everything after the userinfo fetch (tenant resolution, re-home, JIT mirror, invite accept, role reconciliation, AuthState). ensure_user_from_bunyip now just fetches userinfo and delegates, so behavior is unchanged; the placement logic is drivable with stubbed email/email_verified, no network.

tests/bunyip_login.rs (placement asserted on the users row):

  • invited user lands in the inviting tenant, seeded with the invite's role, which survives the bunyip_role=subscriber translation (PMS-172); the invite is consumed;
  • un-invited self-signup user gets their own personal tenant (owned by them, not the shared default);
  • two self-signup users land in distinct tenants (per-user isolation);
  • an UNVERIFIED email does not consume an invite (PMS-248 gate, end to end) - the user self-signs up instead and the invite stays pending.

Verification

cargo check --all-targets + cargo clippy --all-targets clean; bunyip_login (4), tenants (7), invitations (6), auth (14) pass. (One auth test flaked once on sqlx test-db provisioning and passed on rerun - unrelated.)

🤖 Generated with Claude Code

## What Closes the last gap from the org-membership work: the full "authenticate via Bunyip -> land in the right tenant" path was only unit/service-tested because it ran through a live OIDC verifier. ## How Extracts the verifier-free core of `ensure_user_from_bunyip` into `pub place_bunyip_user(auth, tenants, invitations, sub, email, email_verified, claims)` - everything after the userinfo fetch (tenant resolution, re-home, JIT mirror, invite accept, role reconciliation, `AuthState`). `ensure_user_from_bunyip` now just fetches userinfo and delegates, so behavior is unchanged; the placement logic is drivable with stubbed `email`/`email_verified`, no network. `tests/bunyip_login.rs` (placement asserted on the `users` row): - invited user lands in the inviting tenant, seeded with the invite's role, which survives the `bunyip_role=subscriber` translation (PMS-172); the invite is consumed; - un-invited self-signup user gets their own `personal` tenant (owned by them, not the shared default); - two self-signup users land in distinct tenants (per-user isolation); - an UNVERIFIED email does not consume an invite (PMS-248 gate, end to end) - the user self-signs up instead and the invite stays pending. ## Verification `cargo check --all-targets` + `cargo clippy --all-targets` clean; `bunyip_login` (4), `tenants` (7), `invitations` (6), `auth` (14) pass. (One auth test flaked once on sqlx test-db provisioning and passed on rerun - unrelated.) 🤖 Generated with [Claude Code](https://claude.com/claude-code)
test(auth): end-to-end placement tests for the bunyip login path (PMS-249)
Some checks failed
Check / fmt + clippy + compile + tests (pull_request) Failing after 11s
E2E (staging) / Playwright against staging (pull_request) Successful in 34s
Create release / Create release from merged PR (pull_request) Has been skipped
Build OCI container / Build and push mokosh-api image (push) Successful in 6m47s
9291524a16
Closes the coverage gap: PMS-244/245/246 were unit/service-tested, but the full "authenticate via Bunyip -> land in the right tenant" path was not, because it ran through a live OIDC verifier.

Extracts the verifier-free core of `ensure_user_from_bunyip` into a `pub` `place_bunyip_user(auth, tenants, invitations, sub, email, email_verified, claims)` - everything after the userinfo fetch (tenant resolution, re-home, JIT mirror, invite accept, role reconciliation, AuthState build). `ensure_user_from_bunyip` now just fetches userinfo and delegates, so behavior is unchanged; the placement logic is now drivable with stubbed `email` / `email_verified` and no network.

`tests/bunyip_login.rs` exercises it against a real DB (placement asserted on the `users` row, the source of truth):
- an invited user lands in the inviting tenant, is seeded with the invite's role, that role survives the `bunyip_role=subscriber` translation (PMS-172), and the invite is consumed;
- an un-invited self-signup user gets their own `personal` tenant (owned by them, not the shared default);
- two self-signup users land in distinct tenants (per-user isolation);
- an UNVERIFIED email does not consume an invite (the PMS-248 gate, end to end) - the user self-signs up instead and the invite stays pending.

Verification: `cargo check --all-targets` + `cargo clippy --all-targets` clean; `bunyip_login` (4), `tenants` (7), `invitations` (6), `auth` (14) pass (one auth test flaked once on sqlx test-db provisioning and passed on rerun, unrelated).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
longjacksonle deleted branch feat/mapps-249-bunyip-login-e2e 2026-06-11 19:29:53 +02:00
Sign in to join this conversation.
No reviewers
No labels
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
psa-systems/mokosh-server!182
No description provided.