forked from eatvio/eatvio_app
feat(video_calls): ios voip push, mix and crushes fix
This commit is contained in:
@@ -479,6 +479,39 @@ void main() {
|
||||
},
|
||||
);
|
||||
|
||||
test(
|
||||
'_handleNewMessageViaSocket - завершение видеозвонка закрывает только этот чат',
|
||||
() async {
|
||||
const chatId = 'chat-id';
|
||||
final dismissed = <String?>[];
|
||||
chatsCubit.dismissIncomingVideoCall = (uuid) async {
|
||||
dismissed.add(uuid);
|
||||
};
|
||||
chatsCubit.emit(
|
||||
ChatsState(
|
||||
state: BaseState.success,
|
||||
chatRooms: [buildChatRoom(chatId)],
|
||||
),
|
||||
);
|
||||
when(mockWsManager.userId).thenReturn(42);
|
||||
|
||||
final controller = await connectToSocketStream();
|
||||
controller.add(
|
||||
socketEvent(
|
||||
id: 502,
|
||||
authorId: 7,
|
||||
roomId: chatId,
|
||||
data: 'Анна завершил(а) видеозвонок.',
|
||||
),
|
||||
);
|
||||
await Future.delayed(const Duration(milliseconds: 100));
|
||||
|
||||
expect(dismissed, [chatId]);
|
||||
|
||||
await controller.close();
|
||||
},
|
||||
);
|
||||
|
||||
test('close - закрывает cubit и отписывается от подписок', () async {
|
||||
final mockSubscription1 = MockStreamSubscription();
|
||||
|
||||
|
||||
@@ -0,0 +1,46 @@
|
||||
import 'package:eatvio_app/features/video_calls/services/video_call_ended_push_handler.dart';
|
||||
import 'package:flutter_callkit_incoming/entities/call_kit_params.dart';
|
||||
import 'package:flutter_test/flutter_test.dart';
|
||||
|
||||
void main() {
|
||||
const conversation = '11111111-1111-4111-8111-111111111111';
|
||||
|
||||
group('VideoCallEndedPushHandler.callMatchesConversation', () {
|
||||
test('matches the conversation stored as the call handle', () {
|
||||
const call = CallKitParams(id: 'derived-id', handle: conversation);
|
||||
|
||||
expect(
|
||||
VideoCallEndedPushHandler.callMatchesConversation(call, conversation),
|
||||
isTrue,
|
||||
);
|
||||
});
|
||||
|
||||
test('matches the conversation stored in the call payload', () {
|
||||
const call = CallKitParams(
|
||||
id: 'derived-id',
|
||||
handle: 'Итвио',
|
||||
extra: <String, dynamic>{'conversationUuid': conversation},
|
||||
);
|
||||
|
||||
expect(
|
||||
VideoCallEndedPushHandler.callMatchesConversation(
|
||||
call,
|
||||
conversation.toUpperCase(),
|
||||
),
|
||||
isTrue,
|
||||
);
|
||||
});
|
||||
|
||||
test('leaves a call from another chat alone', () {
|
||||
const call = CallKitParams(
|
||||
id: 'other-id',
|
||||
handle: '22222222-2222-4222-8222-222222222222',
|
||||
);
|
||||
|
||||
expect(
|
||||
VideoCallEndedPushHandler.callMatchesConversation(call, conversation),
|
||||
isFalse,
|
||||
);
|
||||
});
|
||||
});
|
||||
}
|
||||
@@ -0,0 +1,150 @@
|
||||
import 'package:eatvio_app/features/video_calls/services/video_call_incoming_push_presenter.dart';
|
||||
import 'package:eatvio_app/features/video_calls/services/video_call_kit_id.dart';
|
||||
import 'package:eatvio_app/features/video_calls/services/video_call_push_payload.dart';
|
||||
import 'package:flutter_callkit_incoming/entities/entities.dart';
|
||||
import 'package:flutter_test/flutter_test.dart';
|
||||
|
||||
void main() {
|
||||
const payload = VideoCallPushPayload(
|
||||
conversationUuid: '11111111-1111-4111-8111-111111111111',
|
||||
counterpartName: ' Anna ',
|
||||
messageId: 26,
|
||||
);
|
||||
|
||||
final callId = VideoCallKitId.iosUuid(
|
||||
conversationUuid: payload.conversationUuid,
|
||||
messageId: payload.messageId,
|
||||
);
|
||||
|
||||
group('VideoCallIncomingPushPresenter', () {
|
||||
test(
|
||||
'iOS keeps the push-reported call and does not show it again',
|
||||
() async {
|
||||
final shown = <CallKitParams>[];
|
||||
final delays = <Duration>[];
|
||||
|
||||
await VideoCallIncomingPushPresenter.showIncomingCall(
|
||||
payload,
|
||||
isIos: true,
|
||||
isIncomingCallClaimed: (_) async => true,
|
||||
reserveIncomingCall: (_) async => true,
|
||||
showCallkitIncoming: (params) async {
|
||||
shown.add(params);
|
||||
},
|
||||
delay: (duration) async {
|
||||
delays.add(duration);
|
||||
},
|
||||
);
|
||||
|
||||
expect(shown, isEmpty);
|
||||
expect(delays, isEmpty);
|
||||
expect(callId, isNotNull);
|
||||
},
|
||||
);
|
||||
|
||||
test('iOS shows the system call once the push does not claim it', () async {
|
||||
final shown = <CallKitParams>[];
|
||||
var polls = 0;
|
||||
|
||||
await VideoCallIncomingPushPresenter.showIncomingCall(
|
||||
payload,
|
||||
isIos: true,
|
||||
claimPollDelays: const <Duration>[
|
||||
Duration.zero,
|
||||
Duration(milliseconds: 300),
|
||||
],
|
||||
isIncomingCallClaimed: (_) async {
|
||||
polls += 1;
|
||||
return false;
|
||||
},
|
||||
reserveIncomingCall: (id) async {
|
||||
expect(id, callId);
|
||||
return true;
|
||||
},
|
||||
showCallkitIncoming: (params) async {
|
||||
shown.add(params);
|
||||
},
|
||||
delay: (_) async {},
|
||||
);
|
||||
|
||||
expect(polls, 2);
|
||||
expect(shown, hasLength(1));
|
||||
expect(shown.single.id, callId);
|
||||
expect(shown.single.nameCaller, 'Anna');
|
||||
expect(shown.single.ios?.configureAudioSession, isFalse);
|
||||
expect(shown.single.ios?.audioSessionActive, isFalse);
|
||||
expect(shown.single.ios?.audioSessionMode, 'videoChat');
|
||||
expect(shown.single.ios?.ringtonePath, 'system_ringtone_default');
|
||||
});
|
||||
|
||||
test('iOS stops polling when the push claims the call', () async {
|
||||
final shown = <CallKitParams>[];
|
||||
var polls = 0;
|
||||
|
||||
await VideoCallIncomingPushPresenter.showIncomingCall(
|
||||
payload,
|
||||
isIos: true,
|
||||
claimPollDelays: const <Duration>[
|
||||
Duration.zero,
|
||||
Duration(milliseconds: 300),
|
||||
Duration(milliseconds: 800),
|
||||
],
|
||||
isIncomingCallClaimed: (_) async {
|
||||
polls += 1;
|
||||
return polls == 2;
|
||||
},
|
||||
reserveIncomingCall: (_) async => true,
|
||||
showCallkitIncoming: (params) async {
|
||||
shown.add(params);
|
||||
},
|
||||
delay: (_) async {},
|
||||
);
|
||||
|
||||
expect(polls, 2);
|
||||
expect(shown, isEmpty);
|
||||
});
|
||||
|
||||
test('iOS does not show when the call was reserved by the push', () async {
|
||||
final shown = <CallKitParams>[];
|
||||
|
||||
await VideoCallIncomingPushPresenter.showIncomingCall(
|
||||
payload,
|
||||
isIos: true,
|
||||
claimPollDelays: const <Duration>[Duration.zero],
|
||||
isIncomingCallClaimed: (_) async => false,
|
||||
reserveIncomingCall: (_) async => false,
|
||||
showCallkitIncoming: (params) async {
|
||||
shown.add(params);
|
||||
},
|
||||
delay: (_) async {},
|
||||
);
|
||||
|
||||
expect(shown, isEmpty);
|
||||
});
|
||||
|
||||
test(
|
||||
'Android shows the incoming call without waiting for a VoIP claim',
|
||||
() async {
|
||||
final shown = <CallKitParams>[];
|
||||
var claimed = false;
|
||||
|
||||
await VideoCallIncomingPushPresenter.showIncomingCall(
|
||||
payload,
|
||||
isIos: false,
|
||||
isIncomingCallClaimed: (_) async {
|
||||
claimed = true;
|
||||
return true;
|
||||
},
|
||||
showCallkitIncoming: (params) async {
|
||||
shown.add(params);
|
||||
},
|
||||
);
|
||||
|
||||
expect(claimed, isFalse);
|
||||
expect(shown, hasLength(1));
|
||||
expect(shown.single.id, payload.conversationUuid);
|
||||
expect(shown.single.android?.ringtonePath, 'system_ringtone_default');
|
||||
},
|
||||
);
|
||||
});
|
||||
}
|
||||
Reference in New Issue
Block a user