high priority medium complexity testing pending testing specialist Tier 7

Acceptance Criteria

Period selector widget tests cover all preset options (last 3 months, last 6 months, last year, custom range) with correct state emission on selection
Custom date range picker tests verify start-date-before-end-date validation and rejection of future end dates
Format selector tests confirm only one format can be active at a time and that state transitions emit correct BLoC events
Confirmation dialog renders correct period label, format label, estimated record count, and cancel/confirm buttons in all states
Progress indicator tests cover idle, in-progress (0%, 50%, 100%), success, and error states with correct widget rendering
Export history list item tests cover normal, expired-URL, and zero-record-period states with correct icon and label rendering
Pagination tests verify that scrolling to end of list triggers load-next-page event and renders skeleton loaders
Re-download tap handler tests verify that tapping triggers the correct BLoC event and navigates to share sheet or shows error snackbar
Golden tests exist for: confirmation dialog, progress indicator success state, export history list item (normal and expired)
Line coverage ≥80% on all five export UI components as reported by flutter test --coverage
All tests pass in CI without flakiness across 3 consecutive runs

Technical Requirements

frameworks
Flutter
flutter_test
BLoC
Riverpod
data models
ExportPeriod
ExportFormat
ExportJob
ExportHistoryItem
performance requirements
Each widget test file must complete in under 10 seconds
Golden test comparisons must use a fixed pixel ratio (2.0) for determinism
security requirements
No real Supabase credentials used in tests — use mock repositories
Expired URL state must be handled without exposing raw signed URL in error messages
ui components
BufdirPeriodSelectorWidget
BufdirFormatSelectorWidget
BufdirExportConfirmationDialog
BufdirExportProgressIndicator
BufdirExportHistoryList

Execution Context

Execution Tier
Tier 7

Tier 7 - 84 tasks

Can start after Tier 6 completes

Implementation Notes

Structure test files mirroring the source: one test file per widget. Use `blocTest` from bloc_test for BLoC event/state verification and `pumpWidget` with a `MaterialApp` wrapper for widget tests. For the pagination test, use a ScrollController and programmatically scroll to the bottom rather than relying on real scroll physics. Golden tests must be generated on a Linux CI runner to avoid platform font differences — document this in a test README.

For expired-URL tests, mock the repository to return an `ExportHistoryItem` with `isExpired: true` and assert that the re-download button shows a 'Link expired' tooltip rather than triggering download. Ensure all BLoC streams are closed in `tearDown` to prevent test pollution.

Testing Requirements

Use flutter_test with MockBloc/MockCubit (bloc_test package) to inject controlled states into each widget under test. Write pumpWidget wrappers that provide the required BLoC/Riverpod providers. Cover happy path, empty state, error state, and boundary conditions for every widget. Use goldentest package (golden_toolkit or alchemist) pinned to a specific Flutter version for reproducible golden files.

Run coverage with `flutter test --coverage` and enforce ≥80% line coverage via a CI lcov threshold check. All tests must be deterministic — avoid real timers; use fake_async or clock overrides.

Component
Bufdir Export Trigger Screen
ui medium
Epic Risks (2)
medium impact medium prob technical

For large exports that run for 10–30 seconds, a static loading spinner will feel broken to users on slow mobile connections. If the UI cannot display meaningful progress during the export pipeline, coordinators may abandon the flow or trigger duplicate exports by pressing the button multiple times.

Mitigation & Contingency

Mitigation: Implement streaming progress events from the orchestrator BLoC through named pipeline stages (querying, mapping, generating, uploading). Display each stage label with a progress indicator on the trigger screen. Disable the generate button immediately on first tap to prevent duplicates.

Contingency: If streaming pipeline progress is not feasible in the first release, implement a deterministic stage-based progress animation (10% querying, 50% generating, 90% uploading) that gives users feedback without requiring real server events.

high impact medium prob technical

Custom date range pickers are among the most common accessibility failures in mobile apps. Blindeforbundet users rely on VoiceOver, and NHF users include people with cognitive impairments. A non-accessible period picker could make the entire export workflow unusable for a significant portion of the intended user base.

Mitigation & Contingency

Mitigation: Build the period picker using Flutter's native date picker semantics as the foundation, with preset shortcuts as primary navigation (reducing the need to interact with the custom range picker at all). Test with VoiceOver on iOS and TalkBack on Android before UI epic sign-off. Engage Blindeforbundet's test contact for accessibility validation.

Contingency: If the custom date range picker cannot be made fully accessible before release, ship only the preset period shortcuts (covering the majority of use cases) and add the custom range picker in a follow-up sprint after dedicated accessibility remediation.