medium priority low complexity testing pending testing specialist Tier 4

Acceptance Criteria

Unit test verifies that LocationPrivacyConfig.load(orgId) calls the Supabase client with the correct organisation filter
Unit test verifies that all fields default to safe values (e.g., retention_days = 0, consent_required = true) when no config row exists for the org
Unit test verifies consent expiry date is calculated correctly: consentGrantedAt + consentDurationDays = expiryDate
Unit test verifies retention policy: isRetentionExpired returns true when now > grantedAt + retentionDays
Unit test verifies that config loaded for org A does not bleed into config loaded for org B (isolation test with two mock responses)
Unit test verifies that a null or partial JSON response from Supabase does not throw an unhandled exception — missing fields use defaults
All tests use Mockito mocks for the Supabase client — no real network calls are made
Test file achieves 100% branch coverage of the LocationPrivacyConfig class

Technical Requirements

frameworks
Flutter
flutter_test
Mockito
apis
Supabase PostgREST (location_privacy_config table)
data models
accessibility_preferences
performance requirements
All unit tests must complete in under 5 seconds total — no async delays or timers
security requirements
Tests must assert that consent_required defaults to true (not false) when config is absent — safe default is mandatory
Tests must assert that precision_level defaults to municipality-level (not exact GPS) when absent

Execution Context

Execution Tier
Tier 4

Tier 4 - 323 tasks

Can start after Tier 3 completes

Implementation Notes

Inject a SupabaseClient (or a thin repository interface) into LocationPrivacyConfig rather than using a global singleton — this enables Mockito mocking without overriding globals. For date calculations, accept an optional DateTime now parameter (defaulting to DateTime.now()) to make tests deterministic without package:clock. Define a LocationPrivacyConfigDefaults const for all default values so tests assert against the same constants used in production code. If a config row exists but a field is null, the fromJson factory should substitute the corresponding default.

Ensure the test file uses setUpAll to register fallback values for Mockito generics if using null safety.

Testing Requirements

Unit tests only — no integration or widget tests required for this task. Use flutter_test with @GenerateMocks([SupabaseClient]) and Mockito's when/thenReturn/thenAnswer pattern. Test cases: (1) happy path load; (2) absent config fallback; (3) consent expiry calculation with fixed clock (use a Clock abstraction or pass DateTime as parameter to make tests deterministic); (4) retention expiry calculation; (5) org isolation with two separate mock setups; (6) partial JSON (null fields). Group tests with group() blocks per feature area.

Run with flutter test --coverage and verify 100% branch coverage.

Component
Location Privacy Configuration
infrastructure low
Epic Risks (3)
high impact medium prob integration

Supabase's hosted PostGIS extension behaviour may differ from the local emulator for spatial RPC functions, causing bounding-box queries to return incorrect results or fail in production while passing locally.

Mitigation & Contingency

Mitigation: Write integration tests against the Supabase emulator from the start and run the same test suite against a staging Supabase project before merging. Use ST_DWithin and ST_MakeEnvelope in plain SQL first, validate with psql, then wrap as RPC.

Contingency: If PostGIS RPC proves unreliable, fall back to client-side bounding box filtering on a full fetch of consented mentor locations (acceptable for up to ~200 mentors per chapter) until the spatial query is stabilised.

medium impact low prob dependency

OpenStreetMap tile usage may require attribution handling and rate limiting. Switching to Google Maps Flutter plugin mid-implementation would require significant rework of the map-provider-integration abstraction.

Mitigation & Contingency

Mitigation: Define the map-provider-integration abstraction interface before selecting the SDK so that the concrete implementation is swappable. Implement OSM first with correct attribution. Document Google Maps as the alternate with its API key setup steps.

Contingency: If OSM tiles are rejected by stakeholders or tile server limits are hit, activate the Google Maps Flutter plugin implementation behind the same interface without touching any UI or service code.

high impact low prob security

Incorrect RLS configuration could allow a coordinator to query mentor locations from a different organisation, constituting a GDPR data breach.

Mitigation & Contingency

Mitigation: Write dedicated RLS integration tests with two isolated test organisations and assert that cross-organisation queries return zero rows. Include these tests in CI. Have a second developer review all RLS policy SQL before migration is applied.

Contingency: If a cross-organisation data leak is discovered post-deployment, immediately disable the map feature via the organisation feature flag, revoke the affected Supabase RLS policy, and notify the data protection officer per the organisation's GDPR incident response procedure.