forked from eatvio/eatvio_app
feat(tests): increased tests coverage
This commit is contained in:
@@ -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);
|
||||
});
|
||||
});
|
||||
}
|
||||
@@ -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);
|
||||
});
|
||||
});
|
||||
}
|
||||
307
test/features/profile/repositories/profile_repository_test.dart
Normal file
307
test/features/profile/repositories/profile_repository_test.dart
Normal 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);
|
||||
});
|
||||
});
|
||||
}
|
||||
Reference in New Issue
Block a user