feat(tests): test coverage is 69.2

This commit is contained in:
misha
2026-01-21 09:19:41 +03:00
parent 775d4fb80f
commit f6809a06b3
16 changed files with 5274 additions and 333 deletions

View File

@@ -14,6 +14,8 @@ import 'about_plan_cubit_test.mocks.dart';
@GenerateNiceMocks([MockSpec<PlanRepository>()])
void main() {
TestWidgetsFlutterBinding.ensureInitialized();
group('AboutPlanCubit', () {
AboutPlanCubit? aboutPlanCubit;
late MockPlanRepository mockPlanRepository;
@@ -411,5 +413,569 @@ void main() {
expect(result.$1, isNull);
expect(result.$2, 'hasPlan');
});
test('likePlan - лайк плана с index', () async {
aboutPlanCubit = AboutPlanCubit(planRepository: mockPlanRepository);
const testPlan = PlanModel(
id: 1,
slug: 'test-plan',
name: 'Test Plan',
image: 'https://example.com/image.jpg',
duration: 7,
state: 'active',
type: PlanType(fit: true, slim: false, behavior: false, wellness: false),
details: 'Test description',
packetsCount: 3,
minPriceOfOptions: 1000.0,
maxPriceOfOptions: 2000.0,
author: Author(
authorSlug: 'author',
authorName: 'Author Name',
authorProfileIcon: 'https://example.com/icon.jpg',
authorIsMe: false,
isEntitySubscribedByMe: null,
authorPlaceInRating: null,
),
totalLikes: 10,
totalViews: 100,
totalComments: 5,
wasLikedByMe: false,
isFavorite: false,
);
when(mockPlanRepository.getPlan('test-plan')).thenAnswer((_) async => testPlan);
when(mockPlanRepository.likePlan('test-plan')).thenAnswer((_) async => {});
await aboutPlanCubit!.getPlan('test-plan');
await aboutPlanCubit!.likePlan(index: 5, slug: 'test-plan');
expect(aboutPlanCubit!.state.planModel!.wasLikedByMe, isTrue);
expect(aboutPlanCubit!.state.planModel!.totalLikes, 11);
await Future.delayed(const Duration(milliseconds: 1200));
verify(mockPlanRepository.emitLikesStateToFeed(any)).called(1);
});
test('likePlan - убирает лайк с index', () async {
aboutPlanCubit = AboutPlanCubit(planRepository: mockPlanRepository);
const testPlan = PlanModel(
id: 1,
slug: 'test-plan',
name: 'Test Plan',
image: 'https://example.com/image.jpg',
duration: 7,
state: 'active',
type: PlanType(fit: true, slim: false, behavior: false, wellness: false),
details: 'Test description',
packetsCount: 3,
minPriceOfOptions: 1000.0,
maxPriceOfOptions: 2000.0,
author: Author(
authorSlug: 'author',
authorName: 'Author Name',
authorProfileIcon: 'https://example.com/icon.jpg',
authorIsMe: false,
isEntitySubscribedByMe: null,
authorPlaceInRating: null,
),
totalLikes: 10,
totalViews: 100,
totalComments: 5,
wasLikedByMe: true,
isFavorite: false,
);
when(mockPlanRepository.getPlan('test-plan')).thenAnswer((_) async => testPlan);
when(mockPlanRepository.likePlan('test-plan')).thenAnswer((_) async => {});
await aboutPlanCubit!.getPlan('test-plan');
await aboutPlanCubit!.likePlan(index: 5, slug: 'test-plan');
expect(aboutPlanCubit!.state.planModel!.wasLikedByMe, isFalse);
expect(aboutPlanCubit!.state.planModel!.totalLikes, 9);
await Future.delayed(const Duration(milliseconds: 1200));
verify(mockPlanRepository.emitLikesStateToFeed(any)).called(1);
});
test('likePlan - обрабатывает ошибку', () async {
aboutPlanCubit = AboutPlanCubit(planRepository: mockPlanRepository);
const testPlan = PlanModel(
id: 1,
slug: 'test-plan',
name: 'Test Plan',
image: 'https://example.com/image.jpg',
duration: 7,
state: 'active',
type: PlanType(fit: true, slim: false, behavior: false, wellness: false),
details: 'Test description',
packetsCount: 3,
minPriceOfOptions: 1000.0,
maxPriceOfOptions: 2000.0,
author: Author(
authorSlug: 'author',
authorName: 'Author Name',
authorProfileIcon: 'https://example.com/icon.jpg',
authorIsMe: false,
isEntitySubscribedByMe: null,
authorPlaceInRating: null,
),
totalLikes: 10,
totalViews: 100,
totalComments: 5,
wasLikedByMe: false,
isFavorite: false,
);
when(mockPlanRepository.getPlan('test-plan')).thenAnswer((_) async => testPlan);
when(mockPlanRepository.likePlan('test-plan')).thenThrow(Exception('Ошибка'));
await aboutPlanCubit!.getPlan('test-plan');
await aboutPlanCubit!.likePlan(index: 5, slug: 'test-plan');
// Проверяем, что состояние изменилось сразу после вызова
expect(aboutPlanCubit!.state.planModel!.wasLikedByMe, isTrue);
expect(aboutPlanCubit!.state.planModel!.totalLikes, 11);
});
test('likePlan - не делает ничего если план не загружен', () async {
aboutPlanCubit = AboutPlanCubit(planRepository: mockPlanRepository);
await aboutPlanCubit!.likePlan(index: null, slug: 'test-plan');
expect(aboutPlanCubit!.state.planModel, isNull);
verifyNever(mockPlanRepository.likePlan(any));
});
test('addToFavorite - добавляет план в избранное с index', () async {
aboutPlanCubit = AboutPlanCubit(planRepository: mockPlanRepository);
const testPlan = PlanModel(
id: 1,
slug: 'test-plan',
name: 'Test Plan',
image: 'https://example.com/image.jpg',
duration: 7,
state: 'active',
type: PlanType(fit: true, slim: false, behavior: false, wellness: false),
details: 'Test description',
packetsCount: 3,
minPriceOfOptions: 1000.0,
maxPriceOfOptions: 2000.0,
author: Author(
authorSlug: 'author',
authorName: 'Author Name',
authorProfileIcon: 'https://example.com/icon.jpg',
authorIsMe: false,
isEntitySubscribedByMe: null,
authorPlaceInRating: null,
),
totalLikes: 10,
totalViews: 100,
totalComments: 5,
wasLikedByMe: false,
isFavorite: false,
);
when(mockPlanRepository.getPlan('test-plan')).thenAnswer((_) async => testPlan);
when(mockPlanRepository.addToFavorite('test-plan')).thenAnswer((_) async => Future<void>.value());
await aboutPlanCubit!.getPlan('test-plan');
await aboutPlanCubit!.addToFavorite(slug: 'test-plan', index: 5);
expect(aboutPlanCubit!.state.planModel!.isFavorite, true);
// Проверяем, что emitFavoriteStateToFeed был вызван сразу после изменения состояния
verify(mockPlanRepository.emitFavoriteStateToFeed(any)).called(1);
});
test('addToFavorite - обрабатывает ошибку', () async {
aboutPlanCubit = AboutPlanCubit(planRepository: mockPlanRepository);
const testPlan = PlanModel(
id: 1,
slug: 'test-plan',
name: 'Test Plan',
image: 'https://example.com/image.jpg',
duration: 7,
state: 'active',
type: PlanType(fit: true, slim: false, behavior: false, wellness: false),
details: 'Test description',
packetsCount: 3,
minPriceOfOptions: 1000.0,
maxPriceOfOptions: 2000.0,
author: Author(
authorSlug: 'author',
authorName: 'Author Name',
authorProfileIcon: 'https://example.com/icon.jpg',
authorIsMe: false,
isEntitySubscribedByMe: null,
authorPlaceInRating: null,
),
totalLikes: 10,
totalViews: 100,
totalComments: 5,
wasLikedByMe: false,
isFavorite: false,
);
when(mockPlanRepository.getPlan('test-plan')).thenAnswer((_) async => testPlan);
when(mockPlanRepository.addToFavorite('test-plan')).thenThrow(Exception('Ошибка'));
await aboutPlanCubit!.getPlan('test-plan');
await aboutPlanCubit!.addToFavorite(slug: 'test-plan', index: 5);
// Проверяем, что состояние изменилось сразу после вызова
expect(aboutPlanCubit!.state.planModel!.isFavorite, true);
});
test('addToFavorite - не делает ничего если план не загружен', () async {
aboutPlanCubit = AboutPlanCubit(planRepository: mockPlanRepository);
await aboutPlanCubit!.addToFavorite(slug: 'test-plan', index: null);
expect(aboutPlanCubit!.state.planModel, isNull);
verifyNever(mockPlanRepository.addToFavorite(any));
});
test('removeFromFavorite - удаляет план из избранного с index', () async {
aboutPlanCubit = AboutPlanCubit(planRepository: mockPlanRepository);
const testPlan = PlanModel(
id: 1,
slug: 'test-plan',
name: 'Test Plan',
image: 'https://example.com/image.jpg',
duration: 7,
state: 'active',
type: PlanType(fit: true, slim: false, behavior: false, wellness: false),
details: 'Test description',
packetsCount: 3,
minPriceOfOptions: 1000.0,
maxPriceOfOptions: 2000.0,
author: Author(
authorSlug: 'author',
authorName: 'Author Name',
authorProfileIcon: 'https://example.com/icon.jpg',
authorIsMe: false,
isEntitySubscribedByMe: null,
authorPlaceInRating: null,
),
totalLikes: 10,
totalViews: 100,
totalComments: 5,
wasLikedByMe: false,
isFavorite: true,
);
when(mockPlanRepository.getPlan('test-plan')).thenAnswer((_) async => testPlan);
when(mockPlanRepository.removeFromFavorite('test-plan')).thenAnswer((_) async => Future<void>.value());
await aboutPlanCubit!.getPlan('test-plan');
await aboutPlanCubit!.removeFromFavorite(slug: 'test-plan', index: 5);
expect(aboutPlanCubit!.state.planModel!.isFavorite, false);
// Проверяем, что emitFavoriteStateToFeed был вызван сразу после изменения состояния
verify(mockPlanRepository.emitFavoriteStateToFeed(any)).called(1);
});
test('removeFromFavorite - обрабатывает ошибку', () async {
aboutPlanCubit = AboutPlanCubit(planRepository: mockPlanRepository);
const testPlan = PlanModel(
id: 1,
slug: 'test-plan',
name: 'Test Plan',
image: 'https://example.com/image.jpg',
duration: 7,
state: 'active',
type: PlanType(fit: true, slim: false, behavior: false, wellness: false),
details: 'Test description',
packetsCount: 3,
minPriceOfOptions: 1000.0,
maxPriceOfOptions: 2000.0,
author: Author(
authorSlug: 'author',
authorName: 'Author Name',
authorProfileIcon: 'https://example.com/icon.jpg',
authorIsMe: false,
isEntitySubscribedByMe: null,
authorPlaceInRating: null,
),
totalLikes: 10,
totalViews: 100,
totalComments: 5,
wasLikedByMe: false,
isFavorite: true,
);
when(mockPlanRepository.getPlan('test-plan')).thenAnswer((_) async => testPlan);
when(mockPlanRepository.removeFromFavorite('test-plan')).thenThrow(Exception('Ошибка'));
await aboutPlanCubit!.getPlan('test-plan');
await aboutPlanCubit!.removeFromFavorite(slug: 'test-plan', index: 5);
// Проверяем, что состояние изменилось сразу после вызова
expect(aboutPlanCubit!.state.planModel!.isFavorite, false);
});
test('removeFromFavorite - не делает ничего если план не загружен', () async {
aboutPlanCubit = AboutPlanCubit(planRepository: mockPlanRepository);
await aboutPlanCubit!.removeFromFavorite(slug: 'test-plan', index: null);
expect(aboutPlanCubit!.state.planModel, isNull);
verifyNever(mockPlanRepository.removeFromFavorite(any));
});
test('chosePlan - выбирает план с optionIndex 1', () async {
aboutPlanCubit = AboutPlanCubit(planRepository: mockPlanRepository);
const testPlan = PlanModel(
id: 1,
slug: 'test-plan',
name: 'Test Plan',
image: 'https://example.com/image.jpg',
duration: 7,
state: 'active',
type: PlanType(fit: true, slim: false, behavior: false, wellness: false),
details: 'Test description',
packetsCount: 3,
minPriceOfOptions: 1000.0,
maxPriceOfOptions: 2000.0,
author: Author(
authorSlug: 'author',
authorName: 'Author Name',
authorProfileIcon: 'https://example.com/icon.jpg',
authorIsMe: false,
isEntitySubscribedByMe: null,
authorPlaceInRating: null,
),
totalLikes: 10,
totalViews: 100,
totalComments: 5,
wasLikedByMe: false,
isFavorite: false,
);
final chosenPlan = ChosenPlanModel(
id: 1,
optionType: 'options2',
startDate: DateTime(2024, 1, 1),
chosenPlanState: ChosenPlanStateEnum.stateStarted,
chatId: 'chat-1',
consultantId: 1,
plan: testPlan,
);
when(mockPlanRepository.getPlan('test-plan')).thenAnswer((_) async => testPlan);
when(mockPlanRepository.chosePlan('test-plan', any)).thenAnswer((_) async => chosenPlan);
await aboutPlanCubit!.getPlan('test-plan');
aboutPlanCubit!.choseOption(1);
final result = await aboutPlanCubit!.chosePlan();
expect(result.$1, isNotNull);
expect(result.$2, isNull);
verify(mockPlanRepository.chosePlan('test-plan', argThat(predicate<Map<String, dynamic>>((map) => map['options_type'] == 'options2')))).called(1);
});
test('chosePlan - выбирает план с optionIndex 2', () async {
aboutPlanCubit = AboutPlanCubit(planRepository: mockPlanRepository);
const testPlan = PlanModel(
id: 1,
slug: 'test-plan',
name: 'Test Plan',
image: 'https://example.com/image.jpg',
duration: 7,
state: 'active',
type: PlanType(fit: true, slim: false, behavior: false, wellness: false),
details: 'Test description',
packetsCount: 3,
minPriceOfOptions: 1000.0,
maxPriceOfOptions: 2000.0,
author: Author(
authorSlug: 'author',
authorName: 'Author Name',
authorProfileIcon: 'https://example.com/icon.jpg',
authorIsMe: false,
isEntitySubscribedByMe: null,
authorPlaceInRating: null,
),
totalLikes: 10,
totalViews: 100,
totalComments: 5,
wasLikedByMe: false,
isFavorite: false,
);
final chosenPlan = ChosenPlanModel(
id: 1,
optionType: 'options3',
startDate: DateTime(2024, 1, 1),
chosenPlanState: ChosenPlanStateEnum.stateStarted,
chatId: 'chat-1',
consultantId: 1,
plan: testPlan,
);
when(mockPlanRepository.getPlan('test-plan')).thenAnswer((_) async => testPlan);
when(mockPlanRepository.chosePlan('test-plan', any)).thenAnswer((_) async => chosenPlan);
await aboutPlanCubit!.getPlan('test-plan');
aboutPlanCubit!.choseOption(2);
final result = await aboutPlanCubit!.chosePlan();
expect(result.$1, isNotNull);
expect(result.$2, isNull);
verify(mockPlanRepository.chosePlan('test-plan', argThat(predicate<Map<String, dynamic>>((map) => map['options_type'] == 'options3')))).called(1);
});
test('chosePlan - возвращает пустой результат когда slug == null', () async {
aboutPlanCubit = AboutPlanCubit(planRepository: mockPlanRepository);
final result = await aboutPlanCubit!.chosePlan();
expect(result.$1, isNull);
expect(result.$2, '');
verifyNever(mockPlanRepository.chosePlan(any, any));
});
test('chosePlan - обрабатывает DioException с другим статусом', () async {
aboutPlanCubit = AboutPlanCubit(planRepository: mockPlanRepository);
const testPlan = PlanModel(
id: 1,
slug: 'test-plan',
name: 'Test Plan',
image: 'https://example.com/image.jpg',
duration: 7,
state: 'active',
type: PlanType(fit: true, slim: false, behavior: false, wellness: false),
details: 'Test description',
packetsCount: 3,
minPriceOfOptions: 1000.0,
maxPriceOfOptions: 2000.0,
author: Author(
authorSlug: 'author',
authorName: 'Author Name',
authorProfileIcon: 'https://example.com/icon.jpg',
authorIsMe: false,
isEntitySubscribedByMe: null,
authorPlaceInRating: null,
),
totalLikes: 10,
totalViews: 100,
totalComments: 5,
wasLikedByMe: false,
isFavorite: false,
);
when(mockPlanRepository.getPlan('test-plan')).thenAnswer((_) async => testPlan);
when(mockPlanRepository.chosePlan('test-plan', any)).thenThrow(
DioException(
requestOptions: RequestOptions(path: '/api/plans/chose'),
response: Response(statusCode: 500, requestOptions: RequestOptions(path: '/api/plans/chose')),
),
);
await aboutPlanCubit!.getPlan('test-plan');
aboutPlanCubit!.choseOption(0);
final result = await aboutPlanCubit!.chosePlan();
expect(result.$1, isNull);
expect(result.$2, '');
});
test('chosePlan - обрабатывает общее исключение', () async {
aboutPlanCubit = AboutPlanCubit(planRepository: mockPlanRepository);
const testPlan = PlanModel(
id: 1,
slug: 'test-plan',
name: 'Test Plan',
image: 'https://example.com/image.jpg',
duration: 7,
state: 'active',
type: PlanType(fit: true, slim: false, behavior: false, wellness: false),
details: 'Test description',
packetsCount: 3,
minPriceOfOptions: 1000.0,
maxPriceOfOptions: 2000.0,
author: Author(
authorSlug: 'author',
authorName: 'Author Name',
authorProfileIcon: 'https://example.com/icon.jpg',
authorIsMe: false,
isEntitySubscribedByMe: null,
authorPlaceInRating: null,
),
totalLikes: 10,
totalViews: 100,
totalComments: 5,
wasLikedByMe: false,
isFavorite: false,
);
when(mockPlanRepository.getPlan('test-plan')).thenAnswer((_) async => testPlan);
when(mockPlanRepository.chosePlan('test-plan', any)).thenThrow(Exception('Общая ошибка'));
await aboutPlanCubit!.getPlan('test-plan');
aboutPlanCubit!.choseOption(0);
final result = await aboutPlanCubit!.chosePlan();
expect(result.$1, isNull);
expect(result.$2, '');
});
test('getPlanWithLoading - устанавливает isLoading в true перед загрузкой', () async {
aboutPlanCubit = AboutPlanCubit(planRepository: mockPlanRepository);
const testPlan = PlanModel(
id: 1,
slug: 'test-plan',
name: 'Test Plan',
image: 'https://example.com/image.jpg',
duration: 7,
state: 'active',
type: PlanType(fit: true, slim: false, behavior: false, wellness: false),
details: 'Test description',
packetsCount: 3,
minPriceOfOptions: 1000.0,
maxPriceOfOptions: 2000.0,
author: Author(
authorSlug: 'author',
authorName: 'Author Name',
authorProfileIcon: 'https://example.com/icon.jpg',
authorIsMe: false,
isEntitySubscribedByMe: null,
authorPlaceInRating: null,
),
totalLikes: 10,
totalViews: 100,
totalComments: 5,
wasLikedByMe: false,
isFavorite: false,
);
when(mockPlanRepository.getPlan('test-plan')).thenAnswer((_) async {
await Future.delayed(const Duration(milliseconds: 50));
return testPlan;
});
final future = aboutPlanCubit!.getPlanWithLoading('test-plan');
// Проверяем, что isLoading установлен в true сразу после вызова
expect(aboutPlanCubit!.state.isLoading, isTrue);
await future;
expect(aboutPlanCubit!.state.isLoading, isFalse);
});
});
}