import 'package:flutter_portal/flutter_portal.dart'; import 'package:flutter_localizations/flutter_localizations.dart'; import 'package:eatvio_app/generated/l10n.dart'; import 'package:eatvio_app/core/locator_service.dart'; import 'package:eatvio_app/core/di/app_config_registration.dart'; import 'package:eatvio_app/core/app_initializer.dart'; import 'package:eatvio_app/core/theme/theme_helper.dart'; import 'package:eatvio_app/features/create_plan/presentation/cubit/create_plan_cubit.dart'; import 'package:eatvio_app/features/create_plan/presentation/widgets/plan_duration_drop_down_widget.dart'; import 'package:eatvio_app/features/create_plan/presentation/widgets/plan_type_choice_widget.dart'; import 'package:eatvio_app/features/create_plan/presentation/widgets/option_widget.dart'; import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:flutter_test/flutter_test.dart'; import '../../fixtures/doubles/create_plan_doubles.dart'; void main() { group('Meal Plan Creation Advanced Widget Tests', () { late FixtureCreatePlanRepository createPlanRepository; late CreatePlanCubit createPlanCubit; setUp(() async { await sl.reset(); createPlanRepository = FixtureCreatePlanRepository(); createPlanCubit = CreatePlanCubit(createPlanRepository: createPlanRepository); sl.registerLazySingleton(() => createPlanCubit); AppConfigRegistration.registerAppConfig(buildType: AppBuildType.tests); }); tearDown(() { createPlanCubit.close(); }); Widget createTestWidget(Widget child) { return MaterialApp( theme: ThemeHelper().themeData(), localizationsDelegates: const [ S.delegate, GlobalMaterialLocalizations.delegate, GlobalWidgetsLocalizations.delegate, GlobalCupertinoLocalizations.delegate, ], supportedLocales: const [Locale('ru')], home: SizedBox( width: 800, height: 600, child: BlocProvider( create: (context) => createPlanCubit, child: Portal( child: Scaffold( body: LayoutBuilder( builder: (context, constraints) => SingleChildScrollView( child: ConstrainedBox( constraints: BoxConstraints(minHeight: constraints.maxHeight), child: child, ), ), ), ), ), ), ), ); } testWidgets('should display PlanTypeChoiceWidget', (WidgetTester tester) async { // Arrange & Act await tester.pumpWidget(createTestWidget(const PlanTypeChoiceWidget())); await tester.pumpAndSettle(); // Assert expect(find.byType(PlanTypeChoiceWidget), findsOneWidget); }); testWidgets('should display PlanDurationDropDownWidget', (WidgetTester tester) async { // Arrange & Act await tester.pumpWidget(createTestWidget(const PlanDurationDropDownWidget())); await tester.pumpAndSettle(); // Assert expect(find.byType(PlanDurationDropDownWidget), findsOneWidget); }); testWidgets('should display OptionWidget', (WidgetTester tester) async { // Arrange & Act await tester.pumpWidget(createTestWidget(const OptionWidget())); await tester.pumpAndSettle(); // Assert expect(find.byType(OptionWidget), findsOneWidget); }); testWidgets('should display meal plan creation form with all widgets', (WidgetTester tester) async { // Arrange Widget completeForm = const Column( children: [ Text('Создание плана питания'), SizedBox(height: 16), PlanTypeChoiceWidget(), SizedBox(height: 16), PlanDurationDropDownWidget(), SizedBox(height: 16), OptionWidget(), ], ); // Act await tester.pumpWidget(createTestWidget(completeForm)); await tester.pumpAndSettle(); // Assert expect(find.text('Создание плана питания'), findsOneWidget); expect(find.byType(PlanTypeChoiceWidget), findsOneWidget); expect(find.byType(PlanDurationDropDownWidget), findsOneWidget); expect(find.byType(OptionWidget), findsOneWidget); }); testWidgets('should handle plan type selection in PlanTypeChoiceWidget', (WidgetTester tester) async { // Arrange await tester.pumpWidget(createTestWidget(const PlanTypeChoiceWidget())); await tester.pumpAndSettle(); // Act - Try to find and tap on plan type options // Note: This test might need adjustment based on actual widget implementation final planTypeWidget = find.byType(PlanTypeChoiceWidget); expect(planTypeWidget, findsOneWidget); // Assert expect(find.byType(PlanTypeChoiceWidget), findsOneWidget); }); testWidgets('should handle duration selection in PlanDurationDropDownWidget', (WidgetTester tester) async { // Arrange await tester.pumpWidget(createTestWidget(const PlanDurationDropDownWidget())); await tester.pumpAndSettle(); // Act - Try to find and interact with duration dropdown final durationWidget = find.byType(PlanDurationDropDownWidget); expect(durationWidget, findsOneWidget); // Assert expect(find.byType(PlanDurationDropDownWidget), findsOneWidget); }); testWidgets('should handle option configuration in OptionWidget', (WidgetTester tester) async { // Arrange await tester.pumpWidget(createTestWidget(const OptionWidget())); await tester.pumpAndSettle(); // Act - Try to find and interact with option widget final optionWidget = find.byType(OptionWidget); expect(optionWidget, findsOneWidget); // Assert expect(find.byType(OptionWidget), findsOneWidget); }); testWidgets('should display meal plan creation screen layout', (WidgetTester tester) async { // Arrange Widget screenLayout = const Padding( padding: EdgeInsets.all(16.0), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Text('Создание плана питания'), Text('Основная информация'), SizedBox(height: 16), PlanTypeChoiceWidget(), SizedBox(height: 24), Text('Настройки плана'), SizedBox(height: 16), PlanDurationDropDownWidget(), SizedBox(height: 16), OptionWidget(), SizedBox(height: 32), SizedBox( width: double.infinity, child: ElevatedButton(onPressed: null, child: Text('Создать план питания')), ), ], ), ); // Act await tester.pumpWidget(createTestWidget(screenLayout)); await tester.pumpAndSettle(); // Assert expect(find.text('Создание плана питания'), findsOneWidget); expect(find.text('Основная информация'), findsOneWidget); expect(find.text('Настройки плана'), findsOneWidget); expect(find.text('Создать план питания'), findsOneWidget); expect(find.byType(PlanTypeChoiceWidget), findsOneWidget); expect(find.byType(PlanDurationDropDownWidget), findsOneWidget); expect(find.byType(OptionWidget), findsOneWidget); }); testWidgets('should display meal plan creation form with validation', (WidgetTester tester) async { // Arrange Widget formWithValidation = Column( children: [ TextFormField( key: const Key('planNameField'), decoration: const InputDecoration(labelText: 'Название плана питания', errorText: 'Название плана питания обязательно'), ), const SizedBox(height: 16), TextFormField( key: const Key('planDescriptionField'), decoration: const InputDecoration(labelText: 'Описание плана питания', errorText: 'Описание плана питания обязательно'), ), const SizedBox(height: 16), const PlanTypeChoiceWidget(), const SizedBox(height: 16), const PlanDurationDropDownWidget(), const SizedBox(height: 16), const OptionWidget(), ], ); // Act await tester.pumpWidget(createTestWidget(formWithValidation)); await tester.pumpAndSettle(); // Assert expect(find.text('Название плана питания обязательно'), findsOneWidget); expect(find.text('Описание плана питания обязательно'), findsOneWidget); expect(find.byType(PlanTypeChoiceWidget), findsOneWidget); expect(find.byType(PlanDurationDropDownWidget), findsOneWidget); expect(find.byType(OptionWidget), findsOneWidget); }); testWidgets('should display meal plan creation form with all sections', (WidgetTester tester) async { // Arrange Widget completeForm = Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ const Text('Информация о плане питания', style: TextStyle(fontSize: 18, fontWeight: FontWeight.bold)), const SizedBox(height: 16), TextFormField( key: const Key('planNameField'), decoration: const InputDecoration(labelText: 'Название плана питания', hintText: 'Введите название плана питания'), ), const SizedBox(height: 16), TextFormField( key: const Key('planDescriptionField'), decoration: const InputDecoration(labelText: 'Описание плана питания', hintText: 'Опишите особенности плана питания'), maxLines: 3, ), const SizedBox(height: 24), const Text('Тип плана питания', style: TextStyle(fontSize: 18, fontWeight: FontWeight.bold)), const SizedBox(height: 16), const PlanTypeChoiceWidget(), const SizedBox(height: 24), const Text('Настройки', style: TextStyle(fontSize: 18, fontWeight: FontWeight.bold)), const SizedBox(height: 16), const PlanDurationDropDownWidget(), const SizedBox(height: 16), const OptionWidget(), const SizedBox(height: 32), SizedBox( width: double.infinity, child: ElevatedButton(key: const Key('createPlanButton'), onPressed: () {}, child: const Text('Создать план питания')), ), ], ); // Act await tester.pumpWidget(createTestWidget(completeForm)); await tester.pumpAndSettle(); // Assert expect(find.text('Информация о плане питания'), findsOneWidget); expect(find.text('Тип плана питания'), findsOneWidget); expect(find.text('Настройки'), findsOneWidget); expect(find.byKey(const Key('planNameField')), findsOneWidget); expect(find.byKey(const Key('planDescriptionField')), findsOneWidget); expect(find.byKey(const Key('createPlanButton')), findsOneWidget); expect(find.byType(PlanTypeChoiceWidget), findsOneWidget); expect(find.byType(PlanDurationDropDownWidget), findsOneWidget); expect(find.byType(OptionWidget), findsOneWidget); }); testWidgets('should display meal plan creation form with image picker', (WidgetTester tester) async { // Arrange Widget formWithImagePicker = Column( children: [ const Text('Изображение плана питания'), const SizedBox(height: 16), Container( key: const Key('imagePickerContainer'), height: 200, width: double.infinity, decoration: BoxDecoration( border: Border.all(color: Colors.grey), borderRadius: BorderRadius.circular(8), ), child: const Center( child: Column( mainAxisAlignment: MainAxisAlignment.center, children: [ Icon(Icons.add_photo_alternate, size: 48, color: Colors.grey), SizedBox(height: 8), Text('Добавить изображение'), ], ), ), ), const SizedBox(height: 16), const PlanTypeChoiceWidget(), ], ); // Act await tester.pumpWidget(createTestWidget(formWithImagePicker)); await tester.pumpAndSettle(); // Assert expect(find.text('Изображение плана питания'), findsOneWidget); expect(find.text('Добавить изображение'), findsOneWidget); expect(find.byKey(const Key('imagePickerContainer')), findsOneWidget); expect(find.byType(PlanTypeChoiceWidget), findsOneWidget); }); testWidgets('should display meal plan creation form with options configuration', (WidgetTester tester) async { // Arrange Widget formWithOptions = Column( children: [ const Text('Настройка опций плана питания'), const SizedBox(height: 16), Container( key: const Key('optionsContainer'), padding: const EdgeInsets.all(16), decoration: BoxDecoration( border: Border.all(color: Colors.grey), borderRadius: BorderRadius.circular(8), ), child: const Column( children: [ Text('Опция 1'), SizedBox(height: 8), Text('Название: Базовый план'), Text('Цена: 1000 руб'), Text('Описание: Включает базовое меню'), SizedBox(height: 16), ElevatedButton(onPressed: null, child: Text('Добавить опцию')), ], ), ), ], ); // Act await tester.pumpWidget(createTestWidget(formWithOptions)); await tester.pumpAndSettle(); // Assert expect(find.text('Настройка опций плана питания'), findsOneWidget); expect(find.text('Опция 1'), findsOneWidget); expect(find.text('Название: Базовый план'), findsOneWidget); expect(find.text('Цена: 1000 руб'), findsOneWidget); expect(find.text('Описание: Включает базовое меню'), findsOneWidget); expect(find.text('Добавить опцию'), findsOneWidget); expect(find.byKey(const Key('optionsContainer')), findsOneWidget); }); testWidgets('should display meal plan creation form with pricing tiers', (WidgetTester tester) async { // Arrange Widget formWithPricingTiers = Column( children: [ const Text('Тарифные планы'), const SizedBox(height: 16), Row( children: [ Expanded( child: Container( key: const Key('basicTierContainer'), padding: const EdgeInsets.all(16), decoration: BoxDecoration( border: Border.all(color: Colors.blue), borderRadius: BorderRadius.circular(8), ), child: const Column( children: [ Text('Базовый', style: TextStyle(fontWeight: FontWeight.bold)), SizedBox(height: 8), Text('1000 руб/мес'), SizedBox(height: 8), Text('Базовые функции'), ], ), ), ), const SizedBox(width: 16), Expanded( child: Container( key: const Key('premiumTierContainer'), padding: const EdgeInsets.all(16), decoration: BoxDecoration( border: Border.all(color: Colors.amber), borderRadius: BorderRadius.circular(8), ), child: const Column( children: [ Text('Премиум', style: TextStyle(fontWeight: FontWeight.bold)), SizedBox(height: 8), Text('2500 руб/мес'), SizedBox(height: 8), Text('Расширенные функции'), ], ), ), ), ], ), ], ); // Act await tester.pumpWidget(createTestWidget(formWithPricingTiers)); await tester.pumpAndSettle(); // Assert expect(find.text('Тарифные планы'), findsOneWidget); expect(find.text('Базовый'), findsOneWidget); expect(find.text('1000 руб/мес'), findsOneWidget); expect(find.text('Премиум'), findsOneWidget); expect(find.text('2500 руб/мес'), findsOneWidget); expect(find.byKey(const Key('basicTierContainer')), findsOneWidget); expect(find.byKey(const Key('premiumTierContainer')), findsOneWidget); }); }); }