Merge remote-tracking branch 'upstream/main' into issue-975

This commit is contained in:
misha
2026-07-15 15:17:44 +03:00
74 changed files with 3880 additions and 251 deletions

View File

@@ -0,0 +1,22 @@
import 'package:eatvio_app/features/chat/models/order_id_to_conversation_model.dart';
import 'package:flutter_test/flutter_test.dart';
import '../../../fixtures/fixture_reader.dart';
void main() {
group('OrderIdToConversationModel', () {
test('fromJson создаёт модель из JSON фикстуры', () {
final json = FixtureReader.readAsMap(
'chat/payments/order_id_to_chat_uuid_response.json',
);
final model = OrderIdToConversationModel.fromJson(json);
expect(model.chosenPlanId, 12);
expect(
model.conversationUuid,
'fbd81429-8019-499a-80e8-e3933cc4d872',
);
});
});
}

View File

@@ -1,25 +1,47 @@
import 'package:eatvio_app/features/chat/models/payment_model.dart';
import 'package:flutter_test/flutter_test.dart';
import '../../../fixtures/fixture_reader.dart';
void main() {
group('PaymentModel', () {
test('создает PaymentModel с правильными значениями', () {
final model = PaymentModel(
paymentUrl: 'https://example.com/payment',
);
final model = PaymentModel(paymentUrl: 'https://example.com/payment');
expect(model.paymentUrl, 'https://example.com/payment');
});
test('fromJson создает PaymentModel из JSON', () {
final json = {
'checkout_url': 'https://example.com/payment',
};
final json = {'checkout_url': 'https://example.com/payment'};
final model = PaymentModel.fromJson(json);
expect(model.paymentUrl, 'https://example.com/payment');
});
test(
'fromJson парсит ответ alfa-bank (checkout_url, order_id, payment_provider)',
() {
final json = FixtureReader.readAsMap(
'chat/payments/payment_response_alfa_bank.json',
);
final model = PaymentModel.fromJson(json);
expect(model.paymentUrl, 'https://qr.nspk.ru/ASDFASDFASDFASDF');
expect(model.orderId, 'alfa_c29_k15138_t1712345678_r1234');
expect(model.paymentProvider, 'alfa-bank');
},
);
test('fromJson парсит mock-ответ (checkout_url без order_id)', () {
final json = FixtureReader.readAsMap('chat/payments/payment_response.json');
final model = PaymentModel.fromJson(json);
expect(model.paymentUrl, 'https://example.com/checkout/payment-123');
expect(model.orderId, isNull);
expect(model.paymentProvider, isNull);
});
});
}

View File

