high priority low complexity testing pending testing specialist Tier 4

Acceptance Criteria

Test file exists at test/infrastructure/repositories/local_org_persistence_repository_test.dart
Test: saveSelectedOrganizationId('org-123') calls adapter.setString with the correct namespaced key and value 'org-123'
Test: getSelectedOrganizationId() returns 'org-123' when adapter.getString returns 'org-123'
Test: getSelectedOrganizationId() returns null when adapter.getString returns null (nothing persisted)
Test: calling saveSelectedOrganizationId('org-456') after saveSelectedOrganizationId('org-123') results in adapter.setString called with 'org-456' (overwrites previous)
All tests use a mock LocalStorageAdapter — no real storage, no SharedPreferences.setMockInitialValues() needed
Tests verify the exact key constant is used (assert the key argument matches LocalStorageKeys.selectedOrgId)
flutter test runs all tests green with zero failures

Technical Requirements

frameworks
Flutter
Dart
flutter_test
data models
Organization
performance requirements
All tests must complete in under 1 second total — pure unit tests with mocks, no I/O
security requirements
Tests must not write to actual device storage — mock adapter must be used exclusively

Execution Context

Execution Tier
Tier 4

Tier 4 - 323 tasks

Can start after Tier 3 completes

Implementation Notes

Use mocktail (preferred for null-safety) or mockito with build_runner. Pattern: setUp creates a MockLocalStorageAdapter and a LocalOrgPersistenceRepository(mockAdapter). Each test uses when(mockAdapter.getString(any)).thenReturn(...) to set up the stub, calls the repository method, then verifies with verify(mockAdapter.getString(LocalStorageKeys.selectedOrgId)).called(1). Keep tests focused on delegation behavior — do NOT test what SharedPreferences does internally.

If the project uses mocktail, use registerFallbackValue for any custom types passed to the adapter.

Testing Requirements

Unit tests only using flutter_test and Mockito (or mocktail). Create a MockLocalStorageAdapter using @GenerateMocks or mocktail's Mock class. Use when()/verify() patterns to assert both the return values and the interactions (key used, value passed). No widget tests or integration tests needed for this repository layer.

Aim for 100% method coverage of LocalOrgPersistenceRepository.

Epic Risks (2)
medium impact medium prob technical

SharedPreferences behaves differently on iOS (NSUserDefaults) vs Android (SharedPreferences) for edge cases such as first-launch cold reads, storage quota exceeded, or process kill mid-write. If the adapter does not account for these differences, the persistence layer can silently return null on one platform while returning a stale value on the other, causing incorrect routing decisions downstream.

Mitigation & Contingency

Mitigation: Write platform-specific integration tests using flutter_test device runners for both iOS and Android. Document known platform delta in the adapter's inline comments and encode defensive fallback for null returns at the repository boundary.

Contingency: If platform delta causes persistent issues, replace SharedPreferences with flutter_secure_storage for this key — the LocalStorageAdapter abstraction makes this a single-file swap with no impact on the repository or service layer.

high impact low prob dependency

The shared_preferences Flutter plugin may have a version conflict with other plugins already in the project pubspec.yaml. A conflict discovered late in the epic blocks all downstream epics.

Mitigation & Contingency

Mitigation: Resolve and pin the shared_preferences version in pubspec.yaml as the very first task of this epic before writing any implementation code. Run flutter pub get and resolve any version conflicts immediately.

Contingency: If version pinning is impossible due to transitive conflicts, implement LocalStorageAdapter using path_provider + dart:io for JSON file storage as an alternative — the interface contract remains unchanged.