Integration test BufdirPreviewService end-to-end
epic-bufdir-report-preview-core-logic-task-010 — Write integration tests for the full preview assembly pipeline using flutter_test with mocked repository and mapper dependencies. Test scenarios: successful assembly returns a BufdirPreviewModel with non-empty sections and a ValidationResult, repository failure propagates as a typed error, prior-period unavailable results in anomaly checks being skipped (no false positives), session cache returns the same model on second call without invoking the repository again, and cache invalidation on period change triggers a fresh repository fetch.
Acceptance Criteria
Technical Requirements
Execution Context
Tier 5 - 253 tasks
Can start after Tier 4 completes
Implementation Notes
Since this is an integration test of the full service pipeline (not a unit test of a single method), wire up a real BufdirPreviewService with mocked dependencies rather than mocking the service itself. This validates that the orchestration logic in assemblePreview() and the session state in the StateNotifier interact correctly. For the cache-hit test, assert that the mocktail verify(mockRepository.fetchAggregatedData).called(1) holds after two assemblePreview calls. For the period-change test, call assemblePreview('period-A', orgId), then assemblePreview('period-B', orgId), and verify fetchAggregatedData was called twice.
Place all fixture builders in a test/fixtures/bufdir_preview_fixtures.dart helper file to keep test bodies readable.
Testing Requirements
Use flutter_test with mocktail for all dependency mocking. Structure tests with group() blocks per scenario. Use fakeAsync and pump() to control async resolution. Mock BufdirPreviewRepository to return: (a) valid BufdirReportData, (b) a typed RepositoryException, (c) valid current-period data with null prior-period.
Mock BufdirReportStructureMapper to return a deterministic ordered list of BufdirReportSection fixtures. Mock BufdirFieldValidationService.validate() to return a ValidationResult with known entries. Use verify() from mocktail to assert call counts on repository methods. Each test should call setUp() to create fresh mock and service instances.
The exact minimum threshold values required by Bufdir guidelines (e.g., minimum participant counts per section) may not be formally documented in machine-readable form. If thresholds must be researched or negotiated during implementation, the validation service will be delayed and may launch with incomplete rules, reducing its effectiveness.
Mitigation & Contingency
Mitigation: Compile threshold rules from the Bufdir reporting guidelines PDF before sprint start. Store rules in a separate configuration file (not hardcoded in the service class) so they can be updated without a service rewrite. Treat unknown thresholds as 'no minimum' to avoid false errors.
Contingency: Launch with completeness and anomaly validation only, shipping threshold compliance rules as a follow-on config update once rules are confirmed with Bufdir. Flag this as a known limitation in the coordinator help text.
BufdirPreviewService coordinates three async operations (fetch aggregated data, map structure, run validation). Race conditions or partial failures in this chain could produce an inconsistent preview model — e.g., a model with field values but no validation results — which would silently mislead coordinators into thinking the report is clean.
Mitigation & Contingency
Mitigation: Model the orchestration as a single BLoC/Cubit state machine with explicit states (Loading, Loaded, Error) and ensure validation is always run atomically after mapping, never in parallel. Write integration tests that simulate network failure at each step of the chain.
Contingency: If a partial failure state reaches production, detect it via the missing validation summary field in the preview model and show a full-screen error state rather than an incomplete preview, prompting the coordinator to retry.