forked from eatvio/eatvio_app
Merge remote-tracking branch 'upstream/main' into issue-914
This commit is contained in:
@@ -433,9 +433,49 @@ void main() {
|
||||
final tempFile = File('${Directory.systemTemp.path}/test_image.jpg');
|
||||
await tempFile.writeAsBytes([1, 2, 3]);
|
||||
cubit.replaceImage(tempFile);
|
||||
cubit.addIngredient(const i.Ingredient(name: 'Test Ingredient', unit: 'gr', portion: '100', productId: 1));
|
||||
cubit.replaceDescriptionInStep('Step 1 description', 0);
|
||||
|
||||
expect(cubit.validateAll(), true);
|
||||
});
|
||||
|
||||
// validateForDraft tests
|
||||
test('validateForDraft - возвращает false когда title не задан', () {
|
||||
expect(cubit.validateForDraft(), false);
|
||||
expect(cubit.state.titleValidationError, 'Поле не заполнено');
|
||||
});
|
||||
|
||||
test('validateForDraft - возвращает false когда title слишком короткий', () {
|
||||
cubit.replaceTitle('AB');
|
||||
expect(cubit.validateForDraft(), false);
|
||||
expect(cubit.state.titleValidationError, 'Минимальная длина 3 символа ');
|
||||
});
|
||||
|
||||
test('validateForDraft - возвращает true когда задан только title', () {
|
||||
cubit.replaceTitle('Мой черновик');
|
||||
expect(cubit.validateForDraft(), true);
|
||||
expect(cubit.state.titleValidationError, isNull);
|
||||
});
|
||||
|
||||
test('validateForDraft - сбрасывает ошибки остальных полей', () {
|
||||
// Сначала вызываем validateAll, чтобы появились ошибки
|
||||
cubit.validateAll();
|
||||
expect(cubit.state.descriptionValidationError, isNotNull);
|
||||
expect(cubit.state.imageValidationError, isNotNull);
|
||||
|
||||
// Теперь задаём title и вызываем validateForDraft
|
||||
cubit.replaceTitle('Мой черновик');
|
||||
final result = cubit.validateForDraft();
|
||||
|
||||
expect(result, true);
|
||||
expect(cubit.state.descriptionValidationError, isNull);
|
||||
expect(cubit.state.cookingTimeValidationError, isNull);
|
||||
expect(cubit.state.activeTimeValidationError, isNull);
|
||||
expect(cubit.state.servingsValidationError, isNull);
|
||||
expect(cubit.state.energyPerServingValidationError, isNull);
|
||||
expect(cubit.state.imageValidationError, isNull);
|
||||
expect(cubit.state.stepsValidationError, isNull);
|
||||
expect(cubit.state.ingredientsValidationError, isNull);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
@@ -10,8 +10,15 @@ import 'package:eatvio_app/features/create_recipe/services/recipe_service.dart';
|
||||
import 'package:flutter_test/flutter_test.dart';
|
||||
import 'package:mocktail/mocktail.dart';
|
||||
|
||||
import 'package:retrofit/retrofit.dart';
|
||||
|
||||
class MockCreateRecipeService extends Mock implements CreateRecipeService {}
|
||||
|
||||
final mockHttpResponse = HttpResponse(
|
||||
null,
|
||||
Response(requestOptions: RequestOptions(path: ''), statusCode: 200),
|
||||
);
|
||||
|
||||
void main() {
|
||||
setUpAll(() {
|
||||
registerFallbackValue(FormData());
|
||||
@@ -140,7 +147,7 @@ void main() {
|
||||
energyPerServing: 300,
|
||||
);
|
||||
|
||||
await repository.publishRecipe(recipe);
|
||||
expect(() => repository.publishRecipe(recipe), throwsException);
|
||||
|
||||
// Методы не должны вызываться, так как изображение отсутствует
|
||||
verifyNever(() => mockService.publishRecipe(formData: any(named: 'formData')));
|
||||
@@ -162,7 +169,7 @@ void main() {
|
||||
energyPerServing: 300,
|
||||
);
|
||||
|
||||
await repository.publishRecipe(recipe);
|
||||
expect(() => repository.publishRecipe(recipe), throwsException);
|
||||
|
||||
// Методы не должны вызываться, так как изображение пустое
|
||||
verifyNever(() => mockService.publishRecipe(formData: any(named: 'formData')));
|
||||
@@ -188,7 +195,7 @@ void main() {
|
||||
// Мокируем ImageCompressUtility.compressFile
|
||||
// Это сложно, так как это статический метод, но мы можем проверить, что вызывается updateRecipe
|
||||
when(() => mockService.updateRecipe(slug: slug, formData: any(named: 'formData')))
|
||||
.thenAnswer((_) async => Future.value());
|
||||
.thenAnswer((_) async => Future.value(mockHttpResponse));
|
||||
|
||||
// Этот тест может упасть из-за ImageCompressUtility, но мы проверяем логику
|
||||
try {
|
||||
@@ -216,7 +223,7 @@ void main() {
|
||||
);
|
||||
|
||||
when(() => mockService.publishRecipe(formData: any(named: 'formData')))
|
||||
.thenAnswer((_) async => Future.value());
|
||||
.thenAnswer((_) async => Future.value(mockHttpResponse));
|
||||
|
||||
try {
|
||||
await repository.publishRecipe(recipe);
|
||||
@@ -243,7 +250,7 @@ void main() {
|
||||
);
|
||||
|
||||
when(() => mockService.publishRecipe(formData: any(named: 'formData')))
|
||||
.thenAnswer((_) async => Future.value());
|
||||
.thenAnswer((_) async => Future.value(mockHttpResponse));
|
||||
|
||||
try {
|
||||
await repository.publishRecipe(recipe);
|
||||
@@ -270,7 +277,7 @@ void main() {
|
||||
);
|
||||
|
||||
when(() => mockService.publishRecipe(formData: any(named: 'formData')))
|
||||
.thenAnswer((_) async => Future.value());
|
||||
.thenAnswer((_) async => Future.value(mockHttpResponse));
|
||||
|
||||
try {
|
||||
await repository.publishRecipe(recipe);
|
||||
@@ -297,7 +304,7 @@ void main() {
|
||||
);
|
||||
|
||||
when(() => mockService.publishRecipe(formData: any(named: 'formData')))
|
||||
.thenAnswer((_) async => Future.value());
|
||||
.thenAnswer((_) async => Future.value(mockHttpResponse));
|
||||
|
||||
try {
|
||||
await repository.publishRecipe(recipe);
|
||||
@@ -364,7 +371,7 @@ void main() {
|
||||
);
|
||||
|
||||
when(() => mockService.publishRecipe(formData: any(named: 'formData')))
|
||||
.thenAnswer((_) async => Future.value());
|
||||
.thenAnswer((_) async => Future.value(mockHttpResponse));
|
||||
|
||||
try {
|
||||
await repository.publishRecipe(recipe);
|
||||
@@ -399,7 +406,7 @@ void main() {
|
||||
);
|
||||
|
||||
when(() => mockService.publishRecipe(formData: any(named: 'formData')))
|
||||
.thenAnswer((_) async => Future.value());
|
||||
.thenAnswer((_) async => Future.value(mockHttpResponse));
|
||||
|
||||
try {
|
||||
await repository.publishRecipe(recipe);
|
||||
@@ -435,7 +442,7 @@ void main() {
|
||||
);
|
||||
|
||||
when(() => mockService.publishRecipe(formData: any(named: 'formData')))
|
||||
.thenAnswer((_) async => Future.value());
|
||||
.thenAnswer((_) async => Future.value(mockHttpResponse));
|
||||
|
||||
try {
|
||||
await repository.publishRecipe(recipe);
|
||||
@@ -472,7 +479,7 @@ void main() {
|
||||
);
|
||||
|
||||
when(() => mockService.publishRecipe(formData: any(named: 'formData')))
|
||||
.thenAnswer((_) async => Future.value());
|
||||
.thenAnswer((_) async => Future.value(mockHttpResponse));
|
||||
|
||||
try {
|
||||
await repository.publishRecipe(recipe);
|
||||
@@ -499,7 +506,7 @@ void main() {
|
||||
);
|
||||
|
||||
when(() => mockService.publishRecipe(formData: any(named: 'formData')))
|
||||
.thenAnswer((_) async => Future.value());
|
||||
.thenAnswer((_) async => Future.value(mockHttpResponse));
|
||||
|
||||
try {
|
||||
await repository.publishRecipe(recipe);
|
||||
|
||||
@@ -9,6 +9,10 @@ import 'package:mockito/mockito.dart';
|
||||
|
||||
import 'recipe_service_test.mocks.dart';
|
||||
|
||||
import 'package:retrofit/retrofit.dart';
|
||||
|
||||
final mockHttpResponse = HttpResponse(null, Response(requestOptions: RequestOptions()));
|
||||
|
||||
@GenerateNiceMocks([MockSpec<CreateRecipeService>()])
|
||||
void main() {
|
||||
group('CreateRecipeService', () {
|
||||
@@ -77,7 +81,7 @@ void main() {
|
||||
final formData = FormData.fromMap({});
|
||||
|
||||
when(mockCreateRecipeService.publishRecipe(formData: formData))
|
||||
.thenAnswer((_) async => Future.value());
|
||||
.thenAnswer((_) async => Future.value(mockHttpResponse));
|
||||
|
||||
await mockCreateRecipeService.publishRecipe(formData: formData);
|
||||
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import 'package:eatvio_app/features/recipe/models/my_recipe_model.dart';
|
||||
import 'package:eatvio_app/features/recipe/presentation/cubit/my_recipes_cubit/my_recieps_cubit.dart';
|
||||
import 'package:eatvio_app/features/recipe/presentation/cubit/my_recipes_cubit/my_recipes_cubit.dart';
|
||||
import 'package:eatvio_app/features/recipe/presentation/cubit/my_recipes_cubit/my_recipes_state.dart';
|
||||
import 'package:eatvio_app/features/create_recipe/reporitories/recipe_repository.dart';
|
||||
import 'package:eatvio_app/features/recipe/repositories/about_recipe_repository.dart';
|
||||
import 'package:eatvio_app/features/recipe/repositories/my_recipes_repository.dart';
|
||||
import 'package:flutter_test/flutter_test.dart';
|
||||
@@ -9,16 +10,18 @@ import 'package:mockito/mockito.dart';
|
||||
|
||||
import 'my_recipes_cubit_test.mocks.dart';
|
||||
|
||||
@GenerateNiceMocks([MockSpec<MyRecipesRepository>(), MockSpec<AboutRecipeRepository>()])
|
||||
@GenerateNiceMocks([MockSpec<MyRecipesRepository>(), MockSpec<AboutRecipeRepository>(), MockSpec<RecipeRepository>()])
|
||||
void main() {
|
||||
group('MyRecipesCubit', () {
|
||||
MyRecipesCubit? cubit;
|
||||
late MockMyRecipesRepository mockMyRecipesRepository;
|
||||
late MockAboutRecipeRepository mockAboutRecipeRepository;
|
||||
late MockRecipeRepository mockRecipeRepository;
|
||||
|
||||
setUp(() {
|
||||
mockMyRecipesRepository = MockMyRecipesRepository();
|
||||
mockAboutRecipeRepository = MockAboutRecipeRepository();
|
||||
mockRecipeRepository = MockRecipeRepository();
|
||||
});
|
||||
|
||||
tearDown(() async {
|
||||
@@ -29,13 +32,13 @@ void main() {
|
||||
});
|
||||
|
||||
test('начальное состояние - loading', () {
|
||||
cubit = MyRecipesCubit(myRecipesRepository: mockMyRecipesRepository, aboutRecipeRepository: mockAboutRecipeRepository);
|
||||
cubit = MyRecipesCubit(myRecipesRepository: mockMyRecipesRepository, aboutRecipeRepository: mockAboutRecipeRepository, recipeRepository: mockRecipeRepository);
|
||||
|
||||
expect(cubit!.state, isA<MyRecipesStateLoading>());
|
||||
});
|
||||
|
||||
test('getMyRecipes - успешная загрузка активных рецептов', () async {
|
||||
cubit = MyRecipesCubit(myRecipesRepository: mockMyRecipesRepository, aboutRecipeRepository: mockAboutRecipeRepository);
|
||||
cubit = MyRecipesCubit(myRecipesRepository: mockMyRecipesRepository, aboutRecipeRepository: mockAboutRecipeRepository, recipeRepository: mockRecipeRepository);
|
||||
|
||||
final testRecipes = [
|
||||
const MyRecipeModel(
|
||||
@@ -66,7 +69,7 @@ void main() {
|
||||
});
|
||||
|
||||
test('setActiveState - фильтрует активные рецепты', () async {
|
||||
cubit = MyRecipesCubit(myRecipesRepository: mockMyRecipesRepository, aboutRecipeRepository: mockAboutRecipeRepository);
|
||||
cubit = MyRecipesCubit(myRecipesRepository: mockMyRecipesRepository, aboutRecipeRepository: mockAboutRecipeRepository, recipeRepository: mockRecipeRepository);
|
||||
|
||||
final testRecipes = [
|
||||
const MyRecipeModel(
|
||||
@@ -112,7 +115,7 @@ void main() {
|
||||
});
|
||||
|
||||
test('setArchivedState - фильтрует архивированные рецепты', () async {
|
||||
cubit = MyRecipesCubit(myRecipesRepository: mockMyRecipesRepository, aboutRecipeRepository: mockAboutRecipeRepository);
|
||||
cubit = MyRecipesCubit(myRecipesRepository: mockMyRecipesRepository, aboutRecipeRepository: mockAboutRecipeRepository, recipeRepository: mockRecipeRepository);
|
||||
|
||||
final testRecipes = [
|
||||
const MyRecipeModel(
|
||||
|
||||
@@ -2,11 +2,13 @@ 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/recipe/presentation/cubit/my_recipes_cubit/my_recieps_cubit.dart';
|
||||
import 'package:eatvio_app/features/recipe/presentation/cubit/my_recipes_cubit/my_recipes_cubit.dart';
|
||||
import 'package:eatvio_app/features/recipe/presentation/cubit/my_recipes_cubit/my_recipes_state.dart';
|
||||
import 'package:eatvio_app/features/recipe/presentation/pages/my_recipes_screen.dart';
|
||||
import 'package:eatvio_app/generated/l10n.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_dotenv/flutter_dotenv.dart';
|
||||
import 'package:flutter_localizations/flutter_localizations.dart';
|
||||
import 'package:flutter_test/flutter_test.dart';
|
||||
import 'package:mockito/annotations.dart';
|
||||
import 'package:mockito/mockito.dart';
|
||||
@@ -26,7 +28,17 @@ void main() {
|
||||
});
|
||||
|
||||
Widget wrap(Widget child) {
|
||||
return MaterialApp(theme: ThemeHelper().themeData(), home: child);
|
||||
return MaterialApp(
|
||||
theme: ThemeHelper().themeData(),
|
||||
localizationsDelegates: const [
|
||||
S.delegate,
|
||||
GlobalMaterialLocalizations.delegate,
|
||||
GlobalWidgetsLocalizations.delegate,
|
||||
GlobalCupertinoLocalizations.delegate,
|
||||
],
|
||||
supportedLocales: S.delegate.supportedLocales,
|
||||
home: child,
|
||||
);
|
||||
}
|
||||
|
||||
testWidgets('renders my recipes screen', (tester) async {
|
||||
|
||||
@@ -5,7 +5,7 @@ import 'package:eatvio_app/core/theme/theme_helper.dart';
|
||||
import 'package:eatvio_app/features/feed/presentation/bloc/recipes_cubit/recipes_cubit.dart';
|
||||
import 'package:eatvio_app/features/feed/presentation/bloc/recipes_cubit/recipes_state.dart';
|
||||
import 'package:eatvio_app/features/recipe/models/my_recipe_model.dart';
|
||||
import 'package:eatvio_app/features/recipe/presentation/cubit/my_recipes_cubit/my_recieps_cubit.dart';
|
||||
import 'package:eatvio_app/features/recipe/presentation/cubit/my_recipes_cubit/my_recipes_cubit.dart';
|
||||
import 'package:eatvio_app/features/recipe/presentation/cubit/my_recipes_cubit/my_recipes_state.dart';
|
||||
import 'package:eatvio_app/features/recipe/presentation/widgets/my_recipe_widget.dart';
|
||||
import 'package:eatvio_app/generated/l10n.dart';
|
||||
|
||||
@@ -7,7 +7,7 @@ import 'package:flutter_test/flutter_test.dart';
|
||||
|
||||
void main() {
|
||||
group('MyRecipesTab smoke', () {
|
||||
Widget wrap(Widget child) {
|
||||
Widget wrap() {
|
||||
return MaterialApp(
|
||||
theme: ThemeHelper().themeData(),
|
||||
localizationsDelegates: const [
|
||||
@@ -17,12 +17,17 @@ void main() {
|
||||
GlobalCupertinoLocalizations.delegate,
|
||||
],
|
||||
supportedLocales: const [Locale('ru')],
|
||||
home: Scaffold(body: child),
|
||||
home: Material(
|
||||
child: MyRecipesTab(
|
||||
selectedIndex: 0,
|
||||
onTabChanged: (_) {},
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
testWidgets('renders my recipes tab', (tester) async {
|
||||
await tester.pumpWidget(wrap(const MyRecipesTab()));
|
||||
await tester.pumpWidget(wrap());
|
||||
await tester.pump();
|
||||
|
||||
expect(find.byType(MyRecipesTab), findsOneWidget);
|
||||
|
||||
@@ -1,9 +1,10 @@
|
||||
import 'package:eatvio_app/features/feed/models/diets_pagination_model.dart';
|
||||
import 'package:eatvio_app/features/feed/models/recipes_model.dart';
|
||||
import 'package:eatvio_app/features/recipe/models/my_recipe_model.dart';
|
||||
import 'package:eatvio_app/features/recipe/presentation/cubit/my_recipes_cubit/my_recieps_cubit.dart';
|
||||
import 'package:eatvio_app/features/recipe/presentation/cubit/my_recipes_cubit/my_recipes_cubit.dart';
|
||||
import 'package:eatvio_app/features/recipe/presentation/cubit/my_recipes_cubit/my_recipes_state.dart';
|
||||
import 'package:eatvio_app/features/recipe/repositories/about_recipe_repository.dart';
|
||||
import 'package:eatvio_app/features/create_recipe/reporitories/recipe_repository.dart';
|
||||
import 'package:eatvio_app/features/recipe/repositories/my_recipes_repository.dart';
|
||||
import 'package:flutter_test/flutter_test.dart';
|
||||
import 'package:mockito/annotations.dart';
|
||||
@@ -13,12 +14,14 @@ import 'my_recipes_cubit_test.mocks.dart';
|
||||
@GenerateNiceMocks([
|
||||
MockSpec<MyRecipesRepository>(),
|
||||
MockSpec<AboutRecipeRepository>(),
|
||||
MockSpec<RecipeRepository>(),
|
||||
])
|
||||
void main() {
|
||||
group('MyRecipesCubit', () {
|
||||
MyRecipesCubit? myRecipesCubit;
|
||||
late MockMyRecipesRepository mockMyRecipesRepository;
|
||||
late MockAboutRecipeRepository mockAboutRecipeRepository;
|
||||
late MockRecipeRepository mockRecipeRepository;
|
||||
|
||||
const testActiveRecipe = MyRecipeModel(
|
||||
id: 1,
|
||||
@@ -85,6 +88,7 @@ void main() {
|
||||
setUp(() {
|
||||
mockMyRecipesRepository = MockMyRecipesRepository();
|
||||
mockAboutRecipeRepository = MockAboutRecipeRepository();
|
||||
mockRecipeRepository = MockRecipeRepository();
|
||||
});
|
||||
|
||||
tearDown(() async {
|
||||
@@ -99,6 +103,7 @@ void main() {
|
||||
myRecipesCubit = MyRecipesCubit(
|
||||
myRecipesRepository: mockMyRecipesRepository,
|
||||
aboutRecipeRepository: mockAboutRecipeRepository,
|
||||
recipeRepository: mockRecipeRepository,
|
||||
);
|
||||
expect(myRecipesCubit!.state, isA<MyRecipesStateLoading>());
|
||||
});
|
||||
@@ -107,6 +112,7 @@ void main() {
|
||||
myRecipesCubit = MyRecipesCubit(
|
||||
myRecipesRepository: mockMyRecipesRepository,
|
||||
aboutRecipeRepository: mockAboutRecipeRepository,
|
||||
recipeRepository: mockRecipeRepository,
|
||||
);
|
||||
|
||||
when(mockMyRecipesRepository.getMyRecipes()).thenAnswer(
|
||||
@@ -127,6 +133,7 @@ void main() {
|
||||
myRecipesCubit = MyRecipesCubit(
|
||||
myRecipesRepository: mockMyRecipesRepository,
|
||||
aboutRecipeRepository: mockAboutRecipeRepository,
|
||||
recipeRepository: mockRecipeRepository,
|
||||
);
|
||||
|
||||
when(mockMyRecipesRepository.getMyRecipes()).thenThrow(Exception('Network error'));
|
||||
@@ -141,6 +148,7 @@ void main() {
|
||||
myRecipesCubit = MyRecipesCubit(
|
||||
myRecipesRepository: mockMyRecipesRepository,
|
||||
aboutRecipeRepository: mockAboutRecipeRepository,
|
||||
recipeRepository: mockRecipeRepository,
|
||||
);
|
||||
|
||||
when(mockMyRecipesRepository.getMyRecipes()).thenAnswer(
|
||||
@@ -161,6 +169,7 @@ void main() {
|
||||
myRecipesCubit = MyRecipesCubit(
|
||||
myRecipesRepository: mockMyRecipesRepository,
|
||||
aboutRecipeRepository: mockAboutRecipeRepository,
|
||||
recipeRepository: mockRecipeRepository,
|
||||
);
|
||||
|
||||
when(mockMyRecipesRepository.getMyRecipes()).thenThrow(Exception('Network error'));
|
||||
@@ -175,6 +184,7 @@ void main() {
|
||||
myRecipesCubit = MyRecipesCubit(
|
||||
myRecipesRepository: mockMyRecipesRepository,
|
||||
aboutRecipeRepository: mockAboutRecipeRepository,
|
||||
recipeRepository: mockRecipeRepository,
|
||||
);
|
||||
|
||||
when(mockMyRecipesRepository.getMyRecipes()).thenAnswer(
|
||||
@@ -195,6 +205,7 @@ void main() {
|
||||
myRecipesCubit = MyRecipesCubit(
|
||||
myRecipesRepository: mockMyRecipesRepository,
|
||||
aboutRecipeRepository: mockAboutRecipeRepository,
|
||||
recipeRepository: mockRecipeRepository,
|
||||
);
|
||||
|
||||
when(mockMyRecipesRepository.getMyRecipes()).thenThrow(Exception('Network error'));
|
||||
@@ -209,6 +220,7 @@ void main() {
|
||||
myRecipesCubit = MyRecipesCubit(
|
||||
myRecipesRepository: mockMyRecipesRepository,
|
||||
aboutRecipeRepository: mockAboutRecipeRepository,
|
||||
recipeRepository: mockRecipeRepository,
|
||||
);
|
||||
|
||||
when(mockAboutRecipeRepository.getRecipe('test-recipe')).thenAnswer((_) async => testRecipe);
|
||||
@@ -225,6 +237,7 @@ void main() {
|
||||
myRecipesCubit = MyRecipesCubit(
|
||||
myRecipesRepository: mockMyRecipesRepository,
|
||||
aboutRecipeRepository: mockAboutRecipeRepository,
|
||||
recipeRepository: mockRecipeRepository,
|
||||
);
|
||||
|
||||
when(mockMyRecipesRepository.getMyRecipes()).thenAnswer(
|
||||
|
||||
Reference in New Issue
Block a user