feat(proj): init
This commit is contained in:
@@ -0,0 +1,139 @@
|
||||
import 'package:flutter/cupertino.dart';
|
||||
import 'package:flutter_test/flutter_test.dart';
|
||||
import 'package:please_pay_me/app/app.dart';
|
||||
import 'package:please_pay_me/core/config/app_config.dart';
|
||||
import 'package:please_pay_me/core/storage/session_storage.dart';
|
||||
import 'package:please_pay_me/data/demo/demo_backend.dart';
|
||||
import 'package:please_pay_me/features/auth/session_controller.dart';
|
||||
import 'package:please_pay_me/theme/theme.dart';
|
||||
|
||||
import 'support/test_setup.dart';
|
||||
|
||||
void main() {
|
||||
setUpAll(setUpTestEnvironment);
|
||||
|
||||
SessionController demoSession({bool seeded = true}) {
|
||||
return SessionController(
|
||||
config: AppConfig.demo,
|
||||
storage: InMemorySessionStorage(),
|
||||
demoBackend: seeded ? DemoBackend() : DemoBackend.empty(),
|
||||
);
|
||||
}
|
||||
|
||||
/// Skeletons pulse forever, so `pumpAndSettle` would time out.
|
||||
Future<void> settle(WidgetTester tester) async {
|
||||
await tester.pump();
|
||||
await tester.pump(const Duration(milliseconds: 400));
|
||||
}
|
||||
|
||||
testWidgets('restoring session shows the branded splash', (tester) async {
|
||||
final session = demoSession();
|
||||
|
||||
await tester.pumpWidget(PleasePayMeApp(session: session));
|
||||
await tester.pump();
|
||||
|
||||
expect(find.text('Дожить до ЗП'), findsOneWidget);
|
||||
expect(find.text('Бюджет от зарплаты до зарплаты'), findsOneWidget);
|
||||
expect(find.byType(CupertinoActivityIndicator), findsOneWidget);
|
||||
});
|
||||
|
||||
testWidgets('signed-out app shows the login screen', (tester) async {
|
||||
final session = demoSession();
|
||||
await session.restore();
|
||||
|
||||
await tester.pumpWidget(PleasePayMeApp(session: session));
|
||||
await settle(tester);
|
||||
|
||||
expect(find.text('Дожить до ЗП'), findsOneWidget);
|
||||
expect(find.text('Войти через Яндекс'), findsOneWidget);
|
||||
});
|
||||
|
||||
testWidgets('demo session opens the overview with the current envelope',
|
||||
(tester) async {
|
||||
final session = demoSession()..startDemo();
|
||||
|
||||
await tester.pumpWidget(PleasePayMeApp(session: session));
|
||||
await settle(tester);
|
||||
|
||||
expect(find.text('Обзор'), findsWidgets);
|
||||
expect(find.text('До аванса'), findsOneWidget);
|
||||
expect(find.text('Остаток бюджета'), findsOneWidget);
|
||||
|
||||
await tester.drag(find.byType(CustomScrollView).first, const Offset(0, -500));
|
||||
await settle(tester);
|
||||
|
||||
// Grouped headers are uppercased by `AppSectionHeader`, as in iOS Settings.
|
||||
expect(find.text('БЛИЖАЙШАЯ ВЫПЛАТА'), findsOneWidget);
|
||||
expect(tester.takeException(), isNull);
|
||||
});
|
||||
|
||||
testWidgets('tabs switch between the main sections', (tester) async {
|
||||
final session = demoSession()..startDemo();
|
||||
|
||||
await tester.pumpWidget(PleasePayMeApp(session: session));
|
||||
await settle(tester);
|
||||
|
||||
for (final tab in ['Журнал', 'Бюджеты', 'Работа', 'Профиль']) {
|
||||
await tester.tap(find.text(tab).last);
|
||||
await settle(tester);
|
||||
expect(tester.takeException(), isNull, reason: 'tab $tab failed to render');
|
||||
}
|
||||
|
||||
expect(find.text('Демо'), findsOneWidget);
|
||||
});
|
||||
|
||||
testWidgets('profile theme switcher applies dark appearance', (tester) async {
|
||||
final session = demoSession()..startDemo();
|
||||
final theme = ThemeController(store: MemoryThemeStore());
|
||||
|
||||
await tester.pumpWidget(PleasePayMeApp(session: session, theme: theme));
|
||||
await settle(tester);
|
||||
|
||||
await tester.tap(find.text('Профиль').last);
|
||||
await settle(tester);
|
||||
|
||||
expect(find.text('Системная'), findsOneWidget);
|
||||
expect(find.text('Светлая'), findsOneWidget);
|
||||
|
||||
await tester.tap(find.text('Тёмная'));
|
||||
await settle(tester);
|
||||
|
||||
expect(theme.preference, ThemePreference.dark);
|
||||
expect(theme.resolve(Brightness.light), Brightness.dark);
|
||||
});
|
||||
|
||||
testWidgets('empty demo backend renders the empty states', (tester) async {
|
||||
final session = demoSession(seeded: false)..startDemo();
|
||||
|
||||
await tester.pumpWidget(PleasePayMeApp(session: session));
|
||||
await settle(tester);
|
||||
|
||||
expect(find.text('Бюджета пока нет'), findsOneWidget);
|
||||
expect(find.text('Создать бюджет'), findsOneWidget);
|
||||
});
|
||||
|
||||
testWidgets('recording an expense updates the remaining amount', (tester) async {
|
||||
final session = demoSession()..startDemo();
|
||||
|
||||
await tester.pumpWidget(PleasePayMeApp(session: session));
|
||||
await settle(tester);
|
||||
|
||||
await tester.tap(find.text('Добавить трату'));
|
||||
await settle(tester);
|
||||
expect(find.text('Новая трата'), findsOneWidget);
|
||||
|
||||
await tester.enterText(find.byType(CupertinoTextField).first, '1000');
|
||||
await settle(tester);
|
||||
|
||||
await tester.tap(find.text('Записать трату'));
|
||||
await tester.pump();
|
||||
await tester.pump(const Duration(milliseconds: 500));
|
||||
|
||||
expect(find.text('Новая трата'), findsNothing);
|
||||
expect(find.text('Трата записана'), findsOneWidget);
|
||||
|
||||
// Let the toast auto-dismiss so no timers outlive the test.
|
||||
await tester.pump(const Duration(seconds: 3));
|
||||
expect(tester.takeException(), isNull);
|
||||
});
|
||||
}
|
||||
Reference in New Issue
Block a user