medium priority medium complexity testing pending testing specialist Tier 2

Acceptance Criteria

Widget test pumps buildMapWidget with an empty markers list and asserts no exceptions are thrown and the widget tree is non-null
Widget test simulates a drag gesture on the map widget and asserts onBoundsChanged callback is invoked at least once
Unit test calls getBoundsFromController() after initial render and asserts the returned LatLngBounds has valid non-NaN north/south/east/west values
Abstraction boundary test: statically verify that no flutter_map import appears in any file that consumes MapProviderIntegration (not the implementation file itself)
Widget test asserts map widget renders with 3 markers without overflow or layout errors
Widget test asserts that disposing the widget does not throw a 'setState called after dispose' or 'controller was disposed' error
Unit test verifies that passing a null or empty center coordinate throws an AssertionError or ArgumentError at the call site, not deep in flutter_map
All tests pass with flutter test --no-sound-null-safety disabled (full null safety required)

Technical Requirements

frameworks
Flutter
flutter_test
flutter_map
performance requirements
Widget tests must complete within 10 seconds including pump cycles — avoid real tile loading in tests (use a mock tile provider)
security requirements
Test fixtures must not embed real mentor coordinates — use fake coordinates (e.g., 0.0, 0.0) in all test data
ui components
MapProviderIntegration.buildMapWidget
MapController (internal)

Execution Context

Execution Tier
Tier 2

Tier 2 - 518 tasks

Can start after Tier 1 completes

Implementation Notes

To prevent network tile calls in tests, inject a TileProvider into OpenStreetMapProviderIntegration and provide a BlankTileProvider (returns transparent image) as a default in test environment. Use Riverpod's ProviderContainer with overrides in widget tests rather than the real DI graph. For the callback test, use tester.drag() on the map widget's finder and await pumpAndSettle() before asserting. The abstraction boundary test can be implemented as a dart analyze custom lint rule or a simple shell script checking imports — document the chosen approach in the test file.

Wrap MapController access in a null-safety guard since the controller may not be attached synchronously after the first pump.

Testing Requirements

Widget tests using flutter_test pumpWidget with a MaterialApp wrapper. For the callback test, use a Completer to capture the onBoundsChanged value and await it after the gesture simulation. Use a mock TileProvider (NetworkTileProvider replacement) or disable tile loading entirely by injecting a blank tile provider so tests do not make network calls. For the abstraction boundary test, write a Dart analysis script or use a linting rule to assert no flutter_map symbols appear in caller files.

Dispose test: use pumpWidget(Container()) after initial render and call tester.pump() to trigger disposal, then assert no errors in the test log.

Component
Map Provider Integration
infrastructure high
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.