feat: add local database persistence
This commit is contained in:
@@ -0,0 +1,115 @@
|
||||
import 'dart:convert';
|
||||
|
||||
import 'package:drift/native.dart';
|
||||
import 'package:flutter_test/flutter_test.dart';
|
||||
import 'package:focus_seed/src/data/focus_seed_store.dart';
|
||||
import 'package:focus_seed/src/data/local/focus_seed_database.dart';
|
||||
import 'package:focus_seed/src/models/app_state.dart';
|
||||
import 'package:focus_seed/src/models/focus_session.dart';
|
||||
import 'package:focus_seed/src/models/habit.dart';
|
||||
import 'package:focus_seed/src/models/mood.dart';
|
||||
import 'package:focus_seed/src/models/reflection_entry.dart';
|
||||
import 'package:shared_preferences/shared_preferences.dart';
|
||||
|
||||
void main() {
|
||||
setUp(() {
|
||||
SharedPreferences.setMockInitialValues({});
|
||||
});
|
||||
|
||||
test('new installs seed localized starter habits into sqlite', () async {
|
||||
final database = FocusSeedDatabase(NativeDatabase.memory());
|
||||
addTearDown(database.close);
|
||||
final store = FocusSeedStore(database: database);
|
||||
|
||||
final state = await store.load(
|
||||
defaultHabitTitles: const ['Plan', 'Focus', 'Reflect'],
|
||||
);
|
||||
|
||||
expect(state.anchor, isEmpty);
|
||||
expect(state.habits.map((habit) => habit.title), [
|
||||
'Plan',
|
||||
'Focus',
|
||||
'Reflect',
|
||||
]);
|
||||
});
|
||||
|
||||
test(
|
||||
'sqlite snapshot round-trips focus, habit, and reflection data',
|
||||
() async {
|
||||
final database = FocusSeedDatabase(NativeDatabase.memory());
|
||||
addTearDown(database.close);
|
||||
final store = FocusSeedStore(database: database);
|
||||
final now = DateTime(2026, 6, 12, 10, 30);
|
||||
final state = AppState(
|
||||
anchor: 'Ship the local database',
|
||||
anchorDateKey: '2026-06-12',
|
||||
habits: [
|
||||
Habit(
|
||||
id: 'habit-1',
|
||||
title: 'Review the plan',
|
||||
createdAt: now.subtract(const Duration(days: 2)),
|
||||
completedDates: const {'2026-06-11', '2026-06-12'},
|
||||
),
|
||||
],
|
||||
sessions: [
|
||||
FocusSession(id: 'session-1', minutes: 25, completedAt: now),
|
||||
],
|
||||
reflections: [
|
||||
ReflectionEntry(
|
||||
id: 'reflection-1',
|
||||
dateKey: '2026-06-12',
|
||||
note: 'Small scope kept it clean.',
|
||||
mood: Mood.clear,
|
||||
createdAt: now.add(const Duration(minutes: 1)),
|
||||
),
|
||||
],
|
||||
);
|
||||
|
||||
await store.save(state);
|
||||
final loaded = await store.load();
|
||||
|
||||
expect(loaded.anchor, 'Ship the local database');
|
||||
expect(loaded.anchorDateKey, '2026-06-12');
|
||||
expect(loaded.habits.single.completedDates, {'2026-06-11', '2026-06-12'});
|
||||
expect(loaded.sessions.single.minutes, 25);
|
||||
expect(loaded.reflections.single.note, 'Small scope kept it clean.');
|
||||
},
|
||||
);
|
||||
|
||||
test('legacy shared preferences json migrates once and is removed', () async {
|
||||
final legacyState = AppState(
|
||||
anchor: 'Migrate safely',
|
||||
anchorDateKey: '2026-06-12',
|
||||
habits: [
|
||||
Habit(
|
||||
id: 'habit-legacy',
|
||||
title: 'Keep existing data',
|
||||
createdAt: DateTime(2026, 6, 10),
|
||||
completedDates: const {'2026-06-12'},
|
||||
),
|
||||
],
|
||||
sessions: [
|
||||
FocusSession(
|
||||
id: 'session-legacy',
|
||||
minutes: 15,
|
||||
completedAt: DateTime(2026, 6, 12, 8),
|
||||
),
|
||||
],
|
||||
reflections: const [],
|
||||
);
|
||||
SharedPreferences.setMockInitialValues({
|
||||
'focus_seed_state_v1': jsonEncode(legacyState.toJson()),
|
||||
});
|
||||
final database = FocusSeedDatabase(NativeDatabase.memory());
|
||||
addTearDown(database.close);
|
||||
final store = FocusSeedStore(database: database);
|
||||
|
||||
final migrated = await store.load();
|
||||
final preferences = await SharedPreferences.getInstance();
|
||||
|
||||
expect(migrated.anchor, 'Migrate safely');
|
||||
expect(migrated.habits.single.title, 'Keep existing data');
|
||||
expect(migrated.sessions.single.minutes, 15);
|
||||
expect(preferences.getString('focus_seed_state_v1'), isNull);
|
||||
});
|
||||
}
|
||||
Reference in New Issue
Block a user