Unit test suite for MentorLocationService
epic-geographic-peer-mentor-map-core-services-task-012 — Write comprehensive unit tests for MentorLocationService covering: consent enforcement (opted-out mentors excluded), bounding box query delegation to repository mock, filter integration via MentorFilterService mock, offline cache hit and miss scenarios, haversine sort correctness, and BLoC state transitions for all event types. Use mocktail for mocking. Target 90%+ coverage on service and BLoC classes.
Acceptance Criteria
Technical Requirements
Execution Context
Tier 5 - 253 tasks
Can start after Tier 4 completes
Implementation Notes
Use `mocktail` `registerFallbackValue` for any custom value objects (e.g., `BoundingBox`, `FilterCriteria`) that are passed to mocked methods. For haversine sort tests, pre-calculate expected distances manually for 3–5 known coordinate pairs and assert ordering. For cache tests, inject a fake clock (via a `Clock` abstraction or `DateTime` factory override) rather than using `Future.delayed`. BLoC tests should use `blocTest` from the `bloc_test` package to keep assertions readable.
Ensure each `group` block has a `setUp` that creates fresh mock instances to prevent test pollution. Add a `tearDown` that verifies no unexpected mock interactions occurred (`verifyNoMoreInteractions`).
Testing Requirements
Pure unit tests using `flutter_test` and `mocktail`. Use `bloc_test` package for BLoC state transition assertions (`blocTest
Create a shared `fixtures/mentor_location_fixtures.dart` file with reusable test data to avoid duplication. Run `flutter test --coverage` and verify lcov report. No widget tests in this task — pure logic only.
The dual BLoC state machines (map view state + filter state) may introduce subtle synchronisation bugs where filter changes do not correctly re-trigger viewport queries, causing stale data to appear on the map.
Mitigation & Contingency
Mitigation: Define all BLoC state transitions in a state diagram before implementation. Use flutter_bloc's BlocObserver in development mode to log every state transition. Write explicit unit tests for filter-change → re-query transitions.
Contingency: If state synchronisation bugs appear in integration testing, refactor to a single unified BLoC that owns both map viewport state and filter state, eliminating cross-BLoC dependencies.
Cached mentor location data may become stale (mentors move, pause, or revoke consent) and coordinators in offline mode could be shown incorrect mentor information, leading to wasted outreach.
Mitigation & Contingency
Mitigation: Display a clear timestamp on cached data indicating when it was last synced. Set cache TTL to 24 hours and show an 'offline — data from [date]' banner. Revoked consent removes the mentor from the cache on next successful sync via contact-cache-sync-repository.
Contingency: If cache staleness causes user complaints, reduce TTL to 4 hours and implement background sync on app foreground. Accept that very-recently-revoked mentors may appear briefly in offline mode — document this as a known limitation in the privacy policy.