Default local storage to Hive with legacy migration
This commit is contained in:
@@ -2,6 +2,8 @@ import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||
import 'package:flutter_test/flutter_test.dart';
|
||||
import 'package:relationship_saver/features/local/local_models.dart';
|
||||
import 'package:relationship_saver/features/local/local_repository.dart';
|
||||
import 'package:relationship_saver/features/local/storage/local_data_store_in_memory.dart';
|
||||
import 'package:relationship_saver/features/local/storage/local_data_store_provider.dart';
|
||||
import 'package:shared_preferences/shared_preferences.dart';
|
||||
|
||||
void main() {
|
||||
@@ -10,7 +12,7 @@ void main() {
|
||||
});
|
||||
|
||||
test('seeds local data on first load', () async {
|
||||
final ProviderContainer container = ProviderContainer();
|
||||
final ProviderContainer container = _createContainer();
|
||||
addTearDown(container.dispose);
|
||||
|
||||
final state = await container.read(localRepositoryProvider.future);
|
||||
@@ -21,7 +23,7 @@ void main() {
|
||||
});
|
||||
|
||||
test('adds and removes person with persistence state update', () async {
|
||||
final ProviderContainer container = ProviderContainer();
|
||||
final ProviderContainer container = _createContainer();
|
||||
addTearDown(container.dispose);
|
||||
|
||||
final initial = await container.read(localRepositoryProvider.future);
|
||||
@@ -49,7 +51,7 @@ void main() {
|
||||
});
|
||||
|
||||
test('adds and removes capture moments', () async {
|
||||
final ProviderContainer container = ProviderContainer();
|
||||
final ProviderContainer container = _createContainer();
|
||||
addTearDown(container.dispose);
|
||||
|
||||
final state = await container.read(localRepositoryProvider.future);
|
||||
@@ -73,7 +75,7 @@ void main() {
|
||||
});
|
||||
|
||||
test('adds, archives, edits, and deletes ideas', () async {
|
||||
final ProviderContainer container = ProviderContainer();
|
||||
final ProviderContainer container = _createContainer();
|
||||
addTearDown(container.dispose);
|
||||
|
||||
final LocalDataState state = await container.read(
|
||||
@@ -124,7 +126,7 @@ void main() {
|
||||
});
|
||||
|
||||
test('adds, updates, toggles, and deletes reminders', () async {
|
||||
final ProviderContainer container = ProviderContainer();
|
||||
final ProviderContainer container = _createContainer();
|
||||
addTearDown(container.dispose);
|
||||
|
||||
final LocalDataState state = await container.read(
|
||||
@@ -172,3 +174,11 @@ void main() {
|
||||
expect(afterDelete.reminders.length, beforeCount);
|
||||
});
|
||||
}
|
||||
|
||||
ProviderContainer _createContainer() {
|
||||
return ProviderContainer(
|
||||
overrides: [
|
||||
localDataStoreProvider.overrideWithValue(InMemoryLocalDataStore()),
|
||||
],
|
||||
);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,81 @@
|
||||
import 'dart:convert';
|
||||
|
||||
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||
import 'package:flutter_test/flutter_test.dart';
|
||||
import 'package:relationship_saver/features/local/local_models.dart';
|
||||
import 'package:relationship_saver/features/local/local_repository.dart';
|
||||
import 'package:relationship_saver/features/local/storage/local_data_store.dart';
|
||||
import 'package:relationship_saver/features/local/storage/local_data_store_hive.dart';
|
||||
import 'package:relationship_saver/features/local/storage/local_data_store_provider.dart';
|
||||
import 'package:relationship_saver/features/local/storage/local_data_store_shared_prefs.dart';
|
||||
import 'package:shared_preferences/shared_preferences.dart';
|
||||
|
||||
void main() {
|
||||
setUp(() {
|
||||
SharedPreferences.setMockInitialValues(<String, Object>{});
|
||||
});
|
||||
|
||||
test(
|
||||
'migrates legacy shared prefs payload into hive store on first load',
|
||||
() async {
|
||||
final LocalDataState legacyState = LocalDataState.seed().copyWith(
|
||||
people: <PersonProfile>[
|
||||
PersonProfile(
|
||||
id: 'legacy-person-1',
|
||||
name: 'Legacy Person',
|
||||
relationship: 'Friend',
|
||||
affinityScore: 82,
|
||||
nextMoment: DateTime(2026, 2, 18, 19),
|
||||
tags: <String>['legacy'],
|
||||
notes: 'from shared prefs',
|
||||
),
|
||||
],
|
||||
);
|
||||
|
||||
final SharedPrefsLocalDataStore legacyStore = SharedPrefsLocalDataStore();
|
||||
await legacyStore.write(
|
||||
rawState: jsonEncode(legacyState.toJson()),
|
||||
schemaVersion: 2,
|
||||
);
|
||||
|
||||
final _FakeHiveStore hiveStore = _FakeHiveStore();
|
||||
final ProviderContainer container = ProviderContainer(
|
||||
overrides: [localDataStoreProvider.overrideWithValue(hiveStore)],
|
||||
);
|
||||
addTearDown(container.dispose);
|
||||
|
||||
final LocalDataState loaded = await container.read(
|
||||
localRepositoryProvider.future,
|
||||
);
|
||||
|
||||
expect(loaded.people.first.name, 'Legacy Person');
|
||||
|
||||
final LocalDataRecord? migrated = await hiveStore.read();
|
||||
expect(migrated, isNotNull);
|
||||
expect(migrated!.schemaVersion, 2);
|
||||
|
||||
final LocalDataRecord? legacyAfter = await legacyStore.read();
|
||||
expect(legacyAfter, isNull);
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
class _FakeHiveStore extends HiveLocalDataStore {
|
||||
LocalDataRecord? _record;
|
||||
|
||||
@override
|
||||
Future<void> clear() async {
|
||||
_record = null;
|
||||
}
|
||||
|
||||
@override
|
||||
Future<LocalDataRecord?> read() async => _record;
|
||||
|
||||
@override
|
||||
Future<void> write({
|
||||
required String rawState,
|
||||
required int schemaVersion,
|
||||
}) async {
|
||||
_record = LocalDataRecord(rawState: rawState, schemaVersion: schemaVersion);
|
||||
}
|
||||
}
|
||||
@@ -7,6 +7,8 @@ import 'package:relationship_saver/features/auth/sign_in_view.dart';
|
||||
import 'package:relationship_saver/features/dashboard/dashboard_view.dart';
|
||||
import 'package:relationship_saver/features/home/app_shell.dart';
|
||||
import 'package:relationship_saver/features/ideas/ideas_view.dart';
|
||||
import 'package:relationship_saver/features/local/storage/local_data_store_in_memory.dart';
|
||||
import 'package:relationship_saver/features/local/storage/local_data_store_provider.dart';
|
||||
import 'package:relationship_saver/features/moments/moments_view.dart';
|
||||
import 'package:relationship_saver/features/people/people_view.dart';
|
||||
import 'package:relationship_saver/features/reminders/reminders_view.dart';
|
||||
@@ -99,6 +101,7 @@ Future<void> pumpResponsive(
|
||||
overrides: [
|
||||
tokenStoreProvider.overrideWithValue(InMemoryTokenStore()),
|
||||
backendGatewayProvider.overrideWithValue(BackendGatewayFake()),
|
||||
localDataStoreProvider.overrideWithValue(InMemoryLocalDataStore()),
|
||||
],
|
||||
child: MaterialApp(theme: AppTheme.light(), home: home),
|
||||
),
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||
import 'package:flutter_test/flutter_test.dart';
|
||||
import 'package:relationship_saver/features/local/local_repository.dart';
|
||||
import 'package:relationship_saver/features/local/storage/local_data_store_in_memory.dart';
|
||||
import 'package:relationship_saver/features/local/storage/local_data_store_provider.dart';
|
||||
import 'package:relationship_saver/features/sync/sync_coordinator.dart';
|
||||
import 'package:relationship_saver/features/sync/sync_queue_repository.dart';
|
||||
import 'package:relationship_saver/features/sync/sync_state.dart';
|
||||
@@ -16,7 +18,10 @@ void main() {
|
||||
|
||||
test('pushPending flushes queued local mutations', () async {
|
||||
final ProviderContainer container = ProviderContainer(
|
||||
overrides: [backendGatewayProvider.overrideWithValue(_TestGateway())],
|
||||
overrides: [
|
||||
backendGatewayProvider.overrideWithValue(_TestGateway()),
|
||||
localDataStoreProvider.overrideWithValue(InMemoryLocalDataStore()),
|
||||
],
|
||||
);
|
||||
addTearDown(container.dispose);
|
||||
|
||||
@@ -77,6 +82,7 @@ void main() {
|
||||
backendGatewayProvider.overrideWithValue(
|
||||
_TestGateway(pullResult: pullResult),
|
||||
),
|
||||
localDataStoreProvider.overrideWithValue(InMemoryLocalDataStore()),
|
||||
],
|
||||
);
|
||||
addTearDown(container.dispose);
|
||||
|
||||
Reference in New Issue
Block a user