Widget tests for progress indicator and summary widget
epic-bufdir-data-aggregation-ui-task-008 — Write flutter_test widget tests covering: AggregationProgressIndicator renders correct stage highlights for each BLoC state, warning banner appears and dismisses correctly, retry button dispatches correct event, AggregationSummaryWidget renders all metric sections from mock AggregationSummaryData, unmapped activity warning section is conditionally shown, and numeric locale formatting is correct. Target 90%+ branch coverage for both widgets.
Acceptance Criteria
Technical Requirements
Execution Context
Tier 5 - 253 tasks
Can start after Tier 4 completes
Implementation Notes
Use bloc_test's MockBloc approach: class MockAggregationBloc extends MockBloc
Key coverage gap to watch: the conditional unmapped warnings section — ensure both the empty and non-empty branches have dedicated tests. Use Key() widgets on critical testable elements (warning section, retry button, stage indicators) to make finders robust.
Testing Requirements
All tests use flutter_test WidgetTester. BLoC states are injected by wrapping the widget under test in BlocProvider(create: (_) => MockAggregationBloc()) and using whenListen / MockBloc patterns. Each test follows Arrange-Act-Assert: (1) arrange: build widget tree with specific state/data; (2) act: pump or tap; (3) assert: find.text / find.byType / find.byKey / expect(tester.getSize()...). Use pumpAndSettle() only where animations are expected; use pump() for instant state changes.
Create a shared test_fixtures.dart file with factory constructors for AggregationSummaryData to avoid test data duplication. Run flutter test --coverage and generate lcov report to verify 90%+ branch coverage. Include a negative test for each conditional render path (both the true and false branch).
For NHF with 1,400 local chapters, rendering a geographic breakdown as a flat list in the AggregationSummaryWidget would produce an unscrollable wall of data that is unusable on a mobile screen. Coordinators need to verify geographic completeness before export, but the raw chapter list is too long to review.
Mitigation & Contingency
Mitigation: Design the geographic distribution section as a collapsible two-level hierarchy: regions are shown expanded by default with their aggregate count, individual chapters are collapsed under each region and expandable on tap. Show only non-zero regions by default with a 'show empty regions' toggle.
Contingency: If the hierarchical display is too complex to implement before the submission deadline, fall back to a region-only summary view with a total count of active chapters per region and a note that chapter-level detail is available in the full export file.
The aggregation BLoC must handle a multi-stage async pipeline with partial success states, warning accumulation across stages, and retry logic for individual failed stages. If the state model is too simplistic (e.g., loading/success/error), warning states and partial results will be lost on retry, confusing coordinators who see warnings disappear and reappear.
Mitigation & Contingency
Mitigation: Model the BLoC state as a rich sealed class hierarchy: AggregationIdle, AggregationRunning(stage, completedStages, accumulatedWarnings), AggregationComplete(result, warnings), AggregationFailed(failedStage, accumulatedWarnings, error). Accumulated warnings persist across retry attempts so coordinators see the full warning history.
Contingency: If state management complexity causes repeated bugs near the deadline, simplify to a single AggregationResult value object that captures success, warnings, and error as nullable fields, and drive both UI components from that single object rather than a live BLoC stream.