import 'dart:convert'; import 'package:flutter_test/flutter_test.dart'; import 'package:nuvolari/core/region/geo.dart'; import 'package:nuvolari/features/places/places_repository.dart'; import 'package:nuvolari/features/places/saved_place.dart'; import 'package:shared_preferences/shared_preferences.dart'; SavedPlace place(String id, String name) => SavedPlace( id: id, name: name, point: const GeoPoint(7.686, 45.070), createdAt: DateTime.utc(2026, 3, 4, 10), ); void main() { TestWidgetsFlutterBinding.ensureInitialized(); setUp(() => SharedPreferences.setMockInitialValues({})); group('SharedPreferencesPlacesStore', () { test('starts empty', () async { expect(await const SharedPreferencesPlacesStore().load(), isEmpty); }); test('round-trips places through storage', () async { const store = SharedPreferencesPlacesStore(); final saved = [place('p1', 'Casa'), place('p2', 'Lavoro')]; await store.save(saved); expect(await store.load(), saved); }); test('save replaces rather than appends', () async { const store = SharedPreferencesPlacesStore(); await store.save([place('p1', 'Casa')]); await store.save([place('p2', 'Lavoro')]); final loaded = await store.load(); expect(loaded, hasLength(1)); expect(loaded.single.name, 'Lavoro'); }); test('writes JSON under a versioned key', () async { await const SharedPreferencesPlacesStore().save([ place('p1', 'Casa'), ]); final prefs = await SharedPreferences.getInstance(); final raw = prefs.getString(SharedPreferencesPlacesStore.storageKey); expect(SharedPreferencesPlacesStore.storageKey, endsWith('.v1')); expect(raw, isNotNull); expect(jsonDecode(raw!), isA>()); }); // Corrupt storage loses the places, which is bad. Throwing here would make // the app unopenable, which is worse: one is recoverable by the user, the // other is a crash loop. test('recovers from corrupt storage instead of throwing', () async { SharedPreferences.setMockInitialValues({ SharedPreferencesPlacesStore.storageKey: 'not json at all', }); expect(await const SharedPreferencesPlacesStore().load(), isEmpty); }); test('ignores entries that are not place objects', () async { SharedPreferences.setMockInitialValues({ SharedPreferencesPlacesStore.storageKey: jsonEncode([ 'nonsense', 42, ]), }); expect(await const SharedPreferencesPlacesStore().load(), isEmpty); }); }); }