medium priority low complexity testing pending testing specialist Tier 2

Acceptance Criteria

TimeWindowService test suite covers all five TimeWindow enum values: thisWeek, thisMonth, thisQuarter, thisYear, and custom
Leap year boundary tests pass: Feb 28 → Mar 1 in a non-leap year and Feb 28 → Feb 29 in a leap year produce correct date ranges
DST boundary tests pass: spring-forward and fall-back dates produce correct durations (23h and 25h days handled)
Custom range passthrough test verifies that start and end dates are forwarded unmodified to the repository query
Invalid range rejection test verifies that start > end throws an ArgumentError (or equivalent domain exception)
ChapterScopeResolver cache-hit test verifies that a second call within TTL does NOT call the Supabase client again
Cache-expiry test uses a fake clock to advance past TTL and verifies that a fresh Supabase fetch is triggered
AuthorizationException is thrown when the caller's role is neither coordinator nor admin
Session-change invalidation test verifies that swapping to a different authenticated user clears the cached scope
All tests are self-contained with no shared mutable state between test cases
Test file coverage report shows ≥ 95% branch coverage for both service classes
All tests pass with `flutter test --coverage` in CI without flakiness

Technical Requirements

frameworks
flutter_test
mockito
build_runner
apis
Supabase client (mocked)
Dart DateTime API
data models
TimeWindow (enum)
ChapterScope
DateRange
performance requirements
Full test suite completes in under 30 seconds
No real network calls — all Supabase interactions mocked
security requirements
Tests must not embed real Supabase credentials or JWT tokens
AuthorizationException path must be explicitly covered to prevent privilege escalation regressions

Execution Context

Execution Tier
Tier 2

Tier 2 - 518 tasks

Can start after Tier 1 completes

Implementation Notes

Ensure TimeWindowService already accepts a clock abstraction (e.g., a `DateTime Function()` parameter defaulting to `DateTime.now`) before writing the DST tests — if it doesn't, refactor the service to accept the injection first. For ChapterScopeResolver, mock `SupabaseClient.from('chapters').select(...)` using mockito's `when(...).thenAnswer(...)` pattern. Use `addTearDown(mockReset)` to reset mock state between tests instead of `setUp`. DST dates for Norway (CET/CEST): spring-forward is last Sunday in March, fall-back is last Sunday in October — use explicit UTC offsets in test fixtures rather than relying on the CI machine's timezone.

Group related tests with `group()` and use descriptive test names that read as sentences.

Testing Requirements

Pure unit tests using flutter_test and mockito. Generate mocks with build_runner (@GenerateMocks annotation). Structure tests in two describe blocks: one for TimeWindowService and one for ChapterScopeResolver. Use a FakeClock or manual DateTime injection to control time in cache-expiry and DST tests — avoid real DateTime.now() calls inside service implementations if not already injected.

Verify branch coverage with `flutter test --coverage` and lcov; fail CI if coverage drops below 95%. Include at least one negative test (invalid input) per public method.

Component
Time Window Service
service low
Epic Risks (3)
medium impact medium prob technical

Materialized views over large activity tables may have refresh latency exceeding the 2-second SLA under high insert load, causing stale data to appear on the dashboard immediately after a peer mentor registers an activity.

Mitigation & Contingency

Mitigation: Design the materialized view refresh trigger to run asynchronously via a Supabase Edge Function rather than a synchronous trigger, and set a maximum staleness tolerance of 5 seconds documented in the feature spec. Add a CONCURRENTLY refresh strategy so reads are never blocked.

Contingency: If refresh latency cannot meet SLA, fall back to a regular (non-materialized) view for the dashboard and accept slightly higher query cost per request. Revisit materialized approach once Supabase pg_cron or background workers are available.

high impact medium prob integration

The aggregation counting rules for the dashboard may diverge from those used in the Bufdir export pipeline (e.g., which activity types count, how duplicate registrations are handled), creating a reconciliation burden for coordinators at reporting time.

Mitigation & Contingency

Mitigation: Run the BufDir Alignment Validator against a shared reference dataset before any view is merged to main. Encode the counting rules as a shared Supabase function called by both the stats views and the export query builder so there is a single source of truth.

Contingency: If divergence is discovered post-launch, ship a visible banner on the dashboard stating that numbers are indicative and may differ from the export until the reconciliation fix is deployed. Prioritize the fix as a P0 defect.

high impact low prob security

Multi-chapter coordinators (up to 5 chapters per NHF requirement) require RLS policies that filter on an array of chapter IDs, which is more complex than single-value RLS and could be misconfigured, leaking data across chapters or blocking legitimate access.

Mitigation & Contingency

Mitigation: Write integration tests that verify cross-chapter isolation for a coordinator assigned to chapters A and B cannot see data from chapter C. Use parameterized RLS policies with auth.uid()-based chapter lookup to avoid hardcoded values.

Contingency: If RLS misconfiguration is detected in testing, temporarily restrict coordinator queries to single-chapter scope (coordinator's primary chapter) and ship multi-chapter support as a fast-follow patch once RLS logic is verified.