qa(plan): add varied gameplay styles, exhaustive nav fuzzing, Pass G account-creation/fake-account

- Pass B: vary style of play (lengths/moods/answer types, result patterns, turn orders, exit/resume
  styles, edge inputs) to hit different code paths.
- Pass C: 'take every avenue' exhaustive nav fuzzing — tap every element, every order, rapid/repeated
  input, interrupt mid-nav, hunt dead-ends/traps.
- Pass G (new): account creation happy path + validation + duplicate/conflict + fake/malicious
  creation attempts (live D3 non-member denial, invite-code abuse, App Check, self-premium).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
null 2026-06-25 12:28:58 -05:00
parent ee19ef3f59
commit 3de4178fd3
1 changed files with 53 additions and 0 deletions

View File

@ -154,6 +154,19 @@ Games: This or That, How Well Do You Know Me, Desire Sync, Connection Challenges
intermediate screen and interaction works (selections register, progress advances, both-answered gating, intermediate screen and interaction works (selections register, progress advances, both-answered gating,
reveal/scoring/summary correct). Premium games (Desire Sync, Memory Lane) need a premium toggle to play. reveal/scoring/summary correct). Premium games (Desire Sync, Memory Lane) need a premium toggle to play.
- The session lifecycle is exercised by the real playthrough: `status` active→completed; reveal/results correct on both. - The session lifecycle is exercised by the real playthrough: `status` active→completed; reveal/results correct on both.
- **VARY THE STYLE OF PLAY (don't just repeat the happy path):** across runs, deliberately exercise *different* ways a
real couple would play each game, because different inputs hit different code paths:
- **Different option/length/mood choices** — every round length (5/10/15), every mood/category, the "All topics"/
shuffle option, and **each distinct answer type** (A/B, Yes/No, True/False, 15 scale, multi-select, free-text).
- **Different answer *patterns* that change the result** — all-match vs all-mismatch vs partial; both-yes vs both-no
vs split (so reveals show "shared", "all private", "0 matches", "perfect/zero score" — verify each renders right).
- **Different turn orders / who-starts** — partner A starts vs partner B starts; the guesser opens before vs after
the subject finishes; both open simultaneously (race); one device much slower than the other.
- **Different exit/resume styles** — finish normally; quit mid-game; background mid-game then resume; cold-kill
mid-game then reopen; "End their game"; re-open a completed session for the replay/results; play two games
back-to-back, and a *different* game type immediately after.
- **Edge inputs** — submit with nothing selected (should be blocked), rapid double-taps on answer/confirm/next,
spamming the start button, tapping during the reveal animation. None should crash, duplicate, or desync.
- Edges: re-open a completed session, leave mid-game (resume), no stuck session, no crash, logcat clean. - Edges: re-open a completed session, leave mid-game (resume), no stuck session, no crash, logcat clean.
- Game start/finish pushes (`onGameSessionUpdate`) exercised here; full delivery/deep-link audit in **Pass E**. - Game start/finish pushes (`onGameSessionUpdate`) exercised here; full delivery/deep-link audit in **Pass E**.
- **Media permissions** (CAMERA, RECORD_AUDIO): granted works, denied degrades gracefully. - **Media permissions** (CAMERA, RECORD_AUDIO): granted works, denied degrades gracefully.
@ -175,6 +188,21 @@ Account); Paywall; Your Progress/Activity; Recovery.
opens correctly each time — e.g. a conversation from the inbox AND from "Discuss" AND from a notification; a game opens correctly each time — e.g. a conversation from the inbox AND from "Discuss" AND from a notification; a game
from the Play hub AND from a notification; Paywall from each gated feature; Settings sub-pages; reveal from Today from the Play hub AND from a notification; Paywall from each gated feature; Settings sub-pages; reveal from Today
AND from history AND from `partner_answered`. A screen that works from one entry but breaks/duplicates from another = bug. AND from history AND from `partner_answered`. A screen that works from one entry but breaks/duplicates from another = bug.
- **TAKE EVERY AVENUE (exhaustive nav fuzzing — actively hunt for nav bugs, don't just walk the happy path):** treat
navigation as something to *break*. On every screen, **tap every interactive element** — each button, card, row,
icon, chip, link, tab, header back-arrow, system back, and any "see all / history / edit / manage" affordance — and
follow where it goes. Then try the *combinations and sequences* a curious user hits:
- **Every order:** switch bottom tabs in many orders, mid-flow (open a game, jump to Messages, come back); enter a
deep screen then tab away then back; open A→B→C then back-back-back.
- **Rapid / repeated input:** double- and triple-tap navigation targets (especially "open game", "Play now",
"Create/Start session", notification taps) to surface double-push/duplicate-screen/stale-route bugs (cf. B-004).
- **Interrupt mid-navigation:** background/rotate/lock during a transition; tap a notification while already on that
screen, on a different screen, and while logged-out/unpaired; cold-start straight onto a deep link.
- **Dead-ends & traps:** from *every* screen confirm there's always a way out (back/close/home) — no screen that
strands the user, needs two backs, exits the app unexpectedly, loops, or lands blank. Re-check the asymmetric-game
waiting screens, replay/results screens, and paywall specifically.
- Log **every** wrong/duplicate/dead destination with the exact tap sequence to reproduce. Wrong/double-back or
dead-end = **P2** (P1 if it traps the user or loses their progress).
- **Back-stack / "double back":** from every entry point, **system back AND the in-app back arrow** return to the - **Back-stack / "double back":** from every entry point, **system back AND the in-app back arrow** return to the
correct previous screen — no dead-ends, no exiting the app unexpectedly, and **no screen that requires pressing correct previous screen — no dead-ends, no exiting the app unexpectedly, and **no screen that requires pressing
back twice** (duplicate/stacked destinations on the back stack = bug). Bottom-tab reselection and deep-link/ back twice** (duplicate/stacked destinations on the back stack = bug). Bottom-tab reselection and deep-link/
@ -203,6 +231,31 @@ Account); Paywall; Your Progress/Activity; Recovery.
couple — migration completes without exposing plaintext or losing/garbling old content, and a half-migrated couple couple — migration completes without exposing plaintext or losing/garbling old content, and a half-migrated couple
is safe (no mixed read failures, no downgrade). This is the riskiest data path for existing users. is safe (no mixed read failures, no downgrade). This is the riskiest data path for existing users.
### Pass G — Account creation, validation & fake-account abuse (MANDATORY — both the happy path AND the attacks)
Cover **every account-creation avenue a real user takes** and **every fake/abusive creation attempt an attacker would
try.** Use throwaway test accounts (sign-out → fresh sign-up; never `pm clear`). Report-first like every pass.
- **Real creation flows (happy path + validation):** sign-up (email/password and any social/anonymous path), profile
creation, and pairing — both **create-invite** and **accept-invite** sides. Verify field validation (invalid/empty
email, weak/short password, mismatched confirm, name length/emoji/unicode), the **error copy is friendly** (no raw
SDK/Firebase error leaking — cf. A-OBS), loading/disabled states, and that a brand-new unpaired account lands on the
correct "create or accept invite" home (not a broken/blank or paired view).
- **Duplicate / conflicting creation:** sign up with an **already-registered email** (clear "already in use", no crash,
offer sign-in); create a second account while one is signed in; re-run onboarding after completing it; accept an
invite while **already paired** (must be rejected cleanly); two devices accepting the **same invite** (single-use —
the second must fail gracefully).
- **Fake / malicious creation attempts (security — expect DENY, never crash or leak):** create an account that is
**NOT a member** of the test couple and attempt every cross-couple action (read messages/answers/dates/entitlements,
write to the couple, self-grant `premium`/`hasPremium`, join/hijack pairing with a guessed/expired/reused invite
code) — all must be **denied by rules** (this is the live execution of **D3**). Probe **invite-code abuse**: replay a
used code, use an expired code, brute-force/guess attempts (CSPRNG entropy + single-use + expiry must hold). Probe
**App Check**: a request without a valid token is rejected. Confirm a malformed/forged sign-up can't bypass profile
or membership requirements. **Any successful unauthorized create/read/write = P0.**
- **Account lifecycle around creation:** sign-out → sign-in (state restores, no stale couple); **delete account** then
re-create with the same email (clean slate, partner notified/unpaired); an unpaired/just-created account tapping a
stale notification or deep link is handled gracefully (no crash, sane landing).
- **Done = every creation avenue exercised** (happy + duplicate + malicious) with each attack **denied** and each happy
path validated end-to-end; findings filed with exact repro.
### Pass E — Notifications (every type delivers, deep-links, leaks nothing) ### Pass E — Notifications (every type delivers, deep-links, leaks nothing)
For each: trigger fires → delivered to the **right partner (never self)** → in **foreground/background/killed** For each: trigger fires → delivered to the **right partner (never self)** → in **foreground/background/killed**
correct channel + copy with **no private content****tap opens exactly the right item** (loaded, not generic Home/ correct channel + copy with **no private content****tap opens exactly the right item** (loaded, not generic Home/