feat(tests): updated tests coverage to 66.5%

This commit is contained in:
misha
2026-01-14 18:47:11 +03:00
parent 497ff19cfa
commit 13ccf56df0
102 changed files with 10146 additions and 379 deletions

View File

@@ -0,0 +1,513 @@
import 'package:eatvio_app/features/chat/repositories/chat_repository.dart';
import 'package:eatvio_app/features/consultant/become_consultant/repositories/consultant_repository.dart';
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/profile/models/profile_model.dart';
import 'package:eatvio_app/features/profile/presentation/bloc/profile_cubit/profile_cubit.dart';
import 'package:eatvio_app/features/profile/presentation/bloc/profile_cubit/profile_state.dart';
import 'package:eatvio_app/features/profile/repositories/profile_repository.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:mockito/annotations.dart';
import 'package:mockito/mockito.dart';
import 'profile_cubit_test.mocks.dart';
@GenerateNiceMocks([
MockSpec<ProfileRepository>(),
MockSpec<ChatRepository>(),
MockSpec<ConsultantRepository>(),
])
void main() {
group('ProfileCubit', () {
ProfileCubit? profileCubit;
late MockProfileRepository mockProfileRepository;
late MockChatRepository mockChatRepository;
late MockConsultantRepository mockConsultantRepository;
setUp(() {
mockProfileRepository = MockProfileRepository();
mockChatRepository = MockChatRepository();
mockConsultantRepository = MockConsultantRepository();
});
tearDown(() async {
if (profileCubit != null && !profileCubit!.isClosed) {
await Future.delayed(const Duration(milliseconds: 100));
await profileCubit!.close();
profileCubit = null;
}
});
test('начальное состояние - loading', () {
profileCubit = ProfileCubit(
profileRepository: mockProfileRepository,
chatRepository: mockChatRepository,
consultantRepository: mockConsultantRepository,
);
expect(profileCubit!.state, isA<ProfileStateLoading>());
});
test('getProfileBySlug - успешная загрузка профиля', () async {
profileCubit = ProfileCubit(
profileRepository: mockProfileRepository,
chatRepository: mockChatRepository,
consultantRepository: mockConsultantRepository,
);
const testProfile = ProfileModel(
id: 1,
slug: 'test-user',
name: 'Test User',
email: 'test@example.com',
phoneConfirmationState: 'confirmed',
isPublicProfile: true,
isBlockedByMe: false,
isBlockedByAuthor: false,
isBlockedByUser: false,
isEntitySubscribedByMe: false,
profilePhotoUrl: 'https://example.com/icon.jpg',
roles: [],
badges: [],
subscriptions: [],
subscribers: [],
);
const myProfile = ProfileModel(
id: 2,
slug: 'my-user',
name: 'My User',
email: 'my@example.com',
phoneConfirmationState: 'confirmed',
isPublicProfile: true,
isBlockedByMe: false,
isBlockedByAuthor: false,
isBlockedByUser: false,
isEntitySubscribedByMe: false,
profilePhotoUrl: 'https://example.com/icon2.jpg',
roles: [],
badges: [],
subscriptions: [],
subscribers: [],
);
const profileDetails = ProfileDetailsModel(
firstName: 'Test',
lastName: 'User',
birthdate: '1990-01-01',
gender: 'male',
country: 'Russia',
city: 'Moscow',
lang: 'ru',
weight: 70.0,
height: 175,
chestCircumference: 100,
waistCircumference: 80,
hipCircumference: 90,
bloodPressureUp: 120,
bloodPressureDown: 80,
hasHypo: false,
hasHyper: false,
aboutAlergy: '',
aboutTakingPils: '',
aboutSportHobbies: '',
favoriteFoods: '',
unfavoriteFoods: '',
additionalInfo: '',
isMoodFillable: true,
isBedtimeFillable: true,
activityCoefficient: 1.2,
);
when(mockProfileRepository.getProfileBySlug('test-user')).thenAnswer((_) async => testProfile);
when(mockProfileRepository.getMyProfile()).thenAnswer((_) async => myProfile);
when(mockProfileRepository.getProfileDetailsBySlug('test-user')).thenAnswer((_) async => profileDetails);
when(mockProfileRepository.getBlogPostsByAuthorSlug(slug: 'test-user')).thenAnswer((_) async => []);
await profileCubit!.getProfileBySlug('test-user');
final state = profileCubit!.state;
expect(state, isA<ProfileStateLoaded>());
if (state is ProfileStateLoaded) {
expect(state.profile.id, 1);
expect(state.isMyProfile, false);
}
});
test('getProfileBySlug - обработка ошибки', () async {
profileCubit = ProfileCubit(
profileRepository: mockProfileRepository,
chatRepository: mockChatRepository,
consultantRepository: mockConsultantRepository,
);
when(mockProfileRepository.getProfileBySlug('test-user')).thenThrow(Exception('Ошибка загрузки'));
expect(() => profileCubit!.getProfileBySlug('test-user'), throwsException);
final state = profileCubit!.state;
expect(state, isA<ProfileStateError>());
});
test('getMyProfile - успешная загрузка моего профиля', () async {
profileCubit = ProfileCubit(
profileRepository: mockProfileRepository,
chatRepository: mockChatRepository,
consultantRepository: mockConsultantRepository,
);
const testProfile = ProfileModel(
id: 1,
slug: 'test-user',
name: 'Test User',
email: 'test@example.com',
phoneConfirmationState: 'confirmed',
isPublicProfile: true,
isBlockedByMe: false,
isBlockedByAuthor: false,
isBlockedByUser: false,
isEntitySubscribedByMe: false,
profilePhotoUrl: 'https://example.com/icon.jpg',
roles: [],
badges: [],
subscriptions: [],
subscribers: [],
);
const profileDetails = ProfileDetailsModel(
firstName: 'Test',
lastName: 'User',
birthdate: '1990-01-01',
gender: 'male',
country: 'Russia',
city: 'Moscow',
lang: 'ru',
weight: 70.0,
height: 175,
chestCircumference: 100,
waistCircumference: 80,
hipCircumference: 90,
bloodPressureUp: 120,
bloodPressureDown: 80,
hasHypo: false,
hasHyper: false,
aboutAlergy: '',
aboutTakingPils: '',
aboutSportHobbies: '',
favoriteFoods: '',
unfavoriteFoods: '',
additionalInfo: '',
isMoodFillable: true,
isBedtimeFillable: true,
activityCoefficient: 1.2,
);
when(mockProfileRepository.getMyProfile()).thenAnswer((_) async => testProfile);
when(mockProfileRepository.getMyProfileDetails()).thenAnswer((_) async => profileDetails);
when(mockProfileRepository.getBlogPostsByAuthorSlug(slug: 'test-user')).thenAnswer((_) async => []);
when(mockProfileRepository.getWeight(period: '1')).thenAnswer((_) async => []);
when(mockProfileRepository.getCircumferences(period: '1')).thenAnswer((_) async => []);
await profileCubit!.getMyProfile();
final state = profileCubit!.state;
expect(state, isA<ProfileStateLoaded>());
if (state is ProfileStateLoaded) {
expect(state.profile.id, 1);
expect(state.isMyProfile, true);
}
});
test('getMyProfile - обработка ошибки', () async {
profileCubit = ProfileCubit(
profileRepository: mockProfileRepository,
chatRepository: mockChatRepository,
consultantRepository: mockConsultantRepository,
);
when(mockProfileRepository.getMyProfile()).thenThrow(Exception('Ошибка загрузки'));
await profileCubit!.getMyProfile();
final state = profileCubit!.state;
expect(state, isA<ProfileStateError>());
});
test('updateFeedBlogPostList - обновляет лайк в списке блогов', () {
profileCubit = ProfileCubit(
profileRepository: mockProfileRepository,
chatRepository: mockChatRepository,
consultantRepository: mockConsultantRepository,
);
const testProfile = ProfileModel(
id: 1,
slug: 'test-user',
name: 'Test User',
email: 'test@example.com',
phoneConfirmationState: 'confirmed',
isPublicProfile: true,
isBlockedByMe: false,
isBlockedByAuthor: false,
isBlockedByUser: false,
isEntitySubscribedByMe: false,
profilePhotoUrl: 'https://example.com/icon.jpg',
roles: [],
badges: [],
subscriptions: [],
subscribers: [],
);
const author = Author(
authorSlug: 'test-user',
authorName: 'Test User',
authorProfileIcon: 'https://example.com/icon.jpg',
authorIsMe: false,
isEntitySubscribedByMe: null,
authorPlaceInRating: null,
);
final blogPost = FeedBlogPostModel(
id: 1,
state: 'published',
title: 'Test Post',
description: 'Test Content',
image: 'https://example.com/image.jpg',
author: author,
videoUrl: '',
createdAt: DateTime.now(),
updatedAt: DateTime.now(),
totalLikes: 10,
totalComments: 5,
totalViews: 100,
wasLikedByMe: false,
);
const profileDetails = ProfileDetailsModel(
firstName: 'Test',
lastName: 'User',
birthdate: '1990-01-01',
gender: 'male',
country: 'Russia',
city: 'Moscow',
lang: 'ru',
weight: 70.0,
height: 175,
chestCircumference: 100,
waistCircumference: 80,
hipCircumference: 90,
bloodPressureUp: 120,
bloodPressureDown: 80,
hasHypo: false,
hasHyper: false,
aboutAlergy: '',
aboutTakingPils: '',
aboutSportHobbies: '',
favoriteFoods: '',
unfavoriteFoods: '',
additionalInfo: '',
isMoodFillable: true,
isBedtimeFillable: true,
activityCoefficient: 1.2,
);
profileCubit!.emit(ProfileState.loaded(
profile: testProfile,
isMyProfile: true,
profileDetails: profileDetails,
blogPosts: [blogPost],
));
profileCubit!.updateFeedBlogPostList(blogPost, true);
final state = profileCubit!.state;
expect(state, isA<ProfileStateLoaded>());
if (state is ProfileStateLoaded) {
expect(state.blogPosts.length, 1);
expect(state.blogPosts.first.wasLikedByMe, true);
expect(state.blogPosts.first.totalLikes, 11);
}
});
test('addCircumference - успешно добавляет обхваты', () async {
profileCubit = ProfileCubit(
profileRepository: mockProfileRepository,
chatRepository: mockChatRepository,
consultantRepository: mockConsultantRepository,
);
const testProfile = ProfileModel(
id: 1,
slug: 'test-user',
name: 'Test User',
email: 'test@example.com',
phoneConfirmationState: 'confirmed',
isPublicProfile: true,
isBlockedByMe: false,
isBlockedByAuthor: false,
isBlockedByUser: false,
isEntitySubscribedByMe: false,
profilePhotoUrl: 'https://example.com/icon.jpg',
roles: [],
badges: [],
subscriptions: [],
subscribers: [],
);
when(mockProfileRepository.addCircumference(
chestCircumference: 100,
waistCircumference: 80,
hipCircumference: 90,
)).thenAnswer((_) async => {});
const profileDetails = ProfileDetailsModel(
firstName: 'Test',
lastName: 'User',
birthdate: '1990-01-01',
gender: 'male',
country: 'Russia',
city: 'Moscow',
lang: 'ru',
weight: 70.0,
height: 175,
chestCircumference: 100,
waistCircumference: 80,
hipCircumference: 90,
bloodPressureUp: 120,
bloodPressureDown: 80,
hasHypo: false,
hasHyper: false,
aboutAlergy: '',
aboutTakingPils: '',
aboutSportHobbies: '',
favoriteFoods: '',
unfavoriteFoods: '',
additionalInfo: '',
isMoodFillable: true,
isBedtimeFillable: true,
activityCoefficient: 1.2,
);
when(mockProfileRepository.getMyProfile()).thenAnswer((_) async => testProfile);
when(mockProfileRepository.getMyProfileDetails()).thenAnswer((_) async => profileDetails);
when(mockProfileRepository.getBlogPostsByAuthorSlug(slug: 'test-user')).thenAnswer((_) async => []);
when(mockProfileRepository.getWeight(period: '1')).thenAnswer((_) async => []);
when(mockProfileRepository.getCircumferences(period: '1')).thenAnswer((_) async => []);
await profileCubit!.addCircumference(
chestCircumference: 100,
waistCircumference: 80,
hipCircumference: 90,
);
verify(mockProfileRepository.addCircumference(
chestCircumference: 100,
waistCircumference: 80,
hipCircumference: 90,
)).called(1);
});
test('addCircumference - обработка ошибки', () async {
profileCubit = ProfileCubit(
profileRepository: mockProfileRepository,
chatRepository: mockChatRepository,
consultantRepository: mockConsultantRepository,
);
when(mockProfileRepository.addCircumference(
chestCircumference: 100,
waistCircumference: 80,
hipCircumference: 90,
)).thenThrow(Exception('Ошибка добавления'));
await profileCubit!.addCircumference(
chestCircumference: 100,
waistCircumference: 80,
hipCircumference: 90,
);
final state = profileCubit!.state;
expect(state, isA<ProfileStateError>());
});
test('addWeight - успешно добавляет вес', () async {
profileCubit = ProfileCubit(
profileRepository: mockProfileRepository,
chatRepository: mockChatRepository,
consultantRepository: mockConsultantRepository,
);
const testProfile = ProfileModel(
id: 1,
slug: 'test-user',
name: 'Test User',
email: 'test@example.com',
phoneConfirmationState: 'confirmed',
isPublicProfile: true,
isBlockedByMe: false,
isBlockedByAuthor: false,
isBlockedByUser: false,
isEntitySubscribedByMe: false,
profilePhotoUrl: 'https://example.com/icon.jpg',
roles: [],
badges: [],
subscriptions: [],
subscribers: [],
);
when(mockProfileRepository.addWeight(weight: 70.5)).thenAnswer((_) async => {});
const profileDetails = ProfileDetailsModel(
firstName: 'Test',
lastName: 'User',
birthdate: '1990-01-01',
gender: 'male',
country: 'Russia',
city: 'Moscow',
lang: 'ru',
weight: 70.0,
height: 175,
chestCircumference: 100,
waistCircumference: 80,
hipCircumference: 90,
bloodPressureUp: 120,
bloodPressureDown: 80,
hasHypo: false,
hasHyper: false,
aboutAlergy: '',
aboutTakingPils: '',
aboutSportHobbies: '',
favoriteFoods: '',
unfavoriteFoods: '',
additionalInfo: '',
isMoodFillable: true,
isBedtimeFillable: true,
activityCoefficient: 1.2,
);
when(mockProfileRepository.getMyProfile()).thenAnswer((_) async => testProfile);
when(mockProfileRepository.getMyProfileDetails()).thenAnswer((_) async => profileDetails);
when(mockProfileRepository.getBlogPostsByAuthorSlug(slug: 'test-user')).thenAnswer((_) async => []);
when(mockProfileRepository.getWeight(period: '1')).thenAnswer((_) async => []);
when(mockProfileRepository.getCircumferences(period: '1')).thenAnswer((_) async => []);
await profileCubit!.addWeight(weight: 70.5);
verify(mockProfileRepository.addWeight(weight: 70.5)).called(1);
});
test('addWeight - обработка ошибки', () async {
profileCubit = ProfileCubit(
profileRepository: mockProfileRepository,
chatRepository: mockChatRepository,
consultantRepository: mockConsultantRepository,
);
when(mockProfileRepository.addWeight(weight: 70.5)).thenThrow(Exception('Ошибка добавления'));
await profileCubit!.addWeight(weight: 70.5);
final state = profileCubit!.state;
expect(state, isA<ProfileStateError>());
});
});
}