feat(tests): increased tests coverage

This commit is contained in:
misha
2025-12-25 12:56:38 +03:00
parent 5b705dfb72
commit 99659f7ea1
132 changed files with 10304 additions and 6226 deletions

View File

@@ -0,0 +1,47 @@
import 'package:eatvio_app/core/theme/theme_helper.dart';
import 'package:eatvio_app/features/profile/models/circumference_model.dart';
import 'package:eatvio_app/features/profile/presentation/widgets/circumference_chart_widget.dart';
import 'package:flutter/material.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:intl/date_symbol_data_local.dart';
void main() {
group('CircumferenceChartWidget smoke', () {
setUpAll(() async {
await initializeDateFormatting('ru', null);
});
Widget wrap(Widget child) {
return MaterialApp(
theme: ThemeHelper().themeData(),
home: Scaffold(body: child),
);
}
testWidgets('renders circumference chart widget with empty points', (tester) async {
await tester.pumpWidget(wrap(const CircumferenceChartWidget(circumferencePoints: [])));
await tester.pump();
await tester.pump(const Duration(milliseconds: 100));
expect(find.byType(CircumferenceChartWidget), findsOneWidget);
});
testWidgets('renders circumference chart widget with points', (tester) async {
final points = [
CircumferenceModel(
id: 1,
userId: 1,
chestCircumference: 90,
waistCircumference: 80,
hipCircumference: 95,
createdAt: DateTime.now(),
updatedAt: DateTime.now(),
),
];
await tester.pumpWidget(wrap(CircumferenceChartWidget(circumferencePoints: points)));
await tester.pump();
await tester.pump(const Duration(milliseconds: 100));
expect(find.byType(CircumferenceChartWidget), findsOneWidget);
});
});
}

View File

@@ -0,0 +1,37 @@
import 'package:eatvio_app/core/theme/theme_helper.dart';
import 'package:eatvio_app/features/profile/models/weight_model.dart';
import 'package:eatvio_app/features/profile/presentation/widgets/weight_chart_widget.dart';
import 'package:flutter/material.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:intl/date_symbol_data_local.dart';
void main() {
group('WeightChartWidget smoke', () {
setUpAll(() async {
await initializeDateFormatting('ru', null);
});
Widget wrap(Widget child) {
return MaterialApp(
theme: ThemeHelper().themeData(),
home: Scaffold(body: child),
);
}
testWidgets('renders weight chart widget with empty points', (tester) async {
await tester.pumpWidget(wrap(const WeightChartWidget(weightPoints: [])));
await tester.pump();
await tester.pump(const Duration(milliseconds: 100));
expect(find.byType(WeightChartWidget), findsOneWidget);
});
testWidgets('renders weight chart widget with points', (tester) async {
final points = [WeightModel(id: 1, userId: 1, weight: 70, bmi: 22.5, createdAt: DateTime.now(), updatedAt: DateTime.now())];
await tester.pumpWidget(wrap(WeightChartWidget(weightPoints: points)));
await tester.pump();
await tester.pump(const Duration(milliseconds: 100));
expect(find.byType(WeightChartWidget), findsOneWidget);
});
});
}

View File

