Merge pull request 'feat(tests)' (#805) from misha/eatvio_app:main into main

Reviewed-on: eatvio/eatvio_app#805
This commit is contained in:
2025-12-12 07:15:24 +00:00
65 changed files with 2092 additions and 1130 deletions

View File

@@ -31,18 +31,18 @@ abstract class ChatRoom with _$ChatRoom {
}
ChatMessageModel? parseLastMessage(dynamic json) {
if (json is List) {
if (json == null || json is List) {
return null;
}
return ChatMessageModel.fromJson(json);
if (json is Map<String, dynamic>) {
return ChatMessageModel.fromJson(json);
}
return null;
}
@freezed
abstract class Users with _$Users {
const factory Users({
@JsonKey(name: "from_chat_user") required ChatUser fromChatUser,
@JsonKey(name: "to_chat_user") required ChatUser toChatUser,
}) = _Users;
const factory Users({@JsonKey(name: "from_chat_user") required ChatUser fromChatUser, @JsonKey(name: "to_chat_user") required ChatUser toChatUser}) = _Users;
factory Users.fromJson(Map<String, dynamic> json) => _$UsersFromJson(json);
}

View File

@@ -0,0 +1,70 @@
import 'package:eatvio_app/features/auth/models/credentials_model.dart';
import 'package:eatvio_app/features/auth/models/oauth_login_request.dart';
import 'package:eatvio_app/features/auth/models/oauth_model.dart';
import 'package:eatvio_app/features/auth/models/token_model.dart';
import 'package:eatvio_app/features/auth/services/auth_service.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:mockito/annotations.dart';
import 'package:mockito/mockito.dart';
import '../../../fixtures/fixture_reader.dart';
import 'auth_service_test.mocks.dart';
@GenerateNiceMocks([MockSpec<AuthService>()])
void main() {
group('AuthService', () {
late MockAuthService mockAuthService;
setUp(() {
mockAuthService = MockAuthService();
});
test('getTokenByCredentials - возвращает токен по учетным данным', () async {
final tokenJson = FixtureReader.readAsMap('auth/token_response.json');
final expectedToken = TokenModel.fromJson(tokenJson);
final credentialsJson = FixtureReader.readAsMap('auth/login_credentials.json');
final credentials = CredentialsModel.fromJson(credentialsJson);
when(mockAuthService.getTokenByCredentials(credentials: credentials))
.thenAnswer((_) async => expectedToken);
final result = await mockAuthService.getTokenByCredentials(credentials: credentials);
expect(result, isA<TokenModel>());
expect(result.token, 'test_token_12345');
verify(mockAuthService.getTokenByCredentials(credentials: credentials)).called(1);
});
test('signInViaSocialMedia - возвращает токен при входе через соцсети', () async {
final tokenJson = FixtureReader.readAsMap('auth/token_response.json');
final expectedToken = TokenModel.fromJson(tokenJson);
final oauthJson = FixtureReader.readAsMap('auth/oauth_signin_request.json');
final oauthRequest = OAuthLoginRequest.fromJson(oauthJson);
when(mockAuthService.signInViaSocialMedia(body: oauthRequest))
.thenAnswer((_) async => expectedToken);
final result = await mockAuthService.signInViaSocialMedia(body: oauthRequest);
expect(result, isA<TokenModel>());
expect(result.token, 'test_token_12345');
verify(mockAuthService.signInViaSocialMedia(body: oauthRequest)).called(1);
});
test('signUpViaSocialMedia - возвращает данные при регистрации через соцсети', () async {
final expectedResponse = {'success': true, 'message': 'User registered'};
final oauthJson = FixtureReader.readAsMap('auth/oauth_signup_request.json');
final oauthModel = OAuthModel.fromJson(oauthJson);
when(mockAuthService.signUpViaSocialMedia(body: oauthModel))
.thenAnswer((_) async => expectedResponse);
final result = await mockAuthService.signUpViaSocialMedia(body: oauthModel);
expect(result, isA<Map<String, Object?>>());
expect(result['success'], true);
verify(mockAuthService.signUpViaSocialMedia(body: oauthModel)).called(1);
});
});
}

View File

@@ -0,0 +1,57 @@
import 'package:dio/dio.dart';
import 'package:eatvio_app/features/auth/services/reset_password_service.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:mockito/annotations.dart';
import 'package:mockito/mockito.dart';
import 'package:retrofit/retrofit.dart';
import '../../../fixtures/fixture_reader.dart';
import 'reset_password_service_test.mocks.dart';
@GenerateNiceMocks([MockSpec<ResetPasswordService>()])
void main() {
group('ResetPasswordService', () {
late MockResetPasswordService mockResetPasswordService;
setUp(() {
mockResetPasswordService = MockResetPasswordService();
});
test('sendEmailCodeForPasswordChange - отправляет код на email', () async {
final requestJson = FixtureReader.readAsMap('auth/reset_password_request.json');
final expectedResponse = HttpResponse(requestJson, Response(
data: requestJson,
statusCode: 200,
requestOptions: RequestOptions(path: '/api/send_password_reset_code'),
));
when(mockResetPasswordService.sendEmailCodeForPasswordChange(data: requestJson))
.thenAnswer((_) async => expectedResponse);
final result = await mockResetPasswordService.sendEmailCodeForPasswordChange(data: requestJson);
expect(result, isA<HttpResponse>());
expect(result.response.statusCode, 200);
verify(mockResetPasswordService.sendEmailCodeForPasswordChange(data: requestJson)).called(1);
});
test('confirmPasswordChange - подтверждает смену пароля', () async {
final requestJson = FixtureReader.readAsMap('auth/reset_password_request.json');
final expectedResponse = HttpResponse({'success': true}, Response(
data: {'success': true},
statusCode: 200,
requestOptions: RequestOptions(path: '/api/confirm_password_reset_code'),
));
when(mockResetPasswordService.confirmPasswordChange(data: requestJson))
.thenAnswer((_) async => expectedResponse);
final result = await mockResetPasswordService.confirmPasswordChange(data: requestJson);
expect(result, isA<HttpResponse>());
expect(result.response.statusCode, 200);
verify(mockResetPasswordService.confirmPasswordChange(data: requestJson)).called(1);
});
});
}

View File

@@ -0,0 +1,53 @@
import 'package:dio/dio.dart';
import 'package:eatvio_app/features/blog_post_create/services/blog_post_service.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:mockito/annotations.dart';
import 'package:mockito/mockito.dart';
import 'blog_post_service_test.mocks.dart';
@GenerateNiceMocks([MockSpec<BlogPostService>()])
void main() {
group('BlogPostService', () {
late MockBlogPostService mockBlogPostService;
setUp(() {
mockBlogPostService = MockBlogPostService();
});
test('createBlogPost - создает пост блога', () async {
final formData = FormData.fromMap({});
when(mockBlogPostService.createBlogPost(formData: formData))
.thenAnswer((_) async => Future.value());
await mockBlogPostService.createBlogPost(formData: formData);
verify(mockBlogPostService.createBlogPost(formData: formData)).called(1);
});
test('updateBlogPost - обновляет пост блога', () async {
const id = 1;
final formData = FormData.fromMap({});
when(mockBlogPostService.updateBlogPost(id: id, formData: formData))
.thenAnswer((_) async => Future.value());
await mockBlogPostService.updateBlogPost(id: id, formData: formData);
verify(mockBlogPostService.updateBlogPost(id: id, formData: formData)).called(1);
});
test('deleteBlogPost - удаляет пост блога', () async {
const id = 1;
when(mockBlogPostService.deleteBlogPost(id: id))
.thenAnswer((_) async => Future.value());
await mockBlogPostService.deleteBlogPost(id: id);
verify(mockBlogPostService.deleteBlogPost(id: id)).called(1);
});
});
}

View File

@@ -0,0 +1,34 @@
import 'package:eatvio_app/features/calendar/models/calendar_model.dart';
import 'package:eatvio_app/features/calendar/services/calendar_service.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:mockito/annotations.dart';
import 'package:mockito/mockito.dart';
import '../../../fixtures/fixture_reader.dart';
import 'calendar_service_test.mocks.dart';
@GenerateNiceMocks([MockSpec<CalendarService>()])
void main() {
group('CalendarService', () {
late MockCalendarService mockCalendarService;
setUp(() {
mockCalendarService = MockCalendarService();
});
test('getCalendar - возвращает календарь', () async {
final json = FixtureReader.readAsList('calendar/calendar_response.json');
final expectedCalendar = json.map((item) => CalendarModel.fromJson(item as Map<String, dynamic>)).toList();
when(mockCalendarService.getCalendar())
.thenAnswer((_) async => expectedCalendar);
final result = await mockCalendarService.getCalendar();
expect(result, isA<List<CalendarModel>>());
expect(result.length, 2);
verify(mockCalendarService.getCalendar()).called(1);
});
});
}

View File

@@ -0,0 +1,39 @@
import 'package:eatvio_app/features/cancel_plan_bottom_sheet/models/cancelation_model.dart';
import 'package:eatvio_app/features/cancel_plan_bottom_sheet/service/cancel_plan_service.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:mockito/annotations.dart';
import 'package:mockito/mockito.dart';
import 'cancel_plan_service_test.mocks.dart';
@GenerateNiceMocks([MockSpec<CancelPlanService>()])
void main() {
group('CancelPlanService', () {
late MockCancelPlanService mockCancelPlanService;
setUp(() {
mockCancelPlanService = MockCancelPlanService();
});
test('cancelChosenPlan - отменяет выбранный план', () async {
const id = 1;
final cancelationModel = CancelationModel(description: 'Test reason', price: 100);
when(mockCancelPlanService.cancelChosenPlan(id: id, body: cancelationModel)).thenAnswer((_) async => Future.value());
await mockCancelPlanService.cancelChosenPlan(id: id, body: cancelationModel);
verify(mockCancelPlanService.cancelChosenPlan(id: id, body: cancelationModel)).called(1);
});
test('cancelChosenPlan - отменяет план без причины', () async {
const id = 1;
when(mockCancelPlanService.cancelChosenPlan(id: id, body: null)).thenAnswer((_) async => Future.value());
await mockCancelPlanService.cancelChosenPlan(id: id, body: null);
verify(mockCancelPlanService.cancelChosenPlan(id: id, body: null)).called(1);
});
});
}

View File

@@ -1,5 +1,6 @@
import 'package:eatvio_app/features/chat/models/chat_message_model.dart';
import 'package:flutter_test/flutter_test.dart';
import '../../../fixtures/fixture_reader.dart';
void main() {
group('ChatMessageModel', () {
@@ -23,22 +24,24 @@ void main() {
});
test('fromJson создает ChatMessageModel из JSON', () {
final json = {
'id': 1,
'data': 'Test message',
'media_data': null,
'author_id': 123,
'updated_at': '2024-01-01T00:00:00Z',
'read_by_to_user': false,
'is_author_message_auth_user': true,
'room_id': 'room-1',
};
final json = FixtureReader.readAsMap('chat/chat_message_response.json');
final model = ChatMessageModel.fromJson(json);
expect(model.id, 1);
expect(model.data, 'Test message');
expect(model.authorId, 123);
expect(model.authorId, 1);
});
test('fromJson создает ChatMessageModel с медиа из JSON', () {
final json = FixtureReader.readAsMap('chat/chat_message_with_media_response.json');
final model = ChatMessageModel.fromJson(json);
expect(model.id, 2);
expect(model.data, 'Message with attachment');
expect(model.mediaData, isNotNull);
expect(model.mediaData!.length, 1);
});
});
}

View File

@@ -2,6 +2,7 @@ import 'package:eatvio_app/features/chat/models/chat_message_model.dart';
import 'package:eatvio_app/features/chat/models/chat_meta_model.dart';
import 'package:eatvio_app/features/chat/models/chat_messages_model.dart';
import 'package:flutter_test/flutter_test.dart';
import '../../../fixtures/fixture_reader.dart';
void main() {
group('ChatMessagesModel', () {
@@ -19,10 +20,7 @@ void main() {
const meta = ChatMetaModel(lastPage: 1);
final model = ChatMessagesModel(
messagesList: [message],
meta: meta,
);
final model = ChatMessagesModel(messagesList: [message], meta: meta);
expect(model.messagesList.length, 1);
expect(model.messagesList.first.id, 1);
@@ -30,30 +28,14 @@ void main() {
});
test('fromJson создает ChatMessagesModel из JSON', () {
final json = {
'data': [
{
'id': 1,
'data': 'Test message',
'media_data': null,
'author_id': 123,
'updated_at': '2024-01-01T00:00:00Z',
'read_by_to_user': false,
'is_author_message_auth_user': true,
'room_id': 'room-1',
}
],
'meta': {
'last_page': 1,
},
};
final json = FixtureReader.readAsMap('chat/chat_messages_response.json');
final model = ChatMessagesModel.fromJson(json);
expect(model.messagesList.length, 1);
expect(model.messagesList.length, 2);
expect(model.messagesList.first.id, 1);
expect(model.messagesList.first.data, 'First message');
expect(model.meta.lastPage, 1);
});
});
}

View File

@@ -2,6 +2,7 @@ import 'package:eatvio_app/features/chat/models/chat_room_model.dart';
import 'package:eatvio_app/features/chat/models/chat_room_settings_model.dart';
import 'package:eatvio_app/features/chat/models/chat_user_model.dart';
import 'package:flutter_test/flutter_test.dart';
import '../../../fixtures/fixture_reader.dart';
void main() {
group('ChatRoomModel', () {
@@ -41,34 +42,12 @@ void main() {
});
test('fromJson создает ChatRoomModel из JSON', () {
final json = {
'id': 'room-1',
'chat_room_setting': {
'room_name': 'Room Name',
'state': 'active',
},
'users': {
'from_chat_user': {
'id': 1,
'name': 'Sender',
'slug': 'sender',
'profile_photo_url': 'https://example.com/sender.jpg',
},
'to_chat_user': {
'id': 2,
'name': 'Receiver',
'slug': 'receiver',
'profile_photo_url': 'https://example.com/receiver.jpg',
},
},
'chosen_plan_id': 1,
'chosen_plan': null,
};
final json = FixtureReader.readAsMap('chat/chat_room_response.json');
final model = ChatRoomModel.fromJson(json);
expect(model.id, 'room-1');
expect(model.chosenPlanId, 1);
expect(model.id, 'chat-1');
expect(model.chosenPlanId, null);
expect(model.users.sender.id, 1);
expect(model.users.receiver.id, 2);
});
@@ -76,22 +55,10 @@ void main() {
group('Users', () {
test('fromJson создает Users из JSON', () {
final json = {
'from_chat_user': {
'id': 1,
'name': 'Sender',
'slug': 'sender',
'profile_photo_url': 'https://example.com/sender.jpg',
},
'to_chat_user': {
'id': 2,
'name': 'Receiver',
'slug': 'receiver',
'profile_photo_url': 'https://example.com/receiver.jpg',
},
};
final roomJson = FixtureReader.readAsMap('chat/chat_room_response.json');
final usersJson = roomJson['users'] as Map<String, dynamic>;
final users = Users.fromJson(json);
final users = Users.fromJson(usersJson);
expect(users.sender.id, 1);
expect(users.receiver.id, 2);

View File

@@ -1,6 +1,7 @@
import 'package:eatvio_app/core/models/pagination_model.dart';
import 'package:eatvio_app/features/chat/models/chat_room_pagination_model.dart';
import 'package:flutter_test/flutter_test.dart';
import '../../../fixtures/fixture_reader.dart';
void main() {
group('ChatRoomPaginationModel', () {
@@ -46,54 +47,12 @@ void main() {
});
test('fromJson создает ChatRoomPaginationModel из JSON', () {
final json = {
'data': [
{
'id': 'room-1',
'last_message': {
'id': 1,
'data': 'Test message',
'media_data': null,
'author_id': 123,
'updated_at': '2024-01-01T00:00:00Z',
'read_by_to_user': false,
'is_author_message_auth_user': true,
'room_id': 'room-1',
},
'users': {
'from_chat_user': {
'id': 1,
'name': 'User 1',
'profile_photo_path': null,
'profile_photo_url': 'https://example.com/user1.jpg',
},
'to_chat_user': {
'id': 2,
'name': 'User 2',
'profile_photo_path': null,
'profile_photo_url': 'https://example.com/user2.jpg',
},
},
'unread_messages_count': 5,
'chosen_plan': null,
},
],
'number_of_unread_chat_rooms': 1,
'meta': {
'current_page': 1,
'from': 1,
'last_page': 1,
'links': [],
'per_page': 10,
'to': 1,
'total': 1,
},
};
final json = FixtureReader.readAsMap('chat/chat_room_pagination_response.json');
final pagination = ChatRoomPaginationModel.fromJson(json);
expect(pagination.data.length, 1);
expect(pagination.data.first.id, 'room-1');
expect(pagination.data.length, 2);
expect(pagination.data.first.id, 'chat-1');
expect(pagination.unreadChatsCount, 1);
});
});
@@ -106,16 +65,7 @@ void main() {
});
test('parseLastMessage создает ChatMessageModel из Map', () {
final json = {
'id': 1,
'data': 'Test message',
'media_data': null,
'author_id': 123,
'updated_at': '2024-01-01T00:00:00Z',
'read_by_to_user': false,
'is_author_message_auth_user': true,
'room_id': 'room-1',
};
final json = FixtureReader.readAsMap('chat/chat_message_response.json');
final result = parseLastMessage(json);
@@ -127,39 +77,12 @@ void main() {
group('ChatRoom', () {
test('fromJson создает ChatRoom из JSON', () {
final json = {
'id': 'room-1',
'last_message': {
'id': 1,
'data': 'Test message',
'media_data': null,
'author_id': 123,
'updated_at': '2024-01-01T00:00:00Z',
'read_by_to_user': false,
'is_author_message_auth_user': true,
'room_id': 'room-1',
},
'users': {
'from_chat_user': {
'id': 1,
'name': 'User 1',
'profile_photo_path': null,
'profile_photo_url': 'https://example.com/user1.jpg',
},
'to_chat_user': {
'id': 2,
'name': 'User 2',
'profile_photo_path': null,
'profile_photo_url': 'https://example.com/user2.jpg',
},
},
'unread_messages_count': 5,
'chosen_plan': null,
};
final paginationJson = FixtureReader.readAsMap('chat/chat_room_pagination_response.json');
final chatRoomJson = (paginationJson['data'] as List).first as Map<String, dynamic>;
final chatRoom = ChatRoom.fromJson(json);
final chatRoom = ChatRoom.fromJson(chatRoomJson);
expect(chatRoom.id, 'room-1');
expect(chatRoom.id, 'chat-1');
expect(chatRoom.unreadMessagesCount, 5);
expect(chatRoom.lastMessage, isNotNull);
});
@@ -194,22 +117,11 @@ void main() {
group('Users', () {
test('fromJson создает Users из JSON', () {
final json = {
'from_chat_user': {
'id': 1,
'name': 'User 1',
'profile_photo_path': null,
'profile_photo_url': 'https://example.com/user1.jpg',
},
'to_chat_user': {
'id': 2,
'name': 'User 2',
'profile_photo_path': null,
'profile_photo_url': 'https://example.com/user2.jpg',
},
};
final paginationJson = FixtureReader.readAsMap('chat/chat_room_pagination_response.json');
final chatRoomJson = (paginationJson['data'] as List).first as Map<String, dynamic>;
final usersJson = chatRoomJson['users'] as Map<String, dynamic>;
final users = Users.fromJson(json);
final users = Users.fromJson(usersJson);
expect(users.fromChatUser.id, 1);
expect(users.toChatUser.id, 2);
@@ -218,14 +130,12 @@ void main() {
group('ChatUser', () {
test('fromJson создает ChatUser из JSON', () {
final json = {
'id': 1,
'name': 'User 1',
'profile_photo_path': null,
'profile_photo_url': 'https://example.com/user1.jpg',
};
final paginationJson = FixtureReader.readAsMap('chat/chat_room_pagination_response.json');
final chatRoomJson = (paginationJson['data'] as List).first as Map<String, dynamic>;
final usersJson = chatRoomJson['users'] as Map<String, dynamic>;
final chatUserJson = usersJson['from_chat_user'] as Map<String, dynamic>;
final chatUser = ChatUser.fromJson(json);
final chatUser = ChatUser.fromJson(chatUserJson);
expect(chatUser.id, 1);
expect(chatUser.name, 'User 1');

View File

@@ -3,23 +3,18 @@ import 'package:dio/dio.dart';
import 'package:eatvio_app/core/models/pagination_model.dart';
import 'package:eatvio_app/features/chat/models/chat_message_model.dart';
import 'package:eatvio_app/features/chat/models/chat_messages_model.dart';
import 'package:eatvio_app/features/chat/models/chat_meta_model.dart';
import 'package:eatvio_app/features/chat/models/chat_room_model.dart' as chat_room;
import 'package:eatvio_app/features/chat/models/chat_room_pagination_model.dart';
import 'package:eatvio_app/features/chat/models/chat_room_settings_model.dart';
import 'package:eatvio_app/features/chat/models/chat_user_model.dart';
import 'package:eatvio_app/features/chat/models/payment_model.dart';
import 'package:eatvio_app/features/chat/models/plan_complain_model.dart';
import 'package:eatvio_app/features/chat/repositories/chat_repository.dart';
import 'package:eatvio_app/features/chat/services/chat_service.dart';
import 'package:eatvio_app/features/plans/enums/chosen_plan_state_enum.dart';
import 'package:eatvio_app/features/plans/models/chosen_plan_model.dart';
import 'package:eatvio_app/features/feed/models/plan_pagination_model.dart';
import 'package:eatvio_app/features/feed/models/diets_pagination_model.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:mockito/annotations.dart';
import 'package:mockito/mockito.dart';
import 'package:retrofit/retrofit.dart';
import '../../../fixtures/fixture_reader.dart';
import 'chat_repository_test.mocks.dart';
@GenerateNiceMocks([MockSpec<ChatService>()])
@@ -35,16 +30,8 @@ void main() {
});
test('emitNewMessageToChats - эмитит новое сообщение в поток', () async {
final message = ChatMessageModel(
id: 1,
data: 'Test message',
mediaData: null,
authorId: 1,
updatedAt: DateTime.now(),
isRead: false,
isCurrentUserAuthor: true,
roomId: 'room-1',
);
final messageFixture = FixtureReader.readAsMap('chat/chat_message_response.json');
final message = ChatMessageModel.fromJson(messageFixture);
chatRepository.emitNewMessageToChats(message);
@@ -123,29 +110,9 @@ void main() {
});
test('getChatRoom - получает комнату чата по UUID', () async {
const uuid = 'room-uuid-123';
const expectedRoom = chat_room.ChatRoomModel(
id: uuid,
chatRoomSettings: ChatRoomSettingsModel(
name: 'Test Room',
state: 'active',
),
users: chat_room.Users(
sender: ChatUserModel(
id: 1,
slug: 'user-1',
name: 'User 1',
profilePhotoUrl: null,
),
receiver: ChatUserModel(
id: 2,
slug: 'user-2',
name: 'User 2',
profilePhotoUrl: null,
),
),
chosenPlanId: null,
);
const uuid = 'chat-1';
final roomFixture = FixtureReader.readAsMap('chat/chat_room_response.json');
final expectedRoom = chat_room.ChatRoomModel.fromJson(roomFixture);
when(mockChatService.getChatRoom(uuid: uuid))
.thenAnswer((_) async => expectedRoom);
@@ -170,19 +137,8 @@ void main() {
});
test('getChatRooms - получает список комнат чата', () async {
const expectedPagination = ChatRoomPaginationModel(
data: [],
unreadChatsCount: 0,
meta: Meta(
currentPage: 1,
from: null,
lastPage: 1,
links: [],
perPage: 10,
to: null,
total: 0,
),
);
final paginationFixture = FixtureReader.readAsMap('chat/chat_room_pagination_response.json');
final expectedPagination = ChatRoomPaginationModel.fromJson(paginationFixture);
when(mockChatService.getChatRooms(query: null, page: 1))
.thenAnswer((_) async => expectedPagination);
@@ -190,24 +146,14 @@ void main() {
final result = await chatRepository.getChatRooms();
expect(result, isA<ChatRoomPaginationModel>());
expect(result.data.length, 2);
verify(mockChatService.getChatRooms(query: null, page: 1)).called(1);
});
test('getChatRooms - получает список комнат с запросом', () async {
const query = 'test query';
const expectedPagination = ChatRoomPaginationModel(
data: [],
unreadChatsCount: 0,
meta: Meta(
currentPage: 1,
from: null,
lastPage: 1,
links: [],
perPage: 10,
to: null,
total: 0,
),
);
final paginationFixture = FixtureReader.readAsMap('chat/chat_room_pagination_response.json');
final expectedPagination = ChatRoomPaginationModel.fromJson(paginationFixture);
when(mockChatService.getChatRooms(query: query, page: 1))
.thenAnswer((_) async => expectedPagination);
@@ -243,23 +189,10 @@ void main() {
});
test('getChatMessages - получает сообщения чата', () async {
const chatId = 'chat-id-123';
const chatId = 'chat-1';
const page = 1;
final expectedMessages = ChatMessagesModel(
messagesList: [
ChatMessageModel(
id: 1,
data: 'Message 1',
mediaData: null,
authorId: 1,
updatedAt: DateTime.now(),
isRead: false,
isCurrentUserAuthor: true,
roomId: chatId,
),
],
meta: const ChatMetaModel(lastPage: 1),
);
final messagesFixture = FixtureReader.readAsMap('chat/chat_messages_response.json');
final expectedMessages = ChatMessagesModel.fromJson(messagesFixture);
when(mockChatService.getChatMessages(id: chatId, page: page))
.thenAnswer((_) async => expectedMessages);
@@ -267,34 +200,14 @@ void main() {
final result = await chatRepository.getChatMessages(chatId, page);
expect(result, isA<ChatMessagesModel>());
expect(result.messagesList.length, 1);
expect(result.messagesList.length, 2);
verify(mockChatService.getChatMessages(id: chatId, page: page)).called(1);
});
test('getChatRoomIdByUserSlug - получает комнату по slug пользователя', () async {
const slug = 'user-slug';
const expectedRoom = chat_room.ChatRoomModel(
id: 'room-id',
chatRoomSettings: ChatRoomSettingsModel(
name: 'Test Room',
state: 'active',
),
users: chat_room.Users(
sender: ChatUserModel(
id: 1,
slug: slug,
name: 'User',
profilePhotoUrl: null,
),
receiver: ChatUserModel(
id: 2,
slug: 'other-user',
name: 'Other User',
profilePhotoUrl: null,
),
),
chosenPlanId: null,
);
const slug = 'user-1';
final roomFixture = FixtureReader.readAsMap('chat/chat_room_response.json');
final expectedRoom = chat_room.ChatRoomModel.fromJson(roomFixture);
when(mockChatService.getChatRoomIdByUserSlug(user: slug))
.thenAnswer((_) async => expectedRoom);
@@ -347,7 +260,8 @@ void main() {
test('getPaymentLink - получает ссылку на оплату', () async {
const planId = 123;
final expectedPayment = PaymentModel(paymentUrl: 'https://payment.url');
final paymentFixture = FixtureReader.readAsMap('chat/payment_response.json');
final expectedPayment = PaymentModel.fromJson(paymentFixture);
when(mockChatService.getPaymentLink(id: planId))
.thenAnswer((_) async => expectedPayment);
@@ -355,49 +269,14 @@ void main() {
final result = await chatRepository.getPaymentLink(id: planId);
expect(result, isA<PaymentModel>());
expect(result.paymentUrl, 'https://payment.url');
expect(result.paymentUrl, 'https://example.com/checkout/payment-123');
verify(mockChatService.getPaymentLink(id: planId)).called(1);
});
test('getChosenPlan - получает выбранный план', () async {
const planId = 123;
final expectedPlan = ChosenPlanModel(
id: planId,
optionType: 'standard',
startDate: DateTime.now(),
chosenPlanState: ChosenPlanStateEnum.stateInCoordination,
chatId: 'chat-id',
consultantId: 1,
plan: const PlanModel(
id: 456,
slug: 'plan-slug',
name: 'Test Plan',
image: '',
duration: 30,
state: 'active',
type: PlanType(
fit: true,
slim: false,
behavior: false,
wellness: false,
),
details: '',
packetsCount: 1,
author: Author(
authorSlug: 'author',
authorName: 'Author',
authorProfileIcon: '',
authorIsMe: false,
),
totalLikes: 0,
totalViews: 0,
totalComments: 0,
isFavorite: false,
minPriceOfOptions: 0.0,
maxPriceOfOptions: 100.0,
wasLikedByMe: false,
),
);
const planId = 1;
final chosenPlanFixture = FixtureReader.readAsMap('chat/chosen_plan_response.json');
final expectedPlan = ChosenPlanModel.fromJson(chosenPlanFixture);
when(mockChatService.getChosenPlan(id: planId))
.thenAnswer((_) async => expectedPlan);
@@ -422,7 +301,8 @@ void main() {
test('complainAboutConsultation - отправляет жалобу на консультацию', () async {
const planId = 123;
final complainModel = PlanComplainModel(description: 'Test complaint');
final complainFixture = FixtureReader.readAsMap('chat/plan_complain_response.json');
final complainModel = PlanComplainModel.fromJson(complainFixture);
when(mockChatService.complainAboutConsultation(id: planId, body: complainModel))
.thenAnswer((_) async => Future.value());

View File

@@ -1,23 +1,16 @@
import 'package:dio/dio.dart';
import 'package:eatvio_app/core/models/pagination_model.dart';
import 'package:eatvio_app/features/chat/models/chat_message_model.dart';
import 'package:eatvio_app/features/chat/models/chat_messages_model.dart';
import 'package:eatvio_app/features/chat/models/chat_meta_model.dart';
import 'package:eatvio_app/features/chat/models/chat_room_model.dart' as chat_room;
import 'package:eatvio_app/features/chat/models/chat_room_pagination_model.dart';
import 'package:eatvio_app/features/chat/models/chat_room_settings_model.dart';
import 'package:eatvio_app/features/chat/models/chat_user_model.dart';
import 'package:eatvio_app/features/chat/models/payment_model.dart';
import 'package:eatvio_app/features/chat/models/plan_complain_model.dart';
import 'package:eatvio_app/features/chat/services/chat_service.dart';
import 'package:eatvio_app/features/plans/enums/chosen_plan_state_enum.dart';
import 'package:eatvio_app/features/plans/models/chosen_plan_model.dart';
import 'package:eatvio_app/features/feed/models/plan_pagination_model.dart';
import 'package:eatvio_app/features/feed/models/diets_pagination_model.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:mockito/annotations.dart';
import 'package:mockito/mockito.dart';
import 'package:retrofit/retrofit.dart';
import '../../../fixtures/fixture_reader.dart';
import 'chat_service_test.mocks.dart';
@GenerateNiceMocks([MockSpec<ChatService>()])
@@ -30,48 +23,24 @@ void main() {
});
test('getChatRooms - возвращает список комнат чата', () async {
const expectedPagination = ChatRoomPaginationModel(
data: [],
unreadChatsCount: 0,
meta: Meta(
currentPage: 1,
from: null,
lastPage: 1,
links: [],
perPage: 10,
to: null,
total: 0,
),
);
final paginationFixture = FixtureReader.readAsMap('chat/chat_room_pagination_response.json');
final expectedPagination = ChatRoomPaginationModel.fromJson(paginationFixture);
when(mockChatService.getChatRooms(query: null, page: 1))
.thenAnswer((_) async => expectedPagination);
when(mockChatService.getChatRooms(query: null, page: 1)).thenAnswer((_) async => expectedPagination);
final result = await mockChatService.getChatRooms(query: null, page: 1);
expect(result, isA<ChatRoomPaginationModel>());
expect(result.data.length, 0);
expect(result.data.length, 2);
verify(mockChatService.getChatRooms(query: null, page: 1)).called(1);
});
test('getChatRooms - возвращает список комнат с запросом', () async {
const query = 'test query';
const expectedPagination = ChatRoomPaginationModel(
data: [],
unreadChatsCount: 0,
meta: Meta(
currentPage: 1,
from: null,
lastPage: 1,
links: [],
perPage: 10,
to: null,
total: 0,
),
);
final paginationFixture = FixtureReader.readAsMap('chat/chat_room_pagination_response.json');
final expectedPagination = ChatRoomPaginationModel.fromJson(paginationFixture);
when(mockChatService.getChatRooms(query: query, page: 1))
.thenAnswer((_) async => expectedPagination);
when(mockChatService.getChatRooms(query: query, page: 1)).thenAnswer((_) async => expectedPagination);
final result = await mockChatService.getChatRooms(query: query, page: 1);
@@ -80,32 +49,11 @@ void main() {
});
test('getChatRoom - возвращает комнату чата по UUID', () async {
const uuid = 'room-uuid-123';
const expectedRoom = chat_room.ChatRoomModel(
id: uuid,
chatRoomSettings: ChatRoomSettingsModel(
name: 'Test Room',
state: 'active',
),
users: chat_room.Users(
sender: ChatUserModel(
id: 1,
slug: 'user-1',
name: 'User 1',
profilePhotoUrl: null,
),
receiver: ChatUserModel(
id: 2,
slug: 'user-2',
name: 'User 2',
profilePhotoUrl: null,
),
),
chosenPlanId: null,
);
const uuid = 'chat-1';
final roomFixture = FixtureReader.readAsMap('chat/chat_room_response.json');
final expectedRoom = chat_room.ChatRoomModel.fromJson(roomFixture);
when(mockChatService.getChatRoom(uuid: uuid))
.thenAnswer((_) async => expectedRoom);
when(mockChatService.getChatRoom(uuid: uuid)).thenAnswer((_) async => expectedRoom);
final result = await mockChatService.getChatRoom(uuid: uuid);
@@ -119,84 +67,34 @@ void main() {
const data = 'Test message';
const socketId = 'socket-id-123';
when(mockChatService.sendMessage(
slug: slug,
data: data,
mediaData: null,
socketId: socketId,
)).thenAnswer((_) async => Future.value());
when(mockChatService.sendMessage(slug: slug, data: data, mediaData: null, socketId: socketId)).thenAnswer((_) async => Future.value());
await mockChatService.sendMessage(
slug: slug,
data: data,
mediaData: null,
socketId: socketId,
);
await mockChatService.sendMessage(slug: slug, data: data, mediaData: null, socketId: socketId);
verify(mockChatService.sendMessage(
slug: slug,
data: data,
mediaData: null,
socketId: socketId,
)).called(1);
verify(mockChatService.sendMessage(slug: slug, data: data, mediaData: null, socketId: socketId)).called(1);
});
test('getChatMessages - возвращает сообщения чата', () async {
const chatId = 'chat-id-123';
const chatId = 'chat-1';
const page = 1;
final expectedMessages = ChatMessagesModel(
messagesList: [
ChatMessageModel(
id: 1,
data: 'Message 1',
mediaData: null,
authorId: 1,
updatedAt: DateTime.now(),
isRead: false,
isCurrentUserAuthor: true,
roomId: chatId,
),
],
meta: const ChatMetaModel(lastPage: 1),
);
final messagesFixture = FixtureReader.readAsMap('chat/chat_messages_response.json');
final expectedMessages = ChatMessagesModel.fromJson(messagesFixture);
when(mockChatService.getChatMessages(id: chatId, page: page))
.thenAnswer((_) async => expectedMessages);
when(mockChatService.getChatMessages(id: chatId, page: page)).thenAnswer((_) async => expectedMessages);
final result = await mockChatService.getChatMessages(id: chatId, page: page);
expect(result, isA<ChatMessagesModel>());
expect(result.messagesList.length, 1);
expect(result.messagesList.length, 2);
verify(mockChatService.getChatMessages(id: chatId, page: page)).called(1);
});
test('getChatRoomIdByUserSlug - возвращает комнату по slug пользователя', () async {
const slug = 'user-slug';
const expectedRoom = chat_room.ChatRoomModel(
id: 'room-id',
chatRoomSettings: ChatRoomSettingsModel(
name: 'Test Room',
state: 'active',
),
users: chat_room.Users(
sender: ChatUserModel(
id: 1,
slug: slug,
name: 'User',
profilePhotoUrl: null,
),
receiver: ChatUserModel(
id: 2,
slug: 'other-user',
name: 'Other User',
profilePhotoUrl: null,
),
),
chosenPlanId: null,
);
const slug = 'user-1';
final roomFixture = FixtureReader.readAsMap('chat/chat_room_response.json');
final expectedRoom = chat_room.ChatRoomModel.fromJson(roomFixture);
when(mockChatService.getChatRoomIdByUserSlug(user: slug))
.thenAnswer((_) async => expectedRoom);
when(mockChatService.getChatRoomIdByUserSlug(user: slug)).thenAnswer((_) async => expectedRoom);
final result = await mockChatService.getChatRoomIdByUserSlug(user: slug);
@@ -208,27 +106,17 @@ void main() {
const chatId = 'chat-id-123';
final messageIds = [1, 2, 3];
when(mockChatService.markMessagesAsRead(
id: chatId,
body: {'messages_ids': messageIds},
)).thenAnswer((_) async => Future.value());
when(mockChatService.markMessagesAsRead(id: chatId, body: {'messages_ids': messageIds})).thenAnswer((_) async => Future.value());
await mockChatService.markMessagesAsRead(
id: chatId,
body: {'messages_ids': messageIds},
);
await mockChatService.markMessagesAsRead(id: chatId, body: {'messages_ids': messageIds});
verify(mockChatService.markMessagesAsRead(
id: chatId,
body: {'messages_ids': messageIds},
)).called(1);
verify(mockChatService.markMessagesAsRead(id: chatId, body: {'messages_ids': messageIds})).called(1);
});
test('cancelChosenPlan - отменяет выбранный план', () async {
const planId = 123;
when(mockChatService.cancelChosenPlan(id: planId))
.thenAnswer((_) async => Future.value());
when(mockChatService.cancelChosenPlan(id: planId)).thenAnswer((_) async => Future.value());
await mockChatService.cancelChosenPlan(id: planId);
@@ -239,8 +127,7 @@ void main() {
const planId = 123;
final date = {'start_date': '2024-01-15'};
when(mockChatService.choseStartPlanDate(id: planId, date: date))
.thenAnswer((_) async => Future.value());
when(mockChatService.choseStartPlanDate(id: planId, date: date)).thenAnswer((_) async => Future.value());
await mockChatService.choseStartPlanDate(id: planId, date: date);
@@ -249,60 +136,24 @@ void main() {
test('getPaymentLink - возвращает ссылку на оплату', () async {
const planId = 123;
final expectedPayment = PaymentModel(paymentUrl: 'https://payment.url');
final paymentFixture = FixtureReader.readAsMap('chat/payment_response.json');
final expectedPayment = PaymentModel.fromJson(paymentFixture);
when(mockChatService.getPaymentLink(id: planId))
.thenAnswer((_) async => expectedPayment);
when(mockChatService.getPaymentLink(id: planId)).thenAnswer((_) async => expectedPayment);
final result = await mockChatService.getPaymentLink(id: planId);
expect(result, isA<PaymentModel>());
expect(result.paymentUrl, 'https://payment.url');
expect(result.paymentUrl, 'https://example.com/checkout/payment-123');
verify(mockChatService.getPaymentLink(id: planId)).called(1);
});
test('getChosenPlan - возвращает выбранный план', () async {
const planId = 123;
final expectedPlan = ChosenPlanModel(
id: planId,
optionType: 'standard',
startDate: DateTime.now(),
chosenPlanState: ChosenPlanStateEnum.stateInCoordination,
chatId: 'chat-id',
consultantId: 1,
plan: const PlanModel(
id: 456,
slug: 'plan-slug',
name: 'Test Plan',
image: '',
duration: 30,
state: 'active',
type: PlanType(
fit: true,
slim: false,
behavior: false,
wellness: false,
),
details: '',
packetsCount: 1,
author: Author(
authorSlug: 'author',
authorName: 'Author',
authorProfileIcon: '',
authorIsMe: false,
),
totalLikes: 0,
totalViews: 0,
totalComments: 0,
isFavorite: false,
minPriceOfOptions: 0.0,
maxPriceOfOptions: 100.0,
wasLikedByMe: false,
),
);
const planId = 1;
final chosenPlanFixture = FixtureReader.readAsMap('chat/chosen_plan_response.json');
final expectedPlan = ChosenPlanModel.fromJson(chosenPlanFixture);
when(mockChatService.getChosenPlan(id: planId))
.thenAnswer((_) async => expectedPlan);
when(mockChatService.getChosenPlan(id: planId)).thenAnswer((_) async => expectedPlan);
final result = await mockChatService.getChosenPlan(id: planId);
@@ -314,8 +165,7 @@ void main() {
test('finishChosenPlan - завершает выбранный план', () async {
const planId = 123;
when(mockChatService.finishChosenPlan(id: planId))
.thenAnswer((_) async => Future.value());
when(mockChatService.finishChosenPlan(id: planId)).thenAnswer((_) async => Future.value());
await mockChatService.finishChosenPlan(id: planId);
@@ -324,30 +174,22 @@ void main() {
test('complainAboutConsultation - отправляет жалобу на консультацию', () async {
const planId = 123;
final complainModel = PlanComplainModel(description: 'Test complaint');
final complainFixture = FixtureReader.readAsMap('chat/plan_complain_response.json');
final complainModel = PlanComplainModel.fromJson(complainFixture);
when(mockChatService.complainAboutConsultation(id: planId, body: complainModel))
.thenAnswer((_) async => Future.value());
when(mockChatService.complainAboutConsultation(id: planId, body: complainModel)).thenAnswer((_) async => Future.value());
await mockChatService.complainAboutConsultation(id: planId, body: complainModel);
verify(mockChatService.complainAboutConsultation(id: planId, body: complainModel))
.called(1);
verify(mockChatService.complainAboutConsultation(id: planId, body: complainModel)).called(1);
});
test('getChatByUserSlug - возвращает HttpResponse', () async {
const slug = 'user-slug';
const chatId = 'chat-id-123';
final response = HttpResponse(
{'id': chatId},
Response(
requestOptions: RequestOptions(path: ''),
statusCode: 200,
),
);
final response = HttpResponse({'id': chatId}, Response(requestOptions: RequestOptions(path: ''), statusCode: 200));
when(mockChatService.getChatByUserSlug(slug: slug))
.thenAnswer((_) async => response);
when(mockChatService.getChatByUserSlug(slug: slug)).thenAnswer((_) async => response);
final result = await mockChatService.getChatByUserSlug(slug: slug);
@@ -357,4 +199,3 @@ void main() {
});
});
}

View File

@@ -0,0 +1,58 @@
import 'package:eatvio_app/features/complaining/models/complain_model.dart';
import 'package:eatvio_app/features/complaining/services/complaining_service.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:mockito/annotations.dart';
import 'package:mockito/mockito.dart';
import 'complaining_service_test.mocks.dart';
@GenerateNiceMocks([MockSpec<ComplainingService>()])
void main() {
group('ComplainingService', () {
late MockComplainingService mockComplainingService;
setUp(() {
mockComplainingService = MockComplainingService();
});
test('sendPlanComplain - отправляет жалобу на план', () async {
const slug = 'test-plan';
const category = 'spam';
const complainModel = ComplainModel(description: 'Test complaint', tags: []);
when(mockComplainingService.sendPlanComplain(slug: slug, category: category, body: complainModel))
.thenAnswer((_) async => Future.value());
await mockComplainingService.sendPlanComplain(slug: slug, category: category, body: complainModel);
verify(mockComplainingService.sendPlanComplain(slug: slug, category: category, body: complainModel)).called(1);
});
test('sendRecipeComplain - отправляет жалобу на рецепт', () async {
const slug = 'test-recipe';
const category = 'spam';
const complainModel = ComplainModel(description: 'Test complaint', tags: []);
when(mockComplainingService.sendRecipeComplain(slug: slug, category: category, body: complainModel))
.thenAnswer((_) async => Future.value());
await mockComplainingService.sendRecipeComplain(slug: slug, category: category, body: complainModel);
verify(mockComplainingService.sendRecipeComplain(slug: slug, category: category, body: complainModel)).called(1);
});
test('sendBlogPostsComplain - отправляет жалобу на пост блога', () async {
const id = 1;
const category = 'spam';
const complainModel = ComplainModel(description: 'Test complaint', tags: []);
when(mockComplainingService.sendBlogPostsComplain(id: id, category: category, body: complainModel))
.thenAnswer((_) async => Future.value());
await mockComplainingService.sendBlogPostsComplain(id: id, category: category, body: complainModel);
verify(mockComplainingService.sendBlogPostsComplain(id: id, category: category, body: complainModel)).called(1);
});
});
}

View File

@@ -0,0 +1,75 @@
import 'package:eatvio_app/features/consultant/become_consultant/models/consultant_cert_photo_model.dart';
import 'package:eatvio_app/features/consultant/become_consultant/models/consultant_profile_model.dart';
import 'package:eatvio_app/features/consultant/become_consultant/models/consultation_request_model.dart';
import 'package:eatvio_app/features/consultant/become_consultant/services/consultant_service.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:mockito/annotations.dart';
import 'package:mockito/mockito.dart';
import '../../../../fixtures/fixture_reader.dart';
import 'consultant_service_test.mocks.dart';
@GenerateNiceMocks([MockSpec<ConsultantService>()])
void main() {
group('ConsultantService', () {
late MockConsultantService mockConsultantService;
setUp(() {
mockConsultantService = MockConsultantService();
});
test('getMyRequestStatus - возвращает статус запроса', () async {
const slug = 'test-consultant';
final json = FixtureReader.readAsMap('consultant/consultation_request.json');
final expectedRequest = ConsultationRequestModel.fromJson(json);
when(mockConsultantService.getMyRequestStatus(slug: slug))
.thenAnswer((_) async => expectedRequest);
final result = await mockConsultantService.getMyRequestStatus(slug: slug);
expect(result, isA<ConsultationRequestModel>());
expect(result.ratingPlace, 12);
verify(mockConsultantService.getMyRequestStatus(slug: slug)).called(1);
});
test('getConsultantRequestStatus - возвращает статус запроса консультанта', () async {
const slug = 'test-consultant';
final json = FixtureReader.readAsMap('consultant/consultation_request.json');
final expectedRequest = ConsultationRequestModel.fromJson(json);
when(mockConsultantService.getConsultantRequestStatus(slug: slug))
.thenAnswer((_) async => expectedRequest);
final result = await mockConsultantService.getConsultantRequestStatus(slug: slug);
expect(result, isA<ConsultationRequestModel>());
verify(mockConsultantService.getConsultantRequestStatus(slug: slug)).called(1);
});
test('getConsultantCertPhotos - возвращает фото сертификатов', () async {
final expectedPhotos = <ConsultantCertPhotoModel>[];
when(mockConsultantService.getConsultantCertPhotos())
.thenAnswer((_) async => expectedPhotos);
final result = await mockConsultantService.getConsultantCertPhotos();
expect(result, isA<List<ConsultantCertPhotoModel>>());
verify(mockConsultantService.getConsultantCertPhotos()).called(1);
});
test('consultantRegistration - регистрирует консультанта', () async {
final profileJson = FixtureReader.readAsMap('consultant/consultant_profile_request.json');
final profile = ConsultantProfileModel.fromJson(profileJson);
when(mockConsultantService.consultantRegistration(consultantModel: profile))
.thenAnswer((_) async => Future.value());
await mockConsultantService.consultantRegistration(consultantModel: profile);
verify(mockConsultantService.consultantRegistration(consultantModel: profile)).called(1);
});
});
}

View File

@@ -0,0 +1,55 @@
import 'package:eatvio_app/features/consultant_rating/models/rating_model.dart';
import 'package:eatvio_app/features/consultant_rating/models/statistics_model.dart';
import 'package:eatvio_app/features/consultant_rating/services/consultant_rating_service.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:mockito/annotations.dart';
import 'package:mockito/mockito.dart';
import 'consultant_rating_service_test.mocks.dart';
@GenerateNiceMocks([MockSpec<ConsultantRatingService>()])
void main() {
group('ConsultantRatingService', () {
late MockConsultantRatingService mockConsultantRatingService;
setUp(() {
mockConsultantRatingService = MockConsultantRatingService();
});
test('getConsultantStatistics - возвращает статистику консультанта', () async {
const date = '2024-01-01';
final expectedStatistics = StatisticsModel(
countReferal: 5,
blogPostsCount: 10,
recipesCount: 15,
dietsCount: 3,
consultationsCount: 20,
qwe: 100,
refLink: 'https://example.com/ref',
);
when(mockConsultantRatingService.getConsultantStatistics(date: date))
.thenAnswer((_) async => expectedStatistics);
final result = await mockConsultantRatingService.getConsultantStatistics(date: date);
expect(result, isA<StatisticsModel>());
expect(result.countReferal, 5);
verify(mockConsultantRatingService.getConsultantStatistics(date: date)).called(1);
});
test('getScoreLogs - возвращает логи оценок', () async {
const date = '2024-01-01';
final expectedLogs = RatingPaginationModel(data: []);
when(mockConsultantRatingService.getScoreLogs(date: date))
.thenAnswer((_) async => expectedLogs);
final result = await mockConsultantRatingService.getScoreLogs(date: date);
expect(result, isA<RatingPaginationModel>());
verify(mockConsultantRatingService.getScoreLogs(date: date)).called(1);
});
});
}

View File

@@ -7,6 +7,8 @@ import 'package:eatvio_app/features/finances_and_consultations_archive/models/us
import 'package:flutter_test/flutter_test.dart';
import 'package:mocktail/mocktail.dart';
import '../../../fixtures/fixture_reader.dart';
class MockConsultationService extends Mock implements ConsultationService {}
class FakeStatisticModel extends Fake implements StatisticModel {}
@@ -69,12 +71,8 @@ void main() {
});
test('getStatistic - успешный запрос', () async {
final mockStatistic = StatisticModel(
total: 10,
inProgress: 5,
finished: 3,
canceled: 2,
);
final json = FixtureReader.readAsMap('consultations/statistic_response.json');
final mockStatistic = StatisticModel.fromJson(json);
when(() => mockService.getStatistics())
.thenAnswer((_) async => mockStatistic);

View File

@@ -0,0 +1,94 @@
import 'package:eatvio_app/features/consultations/models/consultation_model.dart';
import 'package:eatvio_app/features/consultations/services/consultation_service.dart';
import 'package:eatvio_app/features/finances_and_consultations_archive/models/consultant_finance_model.dart';
import 'package:eatvio_app/features/finances_and_consultations_archive/models/statistic_model.dart';
import 'package:eatvio_app/features/finances_and_consultations_archive/models/user_purchases_model.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:mockito/annotations.dart';
import 'package:mockito/mockito.dart';
import 'package:dio/dio.dart';
import '../../../fixtures/fixture_reader.dart';
import 'consultation_service_test.mocks.dart';
@GenerateNiceMocks([MockSpec<Dio>()])
void main() {
group('ConsultationService', () {
late ConsultationService consultationService;
late MockDio mockDio;
setUp(() {
mockDio = MockDio();
consultationService = ConsultationService(mockDio);
});
test('getConsultations - возвращает список консультаций', () async {
final json = FixtureReader.readAsMap('consultations/consultation_pagination_response.json');
final response = Response(
data: json,
statusCode: 200,
requestOptions: RequestOptions(path: '/api/consultations'),
);
when(mockDio.get(any, queryParameters: anyNamed('queryParameters')))
.thenAnswer((_) async => response);
final result = await consultationService.getConsultations();
expect(result, isA<ConsultationPaginationModel>());
expect(result.data.length, 1);
verify(mockDio.get(any, queryParameters: anyNamed('queryParameters'))).called(1);
});
test('getStatistics - возвращает статистику', () async {
final json = FixtureReader.readAsMap('consultations/statistic_response.json');
final response = Response(
data: json,
statusCode: 200,
requestOptions: RequestOptions(path: '/api/consultations/statistics'),
);
when(mockDio.get(any))
.thenAnswer((_) async => response);
final result = await consultationService.getStatistics();
expect(result, isA<StatisticModel>());
expect(result.total, 10);
verify(mockDio.get(any)).called(1);
});
test('getConsultantFinances - возвращает финансы консультанта', () async {
final response = Response(
data: {'data': []},
statusCode: 200,
requestOptions: RequestOptions(path: '/api/finances/my_finances'),
);
when(mockDio.get(any, queryParameters: anyNamed('queryParameters')))
.thenAnswer((_) async => response);
final result = await consultationService.getConsultantFinances(null, null);
expect(result, isA<List<ConsultantFinanceModel>>());
verify(mockDio.get(any, queryParameters: anyNamed('queryParameters'))).called(1);
});
test('getUserPurchases - возвращает покупки пользователя', () async {
final response = Response(
data: {'data': []},
statusCode: 200,
requestOptions: RequestOptions(path: '/api/finances/my_purchases'),
);
when(mockDio.get(any, queryParameters: anyNamed('queryParameters')))
.thenAnswer((_) async => response);
final result = await consultationService.getUserPurchases(null, null);
expect(result, isA<List<UserPurchasesModel>>());
verify(mockDio.get(any, queryParameters: anyNamed('queryParameters'))).called(1);
});
});
}

View File

@@ -0,0 +1,53 @@
import 'package:dio/dio.dart';
import 'package:eatvio_app/features/create_diet/services/create_diet_service.dart';
import 'package:eatvio_app/features/feed/models/diets_pagination_model.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:mockito/annotations.dart';
import 'package:mockito/mockito.dart';
import 'package:retrofit/retrofit.dart';
import 'create_diet_service_test.mocks.dart';
@GenerateNiceMocks([MockSpec<CreateDietService>()])
void main() {
group('CreateDietService', () {
late MockCreateDietService mockCreateDietService;
setUp(() {
mockCreateDietService = MockCreateDietService();
});
test('createPublishedDiet - создает опубликованную диету', () async {
final formData = FormData.fromMap({});
const expectedDiet = CreatedDiet(id: 1);
when(mockCreateDietService.createPublishedDiet(formData: formData))
.thenAnswer((_) async => expectedDiet);
final result = await mockCreateDietService.createPublishedDiet(formData: formData);
expect(result, isA<CreatedDiet>());
expect(result.id, 1);
verify(mockCreateDietService.createPublishedDiet(formData: formData)).called(1);
});
test('getDietPortionsNutrition - возвращает питание порций диеты', () async {
const dietId = 1;
final response = HttpResponse({'data': {}}, Response(
data: {'data': {}},
statusCode: 200,
requestOptions: RequestOptions(path: '/api/diets/show/$dietId/per_portion_nutritions'),
));
when(mockCreateDietService.getDietPortionsNutrition(diet: dietId))
.thenAnswer((_) async => response);
final result = await mockCreateDietService.getDietPortionsNutrition(diet: dietId);
expect(result, isA<HttpResponse>());
expect(result.response.statusCode, 200);
verify(mockCreateDietService.getDietPortionsNutrition(diet: dietId)).called(1);
});
});
}

View File

@@ -0,0 +1,30 @@
import 'package:dio/dio.dart';
import 'package:eatvio_app/features/create_plan/services/create_plan_service.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:mockito/annotations.dart';
import 'package:mockito/mockito.dart';
import 'create_plan_service_test.mocks.dart';
@GenerateNiceMocks([MockSpec<CreatePlanService>()])
void main() {
group('CreatePlanService', () {
late MockCreatePlanService mockCreatePlanService;
setUp(() {
mockCreatePlanService = MockCreatePlanService();
});
test('createPlan - создает план', () async {
final formData = FormData.fromMap({});
when(mockCreatePlanService.createPlan(formData: formData))
.thenAnswer((_) async => Future.value());
await mockCreatePlanService.createPlan(formData: formData);
verify(mockCreatePlanService.createPlan(formData: formData)).called(1);
});
});
}

View File

@@ -0,0 +1,88 @@
import 'package:dio/dio.dart';
import 'package:eatvio_app/core/models/pagination_model.dart';
import 'package:eatvio_app/features/create_recipe/models/recipe_model.dart';
import 'package:eatvio_app/features/create_recipe/models/recipe_tag_model.dart';
import 'package:eatvio_app/features/create_recipe/services/recipe_service.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:mockito/annotations.dart';
import 'package:mockito/mockito.dart';
import 'recipe_service_test.mocks.dart';
@GenerateNiceMocks([MockSpec<CreateRecipeService>()])
void main() {
group('CreateRecipeService', () {
late MockCreateRecipeService mockCreateRecipeService;
setUp(() {
mockCreateRecipeService = MockCreateRecipeService();
});
test('likeRecipe - лайкает рецепт', () async {
const slug = 'test-recipe';
when(mockCreateRecipeService.likeRecipe(slug: slug))
.thenAnswer((_) async => Future.value());
await mockCreateRecipeService.likeRecipe(slug: slug);
verify(mockCreateRecipeService.likeRecipe(slug: slug)).called(1);
});
test('getRecipe - возвращает рецепт', () async {
const id = '1';
const expectedRecipe = RecipeModel(
ingredients: [],
steps: [],
tags: [],
type: 'breakfast',
state: 'published',
title: 'Test Recipe',
description: 'Test Description',
videoUrl: 'https://example.com/video.mp4',
image: 'https://example.com/image.jpg',
totalCookingTime: 30,
activeCookTime: 20,
servings: 4,
energyPerServing: 250,
);
when(mockCreateRecipeService.getRecipe(id))
.thenAnswer((_) async => expectedRecipe);
final result = await mockCreateRecipeService.getRecipe(id);
expect(result, isA<RecipeModel>());
expect(result.title, 'Test Recipe');
verify(mockCreateRecipeService.getRecipe(id)).called(1);
});
test('getTags - возвращает теги рецептов', () async {
const expectedTags = RecipeTagModel(
data: [],
links: Links(first: '', last: '', prev: null, next: null),
meta: Meta(currentPage: 1, from: null, lastPage: 1, links: [], perPage: 10, to: null, total: 0),
);
when(mockCreateRecipeService.getTags())
.thenAnswer((_) async => expectedTags);
final result = await mockCreateRecipeService.getTags();
expect(result, isA<RecipeTagModel>());
verify(mockCreateRecipeService.getTags()).called(1);
});
test('publishRecipe - публикует рецепт', () async {
final formData = FormData.fromMap({});
when(mockCreateRecipeService.publishRecipe(formData: formData))
.thenAnswer((_) async => Future.value());
await mockCreateRecipeService.publishRecipe(formData: formData);
verify(mockCreateRecipeService.publishRecipe(formData: formData)).called(1);
});
});
}

View File

@@ -9,6 +9,7 @@ import 'package:eatvio_app/features/glossary/models/glossary_model.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:mockito/annotations.dart';
import 'package:mockito/mockito.dart';
import '../../../fixtures/fixture_reader.dart';
import 'diary_repository_test.mocks.dart';
@GenerateNiceMocks([MockSpec<DiaryService>()])
@@ -24,23 +25,9 @@ void main() {
test('getDiaryIndexByDate - возвращает список дневников по дате', () async {
const date = '2024-01-15';
final expectedDiaryList = [
const DiaryDayModel(
id: 1,
date: date,
closed: 0,
comment: '',
typeOfDiary: TypeOfDiaryModel(
hasChosenDiet: false,
hasChosenPlan: false,
diaryState: null,
),
meals: [],
chosenPlanId: null,
dayOfChosenDiet: null,
diet: null,
),
];
final json = FixtureReader.readAsMap('diary/diary_day_response.json');
final expectedDiary = DiaryDayModel.fromJson(json);
final expectedDiaryList = [expectedDiary];
when(mockDiaryService.getDiaryIndexByDate(date: date))
.thenAnswer((_) async => expectedDiaryList);
@@ -92,23 +79,8 @@ void main() {
),
];
const glossaryItem = GlossaryPaginationModel(
glossariesList: [
GlossaryModel(
id: 10,
name: 'Яблоко',
grInPortion: 100,
energyOn100Gr: 52.0,
proteinsOn100Gr: 0.3,
fatsOn100Gr: 0.2,
carbohydratesOn100Gr: 14.0,
energyOnPortion: 52.0,
proteinsOnPortion: 0.3,
fatsOnPortion: 0.2,
carbohydratesOnPortion: 14.0,
),
],
);
final glossaryJson = FixtureReader.readAsMap('diary/glossary_pagination_response.json');
final glossaryItem = GlossaryPaginationModel.fromJson(glossaryJson);
when(mockDiaryService.getDiaryIndexByDate(date: date))
.thenAnswer((_) async => diaryList);
@@ -214,23 +186,8 @@ void main() {
),
);
const glossaryItem = GlossaryPaginationModel(
glossariesList: [
GlossaryModel(
id: 10,
name: 'Яблоко',
grInPortion: 100,
energyOn100Gr: 52.0,
proteinsOn100Gr: 0.3,
fatsOn100Gr: 0.2,
carbohydratesOn100Gr: 14.0,
energyOnPortion: 52.0,
proteinsOnPortion: 0.3,
fatsOnPortion: 0.2,
carbohydratesOnPortion: 14.0,
),
],
);
final glossaryJson = FixtureReader.readAsMap('diary/glossary_pagination_response.json');
final glossaryItem = GlossaryPaginationModel.fromJson(glossaryJson);
when(mockDiaryService.getDiaryDay(diary: diaryId))
.thenAnswer((_) async => diaryWrapper);
@@ -246,20 +203,8 @@ void main() {
test('getNutritionData - возвращает данные о питании', () async {
const diaryId = 1;
const expectedNutrition = NutritionDataModel(
dailyNutritionIntake: NutritionModel(
energy: 2000.0,
proteins: 150.0,
fats: 80.0,
carbohydrates: 250.0,
),
dailyNutritionRecommendation: NutritionModel(
energy: 2200.0,
proteins: 160.0,
fats: 90.0,
carbohydrates: 270.0,
),
);
final json = FixtureReader.readAsMap('diary/nutrition_response.json');
final expectedNutrition = NutritionDataModel.fromJson(json);
when(mockDiaryService.getNutrition(diary: diaryId))
.thenAnswer((_) async => expectedNutrition);
@@ -835,23 +780,8 @@ void main() {
diet: null,
);
const glossaryItem = GlossaryPaginationModel(
glossariesList: [
GlossaryModel(
id: 10,
name: 'Яблоко',
grInPortion: 100,
energyOn100Gr: 52.0,
proteinsOn100Gr: 0.3,
fatsOn100Gr: 0.2,
carbohydratesOn100Gr: 14.0,
energyOnPortion: 52.0,
proteinsOnPortion: 0.3,
fatsOnPortion: 0.2,
carbohydratesOnPortion: 14.0,
),
],
);
final glossaryJson = FixtureReader.readAsMap('diary/glossary_pagination_response.json');
final glossaryItem = GlossaryPaginationModel.fromJson(glossaryJson);
when(mockDiaryService.getDiaryDayV2(day: day))
.thenAnswer((_) async => diaryDay);

View File

@@ -6,6 +6,7 @@ import 'package:flutter_test/flutter_test.dart';
import 'package:mockito/annotations.dart';
import 'package:mockito/mockito.dart';
import '../../../fixtures/fixture_reader.dart';
import 'diet_repository_test.mocks.dart';
@GenerateNiceMocks([MockSpec<DietService>()])
@@ -21,10 +22,8 @@ void main() {
test('likeDiet - успешный лайк', () async {
const dietId = 1;
const expectedLikes = DietLikesModel(
totalLikes: 10,
isLiked: true,
);
final json = FixtureReader.readAsMap('diets/diet_likes_response.json');
final expectedLikes = DietLikesModel.fromJson(json);
when(mockService.likeDiet(id: dietId))
.thenAnswer((_) async => expectedLikes);
@@ -37,31 +36,8 @@ void main() {
test('getDiet - успешное получение диеты по id', () async {
const dietId = 1;
const expectedDiet = Diet(
id: dietId,
slug: 'test-diet',
name: 'Test Diet',
image: 'https://example.com/image.jpg',
duration: 7,
state: DietState.active,
type: DietType(veg: true, light: false, carb: false, meat: false),
details: 'Test details',
dailySchedule: {},
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,
dailyNutrition: [],
);
final json = FixtureReader.readAsMap('diets/diet_response.json');
final expectedDiet = Diet.fromJson(json);
when(mockService.getDiet(id: dietId))
.thenAnswer((_) async => expectedDiet);
@@ -75,31 +51,8 @@ void main() {
test('getDietBySlug - успешное получение диеты по slug', () async {
const slug = 'test-diet';
const expectedDiet = Diet(
id: 1,
slug: slug,
name: 'Test Diet',
image: 'https://example.com/image.jpg',
duration: 7,
state: DietState.active,
type: DietType(veg: true, light: false, carb: false, meat: false),
details: 'Test details',
dailySchedule: {},
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,
dailyNutrition: [],
);
final json = FixtureReader.readAsMap('diets/diet_response.json');
final expectedDiet = Diet.fromJson(json);
when(mockService.getDietBySlug(slug: slug))
.thenAnswer((_) async => expectedDiet);
@@ -113,31 +66,10 @@ void main() {
test('addToFavorite - успешное добавление в избранное', () async {
const dietId = 1;
const expectedDiet = Diet(
id: dietId,
slug: 'test-diet',
name: 'Test Diet',
image: 'https://example.com/image.jpg',
duration: 7,
state: DietState.active,
type: DietType(veg: true, light: false, carb: false, meat: false),
details: 'Test details',
dailySchedule: {},
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,
dailyNutrition: [],
);
final json = FixtureReader.readAsMap('diets/diet_response.json');
final dietJson = Map<String, dynamic>.from(json);
dietJson['is_favorite'] = true;
final expectedDiet = Diet.fromJson(dietJson);
when(mockService.addToFavorite(id: dietId))
.thenAnswer((_) async => expectedDiet);
@@ -151,31 +83,8 @@ void main() {
test('removeFromFavorite - успешное удаление из избранного', () async {
const dietId = 1;
const expectedDiet = Diet(
id: dietId,
slug: 'test-diet',
name: 'Test Diet',
image: 'https://example.com/image.jpg',
duration: 7,
state: DietState.active,
type: DietType(veg: true, light: false, carb: false, meat: false),
details: 'Test details',
dailySchedule: {},
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,
dailyNutrition: [],
);
final json = FixtureReader.readAsMap('diets/diet_response.json');
final expectedDiet = Diet.fromJson(json);
when(mockService.removeFromFavorite(id: dietId))
.thenAnswer((_) async => expectedDiet);

View File

@@ -14,6 +14,7 @@ import 'package:flutter_test/flutter_test.dart';
import 'package:mockito/annotations.dart';
import 'package:mockito/mockito.dart';
import '../../../fixtures/fixture_reader.dart';
import 'feed_repository_test.mocks.dart';
@GenerateNiceMocks([MockSpec<FeedService>()])
@@ -86,28 +87,8 @@ void main() {
test('getBlogPost - успешное получение поста', () async {
const postId = 1;
final expectedPost = FeedBlogPostModel(
id: postId,
state: 'published',
image: 'https://example.com/image.jpg',
description: 'Описание',
author: const Author(
authorSlug: 'author-slug',
authorName: 'Автор',
authorProfileIcon: 'https://example.com/photo.jpg',
authorIsMe: false,
isEntitySubscribedByMe: null,
authorPlaceInRating: null,
),
videoUrl: '',
createdAt: DateTime.now(),
updatedAt: DateTime.now(),
title: 'Заголовок',
totalLikes: 10,
totalViews: 100,
totalComments: 5,
wasLikedByMe: false,
);
final json = FixtureReader.readAsMap('feed/feed_blog_post_response.json');
final expectedPost = FeedBlogPostModel.fromJson(json);
when(mockFeedService.getBlogPost(postId: postId)).thenAnswer((_) async => expectedPost);
@@ -246,36 +227,8 @@ void main() {
const duration = 30;
const minPrice = 1000;
const maxPrice = 5000;
final expectedPlans = PlanPaginationModel(
data: [
PlanModel(
id: 1,
slug: 'weight-loss-plan',
name: 'Weight Loss Plan',
image: 'https://example.com/plan.jpg',
duration: duration,
state: 'active',
type: const PlanType(fit: false, slim: true, behavior: false, wellness: false),
details: 'Weight loss plan description',
packetsCount: 30,
author: const Author(
authorSlug: 'consultant-1',
authorName: 'Consultant Name',
authorProfileIcon: 'https://example.com/consultant.jpg',
authorIsMe: false,
),
totalLikes: 100,
totalViews: 1000,
totalComments: 50,
isFavorite: false,
minPriceOfOptions: minPrice.toDouble(),
maxPriceOfOptions: maxPrice.toDouble(),
wasLikedByMe: false,
),
],
links: const Links(first: '', last: '', prev: null, next: null),
meta: const Meta(currentPage: 1, lastPage: 1, total: 1, perPage: 10, from: null, links: [Link(url: null, label: null, active: null)], to: null),
);
final json = FixtureReader.readAsMap('feed/plan_pagination_response.json');
final expectedPlans = PlanPaginationModel.fromJson(json);
when(
mockFeedService.getPlans(page: page, query: query, types: types, duration: duration, minPrice: minPrice, maxPrice: maxPrice),
@@ -310,21 +263,8 @@ void main() {
test('getBlogPostComments - возвращает комментарии поста блога', () async {
const id = '1';
final expectedComments = CommentModel(
data: [
Comment(
id: 1,
authorName: 'User 1',
authorSlug: 'user-1',
authorProfileIcon: 'https://example.com/user1.jpg',
body: 'Great post!',
childrenComments: [],
createdAt: DateTime(2024, 1, 15),
),
],
links: const Links(first: '', last: '', prev: null, next: null),
meta: const Meta(currentPage: 1, lastPage: 1, total: 1, perPage: 10, from: null, links: [Link(url: null, label: null, active: null)], to: null),
);
final json = FixtureReader.readAsMap('feed/comment_response.json');
final expectedComments = CommentModel.fromJson(json);
when(mockFeedService.getBlogPostComments(id: id)).thenAnswer((_) async => expectedComments);
@@ -498,22 +438,8 @@ void main() {
test('getConsultants - возвращает список консультантов', () async {
const name = 'Anna';
final expectedConsultants = [
const FeedConsultantModel(
slug: 'consultant-1',
name: 'Anna Ivanova',
description: 'Test consultant description',
totalScores: 5,
photo: 'https://example.com/consultant1.jpg',
badges: [],
),
];
final expectedPagination = FeedConsultantPaginationModel(
data: expectedConsultants,
links: const Links(first: '', last: '', prev: null, next: null),
meta: const Meta(currentPage: 1, lastPage: 1, total: 1, perPage: 10, from: null, links: [Link(url: null, label: null, active: null)], to: null),
);
final json = FixtureReader.readAsMap('feed/consultant_pagination_response.json');
final expectedPagination = FeedConsultantPaginationModel.fromJson(json);
when(mockFeedService.getConsultants(name: name)).thenAnswer((_) async => expectedPagination);

View File

@@ -0,0 +1,35 @@
import 'package:eatvio_app/features/glossary/models/glossary_model.dart';
import 'package:eatvio_app/features/glossary/services/glossary_service.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:mockito/annotations.dart';
import 'package:mockito/mockito.dart';
import '../../../fixtures/fixture_reader.dart';
import 'glossary_service_test.mocks.dart';
@GenerateNiceMocks([MockSpec<GlossaryService>()])
void main() {
group('GlossaryService', () {
late MockGlossaryService mockGlossaryService;
setUp(() {
mockGlossaryService = MockGlossaryService();
});
test('getGlossaryByQuery - возвращает глоссарий по запросу', () async {
const query = 'яблоко';
final json = FixtureReader.readAsMap('diary/glossary_pagination_response.json');
final expectedGlossary = GlossaryPaginationModel.fromJson(json);
when(mockGlossaryService.getGlossaryByQuery(query: query))
.thenAnswer((_) async => expectedGlossary);
final result = await mockGlossaryService.getGlossaryByQuery(query: query);
expect(result, isA<GlossaryPaginationModel>());
expect(result.glossariesList.length, 1);
verify(mockGlossaryService.getGlossaryByQuery(query: query)).called(1);
});
});
}

View File

@@ -6,6 +6,7 @@ import 'package:flutter_test/flutter_test.dart';
import 'package:mockito/annotations.dart';
import 'package:mockito/mockito.dart';
import '../../../fixtures/fixture_reader.dart';
import 'my_diets_repository_test.mocks.dart';
@GenerateNiceMocks([MockSpec<MyDietsService>()])
@@ -26,30 +27,8 @@ void main() {
const types = 'light,veg';
const duration = 30;
const sorting = 'name';
const expected = DietsPagination(
data: [
Diet(
id: 1,
slug: 'test-diet',
name: 'Test Diet',
image: 'https://someurl.com/img.jpg',
duration: duration,
state: DietState.active,
type: DietType(light: true, veg: false, carb: false, meat: false),
details: 'Test diet description',
dailySchedule: {},
author: Author(authorSlug: '', authorName: '', authorProfileIcon: '', authorIsMe: false),
totalLikes: 1,
totalViews: 1,
totalComments: 1,
wasLikedByMe: false,
isFavorite: false,
dailyNutrition: [],
),
],
links: Links(first: '', last: '', prev: null, next: null),
meta: Meta(currentPage: 1, lastPage: 1, total: 1, perPage: 10, from: null, links: [Link(url: null, label: null, active: null)], to: null),
);
final json = FixtureReader.readAsMap('feed/diets_pagination_response.json');
final expected = DietsPagination.fromJson(json);
when(mockMyDietsService.getDiets(
page: page,
@@ -71,7 +50,7 @@ void main() {
expect(result, isA<DietsPagination>());
expect(result.data.length, 1);
expect(result.data.first.name, 'Test Diet');
expect(result.data.first.name, 'Keto Diet');
verify(mockMyDietsService.getDiets(
page: page,
query: query,
@@ -116,30 +95,26 @@ void main() {
const page = 2;
const query = 'wellness';
const duration = 21;
const expected = DietsPagination(
data: [
Diet(
id: 2,
slug: 'another-diet',
name: 'Another Diet',
image: 'https://someurl.com/img2.jpg',
duration: duration,
state: DietState.draft,
type: DietType(light: false, veg: true, carb: false, meat: false),
details: '',
dailySchedule: {},
author: Author(authorSlug: 'author-slug', authorName: 'Author Name', authorProfileIcon: '', authorIsMe: true),
totalLikes: 5,
totalViews: 10,
totalComments: 2,
wasLikedByMe: true,
isFavorite: true,
dailyNutrition: [],
),
],
links: Links(first: '', last: '', prev: null, next: null),
meta: Meta(currentPage: 2, lastPage: 2, total: 1, perPage: 10, from: null, links: [Link(url: null, label: null, active: null)], to: null),
);
final json = FixtureReader.readAsMap('feed/diets_pagination_response.json');
final dietJson = Map<String, dynamic>.from(json);
final dietData = List<Map<String, dynamic>>.from(dietJson['data'] as List);
dietData.first['id'] = 2;
dietData.first['slug'] = 'another-diet';
dietData.first['name'] = 'Another Diet';
dietData.first['image'] = 'https://someurl.com/img2.jpg';
dietData.first['duration'] = duration;
dietData.first['state'] = 'draft';
dietData.first['type'] = {'light': false, 'veg': true, 'carb': false, 'meat': false};
dietData.first['description_md'] = '';
dietData.first['author'] = {'author_slug': 'author-slug', 'author_name': 'Author Name', 'author_profile_icon': '', 'author_is_me': true, 'is_entity_subscribed_by_me': null, 'author_place_in_rating': null};
dietData.first['total_likes'] = 5;
dietData.first['total_views'] = 10;
dietData.first['total_comments'] = 2;
dietData.first['was_liked_by_me'] = true;
dietData.first['is_favorite'] = true;
dietJson['data'] = dietData;
dietJson['meta'] = {'current_page': 2, 'from': null, 'last_page': 2, 'links': [{'url': null, 'label': null, 'active': null}], 'per_page': 10, 'to': null, 'total': 1, 'total_min_price': null, 'total_max_price': null};
final expected = DietsPagination.fromJson(dietJson);
when(mockMyDietsService.getDiets(
page: page,

View File

@@ -0,0 +1,78 @@
import 'package:eatvio_app/features/my_finance/models/card_model.dart';
import 'package:eatvio_app/features/my_finance/models/payment_url_model.dart';
import 'package:eatvio_app/features/my_finance/services/cards_service.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:mockito/annotations.dart';
import 'package:mockito/mockito.dart';
import 'cards_service_test.mocks.dart';
@GenerateNiceMocks([MockSpec<CardsService>()])
void main() {
group('CardsService', () {
late MockCardsService mockCardsService;
setUp(() {
mockCardsService = MockCardsService();
});
test('getCards - возвращает список карт', () async {
final expectedCards = <CardModel>[];
when(mockCardsService.getCards())
.thenAnswer((_) async => expectedCards);
final result = await mockCardsService.getCards();
expect(result, isA<List<CardModel>>());
verify(mockCardsService.getCards()).called(1);
});
test('addCard - добавляет карту', () async {
final expectedUrl = PaymentUrlModel(paymentUrl: 'https://example.com/payment');
when(mockCardsService.addCard())
.thenAnswer((_) async => expectedUrl);
final result = await mockCardsService.addCard();
expect(result, isA<PaymentUrlModel>());
expect(result.paymentUrl, 'https://example.com/payment');
verify(mockCardsService.addCard()).called(1);
});
test('markAsDefault - помечает карту как основную', () async {
const id = 1;
when(mockCardsService.markAsDefault(id: id))
.thenAnswer((_) async => Future.value());
await mockCardsService.markAsDefault(id: id);
verify(mockCardsService.markAsDefault(id: id)).called(1);
});
test('deleteCard - удаляет карту', () async {
const id = 1;
when(mockCardsService.deleteCard(id: id))
.thenAnswer((_) async => Future.value());
await mockCardsService.deleteCard(id: id);
verify(mockCardsService.deleteCard(id: id)).called(1);
});
test('collectCharge - собирает платеж', () async {
const chosenPlanId = 1;
when(mockCardsService.collectCharge(chosenPlanId: chosenPlanId))
.thenAnswer((_) async => Future.value());
await mockCardsService.collectCharge(chosenPlanId: chosenPlanId);
verify(mockCardsService.collectCharge(chosenPlanId: chosenPlanId)).called(1);
});
});
}

View File

@@ -7,6 +7,7 @@ import 'package:flutter_test/flutter_test.dart';
import 'package:mockito/annotations.dart';
import 'package:mockito/mockito.dart';
import '../../../fixtures/fixture_reader.dart';
import 'my_plans_repository_test.mocks.dart';
@GenerateNiceMocks([MockSpec<MyPlansService>()])
@@ -27,31 +28,8 @@ void main() {
const duration = 30;
const minPrice = 100;
const maxPrice = 500;
final expected = PlanPaginationModel(
data: [
PlanModel(
id: 1,
slug: 'test-plan',
name: 'Test Plan',
image: 'https://someurl.com/img.jpg',
duration: duration,
state: 'active',
type: const PlanType(fit: true, slim: false, behavior: false, wellness: false),
details: 'Test plan description',
packetsCount: 1,
author: const Author(authorSlug: '', authorName: '', authorProfileIcon: '', authorIsMe: false),
totalLikes: 1,
totalViews: 1,
totalComments: 1,
isFavorite: false,
minPriceOfOptions: minPrice.toDouble(),
maxPriceOfOptions: maxPrice.toDouble(),
wasLikedByMe: false,
),
],
links: const Links(first: '', last: '', prev: null, next: null),
meta: const Meta(currentPage: 1, lastPage: 1, total: 1, perPage: 10, from: null, links: [Link(url: null, label: null, active: null)], to: null),
);
final json = FixtureReader.readAsMap('feed/plan_pagination_response.json');
final expected = PlanPaginationModel.fromJson(json);
when(mockMyPlansService.getPlans(
page: page,
@@ -73,7 +51,7 @@ void main() {
expect(result, isA<PlanPaginationModel>());
expect(result.data.length, 1);
expect(result.data.first.name, 'Test Plan');
expect(result.data.first.name, 'Weight Loss Plan');
verify(mockMyPlansService.getPlans(
page: page,
query: query,

View File

@@ -1,173 +1,62 @@
import 'package:dio/dio.dart';
import 'package:eatvio_app/features/notifications/models/notification_model.dart';
import 'package:eatvio_app/features/notifications/service/notifications_service.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:mockito/annotations.dart';
import 'package:mockito/mockito.dart';
import '../../../fixtures/fixture_reader.dart';
import 'notifications_service_test.mocks.dart';
@GenerateMocks([Dio])
@GenerateNiceMocks([MockSpec<Dio>()])
void main() {
group('NotificationsService', () {
late NotificationsService service;
late NotificationsService notificationsService;
late MockDio mockDio;
setUp(() {
mockDio = MockDio();
service = NotificationsService(mockDio);
notificationsService = NotificationsService(mockDio);
});
test('getNotifications returns null when status code is not 200', () async {
when(mockDio.get(any)).thenAnswer((_) async => Response(
requestOptions: RequestOptions(path: '/api/profile/notifications'),
statusCode: 404,
data: {},
));
final result = await service.getNotifications(page: 1);
expect(result, isNull);
});
test('getNotifications parses notifications correctly', () async {
when(mockDio.get(any)).thenAnswer((_) async => Response(
requestOptions: RequestOptions(path: '/api/profile/notifications'),
statusCode: 200,
data: {
'data': [
{
'type': 'diary-reminder-notification',
'read_at': null,
'created_at': '2024-01-15T10:30:00Z',
'data': {},
}
],
'current_page': 1,
'last_page': 1,
'per_page': 10,
'total': 1,
},
));
final result = await service.getNotifications(page: 1);
expect(result, isNotNull);
expect(result!['notifications'], isA<List>());
expect(result['pagination'], isA<Map>());
expect(result['pagination']['current_page'], 1);
});
test('getNotifications handles unknown notification type', () async {
when(mockDio.get(any)).thenAnswer((_) async => Response(
requestOptions: RequestOptions(path: '/api/profile/notifications'),
statusCode: 200,
data: {
'data': [
{
'type': 'unknown-type',
'read_at': null,
'created_at': '2024-01-15T10:30:00Z',
'data': {},
}
],
'current_page': 1,
'last_page': 1,
'per_page': 10,
'total': 1,
},
));
final result = await service.getNotifications(page: 1);
expect(result, isNotNull);
expect(result!['notifications'], isA<List>());
final notifications = result['notifications'] as List;
expect(notifications.first, isA<UnknownNotification>());
});
test('getNotifications handles notification_class_name field', () async {
when(mockDio.get(any)).thenAnswer((_) async => Response(
requestOptions: RequestOptions(path: '/api/profile/notifications'),
statusCode: 200,
data: {
'data': [
{
'notification_class_name': 'App\\Notifications\\DiaryReminderNotification',
'read_at': null,
'created_at': '2024-01-15T10:30:00Z',
'data': {},
}
],
'current_page': 1,
'last_page': 1,
'per_page': 10,
'total': 1,
},
));
final result = await service.getNotifications(page: 1);
expect(result, isNotNull);
expect(result!['notifications'], isA<List>());
});
test('getNotifications handles read_at correctly', () async {
when(mockDio.get(any)).thenAnswer((_) async => Response(
requestOptions: RequestOptions(path: '/api/profile/notifications'),
statusCode: 200,
data: {
'data': [
{
'type': 'diary-reminder-notification',
'read_at': '2024-01-15T10:30:00Z',
'created_at': '2024-01-15T10:30:00Z',
'data': {},
}
],
'current_page': 1,
'last_page': 1,
'per_page': 10,
'total': 1,
},
));
final result = await service.getNotifications(page: 1);
expect(result, isNotNull);
expect(result!['notifications'], isA<List>());
});
test('getNotifications rethrows exceptions', () async {
when(mockDio.get(any)).thenThrow(DioException(
test('getNotifications - возвращает уведомления', () async {
const page = 1;
final json = FixtureReader.readAsMap('notifications/notifications_response.json');
final response = Response(
data: {
'data': json['notifications'],
'current_page': json['pagination']['current_page'],
'last_page': json['pagination']['last_page'],
'per_page': 10,
'total': 1,
},
statusCode: 200,
requestOptions: RequestOptions(path: '/api/profile/notifications'),
));
);
expect(() => service.getNotifications(page: 1), throwsA(isA<DioException>()));
when(mockDio.get(any))
.thenAnswer((_) async => response);
final result = await notificationsService.getNotifications(page: page);
expect(result, isA<Map<String, dynamic>?>());
expect(result, isNotNull);
expect(result!['notifications'], isA<List>());
verify(mockDio.get(any)).called(1);
});
test('markNotificationsAsRead calls correct endpoint', () async {
when(mockDio.post(any)).thenAnswer((_) async => Response(
requestOptions: RequestOptions(path: '/api/profile/mark_notifications_as_readed'),
statusCode: 200,
));
await service.markNotificationsAsRead();
verify(mockDio.post('/api/profile/mark_notifications_as_readed')).called(1);
});
test('markNotificationsAsRead rethrows exceptions', () async {
when(mockDio.post(any)).thenThrow(DioException(
test('markNotificationsAsRead - помечает уведомления как прочитанные', () async {
final response = Response(
data: {},
statusCode: 200,
requestOptions: RequestOptions(path: '/api/profile/mark_notifications_as_readed'),
));
);
expect(() => service.markNotificationsAsRead(), throwsA(isA<DioException>()));
when(mockDio.post(any))
.thenAnswer((_) async => response);
await notificationsService.markNotificationsAsRead();
verify(mockDio.post(any)).called(1);
});
});
}

View File

@@ -0,0 +1,74 @@
import 'package:dio/dio.dart';
import 'package:eatvio_app/features/consultations/models/consultation_model.dart';
import 'package:eatvio_app/features/personal_diet_suggestion/services/personal_diet_suggestion_service.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:mockito/annotations.dart';
import 'package:mockito/mockito.dart';
import '../../../fixtures/fixture_reader.dart';
import 'personal_diet_suggestion_service_test.mocks.dart';
@GenerateNiceMocks([MockSpec<Dio>()])
void main() {
group('PersonalDietSuggestionService', () {
late PersonalDietSuggestionService personalDietSuggestionService;
late MockDio mockDio;
setUp(() {
mockDio = MockDio();
personalDietSuggestionService = PersonalDietSuggestionService(mockDio);
});
test('getConsultationWithPersonalDiets - возвращает консультации с персональными диетами', () async {
final json = FixtureReader.readAsMap('consultations/consultation_pagination_response.json');
final response = Response(
data: json,
statusCode: 200,
requestOptions: RequestOptions(path: '/api/consultations'),
);
when(mockDio.get(any, queryParameters: anyNamed('queryParameters')))
.thenAnswer((_) async => response);
final result = await personalDietSuggestionService.getConsultationWithPersonalDiets();
expect(result, isA<ConsultationPaginationModel>());
verify(mockDio.get(any, queryParameters: anyNamed('queryParameters'))).called(1);
});
test('attachPersonalDiet - прикрепляет персональную диету', () async {
const consultationId = 1;
const dietId = 2;
final response = Response(
data: {},
statusCode: 200,
requestOptions: RequestOptions(path: '/api/chosen_plans/$consultationId/attach_diet'),
);
when(mockDio.post(any, data: anyNamed('data')))
.thenAnswer((_) async => response);
await personalDietSuggestionService.attachPersonalDiet(consultationId: consultationId, dietId: dietId);
verify(mockDio.post(any, data: anyNamed('data'))).called(1);
});
test('reattachPersonalDiet - переприкрепляет персональную диету', () async {
const consultationId = 1;
const dietId = 2;
final response = Response(
data: {},
statusCode: 200,
requestOptions: RequestOptions(path: '/api/chosen_plans/$consultationId/re_attach_diet'),
);
when(mockDio.post(any, data: anyNamed('data')))
.thenAnswer((_) async => response);
await personalDietSuggestionService.reattachPersonalDiet(consultationId: consultationId, dietId: dietId);
verify(mockDio.post(any, data: anyNamed('data'))).called(1);
});
});
}

View File

@@ -1,5 +1,3 @@
import 'package:eatvio_app/core/models/pagination_model.dart';
import 'package:eatvio_app/features/feed/models/diets_pagination_model.dart';
import 'package:eatvio_app/features/feed/models/plan_pagination_model.dart';
import 'package:eatvio_app/features/plans/repositories/plans_repository.dart';
import 'package:eatvio_app/features/plans/services/plans_service.dart';
@@ -7,6 +5,7 @@ import 'package:flutter_test/flutter_test.dart';
import 'package:mockito/annotations.dart';
import 'package:mockito/mockito.dart';
import '../../../fixtures/fixture_reader.dart';
import 'plans_repository_test.mocks.dart';
@GenerateNiceMocks([MockSpec<PlansService>()])
@@ -22,45 +21,15 @@ void main() {
test('getPlansBySlug - успешное получение планов', () async {
const slug = 'test-author';
const plan = 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 details',
packetsCount: 3,
author: Author(
authorSlug: 'test-author',
authorName: 'Author Name',
authorProfileIcon: 'https://example.com/icon.jpg',
authorIsMe: false,
isEntitySubscribedByMe: null,
authorPlaceInRating: null,
),
totalLikes: 10,
totalViews: 100,
totalComments: 5,
isFavorite: false,
minPriceOfOptions: 1000.0,
maxPriceOfOptions: 2000.0,
wasLikedByMe: false,
);
const pagination = PlanPaginationModel(
data: [plan],
links: Links(first: 'https://example.com?page=1', last: 'https://example.com?page=1', prev: null, next: null),
meta: Meta(currentPage: 1, from: 1, lastPage: 1, links: [], perPage: 10, to: 1, total: 1),
);
final paginationJson = FixtureReader.readAsMap('feed/plan_pagination_response.json');
final pagination = PlanPaginationModel.fromJson(paginationJson);
when(mockService.getPlansBySlug(author: slug)).thenAnswer((_) async => pagination);
final result = await repository.getPlansBySlug(slug);
expect(result.length, 1);
expect(result.first.slug, 'test-plan');
expect(result.first.slug, 'weight-loss-plan');
verify(mockService.getPlansBySlug(author: slug)).called(1);
});
});

View File

@@ -1,4 +1,3 @@
import 'package:eatvio_app/features/feed/models/recipes_model.dart';
import 'package:eatvio_app/features/recipe/models/my_recipe_model.dart';
import 'package:eatvio_app/features/recipe/repositories/my_recipes_repository.dart';
import 'package:eatvio_app/features/recipe/services/my_recipes_service.dart';
@@ -6,6 +5,7 @@ import 'package:flutter_test/flutter_test.dart';
import 'package:mockito/annotations.dart';
import 'package:mockito/mockito.dart';
import '../../../fixtures/fixture_reader.dart';
import 'my_recipes_repository_test.mocks.dart';
@GenerateNiceMocks([MockSpec<MyRecipesService>()])
@@ -18,29 +18,11 @@ void main() {
mockMyRecipesService = MockMyRecipesService();
myRecipesRepository = MyRecipesRepository(myRecipesService: mockMyRecipesService);
});
// cancel_bottom_sheet
// dev_tools
test('getMyRecipes returns list of recipes', () async {
const expectedPagination = MyRecipePaginationModel(
data: [
MyRecipeModel(
id: 1,
image: 'https://someurl.com/img.jpg',
state: 'published',
cookingTime: 30,
activeCookingTime: 20,
description: 'Test recipe description',
steps: [
Step(image: 'https://someurl.com/step1.jpg', description: 'Step 1 description'),
],
videoUrl: 'https://someurl.com/video.mp4',
title: 'Test Recipe',
slug: 'test-recipe',
calories: 250.0,
likesCount: 5,
viewsCount: 10,
),
],
);
final json = FixtureReader.readAsMap('recipes/my_recipe_pagination_response.json');
final expectedPagination = MyRecipePaginationModel.fromJson(json);
when(mockMyRecipesService.getMyRecipes()).thenAnswer((_) async => expectedPagination);
@@ -68,42 +50,26 @@ void main() {
});
test('getMyRecipes returns multiple recipes', () async {
const expectedPagination = MyRecipePaginationModel(
data: [
MyRecipeModel(
id: 1,
image: 'https://someurl.com/img1.jpg',
state: 'published',
cookingTime: 30,
activeCookingTime: 20,
description: 'First recipe',
steps: null,
videoUrl: null,
title: 'First Recipe',
slug: 'first-recipe',
calories: 250.0,
likesCount: 5,
viewsCount: 10,
),
MyRecipeModel(
id: 2,
image: 'https://someurl.com/img2.jpg',
state: 'draft',
cookingTime: 45,
activeCookingTime: 30,
description: 'Second recipe',
steps: [
Step(image: 'https://someurl.com/step1.jpg', description: 'Step 1'),
],
videoUrl: 'https://someurl.com/video.mp4',
title: 'Second Recipe',
slug: 'second-recipe',
calories: 350.0,
likesCount: 8,
viewsCount: 15,
),
],
);
final json = FixtureReader.readAsMap('recipes/my_recipe_pagination_response.json');
final paginationData = List<Map<String, dynamic>>.from(json['data'] as List);
final secondRecipe = {
'id': 2,
'image': 'https://someurl.com/img2.jpg',
'state': 'draft',
'cooking_time': 45,
'active_time': 30,
'description_md': 'Second recipe',
'steps': [{'image': 'https://someurl.com/step1.jpg', 'description_md': 'Step 1'}],
'video_url': 'https://someurl.com/video.mp4',
'title': 'Second Recipe',
'slug': 'second-recipe',
'energy_per_serving': 350.0,
'total_likes': 8,
'total_views': 15,
};
paginationData.add(secondRecipe);
final multiJson = {'data': paginationData};
final expectedPagination = MyRecipePaginationModel.fromJson(multiJson);
when(mockMyRecipesService.getMyRecipes()).thenAnswer((_) async => expectedPagination);
@@ -111,7 +77,7 @@ void main() {
expect(result, isA<List<MyRecipeModel>>());
expect(result.length, 2);
expect(result.first.title, 'First Recipe');
expect(result.first.title, 'Test Recipe');
expect(result.last.title, 'Second Recipe');
verify(mockMyRecipesService.getMyRecipes()).called(1);
});

View File

@@ -0,0 +1,60 @@
import 'package:eatvio_app/features/registration/models/location_model.dart';
import 'package:eatvio_app/features/registration/services/registration_service.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:mockito/annotations.dart';
import 'package:mockito/mockito.dart';
import '../../../fixtures/fixture_reader.dart';
import 'registration_service_test.mocks.dart';
@GenerateNiceMocks([MockSpec<RegistrationService>()])
void main() {
group('RegistrationService', () {
late MockRegistrationService mockRegistrationService;
setUp(() {
mockRegistrationService = MockRegistrationService();
});
test('register - регистрирует нового пользователя', () async {
final expectedResponse = {'success': 'true', 'message': 'User registered'};
final registrationData = {'first_name': 'John', 'last_name': 'Doe', 'email': 'john@example.com', 'password': 'password123'};
when(mockRegistrationService.register(sheet: registrationData)).thenAnswer((_) async => expectedResponse);
final result = await mockRegistrationService.register(sheet: registrationData);
expect(result, isA<Map<String, String>>());
verify(mockRegistrationService.register(sheet: registrationData)).called(1);
});
test('getLocationsByAddress - возвращает локации по адресу', () async {
const query = 'Москва';
final locationJson = FixtureReader.readAsMap('registration/location_response.json');
final expectedLocation = LocationModel.fromJson(locationJson);
when(mockRegistrationService.getLocationsByAddress(query: query)).thenAnswer((_) async => expectedLocation);
final result = await mockRegistrationService.getLocationsByAddress(query: query);
expect(result, isA<LocationModel>());
expect(result.locations.length, 2);
verify(mockRegistrationService.getLocationsByAddress(query: query)).called(1);
});
test('getLocationsByCoordinate - возвращает локации по координатам', () async {
const latitude = '55.7558';
const longitude = '37.6173';
final locationJson = FixtureReader.readAsMap('registration/location_response.json');
final expectedLocation = LocationModel.fromJson(locationJson);
when(mockRegistrationService.getLocationsByCoordinate(latitude: latitude, longitude: longitude)).thenAnswer((_) async => expectedLocation);
final result = await mockRegistrationService.getLocationsByCoordinate(latitude: latitude, longitude: longitude);
expect(result, isA<LocationModel>());
expect(result.locations.length, 2);
verify(mockRegistrationService.getLocationsByCoordinate(latitude: latitude, longitude: longitude)).called(1);
});
});
}

View File

@@ -0,0 +1,13 @@
[
{
"date": "2024-01-15",
"is_current_day_included_in_the_chosen_diet_progression": true,
"diary": null
},
{
"date": "2024-01-16",
"is_current_day_included_in_the_chosen_diet_progression": false,
"diary": null
}
]

View File

@@ -0,0 +1,11 @@
{
"id": 1,
"data": "Test message",
"media_data": null,
"author_id": 1,
"updated_at": "2024-01-01T12:00:00Z",
"read_by_to_user": false,
"is_author_message_auth_user": true,
"room_id": "chat-1"
}

View File

@@ -0,0 +1,16 @@
{
"id": 2,
"data": "Message with attachment",
"media_data": [
{
"type": "image",
"url": "https://example.com/image.jpg"
}
],
"author_id": 1,
"updated_at": "2024-01-01T12:05:00Z",
"read_by_to_user": false,
"is_author_message_auth_user": false,
"room_id": "chat-1"
}

View File

@@ -0,0 +1,28 @@
{
"data": [
{
"id": 1,
"data": "First message",
"media_data": null,
"author_id": 1,
"updated_at": "2024-01-01T12:00:00Z",
"read_by_to_user": false,
"is_author_message_auth_user": true,
"room_id": "chat-1"
},
{
"id": 2,
"data": "Second message",
"media_data": null,
"author_id": 2,
"updated_at": "2024-01-01T12:05:00Z",
"read_by_to_user": true,
"is_author_message_auth_user": false,
"room_id": "chat-1"
}
],
"meta": {
"last_page": 1
}
}

View File

@@ -0,0 +1,64 @@
{
"data": [
{
"id": "chat-1",
"last_message": {
"id": 1,
"data": "Last message",
"media_data": null,
"author_id": 1,
"updated_at": "2024-01-01T12:00:00Z",
"read_by_to_user": false,
"is_author_message_auth_user": true,
"room_id": "chat-1"
},
"users": {
"from_chat_user": {
"id": 1,
"name": "User 1",
"profile_photo_path": null,
"profile_photo_url": "https://example.com/user1.jpg"
},
"to_chat_user": {
"id": 2,
"name": "User 2",
"profile_photo_path": null,
"profile_photo_url": "https://example.com/user2.jpg"
}
},
"unread_messages_count": 5,
"chosen_plan": null
},
{
"id": "chat-2",
"last_message": null,
"users": {
"from_chat_user": {
"id": 1,
"name": "User 1",
"profile_photo_path": null,
"profile_photo_url": "https://example.com/user1.jpg"
},
"to_chat_user": {
"id": 3,
"name": "User 3",
"profile_photo_path": null,
"profile_photo_url": "https://example.com/user3.jpg"
}
},
"unread_messages_count": 0,
"chosen_plan": null
}
],
"number_of_unread_chat_rooms": 1,
"meta": {
"current_page": 1,
"from": 1,
"last_page": 1,
"links": [],
"per_page": 10,
"to": 2,
"total": 2
}
}

View File

@@ -0,0 +1,23 @@
{
"id": "chat-1",
"chat_room_setting": {
"room_name": "Test Chat Room",
"state": "active"
},
"users": {
"from_chat_user": {
"id": 1,
"name": "User 1",
"slug": "user-1",
"profile_photo_url": "https://example.com/user1.jpg"
},
"to_chat_user": {
"id": 2,
"name": "User 2",
"slug": "user-2",
"profile_photo_url": "https://example.com/user2.jpg"
}
},
"chosen_plan_id": null
}

View File

@@ -0,0 +1,5 @@
{
"name": "Test Chat Room",
"state": "active"
}

View File

@@ -0,0 +1,69 @@
{
"id": "chat-1",
"chat_room_setting": {
"room_name": "Test Chat Room",
"state": "active"
},
"users": {
"from_chat_user": {
"id": 1,
"name": "User 1",
"slug": "user-1",
"profile_photo_url": "https://example.com/user1.jpg"
},
"to_chat_user": {
"id": 2,
"name": "User 2",
"slug": "user-2",
"profile_photo_url": "https://example.com/user2.jpg"
}
},
"chosen_plan_id": 1,
"chosen_plan": {
"id": 1,
"option_type": "1",
"start_date": "2024-01-01T00:00:00Z",
"last_state": "active",
"chat_id": "chat-1",
"consultant_id": 1,
"plan": {
"id": 1,
"slug": "test-plan",
"name": "Test Plan",
"image": "https://example.com/plan.jpg",
"duration": 30,
"state": "active",
"type": {
"fit": true,
"slim": false,
"behavior": false,
"wellness": false
},
"description_md": "Plan description",
"packets_count": 1,
"packet1_options": {
"items": ["Item 1", "Item 2"],
"price": 1500.0,
"short": "Option 1",
"description": "Description",
"has_personal_diet": false
},
"packet2_options": null,
"packet3_options": null,
"author": {
"author_slug": "author-1",
"author_name": "Author Name",
"author_profile_icon": "https://example.com/author.jpg",
"author_is_me": false
},
"total_likes": 10,
"total_views": 100,
"total_comments": 5,
"is_favorite": false,
"min_price_of_options": 1000.0,
"max_price_of_options": 2000.0,
"was_liked_by_me": false
}
}
}

View File

@@ -0,0 +1,7 @@
{
"id": 1,
"name": "Test User",
"slug": "test-user",
"profile_photo_url": "https://example.com/avatar.jpg"
}

View File

@@ -0,0 +1,47 @@
{
"id": 1,
"option_type": "1",
"start_date": "2024-01-01T00:00:00Z",
"last_state": "in_coordination",
"chat_id": "chat-1",
"consultant_id": 1,
"plan": {
"id": 1,
"slug": "test-plan",
"name": "Test Plan",
"image": "https://example.com/plan.jpg",
"duration": 30,
"state": "active",
"type": {
"fit": true,
"slim": false,
"behavior": false,
"wellness": false
},
"description_md": "Plan description",
"packets_count": 1,
"packet1_options": {
"items": ["Item 1", "Item 2"],
"price": 1500.0,
"short": "Option 1",
"description_md": "Description",
"has_personal_diet": false
},
"packet2_options": null,
"packet3_options": null,
"author": {
"author_slug": "author-1",
"author_name": "Author Name",
"author_profile_icon": "https://example.com/author.jpg",
"author_is_me": false
},
"total_likes": 10,
"total_views": 100,
"total_comments": 5,
"is_favorite": false,
"min_price_of_options": 1000.0,
"max_price_of_options": 2000.0,
"was_liked_by_me": false
}
}

View File

@@ -0,0 +1,4 @@
{
"checkout_url": "https://example.com/checkout/payment-123"
}

View File

@@ -0,0 +1,4 @@
{
"description": "Test complaint description"
}

View File

@@ -0,0 +1,8 @@
{
"key": "test-key-123",
"host": "test-host.example.com",
"port": "443",
"cluster": "eu",
"user_id": 1
}

View File

@@ -0,0 +1,33 @@
{
"data": [
{
"id": 1,
"last_state": "in_progress",
"plan_title": "Weight Loss Plan",
"user_name": "John Doe",
"user_slug": "john-doe",
"consultant_payment": 100.0,
"duration": 30,
"current_diary_day": 5,
"user_profile_photo_url": "photo.jpg",
"consultation_option_price": 50,
"start_date": "2023-01-01",
"end_date": "2023-01-31",
"consultant_id": 10,
"diaries": [
{
"id": 1,
"state": "started",
"date": "2023-01-01"
},
{
"id": 2,
"state": "finished",
"date": "2023-01-02"
}
],
"personal_diet_id": 5
}
]
}

View File

@@ -0,0 +1,7 @@
{
"total": 10,
"in_progress": 5,
"finished": 3,
"canceled": 2
}

View File

@@ -0,0 +1,38 @@
{
"id": 1,
"date": "2024-01-15",
"wakeup": "07:00",
"retire": "23:00",
"closed": 0,
"comment": "",
"state": {
"has_chosen_diet": false,
"has_chosen_plan": false,
"diary_state": null
},
"meals": [
{
"id": 1,
"time": "12:00",
"type_no": 1,
"satiety": 0,
"mood": 0,
"portions": [
{
"id": 1,
"product_nutritional_value_id": 10,
"product_name": "Яблоко",
"quantity": 2,
"portion": "100г",
"from_diet": false,
"state": "eaten"
}
],
"photos": []
}
],
"chosen_plan_id": null,
"day_of_chosen_diet": null,
"chosen_diet": null
}

View File

@@ -0,0 +1,40 @@
{
"diary": {
"id": 1,
"date": "2024-01-15",
"wakeup": "07:00",
"retire": "23:00",
"closed": 0,
"comment": "",
"state": {
"has_chosen_diet": false,
"has_chosen_plan": false,
"diary_state": null
},
"meals": [
{
"id": 1,
"time": "12:00",
"type_no": 1,
"satiety": 0,
"mood": 0,
"portions": [
{
"id": 1,
"product_nutritional_value_id": 10,
"product_name": "Яблоко",
"quantity": 2,
"portion": "100г",
"from_diet": false,
"state": "eaten"
}
],
"photos": []
}
],
"chosen_plan_id": null,
"day_of_chosen_diet": null,
"chosen_diet": null
}
}

View File

@@ -0,0 +1,18 @@
{
"data": [
{
"id": 10,
"name": "Яблоко",
"portion_mass_gr": 100,
"energy_on_100gr": 52.0,
"proteins_on_100gr": 0.3,
"fats_on_100gr": 0.2,
"carbohydrates_on_100gr": 14.0,
"energy_on_portion": 52.0,
"proteins_on_portion": 0.3,
"fats_on_portion": 0.2,
"carbohydrates_on_portion": 14.0
}
]
}

View File

@@ -0,0 +1,15 @@
{
"dailyNutritionIntake": {
"energy": 2000.0,
"proteins": 150.0,
"fats": 80.0,
"carbohydrates": 250.0
},
"dailyNutritionRecommendation": {
"energy": 2200.0,
"proteins": 160.0,
"fats": 90.0,
"carbohydrates": 270.0
}
}

View File

@@ -0,0 +1,5 @@
{
"total_likers": 10,
"is_liked": true
}

31
test/fixtures/diets/diet_response.json vendored Normal file
View File

@@ -0,0 +1,31 @@
{
"id": 1,
"slug": "test-diet",
"name": "Test Diet",
"image": "https://example.com/image.jpg",
"duration": 7,
"state": "active",
"type": {
"veg": true,
"light": false,
"carb": false,
"meat": false
},
"description_md": "Test details",
"daily_schedule": {},
"author": {
"author_slug": "author",
"author_name": "Author Name",
"author_profile_icon": "https://example.com/icon.jpg",
"author_is_me": false,
"is_entity_subscribed_by_me": null,
"author_place_in_rating": null
},
"total_likes": 10,
"total_views": 100,
"total_comments": 5,
"was_liked_by_me": false,
"is_favorite": false,
"daily_nutrition": []
}

View File

@@ -0,0 +1,32 @@
{
"data": [
{
"id": 1,
"author_name": "User 1",
"author_slug": "user-1",
"author_profile_icon": "https://example.com/user1.jpg",
"body": "Great post!",
"children_comments": [],
"created_at": "2024-01-15T12:00:00Z"
}
],
"links": {
"first": "http://localhost/api/comments?page=1",
"last": "http://localhost/api/comments?page=1",
"prev": null,
"next": null
},
"meta": {
"current_page": 1,
"from": 1,
"last_page": 1,
"links": [],
"path": "http://localhost/api/comments",
"per_page": 10,
"to": 1,
"total": 1,
"total_min_price": null,
"total_max_price": null
}
}

View File

@@ -0,0 +1,32 @@
{
"data": [
{
"slug": "consultant-1",
"name": "Anna Ivanova",
"additional_info": "Test consultant description",
"rating_place": 1,
"total_scores": 5,
"profile_photo_url": "https://example.com/consultant1.jpg",
"badges": []
}
],
"links": {
"first": "http://localhost/api/consultants?page=1",
"last": "http://localhost/api/consultants?page=1",
"prev": null,
"next": null
},
"meta": {
"current_page": 1,
"from": 1,
"last_page": 1,
"links": [],
"path": "http://localhost/api/consultants",
"per_page": 10,
"to": 1,
"total": 1,
"total_min_price": null,
"total_max_price": null
}
}

View File

@@ -0,0 +1,53 @@
{
"data": [
{
"id": 1,
"slug": "keto-diet",
"name": "Keto Diet",
"image": "https://example.com/keto.jpg",
"duration": 30,
"state": "active",
"type": {
"light": false,
"veg": false,
"carb": false,
"meat": true
},
"description_md": "Keto diet description",
"daily_schedule": {},
"author": {
"author_slug": "nutritionist-1",
"author_name": "Nutritionist Name",
"author_profile_icon": "https://example.com/nutritionist.jpg",
"author_is_me": false,
"is_entity_subscribed_by_me": null,
"author_place_in_rating": null
},
"total_likes": 50,
"total_views": 500,
"total_comments": 25,
"was_liked_by_me": false,
"is_favorite": false,
"daily_nutrition": []
}
],
"links": {
"first": "http://localhost/api/diets?page=1",
"last": "http://localhost/api/diets?page=1",
"prev": null,
"next": null
},
"meta": {
"current_page": 1,
"from": 1,
"last_page": 1,
"links": [],
"path": "http://localhost/api/diets",
"per_page": 10,
"to": 1,
"total": 1,
"total_min_price": null,
"total_max_price": null
}
}

View File

@@ -0,0 +1,23 @@
{
"id": 1,
"state": "published",
"image": "https://example.com/image.jpg",
"description": "Описание поста",
"author": {
"author_slug": "author-slug",
"author_name": "Автор",
"author_profile_icon": "https://example.com/photo.jpg",
"author_is_me": false,
"is_entity_subscribed_by_me": null,
"author_place_in_rating": null
},
"video_url": "",
"created_at": "2024-01-15T12:00:00Z",
"updated_at": "2024-01-15T12:00:00Z",
"title": "Заголовок",
"total_likes": 10,
"total_views": 100,
"total_comments": 5,
"was_liked_by_me": false
}

View File

@@ -0,0 +1,39 @@
{
"data": [
{
"id": 1,
"state": "published",
"image": "https://example.com/image.jpg",
"description": "Описание поста",
"author": {
"author_slug": "author-slug",
"author_name": "Автор",
"author_profile_icon": "https://example.com/photo.jpg",
"author_is_me": false,
"is_entity_subscribed_by_me": null,
"author_place_in_rating": null
},
"video_url": "",
"created_at": "2024-01-15T12:00:00Z",
"updated_at": "2024-01-15T12:00:00Z",
"title": "Заголовок",
"total_likes": 10,
"total_views": 100,
"total_comments": 5,
"was_liked_by_me": false
}
],
"meta": {
"current_page": 1,
"from": 1,
"last_page": 1,
"links": [],
"path": "http://localhost/api/blog-posts",
"per_page": 10,
"to": 1,
"total": 1,
"total_min_price": null,
"total_max_price": null
}
}

View File

@@ -0,0 +1,63 @@
{
"data": [
{
"id": 1,
"slug": "weight-loss-plan",
"name": "Weight Loss Plan",
"image": "https://example.com/plan.jpg",
"duration": 30,
"state": "active",
"type": {
"fit": false,
"slim": true,
"behavior": false,
"wellness": false
},
"description_md": "Weight loss plan description",
"packets_count": 3,
"packet1_options": {
"items": ["Item 1", "Item 2"],
"price": 1500.0,
"short": "Option 1",
"description_md": "Description",
"has_personal_diet": false
},
"packet2_options": null,
"packet3_options": null,
"author": {
"author_slug": "consultant-1",
"author_name": "Consultant Name",
"author_profile_icon": "https://example.com/consultant.jpg",
"author_is_me": false,
"is_entity_subscribed_by_me": null,
"author_place_in_rating": null
},
"total_likes": 100,
"total_views": 1000,
"total_comments": 50,
"is_favorite": false,
"min_price_of_options": 1000.0,
"max_price_of_options": 5000.0,
"was_liked_by_me": false
}
],
"links": {
"first": "http://localhost/api/plans?page=1",
"last": "http://localhost/api/plans?page=1",
"prev": null,
"next": null
},
"meta": {
"current_page": 1,
"from": 1,
"last_page": 1,
"links": [],
"path": "http://localhost/api/plans",
"per_page": 10,
"to": 1,
"total": 1,
"total_min_price": null,
"total_max_price": null
}
}

View File

@@ -0,0 +1,53 @@
{
"recipes_list": [
{
"id": 1,
"image": "https://example.com/recipe.jpg",
"state": "published",
"cooking_time": 30,
"active_time": 20,
"ingredients": [
{
"name": "Pasta",
"unit": "g",
"portion": "200g",
"product_nutritional_id": "1"
}
],
"description_md": "Test recipe description",
"steps": [
{
"description": "Step 1",
"image": "https://example.com/step1.jpg"
}
],
"video_url": "https://example.com/video.mp4",
"created_at": "2024-01-15T12:00:00Z",
"updated_at": "2024-01-15T12:00:00Z",
"title": "Pasta Recipe",
"type": "recipe",
"slug": "pasta-recipe",
"total_comments": 5,
"was_liked_by_me": false,
"is_favorite": false,
"energy_per_serving": 350.0,
"servings": 4,
"total_likes": 20,
"total_views": 150,
"tags": [
{
"name": "Italian"
}
],
"author": {
"author_slug": "chef-1",
"author_name": "Chef Name",
"author_profile_icon": "https://example.com/chef.jpg",
"author_is_me": false,
"is_entity_subscribed_by_me": null,
"author_place_in_rating": null
}
}
]
}

View File

@@ -0,0 +1,16 @@
{
"notifications": [
{
"type": "chosen_plan_started_to_client_notification",
"plan_name": "Test Plan",
"plan_id": 1,
"is_read": false,
"created_at": "2024-01-15T12:00:00Z"
}
],
"pagination": {
"current_page": 1,
"last_page": 1
}
}

35
test/fixtures/plans/plan_response.json vendored Normal file
View File

@@ -0,0 +1,35 @@
{
"id": 1,
"slug": "test-plan",
"name": "Test Plan",
"image": "https://example.com/image.jpg",
"duration": 7,
"state": "active",
"type": {
"fit": true,
"slim": false,
"behavior": false,
"wellness": false
},
"description_md": "Test details",
"packets_count": 3,
"packet1_options": null,
"packet2_options": null,
"packet3_options": null,
"author": {
"author_slug": "test-author",
"author_name": "Author Name",
"author_profile_icon": "https://example.com/icon.jpg",
"author_is_me": false,
"is_entity_subscribed_by_me": null,
"author_place_in_rating": null
},
"total_likes": 10,
"total_views": 100,
"total_comments": 5,
"is_favorite": false,
"min_price_of_options": 1000.0,
"max_price_of_options": 2000.0,
"was_liked_by_me": false
}

View File

@@ -0,0 +1,25 @@
{
"data": [
{
"id": 1,
"image": "https://someurl.com/img.jpg",
"state": "published",
"cooking_time": 30,
"active_time": 20,
"description_md": "Test recipe description",
"steps": [
{
"image": "https://someurl.com/step1.jpg",
"description_md": "Step 1 description"
}
],
"video_url": "https://someurl.com/video.mp4",
"title": "Test Recipe",
"slug": "test-recipe",
"energy_per_serving": 250.0,
"total_likes": 5,
"total_views": 10
}
]
}

View File

@@ -0,0 +1,21 @@
{
"id": 1,
"image": "https://someurl.com/img.jpg",
"state": "published",
"cooking_time": 30,
"active_time": 20,
"description_md": "Test recipe description",
"steps": [
{
"image": "https://someurl.com/step1.jpg",
"description_md": "Step 1 description"
}
],
"video_url": "https://someurl.com/video.mp4",
"title": "Test Recipe",
"slug": "test-recipe",
"energy_per_serving": 250.0,
"total_likes": 5,
"total_views": 10
}

View File

@@ -0,0 +1,8 @@
{
"locations": [
"Москва, Россия",
"Москва, Московская область, Россия"
],
"response_body": "{\"results\": []}"
}