import 'package:cardash_launcher/data/models/slot_assignment.dart'; import 'package:cardash_launcher/data/models/slot_type.dart'; import 'package:cardash_launcher/data/repositories/settings_repository.dart'; import 'package:cardash_launcher/data/services/pin_service.dart'; import 'package:cardash_launcher/data/services/secure_store.dart'; import 'package:flutter_test/flutter_test.dart'; import 'package:shared_preferences/shared_preferences.dart'; class MemorySecureStore implements SecureStore { final Map values = {}; @override Future read(String key) async => values[key]; @override Future write(String key, String value) async => values[key] = value; @override Future delete(String key) async => values.remove(key); } void main() { TestWidgetsFlutterBinding.ensureInitialized(); group('settings repository', () { test('persists and clears a shortcut assignment', () async { SharedPreferences.setMockInitialValues({}); final prefs = await SharedPreferences.getInstance(); final repository = SettingsRepository(prefs); const assignment = SlotAssignment( packageName: 'com.example.waze', activityName: 'com.example.waze.Main', label: 'Waze', ); expect(repository.slot(SlotType.navigation), isNull); await repository.setSlot(SlotType.navigation, assignment); final restored = repository.slot(SlotType.navigation); expect(restored, isNotNull); expect(restored!.packageName, 'com.example.waze'); expect(restored.label, 'Waze'); await repository.clearSlot(SlotType.navigation); expect(repository.slot(SlotType.navigation), isNull); }); test('stores a custom night window', () async { SharedPreferences.setMockInitialValues({}); final prefs = await SharedPreferences.getInstance(); final repository = SettingsRepository(prefs); await repository.setNightWindow( startMinutes: 20 * 60, endMinutes: 6 * 60, ); expect(repository.nightStartMinutes, 20 * 60); expect(repository.nightEndMinutes, 6 * 60); }); test('home buttons default to enabled and persist a toggle', () async { SharedPreferences.setMockInitialValues({}); final prefs = await SharedPreferences.getInstance(); final repository = SettingsRepository(prefs); expect(repository.slotEnabled(SlotType.navigation), isTrue); expect(repository.slotEnabled(SlotType.music), isTrue); expect(repository.slotEnabled(SlotType.radio), isTrue); await repository.setSlotEnabled(SlotType.music, false); expect(repository.slotEnabled(SlotType.music), isFalse); expect(repository.slotEnabled(SlotType.navigation), isTrue); }); test('pinned apps round-trip through the repository', () async { SharedPreferences.setMockInitialValues({}); final prefs = await SharedPreferences.getInstance(); final repository = SettingsRepository(prefs); const pinned = [ SlotAssignment( packageName: 'com.example.one', activityName: 'com.example.one.Main', label: 'One', ), SlotAssignment( packageName: 'com.example.two', activityName: 'com.example.two.Main', label: 'Two', ), ]; await repository.setPinnedApps(pinned); final restored = repository.pinnedApps; expect(restored.length, 2); expect(restored.first.label, 'One'); expect(restored.last.packageName, 'com.example.two'); await repository.setPinnedApps(const []); expect(repository.pinnedApps, isEmpty); }); }); group('pin service', () { test('sets, verifies and clears a four-digit PIN', () async { final store = MemorySecureStore(); final service = PinService(store, iterations: 50); await service.setPin('1234'); expect(await service.isPinSet(), isTrue); expect(await service.verify('1234'), isTrue); expect(await service.verify('9999'), isFalse); expect(store.values['cardash.pin.hash'], isNot(contains('1234'))); await service.clearPin(); expect(await service.isPinSet(), isFalse); }); test('rejects PINs that are not four digits', () { final service = PinService(MemorySecureStore(), iterations: 10); expect(() => service.setPin('12'), throwsArgumentError); expect(() => service.setPin('abcd'), throwsArgumentError); }); }); }