import 'package:dio/dio.dart'; import 'package:flutter/material.dart'; import 'package:flutter_test/flutter_test.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 retries after initial load error', ( tester, ) async { final api = FakeIgnisApi(); api.tasksError = DioException( requestOptions: RequestOptions(path: '/schedules/tasks'), type: DioExceptionType.connectionError, message: 'No route to host', ); await pumpTestApp(tester, child: const SchedulesScreen(), api: api); await tester.pumpAndSettle(); expect(find.text('Не удалось загрузить расписания'), findsOneWidget); api.tasksError = null; api.tasksData = { 'tasks': [ { 'id': 'job-1', 'target_id': 'kitchen', 'state': false, 'hour': '7', 'minute': '30', 'day_of_week': '1,2,3', 'type': 'cron', }, ], }; await tester.tap(find.text('Повторить')); await tester.pumpAndSettle(); expect(find.text('Выключить группу kitchen'), findsOneWidget); }); testWidgets('api keys screen retries after initial load error', ( tester, ) async { final api = FakeIgnisApi(); api.apiKeysError = DioException( requestOptions: RequestOptions(path: '/api-keys'), type: DioExceptionType.connectionError, message: 'No route to host', ); await pumpTestApp(tester, child: const ApiKeysScreen(), api: api); await tester.pumpAndSettle(); expect(find.text('Не удалось загрузить API-ключи'), findsOneWidget); api.apiKeysError = null; api.apiKeysData = { 'keys': [ {'name': 'Guest', 'key': 'secret', 'is_active': true}, ], }; await tester.tap(find.text('Повторить')); await tester.pumpAndSettle(); expect(find.text('Guest'), findsOneWidget); }); testWidgets('group edit screen shows snackbar when rescan fails', ( tester, ) async { final api = FakeIgnisApi(devicesData: {'devices': []}); api.rescanNetworkError = DioException( requestOptions: RequestOptions(path: '/devices/rescan'), type: DioExceptionType.connectionError, message: 'No route to host', ); await pumpTestApp(tester, child: const GroupEditScreen(), api: api); await tester.pumpAndSettle(); await tester.tap(find.byTooltip('Пересканировать сеть')); await tester.pumpAndSettle(); expect(find.textContaining('Ошибка сканирования'), findsOneWidget); }); testWidgets('home edit screen shows save error when credentials fail', ( tester, ) async { SharedPreferences.setMockInitialValues({}); final settingsService = SettingsService( credentialsStorage: InMemoryCredentialsStorage(), ); final api = FakeIgnisApi(); api.authError = DioException( requestOptions: RequestOptions(path: '/auth/me'), type: DioExceptionType.badResponse, response: Response( requestOptions: RequestOptions(path: '/auth/me'), statusCode: 403, ), ); 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(); await tester.enterText( find.widgetWithText(TextFormField, 'Название'), 'Дом', ); await tester.enterText( find.widgetWithText(TextFormField, 'Адрес сервера'), 'ignis.akokos.ru', ); await tester.enterText( find.widgetWithText(TextFormField, 'API Key'), 'wrong-key', ); final saveButton = find.widgetWithText(ElevatedButton, 'ДОБАВИТЬ'); await tester.ensureVisible(saveButton); await tester.tap(saveButton); await tester.pumpAndSettle(); expect(find.textContaining('Не удалось сохранить дом'), findsOneWidget); expect(await settingsService.getHomes(), isEmpty); }); }