@@ -0,0 +1,307 @@
import 'dart:convert';
import 'dart:io';
import 'package:dio/dio.dart';
import 'package:eatvio_app/features/profile/models/chosen_diets_pagination_model.dart';
import 'package:eatvio_app/features/profile/models/circumference_model.dart';
import 'package:eatvio_app/features/profile/models/profile_model.dart';
import 'package:eatvio_app/features/profile/models/weight_model.dart';
import 'package:retrofit/retrofit.dart';
import 'package:eatvio_app/features/profile/repositories/profile_repository.dart';
import 'package:eatvio_app/features/profile/services/profile_service.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:mockito/annotations.dart';
import 'package:mockito/mockito.dart';
import 'profile_repository_test.mocks.dart';
@GenerateNiceMocks([MockSpec<ProfileService>()])
void main() {
group('ProfileRepository', () {
late ProfileRepository repository;
late MockProfileService mockService;
setUp(() {
mockService = MockProfileService();
repository = ProfileRepository(profileService: mockService);
});
test('getProfileBySlug - возвращает профиль по slug', () async {
const slug = 'test-user';
const expectedProfile = ProfileModel(
id: 1,
slug: slug,
name: 'Test User',
email: 'test@example.com',
phoneConfirmationState: 'confirmed',
isPublicProfile: true,
isBlockedByMe: false,
isBlockedByAuthor: false,
isBlockedByUser: false,
isEntitySubscribedByMe: false,
profilePhotoUrl: 'https://example.com/photo.jpg',
roles: [],
badges: [],
subscriptions: [],
subscribers: [],
);
when(mockService.getProfileBySlug(slug: slug)).thenAnswer((_) async => expectedProfile);
final result = await repository.getProfileBySlug(slug);
expect(result, equals(expectedProfile));
verify(mockService.getProfileBySlug(slug: slug)).called(1);
});
test('getProfileBySlug - пробрасывает исключение при ошибке', () async {
const slug = 'test-user';
final exception = Exception('Ошибка загрузки');
when(mockService.getProfileBySlug(slug: slug)).thenThrow(exception);
expect(() => repository.getProfileBySlug(slug), throwsException);
});
test('getMyProfile - возвращает мой профиль', () async {
const expectedProfile = ProfileModel(
id: 1,
slug: 'me',
name: 'My Name',
email: 'me@example.com',
phoneConfirmationState: 'confirmed',
isPublicProfile: true,
isBlockedByMe: false,
isBlockedByAuthor: false,
isBlockedByUser: false,
isEntitySubscribedByMe: false,
profilePhotoUrl: 'https://example.com/photo.jpg',
roles: [],
badges: [],
subscriptions: [],
subscribers: [],
);
when(mockService.getMyProfile()).thenAnswer((_) async => expectedProfile);
final result = await repository.getMyProfile();
expect(result, equals(expectedProfile));
verify(mockService.getMyProfile()).called(1);
});
test('addCircumference - добавляет обхваты', () async {
when(mockService.addCircumference(chestCircumference: 100, waistCircumference: 80, hipCircumference: 90)).thenAnswer((_) async => Future<void>.value());
await repository.addCircumference(chestCircumference: 100, waistCircumference: 80, hipCircumference: 90);
verify(mockService.addCircumference(chestCircumference: 100, waistCircumference: 80, hipCircumference: 90)).called(1);
});
test('addWeight - добавляет вес', () async {
when(mockService.addWeight(weight: 70.5)).thenAnswer((_) async => Future<void>.value());
await repository.addWeight(weight: 70.5);
verify(mockService.addWeight(weight: 70.5)).called(1);
});
test('getWeight - возвращает вес без slug', () async {
const period = 'month';
final expectedWeights = [WeightModel(id: 1, userId: 1, weight: 70, createdAt: DateTime(2024, 1, 1), updatedAt: DateTime(2024, 1, 1), bmi: 21.6)];
when(mockService.getWeight(period: period)).thenAnswer((_) async => expectedWeights);
final result = await repository.getWeight(period: period);
expect(result, equals(expectedWeights));
verify(mockService.getWeight(period: period)).called(1);
});
test('getWeight - возвращает вес с slug', () async {
const period = 'month';
const slug = 'test-user';
final expectedWeights = [WeightModel(id: 1, userId: 1, weight: 70, createdAt: DateTime(2024, 1, 1), updatedAt: DateTime(2024, 1, 1), bmi: 21.6)];
when(mockService.getWeightBySlug(period: period, slug: slug)).thenAnswer((_) async => expectedWeights);
final result = await repository.getWeight(period: period, slug: slug);
expect(result, equals(expectedWeights));
verify(mockService.getWeightBySlug(period: period, slug: slug)).called(1);
});
test('getCircumferences - возвращает обхваты без slug', () async {
const period = 'month';
final expectedCircumferences = [
CircumferenceModel(
id: 1,
userId: 1,
chestCircumference: 100,
waistCircumference: 80,
hipCircumference: 90,
createdAt: DateTime(2024, 1, 1),
updatedAt: DateTime(2024, 1, 1),
),
];
when(mockService.getCircumferences(period: period)).thenAnswer((_) async => expectedCircumferences);
final result = await repository.getCircumferences(period: period);
expect(result, equals(expectedCircumferences));
verify(mockService.getCircumferences(period: period)).called(1);
});
test('getCircumferences - возвращает обхваты с slug', () async {
const period = 'month';
const slug = 'test-user';
final expectedCircumferences = [
CircumferenceModel(
id: 1,
userId: 1,
chestCircumference: 100,
waistCircumference: 80,
hipCircumference: 90,
createdAt: DateTime(2024, 1, 1),
updatedAt: DateTime(2024, 1, 1),
),
];
when(mockService.getCircumferencesBySlug(period: period, slug: slug)).thenAnswer((_) async => expectedCircumferences);
final result = await repository.getCircumferences(period: period, slug: slug);
expect(result, equals(expectedCircumferences));
verify(mockService.getCircumferencesBySlug(period: period, slug: slug)).called(1);
});
test('subscribe - подписывается на пользователя', () async {
const slug = 'test-user';
when(mockService.subscribe(slug: slug)).thenAnswer((_) async => Future<void>.value());
await repository.subscribe(slug);
verify(mockService.subscribe(slug: slug)).called(1);
});
test('unsubscribe - отписывается от пользователя', () async {
const slug = 'test-user';
when(mockService.unsubscribe(slug: slug)).thenAnswer((_) async => Future<void>.value());
await repository.unsubscribe(slug);
verify(mockService.unsubscribe(slug: slug)).called(1);
});
test('uploadPhoto - загружает фото', () async {
final testFile = File('test_photo.jpg');
when(mockService.uploadPhoto(photo: testFile)).thenAnswer((_) async => Future<void>.value());
await repository.uploadPhoto(testFile);
verify(mockService.uploadPhoto(photo: testFile)).called(1);
});
test('deletePhoto - удаляет фото', () async {
when(mockService.deletePhoto()).thenAnswer((_) async => Future<void>.value());
await repository.deletePhoto();
verify(mockService.deletePhoto()).called(1);
});
test('getChosenDiets - возвращает выбранные диеты', () async {
final expectedDiets = [ChosenDietModel(chosenDietID: 1, chosenPlanId: 1, state: 'active', startDate: DateTime(2024, 1, 1), dietId: 1)];
final paginationModel = ChosenDietsPaginationModel(diets: expectedDiets);
when(mockService.getChosenDiets()).thenAnswer((_) async => paginationModel);
final result = await repository.getChosenDiets();
expect(result, equals(expectedDiets));
verify(mockService.getChosenDiets()).called(1);
});
test('getPassKey - возвращает pass key', () async {
const routeName = 'testRoute';
final routeParams = {'param1': 'value1'};
final responseData = {'key_is': 'test-key'};
final response = HttpResponse(
responseData,
Response(
data: responseData,
statusCode: 200,
requestOptions: RequestOptions(path: '/api/profile/pass_key', method: 'POST'),
),
);
when(mockService.getPassKey(json: anyNamed('json'))).thenAnswer((_) async => response);
final result = await repository.getPassKey(routeName: routeName, routeParams: routeParams);
expect(result, equals('test-key'));
verify(mockService.getPassKey(json: anyNamed('json'))).called(1);
});
test('getMyPhone - возвращает мой телефон', () async {
final response = jsonEncode({'phone': '+1234567890'});
when(mockService.getMyPhone()).thenAnswer((_) async => response);
final result = await repository.getMyPhone();
expect(result, equals('+1234567890'));
verify(mockService.getMyPhone()).called(1);
});
test('sendEmailCode - отправляет код без нового email', () async {
when(mockService.sendEmailCode()).thenAnswer((_) async => Future<void>.value());
await repository.sendEmailCode();
verify(mockService.sendEmailCode()).called(1);
});
test('sendEmailCode - отправляет код с новым email', () async {
const newEmail = 'new@example.com';
when(mockService.sendEmailCode(data: {'new_email': newEmail})).thenAnswer((_) async => Future<void>.value());
await repository.sendEmailCode(newEmail: newEmail);
verify(mockService.sendEmailCode(data: {'new_email': newEmail})).called(1);
});
test('tryVerifyEmailByCode - успешная верификация', () async {
const code = '123456';
when(mockService.tryVerifyEmailByCode(code: '{"code": "$code"}')).thenAnswer((_) async => Future<void>.value());
final result = await repository.tryVerifyEmailByCode(code);
expect(result, isTrue);
verify(mockService.tryVerifyEmailByCode(code: '{"code": "$code"}')).called(1);
});
test('tryVerifyEmailByCode - неуспешная верификация', () async {
const code = '123456';
when(mockService.tryVerifyEmailByCode(code: '{"code": "$code"}')).thenThrow(Exception('Invalid code'));
final result = await repository.tryVerifyEmailByCode(code);
expect(result, isFalse);
});
test('deleteAccount - удаляет аккаунт', () async {
when(mockService.deleteAccount()).thenAnswer((_) async => Future<void>.value());
await repository.deleteAccount();
verify(mockService.deleteAccount()).called(1);
});
});
}