forked from eatvio/eatvio_app
439 lines
18 KiB
Dart
439 lines
18 KiB
Dart
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:eatvio_app/features/create_plan/repositories/create_plan_repository.dart';
|
||
import 'package:eatvio_app/features/glossary/repositories/glossary_repository.dart';
|
||
import 'package:eatvio_app/features/profile/repositories/profile_repository.dart';
|
||
import 'package:flutter/material.dart';
|
||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||
import 'package:flutter_test/flutter_test.dart';
|
||
import 'package:mockito/annotations.dart';
|
||
|
||
import 'advanced_widget_test.mocks.dart';
|
||
|
||
@GenerateMocks([CreatePlanRepository, ProfileRepository, GlossaryRepository])
|
||
void main() {
|
||
group('Meal Plan Creation Advanced Widget Tests', () {
|
||
late MockCreatePlanRepository mockCreatePlanRepository;
|
||
late CreatePlanCubit createPlanCubit;
|
||
|
||
setUp(() async {
|
||
await sl.reset();
|
||
mockCreatePlanRepository = MockCreatePlanRepository();
|
||
createPlanCubit = CreatePlanCubit(createPlanRepository: mockCreatePlanRepository);
|
||
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);
|
||
});
|
||
});
|
||
}
|