Files
eatvio_app/test/features/recipes/presentation/cubit/recipes_cubit_test.dart

193 lines
8.5 KiB
Dart

import 'package:eatvio_app/features/create_recipe/models/recipe_tag_model.dart';
import 'package:eatvio_app/features/create_recipe/reporitories/recipe_repository.dart';
import 'package:eatvio_app/features/feed/models/recipes_model.dart';
import 'package:eatvio_app/features/feed/presentation/bloc/recipes_cubit/recipes_cubit.dart';
import 'package:eatvio_app/features/feed/repositories/feed_repository.dart';
import 'package:eatvio_app/features/recipe/repositories/about_recipe_repository.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:mockito/annotations.dart';
import 'package:mockito/mockito.dart';
import 'package:eatvio_app/features/feed/models/diets_pagination_model.dart';
import 'recipes_cubit_test.mocks.dart';
@GenerateNiceMocks([MockSpec<FeedRepository>(), MockSpec<RecipeRepository>(), MockSpec<AboutRecipeRepository>()])
void main() {
group('RecipesCubit', () {
RecipesCubit? recipesCubit;
late MockFeedRepository mockFeedRepository;
late MockRecipeRepository mockRecipeRepository;
late MockAboutRecipeRepository mockAboutRecipeRepository;
const testRecipe = Recipe(
id: 1,
image: 'https://someurl.com/img.jpg',
state: 'active',
cookingTime: 30,
activeCookingTime: 15,
ingredients: [],
description: 'Test recipe description',
steps: [],
videoUrl: null,
createdAt: null,
updatedAt: null,
title: 'Test Recipe',
type: 'main',
slug: 'test-recipe-slug',
commentsCount: 5,
wasLikedByMe: false,
isFavorite: false,
calories: 300.0,
servings: 4,
likesCount: 10,
viewsCount: 100,
tags: [],
author: Author(authorSlug: '', authorName: '', authorProfileIcon: '', authorIsMe: false),
);
final testRecipesList = [testRecipe];
final testRecipeTags = [RecipeTag(id: 1, name: 'Breakfast', recipesCount: 10, createdAt: DateTime(2024, 1, 1), updatedAt: DateTime(2024, 1, 1))];
setUp(() {
mockFeedRepository = MockFeedRepository();
mockRecipeRepository = MockRecipeRepository();
mockAboutRecipeRepository = MockAboutRecipeRepository();
});
tearDown(() async {
if (recipesCubit != null && !recipesCubit!.isClosed) {
await Future.delayed(const Duration(milliseconds: 100));
recipesCubit!.close();
recipesCubit = null;
}
});
test('начальное состояние - initial state', () {
recipesCubit = RecipesCubit(feedRepository: mockFeedRepository, recipeRepository: mockRecipeRepository, aboutRecipeRepository: mockAboutRecipeRepository);
expect(recipesCubit!.state.recipesList, isEmpty);
expect(recipesCubit!.state.recipesTags, isEmpty);
expect(recipesCubit!.state.selectedTags, isEmpty);
expect(recipesCubit!.state.selectedTagsCounter, 0);
expect(recipesCubit!.state.isLoading, true);
expect(recipesCubit!.state.errorMessage, null);
});
test('loadRecipesList - загружает рецепты успешно', () async {
recipesCubit = RecipesCubit(feedRepository: mockFeedRepository, recipeRepository: mockRecipeRepository, aboutRecipeRepository: mockAboutRecipeRepository);
when(mockFeedRepository.getRecipes(query: null, tags: [])).thenAnswer((_) async => testRecipesList);
when(mockRecipeRepository.getRecipesTags()).thenAnswer((_) async => testRecipeTags);
await recipesCubit!.loadRecipesList();
await Future.delayed(const Duration(milliseconds: 100));
expect(recipesCubit!.state.recipesList.length, 1);
expect(recipesCubit!.state.recipesList.first.title, 'Test Recipe');
expect(recipesCubit!.state.recipesTags.length, 1);
expect(recipesCubit!.state.errorMessage, null);
});
test('loadRecipesList - обрабатывает ошибку', () async {
recipesCubit = RecipesCubit(feedRepository: mockFeedRepository, recipeRepository: mockRecipeRepository, aboutRecipeRepository: mockAboutRecipeRepository);
when(mockFeedRepository.getRecipes(query: null, tags: [])).thenThrow(Exception('Network error'));
await recipesCubit!.loadRecipesList();
await Future.delayed(const Duration(milliseconds: 100));
expect(recipesCubit!.state.errorMessage, isNotNull);
expect(recipesCubit!.state.isLoading, false);
});
test('updateTags - добавляет тег', () {
recipesCubit = RecipesCubit(feedRepository: mockFeedRepository, recipeRepository: mockRecipeRepository, aboutRecipeRepository: mockAboutRecipeRepository);
final tag = RecipeTag(id: 1, name: 'Breakfast', recipesCount: 10, createdAt: DateTime(2024, 1, 1), updatedAt: DateTime(2024, 1, 1));
recipesCubit!.updateTags(tag);
expect(recipesCubit!.state.selectedTags.contains(1), true);
expect(recipesCubit!.state.selectedTagsCounter, 1);
});
test('updateTags - удаляет тег', () {
recipesCubit = RecipesCubit(feedRepository: mockFeedRepository, recipeRepository: mockRecipeRepository, aboutRecipeRepository: mockAboutRecipeRepository);
final tag = RecipeTag(id: 1, name: 'Breakfast', recipesCount: 10, createdAt: DateTime(2024, 1, 1), updatedAt: DateTime(2024, 1, 1));
recipesCubit!.updateTags(tag);
recipesCubit!.updateTags(tag);
expect(recipesCubit!.state.selectedTags.contains(1), false);
expect(recipesCubit!.state.selectedTagsCounter, 0);
});
test('likeRecipe - лайкает рецепт', () async {
recipesCubit = RecipesCubit(feedRepository: mockFeedRepository, recipeRepository: mockRecipeRepository, aboutRecipeRepository: mockAboutRecipeRepository);
when(mockFeedRepository.getRecipes(query: null, tags: [])).thenAnswer((_) async => testRecipesList);
when(mockRecipeRepository.getRecipesTags()).thenAnswer((_) async => testRecipeTags);
await recipesCubit!.loadRecipesList();
await Future.delayed(const Duration(milliseconds: 100));
when(mockAboutRecipeRepository.likeRecipe('test-recipe-slug')).thenAnswer((_) async => Future.value());
recipesCubit!.likeRecipe('test-recipe-slug', 0);
await Future.delayed(const Duration(milliseconds: 300));
expect(recipesCubit!.state.recipesList[0].wasLikedByMe, true);
expect(recipesCubit!.state.recipesList[0].likesCount, 11);
});
test('addRecipeToFavorite - добавляет рецепт в избранное', () async {
recipesCubit = RecipesCubit(feedRepository: mockFeedRepository, recipeRepository: mockRecipeRepository, aboutRecipeRepository: mockAboutRecipeRepository);
when(mockFeedRepository.getRecipes(query: null, tags: [])).thenAnswer((_) async => testRecipesList);
when(mockRecipeRepository.getRecipesTags()).thenAnswer((_) async => testRecipeTags);
await recipesCubit!.loadRecipesList();
await Future.delayed(const Duration(milliseconds: 100));
when(mockAboutRecipeRepository.addToFavorite('test-recipe-slug')).thenAnswer((_) async => Future.value());
recipesCubit!.addRecipeToFavorite('test-recipe-slug', 0);
await Future.delayed(const Duration(milliseconds: 300));
expect(recipesCubit!.state.recipesList[0].isFavorite, true);
});
test('removeRecipeFromFavorite - удаляет рецепт из избранного', () async {
recipesCubit = RecipesCubit(feedRepository: mockFeedRepository, recipeRepository: mockRecipeRepository, aboutRecipeRepository: mockAboutRecipeRepository);
when(mockFeedRepository.getRecipes(query: null, tags: [])).thenAnswer((_) async => [testRecipe.copyWith(isFavorite: true)]);
when(mockRecipeRepository.getRecipesTags()).thenAnswer((_) async => testRecipeTags);
await recipesCubit!.loadRecipesList();
await Future.delayed(const Duration(milliseconds: 100));
when(mockAboutRecipeRepository.removeFromFavorite('test-recipe-slug')).thenAnswer((_) async => Future.value());
recipesCubit!.removeRecipeFromFavorite('test-recipe-slug', 0);
await Future.delayed(const Duration(milliseconds: 300));
expect(recipesCubit!.state.recipesList[0].isFavorite, false);
});
test('deleteRecipe - удаляет рецепт', () async {
recipesCubit = RecipesCubit(feedRepository: mockFeedRepository, recipeRepository: mockRecipeRepository, aboutRecipeRepository: mockAboutRecipeRepository);
when(mockAboutRecipeRepository.deleteRecipe('test-recipe-slug')).thenAnswer((_) async => Future.value());
final result = await recipesCubit!.deleteRecipe('test-recipe-slug');
expect(result, true);
verify(mockAboutRecipeRepository.deleteRecipe('test-recipe-slug')).called(1);
});
});
}