test: expand client-side coverage and fix lifecycle issues
This commit is contained in:
154
test/error_retry_widget_test.dart
Normal file
154
test/error_retry_widget_test.dart
Normal file
@@ -0,0 +1,154 @@
|
||||
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': <Object>[]});
|
||||
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);
|
||||
});
|
||||
}
|
||||
Reference in New Issue
Block a user