import 'dart:convert'; import 'package:flutter_test/flutter_test.dart'; import 'package:ignis_app/models/home_config.dart'; import 'package:ignis_app/services/credentials_storage.dart'; import 'package:ignis_app/services/settings_service.dart'; import 'package:shared_preferences/shared_preferences.dart'; class InMemoryCredentialsStorage implements CredentialsStorage { final Map _apiKeys = {}; @override Future getApiKey(String homeId) async => _apiKeys[homeId]; @override Future setApiKey(String homeId, String apiKey) async { _apiKeys[homeId] = apiKey; } @override Future deleteApiKey(String homeId) async { _apiKeys.remove(homeId); } } void main() { TestWidgetsFlutterBinding.ensureInitialized(); test( 'migrates legacy apiKey from SharedPreferences to credentials storage', () async { final legacyHomes = [ { 'id': 'home-1', 'name': 'Квартира', 'url': 'ignis.akokos.ru', 'apiKey': 'secret-key', 'geofenceEnabled': false, }, ]; SharedPreferences.setMockInitialValues({ 'ignis_homes': jsonEncode(legacyHomes), }); final credentials = InMemoryCredentialsStorage(); final service = SettingsService(credentialsStorage: credentials); final homes = await service.getHomes(); expect(homes, hasLength(1)); expect(homes.single.id, 'home-1'); expect(await service.getHomeApiKey('home-1'), 'secret-key'); final prefs = await SharedPreferences.getInstance(); final storedHomes = jsonDecode(prefs.getString('ignis_homes')!) as List; expect(storedHomes.single, isNot(containsPair('apiKey', 'secret-key'))); }, ); test('stores new api keys outside serialized homes', () async { SharedPreferences.setMockInitialValues({}); final service = SettingsService( credentialsStorage: InMemoryCredentialsStorage(), ); final home = HomeConfig( id: 'home-1', name: 'Квартира', url: 'https://ignis.akokos.ru', ); await service.upsertHome(home, apiKey: 'secret-key'); expect(await service.getHomeApiKey('home-1'), 'secret-key'); final prefs = await SharedPreferences.getInstance(); final storedHomes = jsonDecode(prefs.getString('ignis_homes')!) as List; expect(storedHomes.single, isNot(contains('apiKey'))); }); }