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, actualSeconds: 90, completedAt: now, intention: 'Ship the local database', ), ], 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)), ), ], defaultFocusMinutes: 45, ); 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.sessions.single.actualSeconds, 90); expect(loaded.sessions.single.actualMinutes, 2); expect(loaded.sessions.single.intention, 'Ship the local database'); expect(loaded.reflections.single.note, 'Small scope kept it clean.'); expect(loaded.defaultFocusMinutes, 45); final row = await database.select(database.focusSessionRows).getSingle(); expect(row.plannedMinutes, 25); expect(row.actualSeconds, 90); expect(row.intentionText, 'Ship the local database'); }, ); 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); }); }