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