chore(version): update app version to 1.3.5+85 and improve test coverage reporting in CI

This commit is contained in:
mso7nueh
2025-12-08 11:19:08 +03:00
parent abe4985f0e
commit c2a506cdbf
148 changed files with 12395 additions and 1889 deletions

View File

@@ -4,158 +4,169 @@ import 'package:eatvio_app/features/feed/models/diets_pagination_model.dart';
import 'package:eatvio_app/features/feed/models/feed_blog_post_model.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 'package:mocktail/mocktail.dart';
import 'blog_post_cubit_test.mocks.dart';
class MockFeedRepository extends Mock implements FeedRepository {}
@GenerateNiceMocks([MockSpec<FeedRepository>()])
void main() {
group('BlogPostCubit', () {
BlogPostCubit? blogPostCubit;
late MockFeedRepository mockFeedRepository;
late BlogPostCubit cubit;
late MockFeedRepository mockRepository;
setUp(() {
mockFeedRepository = MockFeedRepository();
mockRepository = MockFeedRepository();
cubit = BlogPostCubit(mockRepository);
});
tearDown(() async {
if (blogPostCubit != null && !blogPostCubit!.isClosed) {
await blogPostCubit!.close();
blogPostCubit = null;
}
tearDown(() {
cubit.close();
});
test('начальное состояние - пустое', () {
blogPostCubit = BlogPostCubit(mockFeedRepository);
expect(blogPostCubit!.state, isA<BlogPostState>());
expect(blogPostCubit!.state.isLoading, isFalse);
expect(blogPostCubit!.state.blogPostModel, isNull);
test('начальное состояние - BlogPostState с isLoading: false', () {
expect(cubit.state, isA<BlogPostState>());
expect(cubit.state.isLoading, false);
});
test('getBlogPost - успешная загрузка поста', () async {
blogPostCubit = BlogPostCubit(mockFeedRepository);
final testPost = FeedBlogPostModel(
id: 1,
state: 'published',
image: 'https://example.com/image.jpg',
description: 'Test description',
author: const Author(
authorSlug: 'author',
authorName: 'Author Name',
authorProfileIcon: 'https://example.com/icon.jpg',
authorIsMe: false,
isEntitySubscribedByMe: null,
authorPlaceInRating: null,
),
const postId = 1;
final mockPost = FeedBlogPostModel(
id: postId,
title: 'Test Post',
state: 'active',
image: '',
description: 'Test Content',
videoUrl: '',
createdAt: DateTime.now(),
updatedAt: DateTime.now(),
title: 'Test Post',
totalLikes: 10,
totalViews: 100,
totalComments: 5,
totalLikes: 0,
totalViews: 0,
totalComments: 0,
wasLikedByMe: false,
author: const Author(authorName: 'Test Author', authorSlug: 'test-author', authorProfileIcon: '', authorIsMe: false),
);
when(mockFeedRepository.getBlogPost(id: 1))
.thenAnswer((_) async => testPost);
when(() => mockRepository.getBlogPost(id: postId)).thenAnswer((_) async => mockPost);
await blogPostCubit!.getBlogPost(1);
await cubit.getBlogPost(postId);
expect(blogPostCubit!.state.blogPostModel, isNotNull);
expect(blogPostCubit!.state.blogPostModel!.id, 1);
expect(blogPostCubit!.state.isLoading, isFalse);
expect(cubit.state.isLoading, false);
expect(cubit.state.blogPostModel, mockPost);
verify(() => mockRepository.getBlogPost(id: postId)).called(1);
});
test('getBlogPost - обработка ошибки', () async {
blogPostCubit = BlogPostCubit(mockFeedRepository);
const postId = 1;
when(mockFeedRepository.getBlogPost(id: anyNamed('id')))
.thenThrow(Exception('Ошибка загрузки'));
when(() => mockRepository.getBlogPost(id: postId)).thenThrow(Exception('Error'));
await blogPostCubit!.getBlogPost(1);
await cubit.getBlogPost(postId);
expect(blogPostCubit!.state.isLoading, isFalse);
expect(cubit.state.isLoading, false);
expect(cubit.state.blogPostModel, null);
});
test('toggleLike - лайк поста', () async {
blogPostCubit = BlogPostCubit(mockFeedRepository);
final testPost = FeedBlogPostModel(
id: 1,
state: 'published',
image: 'https://example.com/image.jpg',
description: 'Test description',
author: const Author(
authorSlug: 'author',
authorName: 'Author Name',
authorProfileIcon: 'https://example.com/icon.jpg',
authorIsMe: false,
isEntitySubscribedByMe: null,
authorPlaceInRating: null,
),
const postId = 1;
final mockPost = FeedBlogPostModel(
id: postId,
title: 'Test Post',
state: 'active',
image: '',
description: 'Test Content',
videoUrl: '',
createdAt: DateTime.now(),
updatedAt: DateTime.now(),
title: 'Test Post',
totalLikes: 10,
totalViews: 100,
totalComments: 5,
totalLikes: 5,
totalViews: 0,
totalComments: 0,
wasLikedByMe: false,
author: const Author(authorName: 'Test Author', authorSlug: 'test-author', authorProfileIcon: '', authorIsMe: false),
);
when(mockFeedRepository.getBlogPost(id: 1))
.thenAnswer((_) async => testPost);
when(mockFeedRepository.likeBlogPost(id: 1))
.thenAnswer((_) async => {});
when(() => mockRepository.likeBlogPost(id: postId)).thenAnswer((_) async => {});
await blogPostCubit!.getBlogPost(1);
await blogPostCubit!.toggleLike();
// Сначала загружаем пост
when(() => mockRepository.getBlogPost(id: postId)).thenAnswer((_) async => mockPost);
await cubit.getBlogPost(postId);
expect(blogPostCubit!.state.blogPostModel!.wasLikedByMe, isTrue);
expect(blogPostCubit!.state.blogPostModel!.totalLikes, 11);
// Затем лайкаем
await cubit.toggleLike();
expect(cubit.state.blogPostModel?.wasLikedByMe, true);
expect(cubit.state.blogPostModel?.totalLikes, 6);
verify(() => mockRepository.likeBlogPost(id: postId)).called(1);
});
test('toggleLike - убирает лайк', () async {
blogPostCubit = BlogPostCubit(mockFeedRepository);
final testPost = FeedBlogPostModel(
id: 1,
state: 'published',
image: 'https://example.com/image.jpg',
description: 'Test description',
author: const Author(
authorSlug: 'author',
authorName: 'Author Name',
authorProfileIcon: 'https://example.com/icon.jpg',
authorIsMe: false,
isEntitySubscribedByMe: null,
authorPlaceInRating: null,
),
const postId = 1;
final mockPost = FeedBlogPostModel(
id: postId,
title: 'Test Post',
state: 'active',
image: '',
description: 'Test Content',
videoUrl: '',
createdAt: DateTime.now(),
updatedAt: DateTime.now(),
title: 'Test Post',
totalLikes: 10,
totalViews: 100,
totalComments: 5,
totalLikes: 5,
totalViews: 0,
totalComments: 0,
wasLikedByMe: true,
author: const Author(authorName: 'Test Author', authorSlug: 'test-author', authorProfileIcon: '', authorIsMe: false),
);
when(mockFeedRepository.getBlogPost(id: 1))
.thenAnswer((_) async => testPost);
when(mockFeedRepository.unlikedBlogPost(id: 1))
.thenAnswer((_) async => {});
when(() => mockRepository.unlikedBlogPost(id: postId)).thenAnswer((_) async => {});
await blogPostCubit!.getBlogPost(1);
await blogPostCubit!.toggleLike();
// Сначала загружаем пост
when(() => mockRepository.getBlogPost(id: postId)).thenAnswer((_) async => mockPost);
await cubit.getBlogPost(postId);
expect(blogPostCubit!.state.blogPostModel!.wasLikedByMe, isFalse);
expect(blogPostCubit!.state.blogPostModel!.totalLikes, 9);
// Затем убираем лайк
await cubit.toggleLike();
expect(cubit.state.blogPostModel?.wasLikedByMe, false);
expect(cubit.state.blogPostModel?.totalLikes, 4);
verify(() => mockRepository.unlikedBlogPost(id: postId)).called(1);
});
test('toggleLike - откат при ошибке', () async {
const postId = 1;
final mockPost = FeedBlogPostModel(
id: postId,
title: 'Test Post',
state: 'active',
image: '',
description: 'Test Content',
videoUrl: '',
createdAt: DateTime.now(),
updatedAt: DateTime.now(),
totalLikes: 5,
totalViews: 0,
totalComments: 0,
wasLikedByMe: false,
author: const Author(authorName: 'Test Author', authorSlug: 'test-author', authorProfileIcon: '', authorIsMe: false),
);
when(() => mockRepository.likeBlogPost(id: postId)).thenThrow(Exception('Error'));
// Сначала загружаем пост
when(() => mockRepository.getBlogPost(id: postId)).thenAnswer((_) async => mockPost);
await cubit.getBlogPost(postId);
// Затем пытаемся лайкнуть (с ошибкой)
await cubit.toggleLike();
// Должен откатиться к исходному состоянию
expect(cubit.state.blogPostModel?.wasLikedByMe, false);
expect(cubit.state.blogPostModel?.totalLikes, 5);
});
test('toggleLike - ничего не делает если пост не загружен', () async {
await cubit.toggleLike();
expect(cubit.state.blogPostModel, null);
verifyNever(() => mockRepository.likeBlogPost(id: any(named: 'id')));
verifyNever(() => mockRepository.unlikedBlogPost(id: any(named: 'id')));
});
});
}