Files
eatvio_app/test/features/diets/presentation/cubit/diets_cubit_test.dart

195 lines
7.9 KiB
Dart

import 'package:easy_debounce/easy_debounce.dart';
import 'package:eatvio_app/core/models/pagination_model.dart';
import 'package:eatvio_app/features/diets/models/diet_likes_model.dart';
import 'package:eatvio_app/features/diets/repositories/diet_repository.dart';
import 'package:eatvio_app/features/feed/models/diets_pagination_model.dart';
import 'package:eatvio_app/features/feed/presentation/bloc/diets_cubit/diets_cubit.dart';
import 'package:eatvio_app/features/feed/repositories/feed_repository.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:mockito/annotations.dart';
import 'package:mockito/mockito.dart';
import 'diets_cubit_test.mocks.dart';
@GenerateNiceMocks([MockSpec<FeedRepository>(), MockSpec<DietRepository>()])
void main() {
group('DietsCubit', () {
DietsCubit? dietsCubit;
late MockFeedRepository mockFeedRepository;
late MockDietRepository mockDietRepository;
const testDiet = Diet(
id: 1,
slug: 'test-diet',
name: 'Test Diet',
image: 'https://someurl.com/img.jpg',
duration: 30,
state: DietState.active,
type: DietType(light: false, veg: false, carb: false, meat: false),
details: 'Test diet description',
dailySchedule: {},
author: Author(authorSlug: '', authorName: '', authorProfileIcon: '', authorIsMe: false),
totalLikes: 1,
totalViews: 1,
totalComments: 1,
wasLikedByMe: false,
isFavorite: false,
dailyNutrition: [],
);
const testDietsPagination = DietsPagination(
data: [testDiet],
links: Links(first: '', last: '', prev: null, next: null),
meta: Meta(currentPage: 1, lastPage: 1, total: 1, perPage: 10, from: null, links: [Link(url: null, label: null, active: null)], to: null),
);
setUp(() {
mockFeedRepository = MockFeedRepository();
mockDietRepository = MockDietRepository();
});
tearDown(() async {
EasyDebounce.cancel('loadDiets');
EasyDebounce.cancel('like_diet');
EasyDebounce.cancel('add_or_remove_diet_from_favorite');
if (dietsCubit != null && !dietsCubit!.isClosed) {
await Future.delayed(const Duration(milliseconds: 100));
dietsCubit!.close();
dietsCubit = null;
}
});
test('начальное состояние - initial state', () {
dietsCubit = DietsCubit(feedRepository: mockFeedRepository, dietsRepository: mockDietRepository);
expect(dietsCubit!.state.dietsList, isEmpty);
expect(dietsCubit!.state.isLoading, true);
expect(dietsCubit!.state.errorMessage, null);
expect(dietsCubit!.state.filterState.durationIndex, 0);
expect(dietsCubit!.state.filterState.sortingIndex, 0);
expect(dietsCubit!.state.filterState.typeIndex, 0);
});
test('loadDiets - загружает диеты успешно', () async {
dietsCubit = DietsCubit(feedRepository: mockFeedRepository, dietsRepository: mockDietRepository);
when(mockFeedRepository.getDiets(query: null, types: null, duration: null, sorting: null)).thenAnswer((_) async => testDietsPagination);
await dietsCubit!.loadDiets();
await Future.delayed(const Duration(milliseconds: 100));
expect(dietsCubit!.state.dietsList.length, 1);
expect(dietsCubit!.state.dietsList.first.name, 'Test Diet');
expect(dietsCubit!.state.errorMessage, null);
});
test('loadDiets - обрабатывает ошибку', () async {
dietsCubit = DietsCubit(feedRepository: mockFeedRepository, dietsRepository: mockDietRepository);
when(mockFeedRepository.getDiets(query: null, types: null, duration: null, sorting: null)).thenThrow(Exception('Network error'));
await dietsCubit!.loadDiets();
await Future.delayed(const Duration(milliseconds: 100));
expect(dietsCubit!.state.errorMessage, isNotNull);
expect(dietsCubit!.state.isLoading, false);
});
test('changeTypeFilter - меняет фильтр типа', () async {
dietsCubit = DietsCubit(feedRepository: mockFeedRepository, dietsRepository: mockDietRepository);
dietsCubit!.changeTypeFilter(1);
await Future.delayed(const Duration(milliseconds: 100));
expect(dietsCubit!.state.filterState.typeIndex, 1);
// Wait for debounce to complete
await Future.delayed(const Duration(milliseconds: 1100));
});
test('changeDurationFilter - меняет фильтр длительности', () async {
dietsCubit = DietsCubit(feedRepository: mockFeedRepository, dietsRepository: mockDietRepository);
dietsCubit!.changeDurationFilter(1);
await Future.delayed(const Duration(milliseconds: 100));
expect(dietsCubit!.state.filterState.durationIndex, 1);
// Wait for debounce to complete
await Future.delayed(const Duration(milliseconds: 1100));
});
test('changeSortingType - меняет тип сортировки', () async {
dietsCubit = DietsCubit(feedRepository: mockFeedRepository, dietsRepository: mockDietRepository);
dietsCubit!.changeSortingType(1);
await Future.delayed(const Duration(milliseconds: 100));
expect(dietsCubit!.state.filterState.sortingIndex, 1);
// Wait for debounce to complete
await Future.delayed(const Duration(milliseconds: 1100));
});
test('likeDiet - лайкает диету', () async {
dietsCubit = DietsCubit(feedRepository: mockFeedRepository, dietsRepository: mockDietRepository);
when(mockFeedRepository.getDiets(query: null, types: null, duration: null, sorting: null)).thenAnswer((_) async => testDietsPagination);
await dietsCubit!.loadDiets();
await Future.delayed(const Duration(milliseconds: 100));
when(mockDietRepository.likeDiet(1)).thenAnswer((_) async => const DietLikesModel(totalLikes: 2, isLiked: true));
dietsCubit!.likeDiet(1, 0);
await Future.delayed(const Duration(milliseconds: 300));
expect(dietsCubit!.state.dietsList[0].wasLikedByMe, true);
expect(dietsCubit!.state.dietsList[0].totalLikes, 2);
});
test('addDietToFavorite - добавляет диету в избранное', () async {
dietsCubit = DietsCubit(feedRepository: mockFeedRepository, dietsRepository: mockDietRepository);
when(mockFeedRepository.getDiets(query: null, types: null, duration: null, sorting: null)).thenAnswer((_) async => testDietsPagination);
await dietsCubit!.loadDiets();
await Future.delayed(const Duration(milliseconds: 100));
when(mockDietRepository.addToFavorite(1)).thenAnswer((_) async => testDiet.copyWith(isFavorite: true));
dietsCubit!.addDietToFavorite(1, 0);
await Future.delayed(const Duration(milliseconds: 300));
expect(dietsCubit!.state.dietsList[0].isFavorite, true);
});
test('removeDietFromFavorite - удаляет диету из избранного', () async {
dietsCubit = DietsCubit(feedRepository: mockFeedRepository, dietsRepository: mockDietRepository);
when(
mockFeedRepository.getDiets(query: null, types: null, duration: null, sorting: null),
).thenAnswer((_) async => testDietsPagination.copyWith(data: [testDiet.copyWith(isFavorite: true)]));
await dietsCubit!.loadDiets();
await Future.delayed(const Duration(milliseconds: 100));
when(mockDietRepository.removeFromFavorite(1)).thenAnswer((_) async => testDiet.copyWith(isFavorite: false));
dietsCubit!.removeDietFromFavorite(1, 0);
await Future.delayed(const Duration(milliseconds: 300));
expect(dietsCubit!.state.dietsList[0].isFavorite, false);
});
test('deleteDiet - удаляет диету', () async {
dietsCubit = DietsCubit(feedRepository: mockFeedRepository, dietsRepository: mockDietRepository);
when(mockDietRepository.deleteDiet(1)).thenAnswer((_) async => Future.value());
final result = await dietsCubit!.deleteDiet(1);
expect(result, true);
verify(mockDietRepository.deleteDiet(1)).called(1);
});
});
}