Files
eatvio_app/test/features/create_plan/advanced_widget_test.dart
2025-11-20 16:58:56 +03:00

433 lines
17 KiB
Dart
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
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>(() => 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<CreatePlanCubit>(
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);
});
});
}