high priority medium complexity testing pending testing specialist Tier 5

Acceptance Criteria

All five specified test scenarios are implemented as named test cases in a single integration test file
Successful assembly test verifies BufdirPreviewModel has at least one section and ValidationResult is non-null with at least one entry
Repository failure test verifies the exact typed error class (not Exception or dynamic) is re-thrown by the service
Prior-period unavailable test verifies ValidationResult contains zero anomaly-comparison entries and no unrelated validation errors are introduced
Cache hit test verifies the repository mock's fetchAggregatedData is called exactly once despite two assemblePreview calls with identical arguments
Cache invalidation test verifies repository is called a second time after period change, returning an updated model
All tests pass with flutter test in CI without requiring a live Supabase connection
Test file is located at test/integration/bufdir_preview_service_integration_test.dart
Each test is independent — no shared mutable state between test cases
Tests run in under 10 seconds total on a standard CI machine

Technical Requirements

frameworks
Flutter
flutter_test
mocktail
apis
BufdirPreviewService.assemblePreview()
BufdirPreviewService.getCachedPreview()
BufdirPreviewService.invalidate()
BufdirPreviewRepository (mocked)
BufdirReportStructureMapper (mocked)
BufdirFieldValidationService (mocked)
data models
BufdirPreviewModel
BufdirReportData
BufdirAggregatedField
ValidationResult
BufdirPreviewSessionState
performance requirements
All integration tests must complete within 10 seconds total
Each individual test must complete within 3 seconds using fakeAsync where appropriate
security requirements
No real Supabase credentials or organisation data in test fixtures — use synthetic periodId and orgId values
Test fixtures must not contain realistic PII (names, addresses, personal numbers)

Execution Context

Execution Tier
Tier 5

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.

Component
Bufdir Preview Service
service high
Epic Risks (2)
medium impact medium prob scope

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.

high impact low prob technical

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.