MotorSignal-App/docs/qa-2026-10-01/auth.md

5.6 KiB

Authenticated isolated QA — 2026-10-01

Environment and scope

Firebase CLI and the cached Firestore emulator were available. The repository's original firebase.emulator.json supports Firestore only; the QA configuration adds Auth. Both services bind to loopback: Auth 127.0.0.1:9099, Firestore 127.0.0.1:8088, project demo-motorsignal-qa. No production accounts, settings, entitlements, rules, or data were changed.

The active rules snapshot auth.firestore.rules is byte-identical to the repository firestore.rules, SHA-256 A731D6319B56D2A13960FCBE621004D448AE611DC5C5657FAB25F0EFBE302EC6. No rules weakening was used. Initial club/ride fixture seeding uses the Admin SDK solely against the explicitly configured local demo emulator. All listed scenario actions use signed-in client SDKs with the real rules enforced; these are automated backend checks, not browser or Flutter end-to-end results.

Six disposable accounts represent owner, admin, organizer (also a club admin), accepted/requesting participant, regular member, and outsider. Account identifiers are in auth.results.json. Passwords are supplied through QA_DEMO_PASSWORD and are not written to evidence. There is no personal account use.

Executed results

  • auth.exercise.mjs: 17/17 PASS, rerun after service restart at approximately 2026-10-01 05:48 UTC.
  • auth.extra.mjs: 7/7 PASS. Uses separate qa-extra-* documents to avoid changing browser fixtures.
  • Total unique SDK cases: 24 PASS, 0 FAIL. Exact IDs and outcomes are in auth.results.json and auth.extra-results.json.
  • Existing Firestore rules suite: 148/148 PASS, auth.rules-results.json. This suite uses rules-unit-testing authenticated contexts and is a separate automated category, not real Auth sign-in coverage.

SDK actions verified registration/sign-out/sign-in, token refresh, sign-out access denial, public club discovery, request membership and administrator approval, personal and official club ride creation, regular-member official creation denial, outsider club-ride request denial, ride request/approval/rejection with cross-account reads, denied self-approval, open joining, accepted participant leaving, organizer removal with count/access updates, start/completion/cancellation, accepted live-presence write and peer read, nonparticipating admin presence denial, and presence denial after completion.

Negative-rule cases emit expected PERMISSION_DENIED messages, including evaluation-budget diagnostics. Their PASS means the attempted unauthorized operation was rejected; it does not establish which individual rule branch denied it. The positive counterparts completed successfully.

SDK sign-in and token refresh do not establish browser reload or mobile process-restart session persistence. See the browser owner's evidence for actual UI outcomes. No Flutter device interaction was performed by this worker.

Reproduction

From repository root, set XDG_CONFIG_HOME to a disposable writable directory (the normal Firebase CLI preference directory was sandbox-inaccessible), then start:

& firebase/emulator-tests/node_modules/.bin/firebase.cmd emulators:start --config docs/qa-2026-10-01/auth.firebase.json --project demo-motorsignal-qa --only auth,firestore

Wait for All emulators ready, set QA_DEMO_PASSWORD to a disposable password, and run node docs/qa-2026-10-01/auth.exercise.mjs, then node docs/qa-2026-10-01/auth.extra.mjs. The first script resets its own fixtures; do not run it while interactive testers rely on them.

The rules suite was run from firebase/emulator-tests with FIRESTORE_EMULATOR_HOST=127.0.0.1:8088 using vitest run --reporter=json --outputFile=../../docs/qa-2026-10-01/auth.rules-results.json. It uses the distinct motorsignal-emulator namespace and clears its own fixture state.

A separate debug-only mobile entry exists at tools/qa_auth_main.dart. It uses the normal app/providers after local Firebase initialization, requires R2_WORKER_URL=http://127.0.0.1:1, and expects adb reverse for ports 9099/8088. The worker URL requirement prevents production sync/billing calls. Device build/install/runtime validation belongs to the exclusive device owner; the existence of this file does not prove mobile authentication works.

Legitimate Pro entitlement blocker

Source inspection: PlayBillingService delivers purchases, EntitlementCoordinator submits them through PurchaseVerificationService to /billing/verify-play-purchase, and only verified entitlement unlocks CSV. The Worker verifier requires Google Play package configuration and Google service-account credentials. FakeBillingService, in-memory entitlement storage, and test-state constructors are mocks; they do not establish legitimate store entitlement.

No established isolated Play tester purchase/verified token or billing verification environment was found in the inspected setup. A Firebase emulator account/role alone does not grant Pro. Real Pro CSV UI validation remains blocked on an authorized Google Play test account with the configured product/test purchase and a verification environment that can validate it. No purchase or production entitlement change was attempted. Export-content automated coverage, if run by the parent, must be reported separately.

Cleanup status

Browser owner completed. auth.cleanup.mjs ran at 2026-10-01T10:51:32.634Z; Auth and Firestore cleanup endpoints both returned HTTP 200 (auth.cleanup-results.json). The Playwright browser closed, and local Next/Firebase emulator processes were stopped. Emulator state is transient and no longer serving. No production fixture persistence or change occurred.