critical priority high complexity testing pending testing specialist Tier 7

Acceptance Criteria

All tests run with flutter test — zero platform channel invocations (verified by absence of MissingPluginException)
Test coverage ≥ 90% line coverage and 100% branch coverage for SpeechRecognitionService
Initialization success path: verify service enters idle state, no bridge calls made until startListening()
Initialization failure path (permission denied at init): verify SpeechRecognitionErrorEvent emitted, state idle
Permission denial on startListening(): verify permissionDenied error event emitted, recoverable=true
startListening() → stopListening() happy path: verify bridge calls in correct order, FinalTranscriptionEvent emitted before stream closes
Double startListening() call: verify ConcurrentSessionException thrown on second call
Partial + final event sequence: verify PartialTranscriptionEvent × 3 followed by FinalTranscriptionEvent emitted in order
All SpeechErrorCode enum values covered by at least one test each
Locale selection: verify 'nb-NO' passed to bridge when device locale is Norwegian; verify fallback to 'en-US' for unsupported locales
dispose() idempotency: verified by calling dispose() three times with no exception
startListening() after dispose(): verified to throw DisposedException
All tests are independent — no shared mutable state between tests (use setUp/tearDown)

Technical Requirements

frameworks
flutter_test
mockito
Dart build_runner (for mockito code gen)
apis
MockNativeSpeechApiBridge (generated mock)
StreamController test helpers
expectLater() with emitsInOrder()
data models
SpeechRecognitionService (class under test)
All SpeechRecognitionEvent subtypes
SpeechErrorCode enum
performance requirements
Full unit test suite must complete in under 30 seconds
Each individual test must complete in under 500ms
security requirements
No real API keys, credentials, or Supabase URLs in test files
Test transcript strings must not contain real personal data

Execution Context

Execution Tier
Tier 7

Tier 7 - 84 tasks

Can start after Tier 6 completes

Implementation Notes

Generate MockNativeSpeechApiBridge with @GenerateMocks([NativeSpeechApiBridge]) and run build_runner once. Structure test file as speech_recognition_service_test.dart with nested group() blocks. For stream testing, collect all emitted events using stream.toList() with a bounded expectation, or use StreamQueue for step-by-step assertion. Example pattern for event sequence test: final queue = StreamQueue(service.startListening()); bridge.simulatePartialResult('hei'); expect(await queue.next, isA()); bridge.simulatePartialResult('hei verden'); expect(await queue.next, isA()); bridge.simulateFinalResult('hei verden', confidence: 0.92); expect(await queue.next, isA()); await queue.cancel().

Use FakeAsync from fake_async package for timeout-related tests to avoid real delays. Add a test for the Norwegian accessibility use case: confirm 'nb-NO' locale is used since HLF and Blindeforbundet users are Norwegian-speaking.

Testing Requirements

Pure unit tests using flutter_test and mockito. Group tests by behavior area: 'initialization', 'session lifecycle', 'event streaming', 'error handling', 'locale selection', 'disposal'. Use StreamQueue from async package for ordered stream assertions. Use verify() and verifyNever() for bridge interaction assertions.

Use throwsA(isA()) for exception assertions. Run with --coverage flag in CI to enforce 90% line coverage threshold.

Component
Speech Recognition Service
service high
Epic Risks (2)
medium impact medium prob technical

The speech_to_text Flutter package delegates accuracy entirely to the OS-native engine. Norwegian accuracy for domain-specific vocabulary (medical terms, organisation names, accessibility terminology) may fall below the 85% acceptance threshold on older devices or in noisy environments, causing user frustration and manual correction overhead that negates the time saving.

Mitigation & Contingency

Mitigation: Configure the SpeechRecognitionService with Norwegian as the explicit locale and test against a representative corpus of peer mentoring vocabulary on target devices. Expose locale switching so users can fallback to Bokmål vs Nynorsk. Clearly set user expectations in the UI that transcription is a starting point for editing, not a finished product.

Contingency: If accuracy is consistently below threshold on specific device/OS combinations, add a device-capability check that hides the dictation button with an explanatory message rather than offering a degraded experience. Document affected device models for QA and org contacts.

medium impact low prob dependency

The speech_to_text Flutter package is a third-party dependency that may introduce breaking API changes or deprecations on major version upgrades, requiring rework of SpeechRecognitionService when Flutter or platform OS versions are updated.

Mitigation & Contingency

Mitigation: Wrap all speech_to_text API calls behind the SpeechRecognitionService interface so that package changes are isolated to one file. Pin the package version in pubspec.yaml and review changelogs before any upgrade. Write integration tests that exercise the package contract so regressions are caught immediately.

Contingency: If the package is abandoned or has unresolvable issues, NativeSpeechApiBridge already provides the platform-channel abstraction needed to implement a direct plugin replacement with minimal changes to SpeechRecognitionService.