Skip to content

test(15-2): hook integration tests — usePronunciation full mocked-API coverage#112

Merged
Simplemart17 merged 3 commits into
mainfrom
feature/15-2-hook-integration-tests
May 17, 2026
Merged

test(15-2): hook integration tests — usePronunciation full mocked-API coverage#112
Simplemart17 merged 3 commits into
mainfrom
feature/15-2-hook-integration-tests

Conversation

@Simplemart17

Copy link
Copy Markdown
Owner

Summary

  • Story 15-2 — NEW src/hooks/__tests__/use-pronunciation.test.tsx (13 cases) closes the largest hook-test gap.
  • Pre-15-2 usePronunciation had zero direct coverage; the other 3 hooks in the spec inventory have substantial shape/binding tests already (Stories 12-2 / 10-8 / 12-1 P8). Full-flow integration extensions to those existing test files deferred to 15-2-followup-existing-hook-flow-integration per Epic 14 retro lesson.
  • 0 source-module modifications — test-only story.
  • 3 operator decisions resolved per Recommended (Q1 react-test-renderer continuity, Q2 defer existing-hook extensions, Q3 mock at assessPronunciation lib boundary).

Story

  • Story ID: 15.2
  • Story Key: 15-2-hook-integration-tests
  • Story File: _bmad-output/implementation-artifacts/15-2-hook-integration-tests.md

Test plan

  • npx jest --no-coverage passes — +13 net cases (2159 → 2172).
  • Spot-check Case 12 (51 calls → history.length === 50, Story 12-12 FIFO integration).
  • Spot-check Case 5 (assessPronunciation throws → captureError("pronunciation-assessment") + classifyError-routed error).

🤖 Generated with Claude Code

3-agent adversarial review surfaced 9 actionable findings on the
usePronunciation hook integration test.

HIGH:
- BH-1 + EH-7 + EH-10: weakSounds assertion missing entirely.
  Added explicit empty-state assertion to Case 3 (default fixture
  scores ≥ 80 → identifyWeakSounds returns []). NEW Case 3b uses a
  low-scoring × 3 same-phoneme fixture so the aggregator actually
  produces a non-empty weakSounds list — pins the full integration
  wiring (hook → identifyWeakSounds → state.weakSounds).
- BH-2: Case 13 only tested snapshot-at-mount, not mirroring. NEW
  Case 13b uses renderer.update + flipped mock to verify the hook
  reflects recorder state CHANGES, not just initial-render values.
- EH-1: no audio-permission-denied path. NEW Case 4b stubs
  hasPermission:false + recorder.error + stopRecording → null and
  verifies the hook routes through the no-audio branch without
  firing captureError (user-driven, not Sentry-page-worthy).
- EH-8: Case 12 FIFO check didn't pin non-containment. Added
  explicit `history.some(h => h.accuracyScore === 0)).toBe(false)`
  so a regression that evicts from the tail (LIFO) or fails to
  evict at all is caught.
- EH-9: no transient isAssessing assertion. NEW Case 6b uses a
  hand-rolled deferred promise (Story 13-3 P8 pattern) to verify
  isAssessing flips true mid-Azure-call and false after settle.

MED:
- BH-5: NEW Case 8c asserts assessFromUri callback reference is
  stable across re-renders (pins useCallback empty-deps contract).
- BH-6: added `expect(isAssessing).toBe(false)` assertion to Case 2
  pinning that startAssessment does NOT set isAssessing — only
  finishAssessment does (Azure call in-flight semantic).
- EH-4: NEW Case 9b verifies clearResult on initial empty state
  is a no-op (pre-init defense).
- EH-6: NEW Case 8b stubs readAsStringAsync rejection (real-world
  cached-file-gone race) and verifies captureError + error surfaced
  + assessPronunciation NOT called.

Deferred (filed as follow-ups):
- 15-2-followup-reentrant-guard (EH-3 — low real-world hazard)
- 15-2-followup-getweakphonemes-ref-stability (EH-5)
- 15-2-followup-permission-denied-distinct-error (UX decision)
- 15-2-followup-distinct-fs-error-tag (telemetry granularity)

Story file housekeeping: Status: review → done; populated File List
+ Completion Notes per Acceptance Auditor APPROVE_WITH_NOTES.

+7 net test cases (13 → 20). All 4 quality gates green: type-check 0
/ lint 0 / prettier clean / jest 2179 tests pass (+7 from this PR).
@Simplemart17 Simplemart17 merged commit 546c5bb into main May 17, 2026
1 check failed
Simplemart17 added a commit that referenced this pull request May 17, 2026
…ters

Symmetry with 15-4/15-5/15-6 entries (added in the retro commit).
Pre-edit the 15-2 + 15-3 lines were plain 'backlog' with no PR
pointer; reviewers of PR #117 had no in-file signal that those
stories were in flight via PRs #112 and #113.

Each line now reads: 'backlog # PR #NNN open — status flips to
"done" when PR merges' matching the established pattern.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant