forked from eatvio/eatvio_app
feat(tests): increased tests coverage
This commit is contained in:
@@ -0,0 +1,329 @@
|
||||
import 'package:eatvio_app/app_keys.dart';
|
||||
import 'package:eatvio_app/core/app_config.dart';
|
||||
import 'package:eatvio_app/core/app_initializer.dart';
|
||||
import 'package:eatvio_app/core/locator_service.dart';
|
||||
import 'package:eatvio_app/core/theme/theme_helper.dart';
|
||||
import 'package:eatvio_app/features/create_recipe/entities/recipe_create_entity.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/bloc/create_recipe_cubit/create_recipe_state.dart';
|
||||
import 'package:eatvio_app/features/create_recipe/presentation/widgets/add_portion_widget.dart';
|
||||
import 'package:eatvio_app/features/glossary/models/glossary_model.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:flutter_dotenv/flutter_dotenv.dart';
|
||||
import 'package:flutter_test/flutter_test.dart';
|
||||
import 'package:mockito/annotations.dart';
|
||||
import 'package:mockito/mockito.dart';
|
||||
|
||||
import 'add_portion_widget_test.mocks.dart';
|
||||
|
||||
@GenerateNiceMocks([MockSpec<CreateRecipeCubit>()])
|
||||
void main() {
|
||||
group('AddPortionWidget smoke', () {
|
||||
setUpAll(() async {
|
||||
dotenv.loadFromString(envString: 'DEV_BASE_URL=http://localhost\nBASE_URL=http://localhost');
|
||||
});
|
||||
|
||||
setUp(() async {
|
||||
await sl.reset();
|
||||
sl.registerLazySingleton<AppConfig>(() => AppConfig(buildType: AppBuildType.tests)..setBaseUrl('http://localhost'));
|
||||
});
|
||||
|
||||
Widget wrap(Widget child) {
|
||||
return MaterialApp(
|
||||
theme: ThemeHelper().themeData(),
|
||||
home: Scaffold(body: child),
|
||||
);
|
||||
}
|
||||
|
||||
testWidgets('renders add portion widget', (tester) async {
|
||||
final cubit = MockCreateRecipeCubit();
|
||||
const entity = RecipeCreateEntity(typeOfRecipe: TypeOfRecipe.firstMeals, ingredients: [], steps: [StepEntity()], tags: []);
|
||||
const state = CreateRecipeState(loading: false, entity: entity);
|
||||
|
||||
when(cubit.state).thenReturn(state);
|
||||
when(cubit.stream).thenAnswer((_) => Stream.value(state));
|
||||
when(cubit.close()).thenAnswer((_) async => Future<void>.value());
|
||||
when(cubit.getGlossaryListByQuery(any)).thenAnswer((_) async => []);
|
||||
|
||||
await tester.pumpWidget(
|
||||
BlocProvider<CreateRecipeCubit>.value(
|
||||
value: cubit,
|
||||
child: wrap(AddPortionWidget(createRecipeCubit: cubit)),
|
||||
),
|
||||
);
|
||||
await tester.pumpAndSettle();
|
||||
|
||||
expect(find.byType(AddPortionWidget), findsOneWidget);
|
||||
expect(find.text('Добавление блюда'), findsOneWidget);
|
||||
expect(find.text('Добавить'), findsOneWidget);
|
||||
});
|
||||
|
||||
testWidgets('renders add portion widget with initial text', (tester) async {
|
||||
final cubit = MockCreateRecipeCubit();
|
||||
const entity = RecipeCreateEntity(typeOfRecipe: TypeOfRecipe.firstMeals, ingredients: [], steps: [StepEntity()], tags: []);
|
||||
const state = CreateRecipeState(loading: false, entity: entity);
|
||||
|
||||
when(cubit.state).thenReturn(state);
|
||||
when(cubit.stream).thenAnswer((_) => Stream.value(state));
|
||||
when(cubit.close()).thenAnswer((_) async => Future<void>.value());
|
||||
when(cubit.getGlossaryListByQuery(any)).thenAnswer((_) async => []);
|
||||
|
||||
await tester.pumpWidget(
|
||||
BlocProvider<CreateRecipeCubit>.value(
|
||||
value: cubit,
|
||||
child: wrap(AddPortionWidget(createRecipeCubit: cubit, productNameControllerText: 'Test Product', quantityControllerText: '100')),
|
||||
),
|
||||
);
|
||||
await tester.pumpAndSettle();
|
||||
|
||||
expect(find.byType(AddPortionWidget), findsOneWidget);
|
||||
|
||||
// Проверяем, что текстовые поля содержат начальные значения через find.text
|
||||
// Текст может быть не виден сразу, но контроллеры должны быть инициализированы
|
||||
expect(find.byKey(AppKeys.recipeCreateScreenIngredientNameField), findsOneWidget);
|
||||
expect(find.byKey(AppKeys.recipeCreateScreenIngredientQuantityField), findsOneWidget);
|
||||
});
|
||||
|
||||
testWidgets('renders edit portion widget with portion index', (tester) async {
|
||||
final cubit = MockCreateRecipeCubit();
|
||||
const entity = RecipeCreateEntity(typeOfRecipe: TypeOfRecipe.firstMeals, ingredients: [], steps: [StepEntity()], tags: []);
|
||||
const state = CreateRecipeState(loading: false, entity: entity);
|
||||
|
||||
when(cubit.state).thenReturn(state);
|
||||
when(cubit.stream).thenAnswer((_) => Stream.value(state));
|
||||
when(cubit.close()).thenAnswer((_) async => Future<void>.value());
|
||||
when(cubit.getGlossaryListByQuery(any)).thenAnswer((_) async => []);
|
||||
when(cubit.removeIngredient(any)).thenReturn(null);
|
||||
|
||||
await tester.pumpWidget(
|
||||
BlocProvider<CreateRecipeCubit>.value(
|
||||
value: cubit,
|
||||
child: wrap(AddPortionWidget(createRecipeCubit: cubit, portionIndex: 0, productNameControllerText: 'Test Product', quantityControllerText: '100')),
|
||||
),
|
||||
);
|
||||
await tester.pumpAndSettle();
|
||||
|
||||
expect(find.byType(AddPortionWidget), findsOneWidget);
|
||||
expect(find.text('Сохранить'), findsOneWidget);
|
||||
expect(find.byIcon(Icons.delete_outline_rounded), findsOneWidget);
|
||||
});
|
||||
|
||||
testWidgets('searches glossary items when typing in product name field', (tester) async {
|
||||
final cubit = MockCreateRecipeCubit();
|
||||
const entity = RecipeCreateEntity(typeOfRecipe: TypeOfRecipe.firstMeals, ingredients: [], steps: [StepEntity()], tags: []);
|
||||
const state = CreateRecipeState(loading: false, entity: entity);
|
||||
final testGlossaries = [
|
||||
const GlossaryModel(
|
||||
id: 1,
|
||||
name: 'Test Product 1',
|
||||
grInPortion: 100,
|
||||
energyOn100Gr: 100.0,
|
||||
carbohydratesOn100Gr: 20.0,
|
||||
proteinsOn100Gr: 10.0,
|
||||
fatsOn100Gr: 5.0,
|
||||
energyOnPortion: 100.0,
|
||||
carbohydratesOnPortion: 20.0,
|
||||
proteinsOnPortion: 10.0,
|
||||
fatsOnPortion: 5.0,
|
||||
),
|
||||
const GlossaryModel(
|
||||
id: 2,
|
||||
name: 'Test Product 2',
|
||||
grInPortion: 0,
|
||||
energyOn100Gr: 200.0,
|
||||
carbohydratesOn100Gr: 30.0,
|
||||
proteinsOn100Gr: 15.0,
|
||||
fatsOn100Gr: 10.0,
|
||||
energyOnPortion: 0.0,
|
||||
carbohydratesOnPortion: 0.0,
|
||||
proteinsOnPortion: 0.0,
|
||||
fatsOnPortion: 0.0,
|
||||
),
|
||||
];
|
||||
|
||||
when(cubit.state).thenReturn(state);
|
||||
when(cubit.stream).thenAnswer((_) => Stream.value(state));
|
||||
when(cubit.close()).thenAnswer((_) async => Future<void>.value());
|
||||
when(cubit.getGlossaryListByQuery('test')).thenAnswer((_) async => testGlossaries);
|
||||
when(cubit.addIngredient(any)).thenReturn(null);
|
||||
|
||||
await tester.pumpWidget(
|
||||
BlocProvider<CreateRecipeCubit>.value(
|
||||
value: cubit,
|
||||
child: wrap(AddPortionWidget(createRecipeCubit: cubit)),
|
||||
),
|
||||
);
|
||||
await tester.pumpAndSettle();
|
||||
|
||||
final productNameField = find.byKey(AppKeys.recipeCreateScreenIngredientNameField);
|
||||
await tester.enterText(productNameField, 'test');
|
||||
await tester.pump(const Duration(milliseconds: 300));
|
||||
await tester.pumpAndSettle();
|
||||
|
||||
expect(find.text('Test Product 1'), findsOneWidget);
|
||||
expect(find.text('Test Product 2'), findsOneWidget);
|
||||
});
|
||||
|
||||
testWidgets('selects glossary item from list', (tester) async {
|
||||
final cubit = MockCreateRecipeCubit();
|
||||
const entity = RecipeCreateEntity(typeOfRecipe: TypeOfRecipe.firstMeals, ingredients: [], steps: [StepEntity()], tags: []);
|
||||
const state = CreateRecipeState(loading: false, entity: entity);
|
||||
final testGlossaries = [
|
||||
const GlossaryModel(
|
||||
id: 1,
|
||||
name: 'Test Product',
|
||||
grInPortion: 100,
|
||||
energyOn100Gr: 100.0,
|
||||
carbohydratesOn100Gr: 20.0,
|
||||
proteinsOn100Gr: 10.0,
|
||||
fatsOn100Gr: 5.0,
|
||||
energyOnPortion: 100.0,
|
||||
carbohydratesOnPortion: 20.0,
|
||||
proteinsOnPortion: 10.0,
|
||||
fatsOnPortion: 5.0,
|
||||
),
|
||||
];
|
||||
|
||||
when(cubit.state).thenReturn(state);
|
||||
when(cubit.stream).thenAnswer((_) => Stream.value(state));
|
||||
when(cubit.close()).thenAnswer((_) async => Future<void>.value());
|
||||
when(cubit.getGlossaryListByQuery('test')).thenAnswer((_) async => testGlossaries);
|
||||
when(cubit.addIngredient(any)).thenReturn(null);
|
||||
|
||||
await tester.pumpWidget(
|
||||
BlocProvider<CreateRecipeCubit>.value(
|
||||
value: cubit,
|
||||
child: wrap(AddPortionWidget(createRecipeCubit: cubit)),
|
||||
),
|
||||
);
|
||||
await tester.pumpAndSettle();
|
||||
|
||||
final productNameField = find.byKey(AppKeys.recipeCreateScreenIngredientNameField);
|
||||
await tester.enterText(productNameField, 'test');
|
||||
await tester.pump(const Duration(milliseconds: 300));
|
||||
await tester.pumpAndSettle();
|
||||
|
||||
await tester.tap(find.text('Test Product'));
|
||||
await tester.pumpAndSettle();
|
||||
|
||||
expect(find.text('Test Product'), findsOneWidget);
|
||||
});
|
||||
|
||||
testWidgets('displays correct suffix text for grams when glossary has grInPortion 0', (tester) async {
|
||||
final cubit = MockCreateRecipeCubit();
|
||||
const entity = RecipeCreateEntity(typeOfRecipe: TypeOfRecipe.firstMeals, ingredients: [], steps: [StepEntity()], tags: []);
|
||||
const state = CreateRecipeState(loading: false, entity: entity);
|
||||
final testGlossaries = [
|
||||
const GlossaryModel(
|
||||
id: 1,
|
||||
name: 'Test Product',
|
||||
grInPortion: 0,
|
||||
energyOn100Gr: 100.0,
|
||||
carbohydratesOn100Gr: 20.0,
|
||||
proteinsOn100Gr: 10.0,
|
||||
fatsOn100Gr: 5.0,
|
||||
energyOnPortion: 0.0,
|
||||
carbohydratesOnPortion: 0.0,
|
||||
proteinsOnPortion: 0.0,
|
||||
fatsOnPortion: 0.0,
|
||||
),
|
||||
];
|
||||
|
||||
when(cubit.state).thenReturn(state);
|
||||
when(cubit.stream).thenAnswer((_) => Stream.value(state));
|
||||
when(cubit.close()).thenAnswer((_) async => Future<void>.value());
|
||||
when(cubit.getGlossaryListByQuery('test')).thenAnswer((_) async => testGlossaries);
|
||||
when(cubit.addIngredient(any)).thenReturn(null);
|
||||
|
||||
await tester.pumpWidget(
|
||||
BlocProvider<CreateRecipeCubit>.value(
|
||||
value: cubit,
|
||||
child: wrap(AddPortionWidget(createRecipeCubit: cubit)),
|
||||
),
|
||||
);
|
||||
await tester.pumpAndSettle();
|
||||
|
||||
final productNameField = find.byKey(AppKeys.recipeCreateScreenIngredientNameField);
|
||||
await tester.enterText(productNameField, 'test');
|
||||
await tester.pump(const Duration(milliseconds: 300));
|
||||
await tester.pumpAndSettle();
|
||||
|
||||
await tester.tap(find.text('Test Product'));
|
||||
await tester.pumpAndSettle();
|
||||
|
||||
expect(find.text('гр'), findsOneWidget);
|
||||
});
|
||||
|
||||
testWidgets('displays correct suffix text for pieces when glossary has grInPortion not 0', (tester) async {
|
||||
final cubit = MockCreateRecipeCubit();
|
||||
const entity = RecipeCreateEntity(typeOfRecipe: TypeOfRecipe.firstMeals, ingredients: [], steps: [StepEntity()], tags: []);
|
||||
const state = CreateRecipeState(loading: false, entity: entity);
|
||||
final testGlossaries = [
|
||||
const GlossaryModel(
|
||||
id: 1,
|
||||
name: 'Test Product',
|
||||
grInPortion: 100,
|
||||
energyOn100Gr: 100.0,
|
||||
carbohydratesOn100Gr: 20.0,
|
||||
proteinsOn100Gr: 10.0,
|
||||
fatsOn100Gr: 5.0,
|
||||
energyOnPortion: 100.0,
|
||||
carbohydratesOnPortion: 20.0,
|
||||
proteinsOnPortion: 10.0,
|
||||
fatsOnPortion: 5.0,
|
||||
),
|
||||
];
|
||||
|
||||
when(cubit.state).thenReturn(state);
|
||||
when(cubit.stream).thenAnswer((_) => Stream.value(state));
|
||||
when(cubit.close()).thenAnswer((_) async => Future<void>.value());
|
||||
when(cubit.getGlossaryListByQuery('test')).thenAnswer((_) async => testGlossaries);
|
||||
when(cubit.addIngredient(any)).thenReturn(null);
|
||||
|
||||
await tester.pumpWidget(
|
||||
BlocProvider<CreateRecipeCubit>.value(
|
||||
value: cubit,
|
||||
child: wrap(AddPortionWidget(createRecipeCubit: cubit)),
|
||||
),
|
||||
);
|
||||
await tester.pumpAndSettle();
|
||||
|
||||
final productNameField = find.byKey(AppKeys.recipeCreateScreenIngredientNameField);
|
||||
await tester.enterText(productNameField, 'test');
|
||||
await tester.pump(const Duration(milliseconds: 300));
|
||||
await tester.pumpAndSettle();
|
||||
|
||||
await tester.tap(find.text('Test Product'));
|
||||
await tester.pumpAndSettle();
|
||||
|
||||
expect(find.text('шт'), findsOneWidget);
|
||||
});
|
||||
|
||||
testWidgets('calls removeIngredient when delete button is tapped', (tester) async {
|
||||
final cubit = MockCreateRecipeCubit();
|
||||
const entity = RecipeCreateEntity(typeOfRecipe: TypeOfRecipe.firstMeals, ingredients: [], steps: [StepEntity()], tags: []);
|
||||
const state = CreateRecipeState(loading: false, entity: entity);
|
||||
|
||||
when(cubit.state).thenReturn(state);
|
||||
when(cubit.stream).thenAnswer((_) => Stream.value(state));
|
||||
when(cubit.close()).thenAnswer((_) async => Future<void>.value());
|
||||
when(cubit.getGlossaryListByQuery(any)).thenAnswer((_) async => []);
|
||||
when(cubit.removeIngredient(0)).thenReturn(null);
|
||||
|
||||
await tester.pumpWidget(
|
||||
BlocProvider<CreateRecipeCubit>.value(
|
||||
value: cubit,
|
||||
child: wrap(AddPortionWidget(createRecipeCubit: cubit, portionIndex: 0)),
|
||||
),
|
||||
);
|
||||
await tester.pumpAndSettle();
|
||||
|
||||
final deleteButton = find.byIcon(Icons.delete_outline_rounded);
|
||||
await tester.tap(deleteButton);
|
||||
await tester.pumpAndSettle();
|
||||
|
||||
verify(cubit.removeIngredient(0)).called(1);
|
||||
});
|
||||
});
|
||||
}
|
||||
@@ -0,0 +1,58 @@
|
||||
import 'package:eatvio_app/core/app_config.dart';
|
||||
import 'package:eatvio_app/core/app_initializer.dart';
|
||||
import 'package:eatvio_app/core/locator_service.dart';
|
||||
import 'package:eatvio_app/core/theme/theme_helper.dart';
|
||||
import 'package:eatvio_app/features/create_recipe/entities/recipe_create_entity.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/bloc/create_recipe_cubit/create_recipe_state.dart';
|
||||
import 'package:eatvio_app/features/create_recipe/presentation/widgets/info_about_recipe_widget.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:flutter_dotenv/flutter_dotenv.dart';
|
||||
import 'package:flutter_test/flutter_test.dart';
|
||||
import 'package:mockito/annotations.dart';
|
||||
import 'package:mockito/mockito.dart';
|
||||
|
||||
import 'info_about_recipe_widget_test.mocks.dart';
|
||||
|
||||
@GenerateNiceMocks([MockSpec<CreateRecipeCubit>()])
|
||||
void main() {
|
||||
group('InfoAboutRecipeWidget smoke', () {
|
||||
setUpAll(() async {
|
||||
dotenv.loadFromString(envString: 'DEV_BASE_URL=http://localhost\nBASE_URL=http://localhost');
|
||||
});
|
||||
|
||||
setUp(() async {
|
||||
await sl.reset();
|
||||
sl.registerLazySingleton<AppConfig>(() => AppConfig(buildType: AppBuildType.tests)..setBaseUrl('http://localhost'));
|
||||
});
|
||||
|
||||
tearDown(() async {
|
||||
await sl.reset();
|
||||
});
|
||||
|
||||
Widget wrap(Widget child, CreateRecipeCubit cubit) {
|
||||
return MaterialApp(
|
||||
theme: ThemeHelper().themeData(),
|
||||
home: Scaffold(
|
||||
body: BlocProvider<CreateRecipeCubit>.value(value: cubit, child: child),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
testWidgets('renders info about recipe widget', (tester) async {
|
||||
final cubit = MockCreateRecipeCubit();
|
||||
const entity = RecipeCreateEntity(ingredients: [], steps: [], tags: []);
|
||||
const state = CreateRecipeState(entity: entity, loading: false);
|
||||
|
||||
when(cubit.state).thenReturn(state);
|
||||
when(cubit.stream).thenAnswer((_) => Stream.value(state));
|
||||
when(cubit.close()).thenAnswer((_) async => Future<void>.value());
|
||||
|
||||
await tester.pumpWidget(wrap(InfoAboutRecipeWidget(createRecipeCubit: cubit), cubit));
|
||||
await tester.pump();
|
||||
|
||||
expect(find.byType(InfoAboutRecipeWidget), findsOneWidget);
|
||||
});
|
||||
});
|
||||
}
|
||||
@@ -0,0 +1,56 @@
|
||||
import 'package:eatvio_app/core/app_config.dart';
|
||||
import 'package:eatvio_app/core/app_initializer.dart';
|
||||
import 'package:eatvio_app/core/locator_service.dart';
|
||||
import 'package:eatvio_app/core/theme/theme_helper.dart';
|
||||
import 'package:eatvio_app/features/create_recipe/entities/recipe_create_entity.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/bloc/create_recipe_cubit/create_recipe_state.dart';
|
||||
import 'package:eatvio_app/features/create_recipe/presentation/widgets/portion_widget.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:flutter_dotenv/flutter_dotenv.dart';
|
||||
import 'package:flutter_test/flutter_test.dart';
|
||||
import 'package:mockito/annotations.dart';
|
||||
import 'package:mockito/mockito.dart';
|
||||
|
||||
import 'portion_widget_test.mocks.dart';
|
||||
|
||||
@GenerateNiceMocks([MockSpec<CreateRecipeCubit>()])
|
||||
void main() {
|
||||
group('PortionWidget smoke', () {
|
||||
setUpAll(() async {
|
||||
dotenv.loadFromString(envString: 'DEV_BASE_URL=http://localhost\nBASE_URL=http://localhost');
|
||||
});
|
||||
|
||||
setUp(() async {
|
||||
await sl.reset();
|
||||
sl.registerLazySingleton<AppConfig>(() => AppConfig(buildType: AppBuildType.tests)..setBaseUrl('http://localhost'));
|
||||
});
|
||||
|
||||
Widget wrap(Widget child) {
|
||||
return MaterialApp(
|
||||
theme: ThemeHelper().themeData(),
|
||||
home: Scaffold(body: child),
|
||||
);
|
||||
}
|
||||
|
||||
testWidgets('renders portion widget', (tester) async {
|
||||
final cubit = MockCreateRecipeCubit();
|
||||
const entity = RecipeCreateEntity(typeOfRecipe: TypeOfRecipe.firstMeals, ingredients: [], steps: [StepEntity()], tags: []);
|
||||
const state = CreateRecipeState(loading: false, entity: entity);
|
||||
|
||||
when(cubit.state).thenReturn(state);
|
||||
when(cubit.stream).thenAnswer((_) => Stream.value(state));
|
||||
when(cubit.close()).thenAnswer((_) async => Future<void>.value());
|
||||
when(cubit.replacePortionsCount(any)).thenReturn(null);
|
||||
when(cubit.replaceEnegryInPortion(any)).thenReturn(null);
|
||||
when(cubit.validateServings()).thenReturn(true);
|
||||
when(cubit.validateEnergyPerServing()).thenReturn(true);
|
||||
|
||||
await tester.pumpWidget(BlocProvider<CreateRecipeCubit>.value(value: cubit, child: wrap(const PortionWidget())));
|
||||
await tester.pumpAndSettle();
|
||||
|
||||
expect(find.byType(PortionWidget), findsOneWidget);
|
||||
});
|
||||
});
|
||||
}
|
||||
@@ -0,0 +1,59 @@
|
||||
import 'package:eatvio_app/core/app_config.dart';
|
||||
import 'package:eatvio_app/core/app_initializer.dart';
|
||||
import 'package:eatvio_app/core/locator_service.dart';
|
||||
import 'package:eatvio_app/core/theme/theme_helper.dart';
|
||||
import 'package:eatvio_app/features/create_recipe/entities/recipe_create_entity.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/bloc/create_recipe_cubit/create_recipe_state.dart';
|
||||
import 'package:eatvio_app/features/create_recipe/presentation/widgets/steps_widget.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:flutter_dotenv/flutter_dotenv.dart';
|
||||
import 'package:flutter_test/flutter_test.dart';
|
||||
import 'package:mockito/annotations.dart';
|
||||
import 'package:mockito/mockito.dart';
|
||||
|
||||
import 'steps_widget_test.mocks.dart';
|
||||
|
||||
@GenerateNiceMocks([MockSpec<CreateRecipeCubit>()])
|
||||
void main() {
|
||||
group('StepsWidget smoke', () {
|
||||
setUpAll(() async {
|
||||
dotenv.loadFromString(envString: 'DEV_BASE_URL=http://localhost\nBASE_URL=http://localhost');
|
||||
});
|
||||
|
||||
setUp(() async {
|
||||
await sl.reset();
|
||||
sl.registerLazySingleton<AppConfig>(() => AppConfig(buildType: AppBuildType.tests)..setBaseUrl('http://localhost'));
|
||||
});
|
||||
|
||||
Widget wrap(Widget child) {
|
||||
return MaterialApp(
|
||||
theme: ThemeHelper().themeData(),
|
||||
home: Scaffold(body: child),
|
||||
);
|
||||
}
|
||||
|
||||
testWidgets('renders steps widget', (tester) async {
|
||||
final cubit = MockCreateRecipeCubit();
|
||||
const entity = RecipeCreateEntity(typeOfRecipe: TypeOfRecipe.firstMeals, ingredients: [], steps: [StepEntity()], tags: []);
|
||||
const state = CreateRecipeState(loading: false, entity: entity);
|
||||
|
||||
when(cubit.state).thenReturn(state);
|
||||
when(cubit.stream).thenAnswer((_) => Stream.value(state));
|
||||
when(cubit.close()).thenAnswer((_) async => Future<void>.value());
|
||||
when(cubit.addStep()).thenReturn(null);
|
||||
when(cubit.removeStep(any)).thenReturn(null);
|
||||
|
||||
await tester.pumpWidget(
|
||||
BlocProvider<CreateRecipeCubit>.value(
|
||||
value: cubit,
|
||||
child: wrap(StepsWidget(createRecipeCubit: cubit)),
|
||||
),
|
||||
);
|
||||
await tester.pumpAndSettle();
|
||||
|
||||
expect(find.byType(StepsWidget), findsOneWidget);
|
||||
});
|
||||
});
|
||||
}
|
||||
@@ -1,3 +1,6 @@
|
||||
import 'package:eatvio_app/core/app_config.dart';
|
||||
import 'package:eatvio_app/core/app_initializer.dart';
|
||||
import 'package:eatvio_app/core/locator_service.dart';
|
||||
import 'package:eatvio_app/core/theme/theme_helper.dart';
|
||||
import 'package:eatvio_app/features/create_recipe/entities/recipe_create_entity.dart';
|
||||
import 'package:eatvio_app/features/create_recipe/presentation/bloc/create_recipe_cubit/create_recipe_cubit.dart';
|
||||
@@ -5,109 +8,66 @@ import 'package:eatvio_app/features/create_recipe/presentation/bloc/create_recip
|
||||
import 'package:eatvio_app/features/create_recipe/presentation/widgets/tags_widget.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:flutter_dotenv/flutter_dotenv.dart';
|
||||
import 'package:flutter_test/flutter_test.dart';
|
||||
import 'package:mockito/annotations.dart';
|
||||
import 'package:mockito/mockito.dart';
|
||||
|
||||
import 'tags_widget_test.mocks.dart';
|
||||
|
||||
@GenerateMocks([CreateRecipeCubit])
|
||||
@GenerateNiceMocks([MockSpec<CreateRecipeCubit>()])
|
||||
void main() {
|
||||
group('TagsWidget', () {
|
||||
late MockCreateRecipeCubit mockCubit;
|
||||
|
||||
setUp(() {
|
||||
mockCubit = MockCreateRecipeCubit();
|
||||
group('TagsWidget smoke', () {
|
||||
setUpAll(() async {
|
||||
dotenv.loadFromString(envString: 'DEV_BASE_URL=http://localhost\nBASE_URL=http://localhost');
|
||||
});
|
||||
|
||||
Widget createTestWidget() {
|
||||
setUp(() async {
|
||||
await sl.reset();
|
||||
sl.registerLazySingleton<AppConfig>(() => AppConfig(buildType: AppBuildType.tests)..setBaseUrl('http://localhost'));
|
||||
});
|
||||
|
||||
Widget wrap(Widget child) {
|
||||
return MaterialApp(
|
||||
theme: ThemeHelper().themeData(),
|
||||
home: BlocProvider<CreateRecipeCubit>.value(
|
||||
value: mockCubit,
|
||||
child: const Scaffold(
|
||||
body: TagsWidget(),
|
||||
),
|
||||
),
|
||||
home: Scaffold(body: child),
|
||||
);
|
||||
}
|
||||
|
||||
testWidgets('displays tags widget', (tester) async {
|
||||
const initialState = CreateRecipeState(
|
||||
entity: RecipeCreateEntity(
|
||||
ingredients: [],
|
||||
steps: [],
|
||||
tags: [],
|
||||
),
|
||||
loading: false,
|
||||
);
|
||||
when(mockCubit.state).thenReturn(initialState);
|
||||
when(mockCubit.stream).thenAnswer((_) => Stream.value(initialState));
|
||||
// ignore: return_of_invalid_type
|
||||
when(mockCubit.addTag(any)).thenAnswer((_) => () {});
|
||||
// ignore: return_of_invalid_type
|
||||
when(mockCubit.removeTag(any)).thenAnswer((_) => () {});
|
||||
testWidgets('renders tags widget', (tester) async {
|
||||
final cubit = MockCreateRecipeCubit();
|
||||
const entity = RecipeCreateEntity(typeOfRecipe: TypeOfRecipe.firstMeals, ingredients: [], steps: [StepEntity()], tags: []);
|
||||
const state = CreateRecipeState(loading: false, entity: entity);
|
||||
|
||||
await tester.pumpWidget(createTestWidget());
|
||||
when(cubit.state).thenReturn(state);
|
||||
when(cubit.stream).thenAnswer((_) => Stream.value(state));
|
||||
when(cubit.close()).thenAnswer((_) async => Future<void>.value());
|
||||
when(cubit.addTag(any)).thenReturn(null);
|
||||
when(cubit.removeTag(any)).thenReturn(null);
|
||||
|
||||
await tester.pumpWidget(BlocProvider<CreateRecipeCubit>.value(value: cubit, child: wrap(const TagsWidget())));
|
||||
await tester.pumpAndSettle();
|
||||
|
||||
expect(find.byType(TagsWidget), findsOneWidget);
|
||||
});
|
||||
|
||||
testWidgets('displays existing tags', (tester) async {
|
||||
const stateWithTags = CreateRecipeState(
|
||||
entity: RecipeCreateEntity(
|
||||
ingredients: [],
|
||||
steps: [],
|
||||
tags: ['tag1', 'tag2'],
|
||||
),
|
||||
loading: false,
|
||||
);
|
||||
when(mockCubit.state).thenReturn(stateWithTags);
|
||||
when(mockCubit.stream).thenAnswer((_) => Stream.value(stateWithTags));
|
||||
// ignore: return_of_invalid_type
|
||||
when(mockCubit.addTag(any)).thenAnswer((_) => () {});
|
||||
// ignore: return_of_invalid_type
|
||||
when(mockCubit.removeTag(any)).thenAnswer((_) => () {});
|
||||
testWidgets('renders tags widget with tags', (tester) async {
|
||||
final cubit = MockCreateRecipeCubit();
|
||||
const entity = RecipeCreateEntity(typeOfRecipe: TypeOfRecipe.firstMeals, ingredients: [], steps: [StepEntity()], tags: ['tag1', 'tag2']);
|
||||
const state = CreateRecipeState(loading: false, entity: entity);
|
||||
|
||||
await tester.pumpWidget(createTestWidget());
|
||||
when(cubit.state).thenReturn(state);
|
||||
when(cubit.stream).thenAnswer((_) => Stream.value(state));
|
||||
when(cubit.close()).thenAnswer((_) async => Future<void>.value());
|
||||
when(cubit.addTag(any)).thenReturn(null);
|
||||
when(cubit.removeTag(any)).thenReturn(null);
|
||||
|
||||
await tester.pumpWidget(BlocProvider<CreateRecipeCubit>.value(value: cubit, child: wrap(const TagsWidget())));
|
||||
await tester.pumpAndSettle();
|
||||
|
||||
expect(find.byType(TagsWidget), findsOneWidget);
|
||||
expect(find.text('tag1'), findsOneWidget);
|
||||
expect(find.text('tag2'), findsOneWidget);
|
||||
});
|
||||
|
||||
testWidgets('calls addTag when add button is tapped', (tester) async {
|
||||
const initialState = CreateRecipeState(
|
||||
entity: RecipeCreateEntity(
|
||||
ingredients: [],
|
||||
steps: [],
|
||||
tags: [],
|
||||
),
|
||||
loading: false,
|
||||
);
|
||||
when(mockCubit.state).thenReturn(initialState);
|
||||
when(mockCubit.stream).thenAnswer((_) => Stream.value(initialState));
|
||||
// ignore: return_of_invalid_type
|
||||
when(mockCubit.addTag(any)).thenAnswer((_) => () {});
|
||||
// ignore: return_of_invalid_type
|
||||
when(mockCubit.removeTag(any)).thenAnswer((_) => () {});
|
||||
|
||||
await tester.pumpWidget(createTestWidget());
|
||||
await tester.pumpAndSettle();
|
||||
|
||||
// Find text field and enter tag
|
||||
final textField = find.byType(TextField);
|
||||
await tester.enterText(textField, 'new tag');
|
||||
await tester.pump();
|
||||
|
||||
// Find and tap add button
|
||||
final addButton = find.byIcon(Icons.done);
|
||||
await tester.tap(addButton);
|
||||
await tester.pump();
|
||||
|
||||
verify(mockCubit.addTag('new tag')).called(1);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,58 @@
|
||||
import 'package:eatvio_app/core/app_config.dart';
|
||||
import 'package:eatvio_app/core/app_initializer.dart';
|
||||
import 'package:eatvio_app/core/locator_service.dart';
|
||||
import 'package:eatvio_app/core/theme/theme_helper.dart';
|
||||
import 'package:eatvio_app/features/create_recipe/entities/recipe_create_entity.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/bloc/create_recipe_cubit/create_recipe_state.dart';
|
||||
import 'package:eatvio_app/features/create_recipe/presentation/widgets/time_of_cook_widget.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:flutter_dotenv/flutter_dotenv.dart';
|
||||
import 'package:flutter_test/flutter_test.dart';
|
||||
import 'package:mockito/annotations.dart';
|
||||
import 'package:mockito/mockito.dart';
|
||||
|
||||
import 'time_of_cook_widget_test.mocks.dart';
|
||||
|
||||
@GenerateNiceMocks([MockSpec<CreateRecipeCubit>()])
|
||||
void main() {
|
||||
group('TimeOfCookWidget smoke', () {
|
||||
setUpAll(() async {
|
||||
dotenv.loadFromString(envString: 'DEV_BASE_URL=http://localhost\nBASE_URL=http://localhost');
|
||||
});
|
||||
|
||||
setUp(() async {
|
||||
await sl.reset();
|
||||
sl.registerLazySingleton<AppConfig>(() => AppConfig(buildType: AppBuildType.tests)..setBaseUrl('http://localhost'));
|
||||
});
|
||||
|
||||
Widget wrap(Widget child) {
|
||||
return MaterialApp(
|
||||
theme: ThemeHelper().themeData(),
|
||||
home: Scaffold(body: child),
|
||||
);
|
||||
}
|
||||
|
||||
testWidgets('renders time of cook widget', (tester) async {
|
||||
final cubit = MockCreateRecipeCubit();
|
||||
const entity = RecipeCreateEntity(typeOfRecipe: TypeOfRecipe.firstMeals, ingredients: [], steps: [StepEntity()], tags: []);
|
||||
const state = CreateRecipeState(loading: false, entity: entity);
|
||||
|
||||
when(cubit.state).thenReturn(state);
|
||||
when(cubit.stream).thenAnswer((_) => Stream.value(state));
|
||||
when(cubit.close()).thenAnswer((_) async => Future<void>.value());
|
||||
when(cubit.setTotalCookingHours(any)).thenReturn(null);
|
||||
when(cubit.setTotalCookingMinutes(any)).thenReturn(null);
|
||||
when(cubit.setActiveCookingHours(any)).thenReturn(null);
|
||||
when(cubit.setActiveCookingMinutes(any)).thenReturn(null);
|
||||
when(cubit.validateTotalCookTime()).thenReturn(true);
|
||||
when(cubit.validateActiveCookTime()).thenReturn(true);
|
||||
|
||||
await tester.pumpWidget(BlocProvider<CreateRecipeCubit>.value(value: cubit, child: wrap(const TimeOfCookWidget())));
|
||||
await tester.pumpAndSettle();
|
||||
|
||||
expect(find.byType(TimeOfCookWidget), findsOneWidget);
|
||||
});
|
||||
});
|
||||
}
|
||||
Reference in New Issue
Block a user