import 'package:flutter/material.dart'; import 'package:flutter_test/flutter_test.dart'; import 'package:ignis_app/models/home_config.dart'; import 'package:ignis_app/screens/api_keys_screen.dart'; import 'package:ignis_app/screens/group_edit_screen.dart'; import 'package:ignis_app/screens/home_edit_screen.dart'; import 'package:ignis_app/screens/schedules_screen.dart'; import 'package:ignis_app/services/settings_service.dart'; import 'package:shared_preferences/shared_preferences.dart'; import 'test_support.dart'; void main() { TestWidgetsFlutterBinding.ensureInitialized(); testWidgets('schedules screen creates one-shot schedule for selected group', ( tester, ) async { final api = FakeIgnisApi( tasksData: {'tasks': []}, groupsData: { 'bedroom': {'name': 'Спальня'}, }, ); await pumpTestApp(tester, child: const SchedulesScreen(), api: api); await tester.pumpAndSettle(); await tester.tap(find.byIcon(Icons.add)); await tester.pumpAndSettle(); await tester.tap(find.byType(DropdownButtonFormField)); await tester.pumpAndSettle(); await tester.tap(find.text('Спальня').last); await tester.pumpAndSettle(); final createScheduleButton = find.widgetWithText( ElevatedButton, 'СОЗДАТЬ РАСПИСАНИЕ', ); await tester.ensureVisible(createScheduleButton); await tester.tap(createScheduleButton); await tester.pumpAndSettle(); expect(api.scheduledOnceParams, isNotNull); expect(api.scheduledOnceParams, containsPair('target_id', 'bedroom')); expect(api.scheduledOnceParams, containsPair('is_group', true)); expect(api.scheduledOnceParams?['run_at'], isA()); }); testWidgets('group edit screen auto-generates id and creates group', ( tester, ) async { final api = FakeIgnisApi( devicesData: { 'devices': [ {'mac': 'AA:BB', 'name': 'Лампа 1'}, ], }, groupsData: [], ); await pumpTestApp(tester, child: const GroupEditScreen(), api: api); await tester.pumpAndSettle(); await tester.enterText( find.widgetWithText(TextFormField, 'Название группы'), 'Спальня родителей', ); await tester.pump(); expect(find.text('spalnya-roditeley'), findsOneWidget); await tester.tap(find.text('Лампа 1')); await tester.pump(); await tester.tap(find.text('СОЗДАТЬ ГРУППУ')); await tester.pumpAndSettle(); expect(api.createdGroupId, 'spalnya-roditeley'); expect(api.createdGroupName, 'Спальня родителей'); expect(api.createdGroupMacs, ['AA:BB']); }); testWidgets('api keys screen validates and shows created key banner', ( tester, ) async { final api = FakeIgnisApi(apiKeysData: {'keys': []}); await pumpTestApp(tester, child: const ApiKeysScreen(), api: api); await tester.pumpAndSettle(); await tester.tap(find.byIcon(Icons.add)); await tester.pumpAndSettle(); await tester.tap(find.text('Создать')); await tester.pumpAndSettle(); expect(find.text('Укажите имя ключа'), findsOneWidget); await tester.enterText( find.widgetWithText(TextFormField, 'Имя ключа'), 'Guest', ); await tester.tap(find.text('Дать права администратора')); await tester.pumpAndSettle(); await tester.tap(find.text('Создать')); await tester.pumpAndSettle(); expect(api.createdApiKeyName, 'Guest'); expect(api.createdApiKeyIsAdmin, isTrue); expect(find.textContaining('Новый ключ создан'), findsOneWidget); expect(find.textContaining('Guest_token'), findsOneWidget); }); testWidgets('home edit screen validates fields and saves normalized home', ( tester, ) async { tester.view.physicalSize = const Size(800, 1400); tester.view.devicePixelRatio = 1; addTearDown(tester.view.resetPhysicalSize); addTearDown(tester.view.resetDevicePixelRatio); SharedPreferences.setMockInitialValues({}); final settingsService = SettingsService( credentialsStorage: InMemoryCredentialsStorage(), ); final api = FakeIgnisApi(authData: {'is_admin': true, 'name': 'owner'}); await pumpTestApp( tester, api: api, settingsService: settingsService, child: Builder( builder: (context) => Scaffold( body: Center( child: ElevatedButton( onPressed: () => Navigator.of( context, ).push(MaterialPageRoute(builder: (_) => const HomeEditScreen())), child: const Text('open'), ), ), ), ), ); await tester.tap(find.text('open')); await tester.pumpAndSettle(); final saveHomeButton = find.widgetWithText(ElevatedButton, 'ДОБАВИТЬ'); await tester.tap(saveHomeButton); await tester.pumpAndSettle(); expect(find.text('Укажите название дома'), findsOneWidget); expect(find.text('Укажите адрес сервера'), findsOneWidget); expect(find.text('Укажите API key'), findsOneWidget); await tester.enterText( find.widgetWithText(TextFormField, 'Название'), 'Квартира', ); await tester.enterText( find.widgetWithText(TextFormField, 'Адрес сервера'), 'ignis.akokos.ru/', ); await tester.enterText( find.widgetWithText(TextFormField, 'API Key'), 'secret-key', ); await tester.enterText( find.widgetWithText(TextFormField, 'Широта'), '55.75', ); await tester.enterText( find.widgetWithText(TextFormField, 'Долгота'), '37.61', ); await tester.pump(); await tester.tap(saveHomeButton); await tester.pumpAndSettle(); final homes = await settingsService.getHomes(); final savedHome = homes.single; final savedApiKey = await settingsService.getHomeApiKey(savedHome.id); expect(homes, hasLength(1)); expect(savedHome.name, 'Квартира'); expect(savedHome.url, 'https://ignis.akokos.ru'); expect(savedHome.latitude, 55.75); expect(savedHome.longitude, 37.61); expect(savedHome.geofenceEnabled, isFalse); expect(savedHome.geofenceRadiusMeters, HomeConfig.defaultGeofenceRadiusMeters); expect(savedApiKey, 'secret-key'); }); }