forked from eatvio/eatvio_app
feat(payment, chat): promo code mocked BottomSheet added
This commit is contained in:
131
test/features/payment/consultation_payment_flow_test.dart
Normal file
131
test/features/payment/consultation_payment_flow_test.dart
Normal file
@@ -0,0 +1,131 @@
|
||||
import 'package:eatvio_app/generated/l10n.dart';
|
||||
import 'package:eatvio_app/features/payment/presentation/payment_flow.dart';
|
||||
import 'package:eatvio_app/features/payment/presentation/widgets/promo_code_modal.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_localizations/flutter_localizations.dart';
|
||||
import 'package:flutter_test/flutter_test.dart';
|
||||
|
||||
void main() {
|
||||
TestWidgetsFlutterBinding.ensureInitialized();
|
||||
|
||||
Widget createTestApp() {
|
||||
return const MaterialApp(
|
||||
localizationsDelegates: [
|
||||
S.delegate,
|
||||
GlobalMaterialLocalizations.delegate,
|
||||
GlobalWidgetsLocalizations.delegate,
|
||||
GlobalCupertinoLocalizations.delegate,
|
||||
],
|
||||
supportedLocales: [Locale('ru')],
|
||||
home: Scaffold(body: SizedBox()),
|
||||
);
|
||||
}
|
||||
|
||||
group('showConsultationPaymentFlow', () {
|
||||
late bool gateCalled;
|
||||
late bool? gateResult;
|
||||
late bool formCalled;
|
||||
late PromoCodeResult? formResult;
|
||||
late bool sbpCalled;
|
||||
late int sbpPlanId;
|
||||
|
||||
Future<bool?> mockGate(BuildContext context) async {
|
||||
gateCalled = true;
|
||||
return gateResult;
|
||||
}
|
||||
|
||||
Future<PromoCodeResult?> mockForm(
|
||||
BuildContext context, {
|
||||
Future<PromoValidation> Function(String)? onValidate,
|
||||
}) async {
|
||||
formCalled = true;
|
||||
return formResult;
|
||||
}
|
||||
|
||||
Future<void> mockSbp(BuildContext context, {required int planId}) async {
|
||||
sbpCalled = true;
|
||||
sbpPlanId = planId;
|
||||
}
|
||||
|
||||
setUp(() {
|
||||
gateCalled = false;
|
||||
gateResult = null;
|
||||
formCalled = false;
|
||||
formResult = null;
|
||||
sbpCalled = false;
|
||||
sbpPlanId = 0;
|
||||
});
|
||||
|
||||
testWidgets('Нет → вызывает SbpBanks (не форму)', (tester) async {
|
||||
gateResult = false;
|
||||
await tester.pumpWidget(createTestApp());
|
||||
|
||||
await showConsultationPaymentFlow(
|
||||
tester.element(find.byType(SizedBox)),
|
||||
planId: 42,
|
||||
showGate: mockGate,
|
||||
showForm: mockForm,
|
||||
showSbp: mockSbp,
|
||||
);
|
||||
|
||||
expect(gateCalled, isTrue);
|
||||
expect(formCalled, isFalse);
|
||||
expect(sbpCalled, isTrue);
|
||||
expect(sbpPlanId, 42);
|
||||
});
|
||||
|
||||
testWidgets('Да → форма → Пропустить → вызывает SbpBanks', (tester) async {
|
||||
gateResult = true;
|
||||
formResult = PromoCodeResult();
|
||||
await tester.pumpWidget(createTestApp());
|
||||
|
||||
await showConsultationPaymentFlow(
|
||||
tester.element(find.byType(SizedBox)),
|
||||
planId: 42,
|
||||
showGate: mockGate,
|
||||
showForm: mockForm,
|
||||
showSbp: mockSbp,
|
||||
);
|
||||
|
||||
expect(gateCalled, isTrue);
|
||||
expect(formCalled, isTrue);
|
||||
expect(sbpCalled, isTrue);
|
||||
expect(sbpPlanId, 42);
|
||||
});
|
||||
|
||||
testWidgets('Да → форма отменена (null) → Sbp не вызывается', (tester) async {
|
||||
gateResult = true;
|
||||
formResult = null;
|
||||
await tester.pumpWidget(createTestApp());
|
||||
|
||||
await showConsultationPaymentFlow(
|
||||
tester.element(find.byType(SizedBox)),
|
||||
planId: 42,
|
||||
showGate: mockGate,
|
||||
showForm: mockForm,
|
||||
showSbp: mockSbp,
|
||||
);
|
||||
|
||||
expect(gateCalled, isTrue);
|
||||
expect(formCalled, isTrue);
|
||||
expect(sbpCalled, isFalse);
|
||||
});
|
||||
|
||||
testWidgets('гейт отменён (null) → ничего не вызывается', (tester) async {
|
||||
gateResult = null;
|
||||
await tester.pumpWidget(createTestApp());
|
||||
|
||||
await showConsultationPaymentFlow(
|
||||
tester.element(find.byType(SizedBox)),
|
||||
planId: 42,
|
||||
showGate: mockGate,
|
||||
showForm: mockForm,
|
||||
showSbp: mockSbp,
|
||||
);
|
||||
|
||||
expect(gateCalled, isTrue);
|
||||
expect(formCalled, isFalse);
|
||||
expect(sbpCalled, isFalse);
|
||||
});
|
||||
});
|
||||
}
|
||||
@@ -0,0 +1,65 @@
|
||||
import 'package:eatvio_app/core/theme/theme_helper.dart';
|
||||
import 'package:eatvio_app/core/widgets/bottom_sheet_handler_bar.dart';
|
||||
import 'package:eatvio_app/features/payment/presentation/widgets/promo_code_gate_bottom_sheet.dart';
|
||||
import 'package:eatvio_app/generated/l10n.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_localizations/flutter_localizations.dart';
|
||||
import 'package:flutter_test/flutter_test.dart';
|
||||
|
||||
void main() {
|
||||
TestWidgetsFlutterBinding.ensureInitialized();
|
||||
|
||||
group('PromoCodeGateBottomSheet', () {
|
||||
Widget createTestWidget({required ValueChanged<bool?> onResult}) {
|
||||
return MaterialApp(
|
||||
theme: ThemeHelper().themeData(),
|
||||
localizationsDelegates: const [
|
||||
S.delegate,
|
||||
GlobalMaterialLocalizations.delegate,
|
||||
GlobalWidgetsLocalizations.delegate,
|
||||
GlobalCupertinoLocalizations.delegate,
|
||||
],
|
||||
supportedLocales: const [Locale('ru')],
|
||||
home: Scaffold(
|
||||
body: PromoCodeGateBottomSheet(onResult: onResult),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
testWidgets('показывает заголовок, BottomSheetHandlerBar и кнопки Да/Нет', (tester) async {
|
||||
await tester.pumpWidget(createTestWidget(onResult: (_) {}));
|
||||
await tester.pump();
|
||||
|
||||
expect(find.byType(BottomSheetHandlerBar), findsOneWidget);
|
||||
expect(find.text('У вас есть промокод?'), findsOneWidget);
|
||||
expect(find.text('Да'), findsOneWidget);
|
||||
expect(find.text('Нет'), findsOneWidget);
|
||||
});
|
||||
|
||||
testWidgets('tap Да вызывает onResult(true)', (tester) async {
|
||||
bool? result;
|
||||
await tester.pumpWidget(
|
||||
createTestWidget(onResult: (v) => result = v),
|
||||
);
|
||||
await tester.pump();
|
||||
|
||||
await tester.tap(find.text('Да'));
|
||||
await tester.pump();
|
||||
|
||||
expect(result, isTrue);
|
||||
});
|
||||
|
||||
testWidgets('tap Нет вызывает onResult(false)', (tester) async {
|
||||
bool? result;
|
||||
await tester.pumpWidget(
|
||||
createTestWidget(onResult: (v) => result = v),
|
||||
);
|
||||
await tester.pump();
|
||||
|
||||
await tester.tap(find.text('Нет'));
|
||||
await tester.pump();
|
||||
|
||||
expect(result, isFalse);
|
||||
});
|
||||
});
|
||||
}
|
||||
@@ -0,0 +1,101 @@
|
||||
import 'package:eatvio_app/core/theme/theme_helper.dart';
|
||||
import 'package:eatvio_app/features/payment/presentation/widgets/promo_code_modal.dart';
|
||||
import 'package:eatvio_app/generated/l10n.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_localizations/flutter_localizations.dart';
|
||||
import 'package:flutter_test/flutter_test.dart';
|
||||
|
||||
void main() {
|
||||
TestWidgetsFlutterBinding.ensureInitialized();
|
||||
|
||||
group('ItvioPromoCodeModal', () {
|
||||
Widget createTestWidget({
|
||||
Future<PromoValidation> Function(String)? onValidate,
|
||||
}) {
|
||||
return MaterialApp(
|
||||
theme: ThemeHelper().themeData(),
|
||||
localizationsDelegates: const [
|
||||
S.delegate,
|
||||
GlobalMaterialLocalizations.delegate,
|
||||
GlobalWidgetsLocalizations.delegate,
|
||||
GlobalCupertinoLocalizations.delegate,
|
||||
],
|
||||
supportedLocales: const [Locale('ru')],
|
||||
home: Builder(
|
||||
builder: (context) => ElevatedButton(
|
||||
onPressed: () => ItvioPromoCodeModal.show(
|
||||
context,
|
||||
onValidate: onValidate,
|
||||
),
|
||||
child: const Text('Open'),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
testWidgets('показывает заголовок Есть промокод? и кнопки Применить/Пропустить', (tester) async {
|
||||
await tester.pumpWidget(createTestWidget());
|
||||
await tester.tap(find.text('Open'));
|
||||
await tester.pumpAndSettle();
|
||||
|
||||
expect(find.text('Есть промокод?'), findsOneWidget);
|
||||
expect(find.text('Применить'), findsOneWidget);
|
||||
expect(find.text('Пропустить'), findsOneWidget);
|
||||
});
|
||||
|
||||
testWidgets('Применить с пустым полем показывает ошибку и не закрывает', (tester) async {
|
||||
await tester.pumpWidget(createTestWidget());
|
||||
await tester.tap(find.text('Open'));
|
||||
await tester.pumpAndSettle();
|
||||
|
||||
await tester.tap(find.text('Применить'));
|
||||
await tester.pump();
|
||||
|
||||
expect(find.text('Введите промокод'), findsAtLeast(1));
|
||||
expect(find.text('Применить'), findsOneWidget);
|
||||
});
|
||||
|
||||
testWidgets('Применить с вводом вызывает onValidate и показывает ошибку', (tester) async {
|
||||
PromoValidation? captured;
|
||||
await tester.pumpWidget(
|
||||
createTestWidget(
|
||||
onValidate: (code) async {
|
||||
captured ??= PromoValidation.failure('Промокод не найден или истёк');
|
||||
return captured!;
|
||||
},
|
||||
),
|
||||
);
|
||||
await tester.tap(find.text('Open'));
|
||||
await tester.pumpAndSettle();
|
||||
|
||||
await tester.enterText(find.byType(TextField), 'TEST123');
|
||||
await tester.tap(find.text('Применить'));
|
||||
await tester.pump();
|
||||
|
||||
expect(captured, isNotNull);
|
||||
expect(find.text('Промокод не найден или истёк'), findsOneWidget);
|
||||
expect(find.text('Применить'), findsOneWidget);
|
||||
});
|
||||
|
||||
testWidgets('Пропустить закрывает шторку', (tester) async {
|
||||
await tester.pumpWidget(createTestWidget());
|
||||
await tester.tap(find.text('Open'));
|
||||
await tester.pumpAndSettle();
|
||||
|
||||
await tester.tap(find.text('Пропустить'));
|
||||
await tester.pumpAndSettle();
|
||||
|
||||
expect(find.text('Есть промокод?'), findsNothing);
|
||||
});
|
||||
|
||||
testWidgets('отсутствует UI applied-состояния (Промокод применён)', (tester) async {
|
||||
await tester.pumpWidget(createTestWidget());
|
||||
await tester.tap(find.text('Open'));
|
||||
await tester.pumpAndSettle();
|
||||
|
||||
expect(find.text('Промокод применён!'), findsNothing);
|
||||
expect(find.text('Продолжить'), findsNothing);
|
||||
expect(find.text('Убрать промокод'), findsNothing);
|
||||
});
|
||||
});
|
||||
}
|
||||
Reference in New Issue
Block a user