forked from eatvio/eatvio_app
Если альфа скорринг пройден, не показываем кнопка привязки карты при консультации.
This commit is contained in:
@@ -107,7 +107,9 @@ class CubitRegistrations {
|
||||
sl.registerFactory<FeedProfileCubit>(() => FeedProfileCubit(profileRepository: sl()));
|
||||
|
||||
// Chat related cubits
|
||||
sl.registerFactory<ChatRoomCubit>(() => ChatRoomCubit(cardsRepository: sl(), chatRepository: sl(), wsManager: sl()));
|
||||
sl.registerFactory<ChatRoomCubit>(
|
||||
() => ChatRoomCubit(cardsRepository: sl(), chatRepository: sl(), wsManager: sl(), consultantRepository: sl()),
|
||||
);
|
||||
|
||||
// Profile related cubits
|
||||
sl.registerFactory<ProfileCubit>(() => ProfileCubit(profileRepository: sl(), chatRepository: sl(), consultantRepository: sl()));
|
||||
|
||||
@@ -17,6 +17,7 @@ import 'package:eatvio_app/features/chat/presentation/bloc/chat_room_cubit/chat_
|
||||
import 'package:eatvio_app/features/chat/presentation/bloc/chats_cubit/chats_cubit.dart';
|
||||
import 'package:eatvio_app/features/chat/repositories/chat_repository.dart';
|
||||
import 'package:eatvio_app/features/chat/utils/chat_counterpart_utils.dart';
|
||||
import 'package:eatvio_app/features/consultant/become_consultant/repositories/consultant_repository.dart';
|
||||
import 'package:eatvio_app/features/my_finance/models/card_model.dart';
|
||||
import 'package:eatvio_app/features/my_finance/repositories/cards_repository.dart';
|
||||
import 'package:eatvio_app/features/plans/models/chosen_plan_model.dart';
|
||||
@@ -27,6 +28,7 @@ import 'package:uuid/uuid.dart';
|
||||
class ChatRoomCubit extends Cubit<ChatRoomState> {
|
||||
final ChatRepository chatRepository;
|
||||
final CardsRepository cardsRepository;
|
||||
final ConsultantRepository consultantRepository;
|
||||
final WsManager wsManager;
|
||||
|
||||
StreamSubscription<ChannelReadEvent>? typingSubscription;
|
||||
@@ -39,7 +41,12 @@ class ChatRoomCubit extends Cubit<ChatRoomState> {
|
||||
void Function(bool isOnline)? _presenceOnlineListener;
|
||||
var uuid = const Uuid();
|
||||
|
||||
ChatRoomCubit({required this.chatRepository, required this.wsManager, required this.cardsRepository}) : super(const ChatRoomState.loading());
|
||||
ChatRoomCubit({
|
||||
required this.chatRepository,
|
||||
required this.wsManager,
|
||||
required this.cardsRepository,
|
||||
required this.consultantRepository,
|
||||
}) : super(const ChatRoomState.loading());
|
||||
|
||||
void setTimer() {
|
||||
_timer?.cancel();
|
||||
@@ -91,6 +98,18 @@ class ChatRoomCubit extends Cubit<ChatRoomState> {
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> checkAlfaScoringStatus(String slug) async {
|
||||
try {
|
||||
final status = await consultantRepository.getMyRequestStatus(slug);
|
||||
if (status.legalEntity?.alfaScoringStatus.isComplete == true) {
|
||||
_emitLoaded((current) => current.copyWith(isAlfaScoringComplete: true));
|
||||
}
|
||||
} catch (e, st) {
|
||||
await reportFrom(e, st, this);
|
||||
log(e.toString(), stackTrace: st);
|
||||
}
|
||||
}
|
||||
|
||||
/// Инициализирует чат по [uuid] либо по [orderId] (resolve → conversation_uuid).
|
||||
///
|
||||
/// При наличии [orderId] сначала вызывается
|
||||
@@ -137,8 +156,12 @@ class ChatRoomCubit extends Cubit<ChatRoomState> {
|
||||
);
|
||||
await _subscribeToPresenceChannel(chatId: chatRoom.id);
|
||||
|
||||
if (chosenPlan?.consultantId == chatRoom.users.sender.id) {
|
||||
if (chosenPlan?.consultantId == wsManager.userId) {
|
||||
final mySlug = chatRoom.users.sender.id == wsManager.userId
|
||||
? chatRoom.users.sender.slug
|
||||
: chatRoom.users.receiver.slug;
|
||||
await checkCards();
|
||||
await checkAlfaScoringStatus(mySlug);
|
||||
}
|
||||
return resolvedUuid;
|
||||
} catch (e, st) {
|
||||
|
||||
@@ -14,6 +14,7 @@ abstract class ChatRoomState with _$ChatRoomState {
|
||||
required ChatRoomModel chatRoom,
|
||||
required List<ChatMessageModel> chatMessages,
|
||||
required bool hasCard,
|
||||
@Default(false) bool isAlfaScoringComplete,
|
||||
required bool isTyping,
|
||||
required bool isLoading,
|
||||
}) = ChatRoomStateLoaded;
|
||||
|
||||
@@ -190,7 +190,10 @@ class _ChatScreenState extends State<ChatScreen> {
|
||||
BannerType? bannerType;
|
||||
if (chosenPlan == null || chosenPlan.chosenPlanState == ChosenPlanStateEnum.stateCanceledByTheInitiator) {
|
||||
bannerType = null;
|
||||
} else if (amIConsultant && !state.hasCard && chosenPlan.chosenPlanState == ChosenPlanStateEnum.stateInCoordination) {
|
||||
} else if (amIConsultant &&
|
||||
!state.hasCard &&
|
||||
!state.isAlfaScoringComplete &&
|
||||
chosenPlan.chosenPlanState == ChosenPlanStateEnum.stateInCoordination) {
|
||||
bannerType = BannerType.card;
|
||||
} else if (amIConsultant && chosenPlan.chosenPlanState == ChosenPlanStateEnum.stateInCoordination) {
|
||||
bannerType = BannerType.date;
|
||||
|
||||
@@ -36,6 +36,7 @@ void main() {
|
||||
expect((state as ChatRoomStateLoaded).chatRoom, chatRoom);
|
||||
expect(state.chatMessages, isEmpty);
|
||||
expect(state.hasCard, isFalse);
|
||||
expect(state.isAlfaScoringComplete, isFalse);
|
||||
expect(state.isTyping, isFalse);
|
||||
expect(state.isLoading, isFalse);
|
||||
});
|
||||
|
||||
@@ -9,6 +9,8 @@ import 'package:eatvio_app/features/chat/models/chat_user_model.dart';
|
||||
import 'package:eatvio_app/features/chat/presentation/bloc/chat_room_cubit/chat_room_cubit.dart';
|
||||
import 'package:eatvio_app/features/chat/presentation/bloc/chat_room_cubit/chat_room_state.dart';
|
||||
import 'package:eatvio_app/features/chat/repositories/chat_repository.dart';
|
||||
import 'package:eatvio_app/features/consultant/become_consultant/models/consultation_request_model.dart';
|
||||
import 'package:eatvio_app/features/consultant/become_consultant/repositories/consultant_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';
|
||||
@@ -21,11 +23,13 @@ import 'package:flutter_test/flutter_test.dart';
|
||||
import 'package:mockito/annotations.dart';
|
||||
import 'package:mockito/mockito.dart';
|
||||
import 'package:dart_pusher_channels/dart_pusher_channels.dart';
|
||||
import '../../../../fixtures/fixture_reader.dart';
|
||||
import 'chat_room_cubit_test.mocks.dart';
|
||||
|
||||
@GenerateNiceMocks([
|
||||
MockSpec<ChatRepository>(),
|
||||
MockSpec<CardsRepository>(),
|
||||
MockSpec<ConsultantRepository>(),
|
||||
MockSpec<WsManager>(),
|
||||
MockSpec<StreamSubscription<ChannelReadEvent>>(),
|
||||
MockSpec<PusherChannelsClient>(),
|
||||
@@ -36,8 +40,17 @@ void main() {
|
||||
late ChatRoomCubit chatRoomCubit;
|
||||
late MockChatRepository mockChatRepository;
|
||||
late MockCardsRepository mockCardsRepository;
|
||||
late MockConsultantRepository mockConsultantRepository;
|
||||
late MockWsManager mockWsManager;
|
||||
|
||||
ConsultationRequestModel requestWithScoring(String scoringStatus) {
|
||||
final json = FixtureReader.readAsMap('consultant/consultation_request.json');
|
||||
final legal = Map<String, dynamic>.from(json['legal_entity_resource'] as Map);
|
||||
legal['alfa_scoring_status'] = scoringStatus;
|
||||
json['legal_entity_resource'] = legal;
|
||||
return ConsultationRequestModel.fromJson(json);
|
||||
}
|
||||
|
||||
const testChatRoom = chat_room.ChatRoomModel(
|
||||
id: 'chat-id',
|
||||
chatRoomSettings: ChatRoomSettingsModel(name: 'Test Room', state: 'active'),
|
||||
@@ -67,8 +80,14 @@ void main() {
|
||||
setUp(() {
|
||||
mockChatRepository = MockChatRepository();
|
||||
mockCardsRepository = MockCardsRepository();
|
||||
mockConsultantRepository = MockConsultantRepository();
|
||||
mockWsManager = MockWsManager();
|
||||
chatRoomCubit = ChatRoomCubit(chatRepository: mockChatRepository, wsManager: mockWsManager, cardsRepository: mockCardsRepository);
|
||||
chatRoomCubit = ChatRoomCubit(
|
||||
chatRepository: mockChatRepository,
|
||||
wsManager: mockWsManager,
|
||||
cardsRepository: mockCardsRepository,
|
||||
consultantRepository: mockConsultantRepository,
|
||||
);
|
||||
});
|
||||
|
||||
tearDown(() async {
|
||||
@@ -405,7 +424,7 @@ void main() {
|
||||
await chatRoomCubit.initChat('uuid');
|
||||
await Future.delayed(const Duration(milliseconds: 200));
|
||||
|
||||
// Мокаем getCards без создания реальных CardModel
|
||||
reset(mockCardsRepository);
|
||||
when(mockCardsRepository.getCards()).thenAnswer((_) async => []);
|
||||
|
||||
await chatRoomCubit.checkCards();
|
||||
@@ -1186,7 +1205,7 @@ void main() {
|
||||
verifyNever(mockChatRepository.sendMessage(data: anyNamed('data'), files: anyNamed('files'), slug: anyNamed('slug')));
|
||||
});
|
||||
|
||||
test('initChat - вызывает checkCards если consultantId == sender.id', () async {
|
||||
test('initChat - вызывает checkCards и checkAlfaScoringStatus если consultantId == userId', () async {
|
||||
const uuid = 'room-uuid';
|
||||
const planId = 123;
|
||||
final chatRoomWithPlan = testChatRoom.copyWith(chosenPlanId: planId);
|
||||
@@ -1215,10 +1234,11 @@ void main() {
|
||||
startDate: DateTime.now(),
|
||||
chosenPlanState: ChosenPlanStateEnum.stateStarted,
|
||||
chatId: 'chat-1',
|
||||
consultantId: 1, // совпадает с sender.id
|
||||
consultantId: 1,
|
||||
plan: testPlan,
|
||||
);
|
||||
|
||||
when(mockWsManager.userId).thenReturn(1);
|
||||
when(mockChatRepository.getChatRoom(uuid)).thenAnswer((_) async => chatRoomWithPlan);
|
||||
when(mockChatRepository.getChatMessages(uuid, 1)).thenAnswer((_) async => testChatMessages);
|
||||
when(mockChatRepository.getChosenPlan(id: planId)).thenAnswer((_) async => chosenPlan);
|
||||
@@ -1228,14 +1248,16 @@ void main() {
|
||||
when(mockWsManager.directChatStream).thenReturn(null);
|
||||
when(mockWsManager.clientTypingStream).thenReturn(null);
|
||||
when(mockCardsRepository.getCards()).thenAnswer((_) async => []);
|
||||
when(mockConsultantRepository.getMyRequestStatus('user-1')).thenAnswer((_) async => requestWithScoring('none'));
|
||||
|
||||
await chatRoomCubit.initChat(uuid);
|
||||
await Future.delayed(const Duration(milliseconds: 200));
|
||||
|
||||
verify(mockCardsRepository.getCards()).called(1);
|
||||
verify(mockConsultantRepository.getMyRequestStatus('user-1')).called(1);
|
||||
});
|
||||
|
||||
test('initChat - не вызывает checkCards если consultantId != sender.id', () async {
|
||||
test('initChat - не вызывает checkCards если consultantId != userId', () async {
|
||||
const uuid = 'room-uuid';
|
||||
const planId = 123;
|
||||
final chatRoomWithPlan = testChatRoom.copyWith(chosenPlanId: planId);
|
||||
@@ -1264,10 +1286,11 @@ void main() {
|
||||
startDate: DateTime.now(),
|
||||
chosenPlanState: ChosenPlanStateEnum.stateStarted,
|
||||
chatId: 'chat-1',
|
||||
consultantId: 2, // не совпадает с sender.id (1)
|
||||
consultantId: 2,
|
||||
plan: testPlan,
|
||||
);
|
||||
|
||||
when(mockWsManager.userId).thenReturn(1);
|
||||
when(mockChatRepository.getChatRoom(uuid)).thenAnswer((_) async => chatRoomWithPlan);
|
||||
when(mockChatRepository.getChatMessages(uuid, 1)).thenAnswer((_) async => testChatMessages);
|
||||
when(mockChatRepository.getChosenPlan(id: planId)).thenAnswer((_) async => chosenPlan);
|
||||
@@ -1281,6 +1304,55 @@ void main() {
|
||||
await Future.delayed(const Duration(milliseconds: 200));
|
||||
|
||||
verifyNever(mockCardsRepository.getCards());
|
||||
verifyNever(mockConsultantRepository.getMyRequestStatus(any));
|
||||
});
|
||||
|
||||
test('checkAlfaScoringStatus - устанавливает isAlfaScoringComplete при scoring_complete', () async {
|
||||
const uuid = 'room-uuid';
|
||||
when(mockChatRepository.getChatRoom(uuid)).thenAnswer((_) async => testChatRoom);
|
||||
when(mockChatRepository.getChatMessages(uuid, 1)).thenAnswer((_) async => testChatMessages);
|
||||
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);
|
||||
when(mockChatRepository.getChosenPlan(id: anyNamed('id'))).thenAnswer((_) async => throw Exception('No plan'));
|
||||
|
||||
await chatRoomCubit.initChat(uuid);
|
||||
await Future.delayed(const Duration(milliseconds: 200));
|
||||
|
||||
when(mockConsultantRepository.getMyRequestStatus('user-1'))
|
||||
.thenAnswer((_) async => requestWithScoring('scoring_complete'));
|
||||
|
||||
await chatRoomCubit.checkAlfaScoringStatus('user-1');
|
||||
await Future.delayed(const Duration(milliseconds: 100));
|
||||
|
||||
final state = chatRoomCubit.state as ChatRoomStateLoaded;
|
||||
expect(state.isAlfaScoringComplete, true);
|
||||
});
|
||||
|
||||
test('checkAlfaScoringStatus - не устанавливает isAlfaScoringComplete при scoring_failed', () async {
|
||||
const uuid = 'room-uuid';
|
||||
when(mockChatRepository.getChatRoom(uuid)).thenAnswer((_) async => testChatRoom);
|
||||
when(mockChatRepository.getChatMessages(uuid, 1)).thenAnswer((_) async => testChatMessages);
|
||||
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);
|
||||
when(mockChatRepository.getChosenPlan(id: anyNamed('id'))).thenAnswer((_) async => throw Exception('No plan'));
|
||||
|
||||
await chatRoomCubit.initChat(uuid);
|
||||
await Future.delayed(const Duration(milliseconds: 200));
|
||||
|
||||
when(mockConsultantRepository.getMyRequestStatus('user-1'))
|
||||
.thenAnswer((_) async => requestWithScoring('scoring_failed'));
|
||||
|
||||
await chatRoomCubit.checkAlfaScoringStatus('user-1');
|
||||
await Future.delayed(const Duration(milliseconds: 100));
|
||||
|
||||
final state = chatRoomCubit.state as ChatRoomStateLoaded;
|
||||
expect(state.isAlfaScoringComplete, false);
|
||||
});
|
||||
|
||||
test('choseStartPlanDate - обрабатывает ошибку', () async {
|
||||
|
||||
Reference in New Issue
Block a user