forked from eatvio/eatvio_app
277 lines
11 KiB
Dart
277 lines
11 KiB
Dart
import 'package:eatvio_app/app_keys.dart';
|
|
import 'package:eatvio_app/core/theme/theme_helper.dart';
|
|
import 'package:eatvio_app/features/create_recipe/presentation/bloc/create_recipe_cubit/create_recipe_cubit.dart';
|
|
import 'package:eatvio_app/features/create_recipe/presentation/widgets/info_about_recipe_widget.dart';
|
|
import 'package:eatvio_app/features/create_recipe/presentation/widgets/ingredients_widget.dart';
|
|
import 'package:eatvio_app/features/create_recipe/presentation/widgets/steps_widget.dart';
|
|
import 'package:eatvio_app/features/create_recipe/reporitories/recipe_repository.dart';
|
|
import 'package:eatvio_app/features/glossary/repositories/glossary_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 'simple_widget_test.mocks.dart';
|
|
|
|
@GenerateMocks([RecipeRepository, GlossaryRepository])
|
|
void main() {
|
|
group('Recipe Creation Widget Tests', () {
|
|
late MockRecipeRepository mockRecipeRepository;
|
|
late MockGlossaryRepository mockGlossaryRepository;
|
|
late CreateRecipeCubit createRecipeCubit;
|
|
|
|
setUp(() {
|
|
mockRecipeRepository = MockRecipeRepository();
|
|
mockGlossaryRepository = MockGlossaryRepository();
|
|
createRecipeCubit = CreateRecipeCubit(recipeRepository: mockRecipeRepository, glossaryRepository: mockGlossaryRepository);
|
|
});
|
|
|
|
tearDown(() {
|
|
createRecipeCubit.close();
|
|
});
|
|
|
|
Widget createTestWidget(Widget child) {
|
|
return MaterialApp(
|
|
theme: ThemeHelper().themeData(),
|
|
home: BlocProvider<CreateRecipeCubit>(
|
|
create: (context) => createRecipeCubit,
|
|
child: Scaffold(body: child),
|
|
),
|
|
);
|
|
}
|
|
|
|
testWidgets('should display InfoAboutRecipeWidget with all form fields', (WidgetTester tester) async {
|
|
// Arrange & Act
|
|
await tester.pumpWidget(createTestWidget(InfoAboutRecipeWidget(createRecipeCubit: createRecipeCubit)));
|
|
await tester.pumpAndSettle();
|
|
|
|
// Assert
|
|
expect(find.byKey(AppKeys.recipeCreateScreenTitleField), findsOneWidget);
|
|
expect(find.byKey(AppKeys.recipeCreateScreenTypeDropdown), findsOneWidget);
|
|
expect(find.byKey(AppKeys.recipeCreateScreenPortionsField), findsOneWidget);
|
|
expect(find.byKey(AppKeys.recipeCreateScreenCaloriesField), findsOneWidget);
|
|
expect(find.byKey(AppKeys.recipeCreateScreenTotalHoursField), findsOneWidget);
|
|
expect(find.byKey(AppKeys.recipeCreateScreenTotalMinutesField), findsOneWidget);
|
|
expect(find.byKey(AppKeys.recipeCreateScreenActiveHoursField), findsOneWidget);
|
|
expect(find.byKey(AppKeys.recipeCreateScreenActiveMinutesField), findsOneWidget);
|
|
expect(find.byKey(AppKeys.recipeCreateScreenDescriptionField), findsOneWidget);
|
|
});
|
|
|
|
testWidgets('should display IngredientsWidget with add button', (WidgetTester tester) async {
|
|
// Arrange & Act
|
|
await tester.pumpWidget(createTestWidget(const IngredientsWidget()));
|
|
await tester.pumpAndSettle();
|
|
|
|
// Assert
|
|
expect(find.byKey(AppKeys.recipeCreateScreenAddIngredientButton), findsOneWidget);
|
|
});
|
|
|
|
testWidgets('should display StepsWidget with add button', (WidgetTester tester) async {
|
|
// Arrange & Act
|
|
await tester.pumpWidget(createTestWidget(StepsWidget(createRecipeCubit: createRecipeCubit)));
|
|
await tester.pumpAndSettle();
|
|
|
|
// Assert
|
|
expect(find.byKey(AppKeys.recipeCreateScreenAddStepButton), findsOneWidget);
|
|
});
|
|
|
|
testWidgets('should update title when user types in title field', (WidgetTester tester) async {
|
|
// Arrange
|
|
await tester.pumpWidget(createTestWidget(InfoAboutRecipeWidget(createRecipeCubit: createRecipeCubit)));
|
|
await tester.pumpAndSettle();
|
|
|
|
const testTitle = 'Тестовый рецепт';
|
|
|
|
// Act
|
|
await tester.enterText(find.byKey(AppKeys.recipeCreateScreenTitleField), testTitle);
|
|
await tester.pump();
|
|
|
|
// Assert
|
|
expect(find.text(testTitle), findsOneWidget);
|
|
});
|
|
|
|
testWidgets('should update portions when user types in portions field', (WidgetTester tester) async {
|
|
// Arrange
|
|
await tester.pumpWidget(createTestWidget(InfoAboutRecipeWidget(createRecipeCubit: createRecipeCubit)));
|
|
await tester.pumpAndSettle();
|
|
|
|
const testPortions = '4';
|
|
|
|
// Act
|
|
await tester.enterText(find.byKey(AppKeys.recipeCreateScreenPortionsField), testPortions);
|
|
await tester.pump();
|
|
|
|
// Assert
|
|
expect(find.text(testPortions), findsOneWidget);
|
|
});
|
|
|
|
testWidgets('should update calories when user types in calories field', (WidgetTester tester) async {
|
|
// Arrange
|
|
await tester.pumpWidget(createTestWidget(InfoAboutRecipeWidget(createRecipeCubit: createRecipeCubit)));
|
|
await tester.pumpAndSettle();
|
|
|
|
const testCalories = '250';
|
|
|
|
// Act
|
|
await tester.enterText(find.byKey(AppKeys.recipeCreateScreenCaloriesField), testCalories);
|
|
await tester.pump();
|
|
|
|
// Assert
|
|
expect(find.text(testCalories), findsOneWidget);
|
|
});
|
|
|
|
testWidgets('should update description when user types in description field', (WidgetTester tester) async {
|
|
// Arrange
|
|
await tester.pumpWidget(createTestWidget(InfoAboutRecipeWidget(createRecipeCubit: createRecipeCubit)));
|
|
await tester.pumpAndSettle();
|
|
|
|
const testDescription = 'Это тестовое описание рецепта';
|
|
|
|
// Act
|
|
await tester.enterText(find.byKey(AppKeys.recipeCreateScreenDescriptionField), testDescription);
|
|
await tester.pump();
|
|
|
|
// Assert
|
|
expect(find.text(testDescription), findsOneWidget);
|
|
});
|
|
|
|
testWidgets('should update cooking time fields', (WidgetTester tester) async {
|
|
// Arrange
|
|
await tester.pumpWidget(createTestWidget(InfoAboutRecipeWidget(createRecipeCubit: createRecipeCubit)));
|
|
await tester.pumpAndSettle();
|
|
|
|
const testHours = '1';
|
|
const testMinutes = '30';
|
|
|
|
// Act
|
|
await tester.enterText(find.byKey(AppKeys.recipeCreateScreenTotalHoursField), testHours);
|
|
await tester.enterText(find.byKey(AppKeys.recipeCreateScreenTotalMinutesField), testMinutes);
|
|
await tester.pump();
|
|
|
|
// Assert
|
|
expect(find.text(testHours), findsOneWidget);
|
|
expect(find.text(testMinutes), findsOneWidget);
|
|
});
|
|
|
|
testWidgets('should update active cooking time fields', (WidgetTester tester) async {
|
|
// Arrange
|
|
await tester.pumpWidget(createTestWidget(InfoAboutRecipeWidget(createRecipeCubit: createRecipeCubit)));
|
|
await tester.pumpAndSettle();
|
|
|
|
const testActiveHours = '0';
|
|
const testActiveMinutes = '45';
|
|
|
|
// Act
|
|
await tester.enterText(find.byKey(AppKeys.recipeCreateScreenActiveHoursField), testActiveHours);
|
|
await tester.enterText(find.byKey(AppKeys.recipeCreateScreenActiveMinutesField), testActiveMinutes);
|
|
await tester.pump();
|
|
|
|
// Assert
|
|
expect(find.text(testActiveHours), findsOneWidget);
|
|
expect(find.text(testActiveMinutes), findsOneWidget);
|
|
});
|
|
|
|
testWidgets('should add ingredient when add ingredient button is tapped', (WidgetTester tester) async {
|
|
// Arrange
|
|
await tester.pumpWidget(createTestWidget(const IngredientsWidget()));
|
|
await tester.pumpAndSettle();
|
|
|
|
// Act
|
|
await tester.tap(find.byKey(AppKeys.recipeCreateScreenAddIngredientButton));
|
|
await tester.pump(const Duration(milliseconds: 300));
|
|
|
|
// Assert - should show ingredient modal or form
|
|
expect(find.byKey(AppKeys.recipeCreateScreenIngredientNameField), findsOneWidget);
|
|
expect(find.byKey(AppKeys.recipeCreateScreenIngredientQuantityField), findsOneWidget);
|
|
expect(find.byKey(AppKeys.recipeCreateScreenIngredientAddButton), findsOneWidget);
|
|
});
|
|
|
|
testWidgets('should add step when add step button is tapped', (WidgetTester tester) async {
|
|
// Arrange
|
|
await tester.pumpWidget(createTestWidget(StepsWidget(createRecipeCubit: createRecipeCubit)));
|
|
await tester.pumpAndSettle();
|
|
|
|
// Act
|
|
await tester.tap(find.byKey(AppKeys.recipeCreateScreenAddStepButton));
|
|
await tester.pump(const Duration(milliseconds: 300));
|
|
|
|
// Assert - should show additional step field
|
|
expect(find.byKey(AppKeys.recipeCreateScreenStepDescriptionField), findsAtLeastNWidgets(2));
|
|
});
|
|
|
|
testWidgets('should add tag when add tag button is tapped', (WidgetTester tester) async {
|
|
// Arrange
|
|
await tester.pumpWidget(createTestWidget(InfoAboutRecipeWidget(createRecipeCubit: createRecipeCubit)));
|
|
await tester.pumpAndSettle();
|
|
|
|
const testTag = 'тестовый тег';
|
|
|
|
// Act
|
|
await tester.enterText(find.byKey(AppKeys.recipeCreateScreenTagField), testTag);
|
|
await tester.tap(find.byKey(AppKeys.recipeCreateScreenAddTagButton));
|
|
await tester.pump(const Duration(milliseconds: 300));
|
|
|
|
// Assert - should show the added tag
|
|
expect(find.text(testTag), findsOneWidget);
|
|
});
|
|
|
|
testWidgets('should display loading state when cubit is loading', (WidgetTester tester) async {
|
|
// Arrange
|
|
final loadingCubit = CreateRecipeCubit(recipeRepository: mockRecipeRepository, glossaryRepository: mockGlossaryRepository);
|
|
|
|
Widget loadingWidget() {
|
|
return MaterialApp(
|
|
theme: ThemeHelper().themeData(),
|
|
home: BlocProvider<CreateRecipeCubit>(
|
|
create: (context) => loadingCubit,
|
|
child: const Scaffold(body: Center(child: CircularProgressIndicator())),
|
|
),
|
|
);
|
|
}
|
|
|
|
// Act
|
|
await tester.pumpWidget(loadingWidget());
|
|
await tester.pump();
|
|
|
|
// Assert - should show loading indicator
|
|
expect(find.byType(CircularProgressIndicator), findsOneWidget);
|
|
|
|
loadingCubit.close();
|
|
});
|
|
|
|
testWidgets('should display form labels correctly', (WidgetTester tester) async {
|
|
// Arrange & Act
|
|
await tester.pumpWidget(createTestWidget(InfoAboutRecipeWidget(createRecipeCubit: createRecipeCubit)));
|
|
await tester.pumpAndSettle();
|
|
|
|
// Assert
|
|
expect(find.text('Название'), findsOneWidget);
|
|
expect(find.text('Тип блюда'), findsOneWidget);
|
|
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 form fields', (WidgetTester tester) async {
|
|
// Arrange & Act
|
|
await tester.pumpWidget(createTestWidget(InfoAboutRecipeWidget(createRecipeCubit: createRecipeCubit)));
|
|
await tester.pumpAndSettle();
|
|
|
|
// Assert
|
|
expect(find.text('Например: тар-тар из говядины'), findsOneWidget);
|
|
});
|
|
|
|
testWidgets('should display time input fields with correct labels', (WidgetTester tester) async {
|
|
// Arrange & Act
|
|
await tester.pumpWidget(createTestWidget(InfoAboutRecipeWidget(createRecipeCubit: createRecipeCubit)));
|
|
await tester.pumpAndSettle();
|
|
|
|
// Assert
|
|
expect(find.text('Часы'), findsAtLeastNWidgets(2)); // Total and Active hours
|
|
expect(find.text('Минуты'), findsAtLeastNWidgets(2)); // Total and Active minutes
|
|
});
|
|
});
|
|
}
|