BLoC and fl_chart Adapter Integration Tests
epic-coordinator-statistics-dashboard-core-logic-task-014 — Write bloc_test unit tests for StatsBloc and PersonalStatsBloC covering: loading/loaded/error state transitions, FilterChanged debounce behaviour, activity stream invalidation trigger, and auto-refresh flow. Write widget tests for FlChartAdapter verifying that BarData and PieChartData are constructed with correct design token colours and that adapters render without exceptions when given empty and populated view models.
Acceptance Criteria
Technical Requirements
Execution Context
Tier 5 - 253 tasks
Can start after Tier 4 completes
Implementation Notes
The most error-prone part is the debounce test: use FakeAsync.withZone, add multiple FilterChanged events, advance time by less than the debounce duration, verify service not called, then advance past debounce and verify exactly one call. For the activity stream invalidation test, expose a StreamController in the mock service and add an event to it mid-test to trigger the BLoC reaction. For FlChartAdapter widget tests, wrap in a ProviderScope or BlocProvider as appropriate and inject a ThemeData carrying design tokens — this ensures colour assertions test the real token resolution path. Avoid testing fl_chart internal rendering; only assert on the data objects the adapter constructs.
Testing Requirements
BLoC tests with bloc_test package using blocTest
Design token colour assertions should compare Color values from the app's AppColors constants, not hardcoded hex strings, so that the test breaks if tokens change unexpectedly. Each BLoC gets its own test file. Adapter widget tests live in a separate adapters_test.dart file.
fl_chart's default colour palette may not meet WCAG 2.2 AA contrast requirements when rendered on the app's dark or light backgrounds. If segment colours are insufficient, the donut chart will fail accessibility audits, which is a compliance blocker for all three organisations.
Mitigation & Contingency
Mitigation: Define all chart colours in the design token system with pre-validated contrast ratios. Run the contrast-ratio-validator against every chart colour during the adapter's unit tests. Use the contrast-safe-color-palette as the source palette.
Contingency: If a colour fails validation, replace with the nearest compliant token. If activity types exceed the available token set, implement a deterministic hashing algorithm that maps activity type IDs to compliant colours.
StatsBloc subscribing to the activity registration stream creates a long-lived subscription. If the subscription is not disposed correctly when the dashboard is closed, it will cause a stream leak and potentially trigger re-fetches on a disposed BLoC, resulting in uncaught errors in production.
Mitigation & Contingency
Mitigation: Implement subscription disposal in the BLoC's close() override. Write a widget test that navigates away from the dashboard and asserts no BLoC events are emitted after disposal.
Contingency: If leaks are detected in QA, add a mounted check guard before emitting states from async callbacks, and audit all other BLoC stream subscriptions in the codebase for the same pattern.
PersonalStatsService's Phase 4 gamification data structure is designed against an assumed future schema. If the Phase 4 Spotify Wrapped feature defines a different data contract when it is developed, the structure built now will require a breaking change and migration.
Mitigation & Contingency
Mitigation: Document the contribution data structure with explicit field semantics and versioning comments. Keep the Phase 4 fields as optional/nullable so they do not break existing consumers if the schema evolves.
Contingency: If the Phase 4 schema diverges significantly, the personal stats data can be re-mapped in a thin adapter layer without changing PersonalStatsService's core implementation.