feat(test): diet, plan, registration

This commit is contained in:
mso7nueh
2025-10-21 21:02:17 +03:00
parent 1841199291
commit ed612aa019
13 changed files with 32985 additions and 66 deletions

View File

@@ -0,0 +1,484 @@
import 'package:eatvio_app/core/theme/theme_helper.dart';
import 'package:eatvio_app/features/create_diet/presentation/cubit/create_diet_cubit.dart';
import 'package:eatvio_app/features/create_diet/repositories/create_diet_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 'basic_widget_test.mocks.dart';
@GenerateMocks([CreateDietRepository, ProfileRepository, GlossaryRepository])
void main() {
group('Diet Creation Basic Widget Tests', () {
late MockCreateDietRepository mockCreateDietRepository;
late MockProfileRepository mockProfileRepository;
late MockGlossaryRepository mockGlossaryRepository;
late CreateDietCubit createDietCubit;
setUp(() {
mockCreateDietRepository = MockCreateDietRepository();
mockProfileRepository = MockProfileRepository();
mockGlossaryRepository = MockGlossaryRepository();
createDietCubit = CreateDietCubit(
createDietRepository: mockCreateDietRepository,
profileRepository: mockProfileRepository,
glossaryRepository: mockGlossaryRepository,
);
});
tearDown(() {
createDietCubit.close();
});
Widget createTestWidget(Widget child) {
return MaterialApp(
theme: ThemeHelper().themeData(),
home: BlocProvider<CreateDietCubit>(
create: (context) => createDietCubit,
child: Scaffold(body: SingleChildScrollView(child: child)),
),
);
}
testWidgets('should create CreateDietCubit successfully', (WidgetTester tester) async {
// Arrange & Act
final cubit = CreateDietCubit(
createDietRepository: mockCreateDietRepository,
profileRepository: mockProfileRepository,
glossaryRepository: mockGlossaryRepository,
);
// Assert
expect(cubit, isA<CreateDietCubit>());
expect(cubit.state.isLoading, isFalse);
expect(cubit.state.isDietPublishing, isFalse);
cubit.close();
});
testWidgets('should display basic diet form fields', (WidgetTester tester) async {
// Arrange
Widget formWidget = Column(
children: [
TextFormField(
key: const Key('dietNameField'),
decoration: const InputDecoration(labelText: 'Название диеты', hintText: 'Например: Здоровая диета'),
),
const SizedBox(height: 16),
TextFormField(
key: const Key('dietDescriptionField'),
decoration: const InputDecoration(labelText: 'Описание диеты'),
maxLines: 3,
),
const SizedBox(height: 16),
DropdownButtonFormField<int>(
key: const Key('dietDurationField'),
decoration: const InputDecoration(labelText: 'Продолжительность'),
items: const [
DropdownMenuItem(value: 7, child: Text('7 дней')),
DropdownMenuItem(value: 14, child: Text('14 дней')),
DropdownMenuItem(value: 21, child: Text('21 день')),
],
onChanged: (value) {},
),
const SizedBox(height: 16),
ElevatedButton(key: const Key('publishDietButton'), onPressed: () {}, child: const Text('Опубликовать диету')),
],
);
// Act
await tester.pumpWidget(createTestWidget(formWidget));
await tester.pumpAndSettle();
// Assert
expect(find.byKey(const Key('dietNameField')), findsOneWidget);
expect(find.byKey(const Key('dietDescriptionField')), findsOneWidget);
expect(find.byKey(const Key('dietDurationField')), findsOneWidget);
expect(find.byKey(const Key('publishDietButton')), findsOneWidget);
});
testWidgets('should update diet name when user types in name field', (WidgetTester tester) async {
// Arrange
Widget formWidget = TextFormField(
key: const Key('dietNameField'),
decoration: const InputDecoration(labelText: 'Название диеты', hintText: 'Например: Здоровая диета'),
);
await tester.pumpWidget(createTestWidget(formWidget));
await tester.pumpAndSettle();
const testName = 'Тестовая диета';
// Act
await tester.enterText(find.byKey(const Key('dietNameField')), testName);
await tester.pump();
// Assert
expect(find.text(testName), findsOneWidget);
});
testWidgets('should update diet description when user types in description field', (WidgetTester tester) async {
// Arrange
Widget formWidget = TextFormField(
key: const Key('dietDescriptionField'),
decoration: const InputDecoration(labelText: 'Описание диеты'),
maxLines: 3,
);
await tester.pumpWidget(createTestWidget(formWidget));
await tester.pumpAndSettle();
const testDescription = 'Это тестовое описание диеты для похудения';
// Act
await tester.enterText(find.byKey(const Key('dietDescriptionField')), testDescription);
await tester.pump();
// Assert
expect(find.text(testDescription), findsOneWidget);
});
testWidgets('should display diet type selection', (WidgetTester tester) async {
// Arrange
Widget typeWidget = Column(
children: [
const Text('Тип диеты'),
const SizedBox(height: 8),
Row(
children: [
Expanded(
child: CheckboxListTile(key: const Key('veganTypeCheckbox'), title: const Text('Веганская'), value: false, onChanged: (value) {}),
),
Expanded(
child: CheckboxListTile(key: const Key('meatTypeCheckbox'), title: const Text('Мясная'), value: false, onChanged: (value) {}),
),
],
),
Row(
children: [
Expanded(
child: CheckboxListTile(key: const Key('carbTypeCheckbox'), title: const Text('Углеводная'), value: false, onChanged: (value) {}),
),
Expanded(
child: CheckboxListTile(key: const Key('lightTypeCheckbox'), title: const Text('Легкая'), value: false, onChanged: (value) {}),
),
],
),
],
);
// Act
await tester.pumpWidget(createTestWidget(typeWidget));
await tester.pumpAndSettle();
// Assert
expect(find.text('Тип диеты'), findsOneWidget);
expect(find.byKey(const Key('veganTypeCheckbox')), findsOneWidget);
expect(find.byKey(const Key('meatTypeCheckbox')), findsOneWidget);
expect(find.byKey(const Key('carbTypeCheckbox')), findsOneWidget);
expect(find.byKey(const Key('lightTypeCheckbox')), findsOneWidget);
});
testWidgets('should handle diet type selection', (WidgetTester tester) async {
// Arrange
bool veganSelected = false;
Widget typeWidget = CheckboxListTile(
key: const Key('veganTypeCheckbox'),
title: const Text('Веганская'),
value: veganSelected,
onChanged: (value) {
veganSelected = value ?? false;
},
);
await tester.pumpWidget(createTestWidget(typeWidget));
await tester.pumpAndSettle();
// Act
await tester.tap(find.byKey(const Key('veganTypeCheckbox')));
await tester.pump();
// Assert
expect(veganSelected, isTrue);
});
testWidgets('should display diet duration dropdown', (WidgetTester tester) async {
// Arrange
Widget durationWidget = DropdownButtonFormField<int>(
key: const Key('dietDurationField'),
decoration: const InputDecoration(labelText: 'Продолжительность диеты'),
items: const [
DropdownMenuItem(value: 7, child: Text('7 дней')),
DropdownMenuItem(value: 14, child: Text('14 дней')),
DropdownMenuItem(value: 21, child: Text('21 день')),
DropdownMenuItem(value: 30, child: Text('30 дней')),
],
onChanged: (value) {},
);
// Act
await tester.pumpWidget(createTestWidget(durationWidget));
await tester.pumpAndSettle();
// Assert
expect(find.byKey(const Key('dietDurationField')), findsOneWidget);
expect(find.text('Продолжительность диеты'), findsOneWidget);
});
testWidgets('should display diet status dropdown', (WidgetTester tester) async {
// Arrange
Widget statusWidget = DropdownButtonFormField<String>(
key: const Key('dietStatusField'),
decoration: const InputDecoration(labelText: 'Статус диеты'),
items: const [
DropdownMenuItem(value: 'active', child: Text('Активная')),
DropdownMenuItem(value: 'draft', child: Text('Черновик')),
DropdownMenuItem(value: 'personal', child: Text('Личная')),
],
onChanged: (value) {},
);
// Act
await tester.pumpWidget(createTestWidget(statusWidget));
await tester.pumpAndSettle();
// Assert
expect(find.byKey(const Key('dietStatusField')), findsOneWidget);
expect(find.text('Статус диеты'), findsOneWidget);
});
testWidgets('should display form labels correctly', (WidgetTester tester) async {
// Arrange
Widget formWidget = const Column(
children: [Text('Название диеты'), Text('Описание диеты'), Text('Продолжительность'), Text('Тип диеты'), Text('Статус')],
);
// Act
await tester.pumpWidget(createTestWidget(formWidget));
await tester.pumpAndSettle();
// Assert
expect(find.text('Название диеты'), findsOneWidget);
expect(find.text('Описание диеты'), findsOneWidget);
expect(find.text('Продолжительность'), findsOneWidget);
expect(find.text('Тип диеты'), findsOneWidget);
expect(find.text('Статус'), findsOneWidget);
});
testWidgets('should display placeholder text in name field', (WidgetTester tester) async {
// Arrange
Widget formWidget = TextFormField(
key: const Key('dietNameField'),
decoration: const InputDecoration(labelText: 'Название диеты', hintText: 'Например: Здоровая диета'),
);
// Act
await tester.pumpWidget(createTestWidget(formWidget));
await tester.pumpAndSettle();
// Assert
expect(find.text('Например: Здоровая диета'), findsOneWidget);
});
testWidgets('should display publish button', (WidgetTester tester) async {
// Arrange
Widget buttonWidget = ElevatedButton(key: const Key('publishDietButton'), onPressed: () {}, child: const Text('Опубликовать диету'));
// Act
await tester.pumpWidget(createTestWidget(buttonWidget));
await tester.pumpAndSettle();
// Assert
expect(find.byKey(const Key('publishDietButton')), findsOneWidget);
expect(find.text('Опубликовать диету'), findsOneWidget);
});
testWidgets('should handle publish button tap', (WidgetTester tester) async {
// Arrange
bool buttonPressed = false;
Widget buttonWidget = ElevatedButton(
key: const Key('publishDietButton'),
onPressed: () {
buttonPressed = true;
},
child: const Text('Опубликовать диету'),
);
await tester.pumpWidget(createTestWidget(buttonWidget));
await tester.pumpAndSettle();
// Act
await tester.tap(find.byKey(const Key('publishDietButton')));
await tester.pump();
// Assert
expect(buttonPressed, isTrue);
});
testWidgets('should display loading state', (WidgetTester tester) async {
// Arrange
Widget loadingWidget = const Center(child: CircularProgressIndicator());
// Act
await tester.pumpWidget(createTestWidget(loadingWidget));
await tester.pump();
// Assert
expect(find.byType(CircularProgressIndicator), findsOneWidget);
});
testWidgets('should display error message', (WidgetTester tester) async {
// Arrange
Widget errorWidget = const Center(child: Text('Произошла ошибка при создании диеты'));
// Act
await tester.pumpWidget(createTestWidget(errorWidget));
await tester.pumpAndSettle();
// Assert
expect(find.text('Произошла ошибка при создании диеты'), findsOneWidget);
});
testWidgets('should display success message', (WidgetTester tester) async {
// Arrange
Widget successWidget = const Center(child: Text('Диета успешно создана!'));
// Act
await tester.pumpWidget(createTestWidget(successWidget));
await tester.pumpAndSettle();
// Assert
expect(find.text('Диета успешно создана!'), findsOneWidget);
});
testWidgets('should validate required fields', (WidgetTester tester) async {
// Arrange
Widget validationWidget = Column(
children: [
TextFormField(
key: const Key('dietNameField'),
decoration: const InputDecoration(labelText: 'Название диеты', errorText: 'Название диеты обязательно'),
),
const SizedBox(height: 16),
TextFormField(
key: const Key('dietDescriptionField'),
decoration: const InputDecoration(labelText: 'Описание диеты', errorText: 'Описание диеты обязательно'),
),
],
);
// Act
await tester.pumpWidget(createTestWidget(validationWidget));
await tester.pumpAndSettle();
// Assert
expect(find.text('Название диеты обязательно'), findsOneWidget);
expect(find.text('Описание диеты обязательно'), findsOneWidget);
});
testWidgets('should display complete diet creation form', (WidgetTester tester) async {
// Arrange
Widget completeForm = Column(
children: [
TextFormField(
key: const Key('dietNameField'),
decoration: const InputDecoration(labelText: 'Название диеты', hintText: 'Например: Здоровая диета'),
),
const SizedBox(height: 16),
TextFormField(
key: const Key('dietDescriptionField'),
decoration: const InputDecoration(labelText: 'Описание диеты'),
maxLines: 3,
),
const SizedBox(height: 16),
DropdownButtonFormField<int>(
key: const Key('dietDurationField'),
decoration: const InputDecoration(labelText: 'Продолжительность'),
items: const [
DropdownMenuItem(value: 7, child: Text('7 дней')),
DropdownMenuItem(value: 14, child: Text('14 дней')),
DropdownMenuItem(value: 21, child: Text('21 день')),
],
onChanged: (value) {},
),
const SizedBox(height: 16),
DropdownButtonFormField<String>(
key: const Key('dietStatusField'),
decoration: const InputDecoration(labelText: 'Статус диеты'),
items: const [
DropdownMenuItem(value: 'active', child: Text('Активная')),
DropdownMenuItem(value: 'draft', child: Text('Черновик')),
],
onChanged: (value) {},
),
const SizedBox(height: 32),
ElevatedButton(key: const Key('publishDietButton'), onPressed: () {}, child: const Text('Опубликовать диету')),
],
);
// Act
await tester.pumpWidget(createTestWidget(completeForm));
await tester.pumpAndSettle();
// Assert
expect(find.byKey(const Key('dietNameField')), findsOneWidget);
expect(find.byKey(const Key('dietDescriptionField')), findsOneWidget);
expect(find.byKey(const Key('dietDurationField')), findsOneWidget);
expect(find.byKey(const Key('dietStatusField')), findsOneWidget);
expect(find.byKey(const Key('publishDietButton')), findsOneWidget);
});
testWidgets('should display diet type options', (WidgetTester tester) async {
// Arrange
Widget typeOptionsWidget = const Column(
children: [
Text('Выберите тип диеты:'),
SizedBox(height: 8),
Text('• Веганская - без продуктов животного происхождения'),
Text('• Мясная - с мясными продуктами'),
Text('• Углеводная - с высоким содержанием углеводов'),
Text('• Легкая - низкокалорийная диета'),
],
);
// Act
await tester.pumpWidget(createTestWidget(typeOptionsWidget));
await tester.pumpAndSettle();
// Assert
expect(find.text('Выберите тип диеты:'), findsOneWidget);
expect(find.text('• Веганская - без продуктов животного происхождения'), findsOneWidget);
expect(find.text('• Мясная - с мясными продуктами'), findsOneWidget);
expect(find.text('• Углеводная - с высоким содержанием углеводов'), findsOneWidget);
expect(find.text('• Легкая - низкокалорийная диета'), findsOneWidget);
});
testWidgets('should display diet duration options', (WidgetTester tester) async {
// Arrange
Widget durationOptionsWidget = const Column(
children: [
Text('Доступные продолжительности:'),
SizedBox(height: 8),
Text('• 7 дней - недельная диета'),
Text('• 14 дней - двухнедельная диета'),
Text('• 21 день - трехнедельная диета'),
Text('• 30 дней - месячная диета'),
],
);
// Act
await tester.pumpWidget(createTestWidget(durationOptionsWidget));
await tester.pumpAndSettle();
// Assert
expect(find.text('Доступные продолжительности:'), findsOneWidget);
expect(find.text('• 7 дней - недельная диета'), findsOneWidget);
expect(find.text('• 14 дней - двухнедельная диета'), findsOneWidget);
expect(find.text('• 21 день - трехнедельная диета'), findsOneWidget);
expect(find.text('• 30 дней - месячная диета'), findsOneWidget);
});
});
}