@@ -11,6 +11,7 @@ import 'package:eatvio_app/features/chat/presentation/bloc/chat_room_cubit/chat_
import 'package:eatvio_app/features/chat/repositories/chat_repository.dart';
import 'package:eatvio_app/features/my_finance/repositories/cards_repository.dart';
import 'package:eatvio_app/features/my_finance/models/card_model.dart';
import 'package:eatvio_app/features/chat/models/order_id_to_conversation_model.dart';
import 'package:eatvio_app/features/chat/models/payment_model.dart';
import 'package:eatvio_app/features/feed/models/diets_pagination_model.dart';
import 'package:eatvio_app/features/feed/models/plan_pagination_model.dart';
@@ -102,6 +103,89 @@ void main() {
// Let's check that at least the repository methods were called
verify(mockChatRepository.getChatRoom(uuid)).called(1);
verify(mockChatRepository.getChatMessages(uuid, 1)).called(1);
verifyNever(
mockChatRepository.resolveOrderIdToConversation(orderId: anyNamed('orderId')),
);
});
test('initChat - с orderId резолвит conversation и инициализирует чат', () async {
const orderId = 'alfa_c29_k15138_t1712345678_r1234';
const conversationUuid = 'fbd81429-8019-499a-80e8-e3933cc4d872';
const chosenPlanId = 12;
final resolved = OrderIdToConversationModel(
chosenPlanId: chosenPlanId,
conversationUuid: conversationUuid,
);
final chatRoomWithPlan = testChatRoom.copyWith(chosenPlanId: chosenPlanId);
const testPlan = PlanModel(
id: 1,
slug: 'test-plan',
name: 'Test Plan',
image: 'https://example.com/image.jpg',
duration: 7,
state: 'active',
type: PlanType(fit: true, slim: false, behavior: false, wellness: false),
details: 'Test details',
packetsCount: 3,
author: Author(
authorSlug: 'author',
authorName: 'Author Name',
authorProfileIcon: 'https://example.com/icon.jpg',
authorIsMe: false,
),
totalLikes: 10,
totalViews: 100,
totalComments: 5,
isFavorite: false,
minPriceOfOptions: 1000,
maxPriceOfOptions: 2000,
wasLikedByMe: false,
);
final chosenPlan = ChosenPlanModel(
id: chosenPlanId,
optionType: 'options1',
startDate: DateTime.now(),
chosenPlanState: ChosenPlanStateEnum.statePendingPayment,
chatId: 'chat-1',
consultantId: 2,
plan: testPlan,
);
when(
mockChatRepository.resolveOrderIdToConversation(orderId: orderId),
).thenAnswer((_) async => resolved);
when(mockChatRepository.getChatRoom(conversationUuid)).thenAnswer((_) async => chatRoomWithPlan);
when(mockChatRepository.getChatMessages(conversationUuid, 1)).thenAnswer((_) async => testChatMessages);
when(mockChatRepository.getChosenPlan(id: chosenPlanId)).thenAnswer((_) async => chosenPlan);
when(mockWsManager.client).thenReturn(null);
when(mockWsManager.initPrivateDirectChatChannel(any)).thenAnswer((_) async => Future.value());
when(mockWsManager.subscribeDirectChatChannel()).thenReturn(null);
when(mockWsManager.directChatStream).thenReturn(null);
when(mockWsManager.clientTypingStream).thenReturn(null);
await chatRoomCubit.initChat(null, orderId: orderId);
await Future.delayed(const Duration(milliseconds: 200));
verify(mockChatRepository.resolveOrderIdToConversation(orderId: orderId)).called(1);
verify(mockChatRepository.getChatRoom(conversationUuid)).called(1);
verify(mockChatRepository.getChosenPlan(id: chosenPlanId)).called(1);
verify(mockChatRepository.getChatMessages(conversationUuid, 1)).called(1);
expect(chatRoomCubit.state, isA<ChatRoomStateLoaded>());
final loaded = chatRoomCubit.state as ChatRoomStateLoaded;
expect(loaded.chatRoom.chosenPlan?.id, chosenPlanId);
});
test('initChat - при ошибке resolve не вызывает getChatRoom', () async {
const orderId = 'alfa_c29_k15138_t1712345678_r1234';
when(
mockChatRepository.resolveOrderIdToConversation(orderId: orderId),
).thenThrow(Exception('Resolve failed'));
await chatRoomCubit.initChat(null, orderId: orderId);
await Future.delayed(const Duration(milliseconds: 100));
expect(chatRoomCubit.state, isA<ChatRoomStateError>());
verifyNever(mockChatRepository.getChatRoom(any));
});
test('initChat - обрабатывает ошибку', () async {
@@ -678,7 +762,7 @@ void main() {
when(mockChatRepository.getChatRoom(uuid)).thenAnswer((_) async => chatRoomWithPlan);
when(mockChatRepository.getChatMessages(uuid, 1)).thenAnswer((_) async => testChatMessages);
when(mockChatRepository.getChosenPlan(id: planId)).thenAnswer((_) async => chosenPlan);
when(mockChatRepository.getPaymentLink(id: planId)).thenAnswer((_) async => PaymentModel(paymentUrl: paymentUrl));
when(mockChatRepository.getPaymentLink(id: planId, paymentProvider: 'alfa-bank')).thenAnswer((_) async => PaymentModel(paymentUrl: paymentUrl));
when(mockWsManager.client).thenReturn(null);
when(mockWsManager.initPrivateDirectChatChannel(any)).thenAnswer((_) async => Future.value());
when(mockWsManager.subscribeDirectChatChannel()).thenReturn(null);
@@ -691,7 +775,7 @@ void main() {
final result = await chatRoomCubit.getPaymentLink();
expect(result, paymentUrl);
verify(mockChatRepository.getPaymentLink(id: planId)).called(1);
verify(mockChatRepository.getPaymentLink(id: planId, paymentProvider: 'alfa-bank')).called(1);
});
test('getPaymentLink - обрабатывает ошибку', () async {
@@ -730,7 +814,7 @@ void main() {
when(mockChatRepository.getChatRoom(uuid)).thenAnswer((_) async => chatRoomWithPlan);
when(mockChatRepository.getChatMessages(uuid, 1)).thenAnswer((_) async => testChatMessages);
when(mockChatRepository.getChosenPlan(id: planId)).thenAnswer((_) async => chosenPlan);
when(mockChatRepository.getPaymentLink(id: planId)).thenThrow(Exception('Payment error'));
when(mockChatRepository.getPaymentLink(id: planId, paymentProvider: 'alfa-bank')).thenThrow(Exception('Payment error'));
when(mockWsManager.client).thenReturn(null);
when(mockWsManager.initPrivateDirectChatChannel(any)).thenAnswer((_) async => Future.value());
when(mockWsManager.subscribeDirectChatChannel()).thenReturn(null);

View File

@@ -149,7 +149,8 @@ void main() {
when(chatRoomCubit.state).thenReturn(state);
when(chatRoomCubit.stream).thenAnswer((_) => const Stream<ChatRoomState>.empty());
when(chatRoomCubit.close()).thenAnswer((_) async => Future<void>.value());
when(chatRoomCubit.initChat(any, sendInitialMessage: anyNamed('sendInitialMessage'))).thenAnswer((_) async => Future<void>.value());
when(chatRoomCubit.initChat(any, sendInitialMessage: anyNamed('sendInitialMessage'), orderId: anyNamed('orderId')))
.thenAnswer((_) async => 'uuid');
when(chatRoomCubit.setTimer()).thenReturn(null);

View File

@@ -33,7 +33,8 @@ void main() {
when(cubit.state).thenReturn(const ChatRoomState.loading());
when(cubit.stream).thenAnswer((_) => const Stream<ChatRoomState>.empty());
when(cubit.close()).thenAnswer((_) async => Future<void>.value());
when(cubit.initChat(any, sendInitialMessage: anyNamed('sendInitialMessage'))).thenAnswer((_) async => Future<void>.value());
when(cubit.initChat(any, sendInitialMessage: anyNamed('sendInitialMessage'), orderId: anyNamed('orderId')))
.thenAnswer((_) async => 'uuid');
when(cubit.setTimer()).thenReturn(null);
sl.registerFactory<ChatRoomCubit>(() => cubit);

View File

@@ -5,12 +5,15 @@ 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_room_model.dart' as chat_room;
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/order_id_to_conversation_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:flutter_test/flutter_test.dart';
import 'package:mockito/annotations.dart';
@@ -32,7 +35,9 @@ void main() {
});
test('emitNewMessageToChats - эмитит новое сообщение в поток', () async {
final messageFixture = FixtureReader.readAsMap('chat/chat_message_response.json');
final messageFixture = FixtureReader.readAsMap(
'chat/chat_message_response.json',
);
final message = ChatMessageModel.fromJson(messageFixture);
chatRepository.emitNewMessageToChats(message);
@@ -45,12 +50,14 @@ 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());
// Note: SocketIdStorage is static and can't be easily mocked
// This test verifies the repository calls the service correctly
@@ -68,12 +75,14 @@ void main() {
const data = 'Test message with files';
const socketId = 'socket-id-123';
when(mockChatService.sendMessage(
slug: slug,
data: data,
mediaData: anyNamed('mediaData'),
socketId: socketId,
)).thenAnswer((_) async => Future.value());
when(
mockChatService.sendMessage(
slug: slug,
data: data,
mediaData: anyNamed('mediaData'),
socketId: socketId,
),
).thenAnswer((_) async => Future.value());
// Создаем временные файлы для теста
final tempFile1 = File('test1.jpg');
@@ -113,11 +122,14 @@ void main() {
test('getChatRoom - получает комнату чата по UUID', () async {
const uuid = 'chat-1';
final roomFixture = FixtureReader.readAsMap('chat/chat_room_response.json');
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 chatRepository.getChatRoom(uuid);
@@ -132,18 +144,20 @@ void main() {
when(mockChatService.getChatRoom(uuid: uuid)).thenThrow(error);
expect(
() => chatRepository.getChatRoom(uuid),
throwsException,
);
expect(() => chatRepository.getChatRoom(uuid), throwsException);
});
test('getChatRooms - получает список комнат чата', () async {
final paginationFixture = FixtureReader.readAsMap('chat/chat_room_pagination_response.json');
final expectedPagination = ChatRoomPaginationModel.fromJson(paginationFixture);
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 chatRepository.getChatRooms();
@@ -154,11 +168,16 @@ void main() {
test('getChatRooms - получает список комнат с запросом', () async {
const query = 'test query';
final paginationFixture = FixtureReader.readAsMap('chat/chat_room_pagination_response.json');
final expectedPagination = ChatRoomPaginationModel.fromJson(paginationFixture);
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 chatRepository.getChatRooms(query: query);
@@ -181,8 +200,9 @@ void main() {
),
);
when(mockChatService.getChatRooms(query: null, page: 2))
.thenAnswer((_) async => expectedPagination);
when(
mockChatService.getChatRooms(query: null, page: 2),
).thenAnswer((_) async => expectedPagination);
final result = await chatRepository.getChatRooms(page: 2);
@@ -193,11 +213,14 @@ void main() {
test('getChatMessages - получает сообщения чата', () async {
const chatId = 'chat-1';
const page = 1;
final messagesFixture = FixtureReader.readAsMap('chat/chat_messages_response.json');
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 chatRepository.getChatMessages(chatId, page);
@@ -206,42 +229,53 @@ void main() {
verify(mockChatService.getChatMessages(id: chatId, page: page)).called(1);
});
test('getChatRoomIdByUserSlug - получает комнату по slug пользователя', () async {
const slug = 'user-1';
final roomFixture = FixtureReader.readAsMap('chat/chat_room_response.json');
final expectedRoom = chat_room.ChatRoomModel.fromJson(roomFixture);
test(
'getChatRoomIdByUserSlug - получает комнату по slug пользователя',
() async {
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 chatRepository.getChatRoomIdByUserSlug(slug: slug);
final result = await chatRepository.getChatRoomIdByUserSlug(slug: slug);
expect(result, isA<chat_room.ChatRoomModel>());
verify(mockChatService.getChatRoomIdByUserSlug(user: slug)).called(1);
});
expect(result, isA<chat_room.ChatRoomModel>());
verify(mockChatService.getChatRoomIdByUserSlug(user: slug)).called(1);
},
);
test('markMessagesAsRead - отмечает сообщения как прочитанные', () async {
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 chatRepository.markMessagesAsRead(chatId, 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 chatRepository.cancelChosenPlan(id: planId);
@@ -252,36 +286,114 @@ 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 chatRepository.choseStartPlanDate(id: planId, date: date);
verify(mockChatService.choseStartPlanDate(id: planId, date: date)).called(1);
verify(
mockChatService.choseStartPlanDate(id: planId, date: date),
).called(1);
});
test('getPaymentLink - получает ссылку на оплату', () async {
const planId = 123;
final paymentFixture = FixtureReader.readAsMap('chat/payment_response.json');
final paymentFixture = FixtureReader.readAsMap(
'chat/payments/payment_response.json',
);
final expectedPayment = PaymentModel.fromJson(paymentFixture);
when(mockChatService.getPaymentLink(id: planId))
.thenAnswer((_) async => expectedPayment);
when(
mockChatService.getPaymentLink(
id: planId,
body: {'payment_provider': 'mock'},
),
).thenAnswer((_) async => expectedPayment);
final result = await chatRepository.getPaymentLink(id: planId);
final result = await chatRepository.getPaymentLink(
id: planId,
paymentProvider: 'mock',
);
expect(result, isA<PaymentModel>());
expect(result.paymentUrl, 'https://example.com/checkout/payment-123');
verify(mockChatService.getPaymentLink(id: planId)).called(1);
verify(
mockChatService.getPaymentLink(
id: planId,
body: {'payment_provider': 'mock'},
),
).called(1);
});
test(
'getPaymentLink - передаёт payment_provider в тело запроса alfa-bank',
() async {
const planId = 123;
final paymentFixture = FixtureReader.readAsMap(
'chat/payments/payment_response_alfa_bank.json',
);
final expectedPayment = PaymentModel.fromJson(paymentFixture);
when(
mockChatService.getPaymentLink(
id: planId,
body: {'payment_provider': 'alfa-bank'},
),
).thenAnswer((_) async => expectedPayment);
final result = await chatRepository.getPaymentLink(
id: planId,
paymentProvider: 'alfa-bank',
);
expect(result, isA<PaymentModel>());
expect(result.paymentUrl, 'https://qr.nspk.ru/ASDFASDFASDFASDF');
expect(result.orderId, 'alfa_c29_k15138_t1712345678_r1234');
expect(result.paymentProvider, 'alfa-bank');
verify(
mockChatService.getPaymentLink(
id: planId,
body: {'payment_provider': 'alfa-bank'},
),
).called(1);
},
);
test('resolveOrderIdToConversation - получает модель по orderId', () async {
const orderId = 'alfa_c29_k15138_t1712345678_r1234';
final fixture = FixtureReader.readAsMap(
'chat/payments/order_id_to_chat_uuid_response.json',
);
final expected = OrderIdToConversationModel.fromJson(fixture);
when(
mockChatService.resolveOrderIdToConversation(orderId: orderId),
).thenAnswer((_) async => expected);
final result = await chatRepository.resolveOrderIdToConversation(
orderId: orderId,
);
expect(result, isA<OrderIdToConversationModel>());
expect(result.chosenPlanId, 12);
expect(result.conversationUuid, "fbd81429-8019-499a-80e8-e3933cc4d872");
verify(
mockChatService.resolveOrderIdToConversation(orderId: orderId),
).called(1);
});
test('getChosenPlan - получает выбранный план', () async {
const planId = 1;
final chosenPlanFixture = FixtureReader.readAsMap('chat/chosen_plan_response.json');
final chosenPlanFixture = FixtureReader.readAsMap(
'chat/chosen_plan/chosen_plan_in_progress_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 chatRepository.getChosenPlan(id: planId);
@@ -290,66 +402,140 @@ void main() {
verify(mockChatService.getChosenPlan(id: planId)).called(1);
});
group('getChosenPlan payment polling statuses', () {
test('getChosenPlan - возвращает план в статусе pending_payment', () async {
const planId = 1;
final fixture = FixtureReader.readAsMap(
'chat/chosen_plan/chosen_plan_pending_payment_response.json',
);
final expectedPlan = ChosenPlanModel.fromJson(fixture);
when(mockChatService.getChosenPlan(id: planId)).thenAnswer((_) async => expectedPlan);
final result = await chatRepository.getChosenPlan(id: planId);
expect(result.chosenPlanState, ChosenPlanStateEnum.statePendingPayment);
verify(mockChatService.getChosenPlan(id: planId)).called(1);
});
test('getChosenPlan - возвращает план в статусе paid', () async {
const planId = 1;
final fixture = FixtureReader.readAsMap(
'chat/chosen_plan/chosen_plan_paid_response.json',
);
final expectedPlan = ChosenPlanModel.fromJson(fixture);
when(mockChatService.getChosenPlan(id: planId)).thenAnswer((_) async => expectedPlan);
final result = await chatRepository.getChosenPlan(id: planId);
expect(result.chosenPlanState, ChosenPlanStateEnum.statePaid);
verify(mockChatService.getChosenPlan(id: planId)).called(1);
});
test('getChosenPlan - возвращает план в статусе payment_failed', () async {
const planId = 1;
final fixture = FixtureReader.readAsMap(
'chat/chosen_plan/chosen_plan_payment_failed_response.json',
);
final expectedPlan = ChosenPlanModel.fromJson(fixture);
when(mockChatService.getChosenPlan(id: planId)).thenAnswer((_) async => expectedPlan);
final result = await chatRepository.getChosenPlan(id: planId);
expect(result.chosenPlanState, ChosenPlanStateEnum.statePaymentFailed);
verify(mockChatService.getChosenPlan(id: planId)).called(1);
});
test('getChosenPlan - возвращает план в статусе canceled_by_the_initiator', () async {
const planId = 1;
final fixture = FixtureReader.readAsMap(
'chat/chosen_plan/chosen_plan_canceled_by_the_initiator_response.json',
);
final expectedPlan = ChosenPlanModel.fromJson(fixture);
when(mockChatService.getChosenPlan(id: planId)).thenAnswer((_) async => expectedPlan);
final result = await chatRepository.getChosenPlan(id: planId);
expect(result.chosenPlanState, ChosenPlanStateEnum.stateCanceledByTheInitiator);
verify(mockChatService.getChosenPlan(id: planId)).called(1);
});
});
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 chatRepository.finishChosenPlan(id: planId);
verify(mockChatService.finishChosenPlan(id: planId)).called(1);
});
test('complainAboutConsultation - отправляет жалобу на консультацию', () async {
const planId = 123;
final complainFixture = FixtureReader.readAsMap('chat/plan_complain_response.json');
final complainModel = PlanComplainModel.fromJson(complainFixture);
test(
'complainAboutConsultation - отправляет жалобу на консультацию',
() async {
const planId = 123;
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 chatRepository.complainAboutConsultation(
id: planId,
body: complainModel,
);
await chatRepository.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 - возвращает ID чата при успешном ответе', () async {
const slug = 'user-slug';
const chatId = 'chat-id-123';
final response = HttpResponse(
{'id': chatId},
Response(
requestOptions: RequestOptions(path: ''),
statusCode: 200,
),
);
test(
'getChatByUserSlug - возвращает ID чата при успешном ответе',
() async {
const slug = 'user-slug';
const chatId = 'chat-id-123';
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 chatRepository.getChatByUserSlug(slug);
final result = await chatRepository.getChatByUserSlug(slug);
expect(result, chatId);
verify(mockChatService.getChatByUserSlug(slug: slug)).called(1);
});
expect(result, chatId);
verify(mockChatService.getChatByUserSlug(slug: slug)).called(1);
},
);
test('getChatByUserSlug - возвращает 404 при отсутствии чата', () async {
const slug = 'user-slug';
final response = HttpResponse(
{},
Response(
requestOptions: RequestOptions(path: ''),
statusCode: 404,
),
Response(requestOptions: RequestOptions(path: ''), statusCode: 404),
);
when(mockChatService.getChatByUserSlug(slug: slug))
.thenAnswer((_) async => response);
when(
mockChatService.getChatByUserSlug(slug: slug),
).thenAnswer((_) async => response);
final result = await chatRepository.getChatByUserSlug(slug);
@@ -357,17 +543,20 @@ void main() {
verify(mockChatService.getChatByUserSlug(slug: slug)).called(1);
});
test('getChatByUserSlug - пробрасывает исключение при ошибке сети', () async {
const slug = 'user-slug';
test(
'getChatByUserSlug - пробрасывает исключение при ошибке сети',
() async {
const slug = 'user-slug';
when(mockChatService.getChatByUserSlug(slug: slug))
.thenThrow(Exception('Network error'));
when(
mockChatService.getChatByUserSlug(slug: slug),
).thenThrow(Exception('Network error'));
await expectLater(
chatRepository.getChatByUserSlug(slug),
throwsA(isA<Exception>()),
);
});
await expectLater(
chatRepository.getChatByUserSlug(slug),
throwsA(isA<Exception>()),
);
},
);
});
}

View File

@@ -1,8 +1,10 @@
import 'package:dio/dio.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_room_model.dart' as chat_room;
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/order_id_to_conversation_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';
@@ -24,10 +26,16 @@ void main() {
});
test('getChatRooms - возвращает список комнат чата', () async {
final paginationFixture = FixtureReader.readAsMap('chat/chat_room_pagination_response.json');
final expectedPagination = ChatRoomPaginationModel.fromJson(paginationFixture);
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);
@@ -38,10 +46,16 @@ void main() {
test('getChatRooms - возвращает список комнат с запросом', () async {
const query = 'test query';
final paginationFixture = FixtureReader.readAsMap('chat/chat_room_pagination_response.json');
final expectedPagination = ChatRoomPaginationModel.fromJson(paginationFixture);
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);
@@ -51,10 +65,14 @@ void main() {
test('getChatRoom - возвращает комнату чата по UUID', () async {
const uuid = 'chat-1';
final roomFixture = FixtureReader.readAsMap('chat/chat_room_response.json');
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);
@@ -67,62 +85,114 @@ void main() {
const slug = 'user-slug';
const data = 'Test message';
const socketId = 'socket-id-123';
final messageFixture = FixtureReader.readAsMap('chat/chat_message_response.json');
final messageFixture = FixtureReader.readAsMap(
'chat/chat_message_response.json',
);
final expectedMessage = ChatMessageModel.fromJson(messageFixture);
// ignore: null_argument_to_non_null_type
when(mockChatService.sendMessage(slug: slug, data: data, mediaData: null, socketId: socketId)).thenAnswer((_) async => expectedMessage);
when(
mockChatService.sendMessage(
slug: slug,
data: data,
mediaData: null,
socketId: socketId,
),
).thenAnswer((_) async => expectedMessage);
final result = await mockChatService.sendMessage(slug: slug, data: data, mediaData: null, socketId: socketId);
final result = await mockChatService.sendMessage(
slug: slug,
data: data,
mediaData: null,
socketId: socketId,
);
expect(result, isA<ChatMessageModel>());
expect(result.data, data);
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-1';
const page = 1;
final messagesFixture = FixtureReader.readAsMap('chat/chat_messages_response.json');
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);
final result = await mockChatService.getChatMessages(
id: chatId,
page: page,
);
expect(result, isA<ChatMessagesModel>());
expect(result.messagesList.length, 2);
verify(mockChatService.getChatMessages(id: chatId, page: page)).called(1);
});
test('getChatRoomIdByUserSlug - возвращает комнату по slug пользователя', () async {
const slug = 'user-1';
final roomFixture = FixtureReader.readAsMap('chat/chat_room_response.json');
final expectedRoom = chat_room.ChatRoomModel.fromJson(roomFixture);
test(
'getChatRoomIdByUserSlug - возвращает комнату по slug пользователя',
() async {
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);
final result = await mockChatService.getChatRoomIdByUserSlug(
user: slug,
);
expect(result, isA<chat_room.ChatRoomModel>());
verify(mockChatService.getChatRoomIdByUserSlug(user: slug)).called(1);
});
expect(result, isA<chat_room.ChatRoomModel>());
verify(mockChatService.getChatRoomIdByUserSlug(user: slug)).called(1);
},
);
test('markMessagesAsRead - отмечает сообщения как прочитанные', () async {
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);
@@ -133,33 +203,80 @@ 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);
verify(mockChatService.choseStartPlanDate(id: planId, date: date)).called(1);
verify(
mockChatService.choseStartPlanDate(id: planId, date: date),
).called(1);
});
test('getPaymentLink - возвращает ссылку на оплату', () async {
const planId = 123;
final paymentFixture = FixtureReader.readAsMap('chat/payment_response.json');
final paymentFixture = FixtureReader.readAsMap(
'chat/payments/payment_response.json',
);
final expectedPayment = PaymentModel.fromJson(paymentFixture);
when(mockChatService.getPaymentLink(id: planId)).thenAnswer((_) async => expectedPayment);
when(
mockChatService.getPaymentLink(id: planId, body: {'payment_provider': 'mock'}),
).thenAnswer((_) async => expectedPayment);
final result = await mockChatService.getPaymentLink(id: planId);
final result = await mockChatService.getPaymentLink(
id: planId,
body: {'payment_provider': 'mock'},
);
expect(result, isA<PaymentModel>());
expect(result.paymentUrl, 'https://example.com/checkout/payment-123');
verify(mockChatService.getPaymentLink(id: planId)).called(1);
verify(mockChatService.getPaymentLink(id: planId, body: {'payment_provider': 'mock'})).called(1);
});
test(
'getPaymentLink - возвращает ссылку на оплату alfa-bank',
() async {
const planId = 123;
final requestFixture = FixtureReader.readAsMap(
'chat/payments/payment_alfabank_request.json',
);
final requestBody = Map<String, String>.from(requestFixture);
final paymentFixture = FixtureReader.readAsMap(
'chat/payments/payment_response_alfa_bank.json',
);
final expectedPayment = PaymentModel.fromJson(paymentFixture);
when(
mockChatService.getPaymentLink(id: planId, body: requestBody),
).thenAnswer((_) async => expectedPayment);
final result = await mockChatService.getPaymentLink(
id: planId,
body: requestBody,
);
expect(result, isA<PaymentModel>());
expect(result.paymentUrl, 'https://qr.nspk.ru/ASDFASDFASDFASDF');
expect(result.orderId, 'alfa_c29_k15138_t1712345678_r1234');
expect(result.paymentProvider, 'alfa-bank');
verify(
mockChatService.getPaymentLink(id: planId, body: requestBody),
).called(1);
},
);
test('getChosenPlan - возвращает выбранный план', () async {
const planId = 1;
final chosenPlanFixture = FixtureReader.readAsMap('chat/chosen_plan_response.json');
final chosenPlanFixture = FixtureReader.readAsMap(
'chat/chosen_plan/chosen_plan_in_progress_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);
@@ -171,31 +288,80 @@ 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);
verify(mockChatService.finishChosenPlan(id: planId)).called(1);
});
test('complainAboutConsultation - отправляет жалобу на консультацию', () async {
const planId = 123;
final complainFixture = FixtureReader.readAsMap('chat/plan_complain_response.json');
final complainModel = PlanComplainModel.fromJson(complainFixture);
test(
'complainAboutConsultation - отправляет жалобу на консультацию',
() async {
const planId = 123;
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);
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(
'resolveOrderIdToConversation - возвращает модель по orderId',
() async {
const orderId = 'alfa_c29_k15138_t1712345678_r1234';
final fixture = FixtureReader.readAsMap(
'chat/payments/order_id_to_chat_uuid_response.json',
);
final expected = OrderIdToConversationModel.fromJson(fixture);
when(
mockChatService.resolveOrderIdToConversation(orderId: orderId),
).thenAnswer((_) async => expected);
final result = await mockChatService.resolveOrderIdToConversation(
orderId: orderId,
);
expect(result, isA<OrderIdToConversationModel>());
expect(result.chosenPlanId, 12);
verify(
mockChatService.resolveOrderIdToConversation(orderId: orderId),
).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);