high priority low complexity testing pending testing specialist Tier 2

Acceptance Criteria

Test file exists for PeriodConfigurationRepository with at least 7 distinct test cases
Test file exists for BufdirAggregationRepository with at least 6 distinct test cases
Supabase client is mocked using Mockito — no real network calls are made in any test
Successful fetch test verifies that the returned List<PeriodPreset> matches the mock response payload
Cache hit test verifies that the Supabase client is NOT called when valid cached data exists
Network error fallback test verifies that cached data is returned when a SocketException or TimeoutException occurs
RLS-denied response test verifies that a PostgrestException with code 403 maps to PermissionException
Empty result set test verifies that an empty list is returned without throwing an exception
BufdirAggregationRepository invalid date range test verifies that ArgumentError is thrown when endDate < startDate without a network call
Test coverage report shows 90%+ line coverage for both repository classes
All tests pass with flutter test --coverage and produce no flaky failures

Technical Requirements

frameworks
flutter_test
Mockito
build_runner
apis
Supabase client mock interfaces
data models
PeriodPreset
BufdirCategoryCount
performance requirements
All unit tests must complete in under 5 seconds total
No test should rely on timers or async delays longer than 100 ms
security requirements
Mock responses must not include real organisation IDs or personal data
Test fixtures should use clearly fictional data (e.g. org_id: 'test-org-123')

Execution Context

Execution Tier
Tier 2

Tier 2 - 518 tasks

Can start after Tier 1 completes

Implementation Notes

Run `flutter pub add --dev mockito build_runner` if not already present. Annotate the test file with @GenerateMocks([SupabaseClient, SupabaseQueryBuilder]) and run `flutter pub run build_runner build` to generate mocks. Organise test cases into two describe-style groups: 'PeriodConfigurationRepository' and 'BufdirAggregationRepository'. For the cache hit test, pre-seed the mock local cache with data and verify that the Supabase mock's fetch method is called zero times using Mockito's verifyNever.

For the network error fallback, throw a SocketException from the mock and assert the repository returns the pre-seeded cached list. For the RLS test, throw a PostgrestException with statusCode 403 and assert the caught exception is of type PermissionException. Keep test fixtures in a separate test/fixtures/ directory as JSON files loaded with rootBundle.loadString or hardcoded maps to keep tests readable.

Testing Requirements

Unit tests only — no widget tests or integration tests in this task. Use flutter_test test groups to organise tests by repository class and scenario. Use Mockito's @GenerateMocks annotation and build_runner to generate mock classes. Structure tests using the Arrange-Act-Assert pattern with descriptive test names.

Generate a coverage report using `flutter test --coverage` and verify both repository files appear above 90% line coverage in the LCOV report. Document any untested branches (e.g. platform-specific code paths) with a comment explaining why they are excluded.

Component
Period Configuration Repository
data low
Epic Risks (3)
high impact medium prob security

Supabase RLS policies for period preset configuration may be missing or incorrectly scoped, causing one organisation's presets to leak to another or write operations to fail silently.

Mitigation & Contingency

Mitigation: Define and review RLS policies for the bufdir_period_presets table in the migration file before any repository code is written. Include an integration test that verifies cross-organisation isolation using two distinct org credentials.

Contingency: If RLS is misconfigured in production, immediately disable the period preset fetch endpoint and fall back to hardcoded global presets until the policy is corrected and redeployed.

medium impact medium prob technical

The activities table may lack a composite index on (organisation_id, activity_date), causing the range count query in BufdirAggregationRepository to perform a full table scan and exceed acceptable response time for large organisations.

Mitigation & Contingency

Mitigation: Add a migration that creates a composite index on (organisation_id, activity_date) as part of this epic. Benchmark the count query against a representative dataset (10 000+ rows) before marking the epic complete.

Contingency: If query latency is unacceptable after indexing, move the count query to a Supabase RPC function that leverages a materialised view or partial index, accepting a slight staleness window.

medium impact medium prob technical

Flutter's native date picker widgets have known accessibility gaps (missing semantic labels, non-standard focus traversal) that may prevent WCAG 2.2 AA compliance out of the box, requiring a custom implementation.

Mitigation & Contingency

Mitigation: Evaluate third-party accessible date picker packages (e.g., table_calendar with custom semantics) against WCAG 2.2 AA criteria before beginning implementation. Document the chosen approach in the epic kick-off.

Contingency: If no package meets accessibility requirements, implement a simple text-field-based date entry with explicit semantic labels and format hints as an accessible fallback, deferring a fully visual calendar to a later iteration.