Skip to content

Commit

Permalink
feat: mls conferencing [FS-1282] (#14443)
Browse files Browse the repository at this point in the history
  • Loading branch information
atomrc authored Feb 1, 2023
1 parent 6086dad commit 2db00a9
Show file tree
Hide file tree
Showing 11 changed files with 501 additions and 100 deletions.
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
"@emotion/react": "11.10.5",
"@types/eslint": "^8.4.10",
"@wireapp/avs": "9.0.20",
"@wireapp/core": "38.7.1",
"@wireapp/core": "38.8.1",
"@wireapp/lru-cache": "3.8.1",
"@wireapp/react-ui-kit": "9.3.4",
"@wireapp/store-engine-dexie": "2.0.4",
Expand Down
90 changes: 67 additions & 23 deletions src/script/calling/CallingRepository.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,12 @@
*
*/

import {ConversationProtocol, CONVERSATION_TYPE} from '@wireapp/api-client/lib/conversation';
import 'jsdom-worker';
import ko, {Subscription} from 'knockout';

import {CONV_TYPE, CALL_TYPE, STATE as CALL_STATE, REASON, Wcall} from '@wireapp/avs';
import {Runtime} from '@wireapp/commons';

import {Call} from 'src/script/calling/Call';
import {CallingRepository} from 'src/script/calling/CallingRepository';
Expand All @@ -47,8 +49,14 @@ const createSelfParticipant = () => {
return new Participant(selfUser, 'client1');
};

const createConversationId = () => {
return {domain: '', id: createRandomUuid()};
const createConversation = (
type: CONVERSATION_TYPE = CONVERSATION_TYPE.ONE_TO_ONE,
protocol: ConversationProtocol = ConversationProtocol.PROTEUS,
) => {
const conversation = new Conversation(createRandomUuid(), '', protocol);
conversation.participating_user_ets.push(new User(createRandomUuid()));
conversation.type(type);
return conversation;
};

describe('CallingRepository', () => {
Expand All @@ -57,6 +65,7 @@ describe('CallingRepository', () => {
let wCall: Wcall;
let wUser: number;
const selfUser = new User(createRandomUuid());
selfUser.isMe = true;
const clientId = createRandomUuid();

const mediaDevices = {
Expand Down Expand Up @@ -85,14 +94,33 @@ describe('CallingRepository', () => {
});

describe('startCall', () => {
it('starts a normal call in a 1:1 conversation', () => {
const conversationId = createConversationId();
const conversationType = CONV_TYPE.ONEONONE;
it.each([ConversationProtocol.PROTEUS, ConversationProtocol.MLS])(
'starts a normal call in a 1:1 conversation for proteus or MLS conversation',
async protocol => {
const conversation = createConversation(CONVERSATION_TYPE.ONE_TO_ONE, protocol);
const callType = CALL_TYPE.NORMAL;
spyOn(wCall, 'start');
await callingRepository.startCall(conversation, callType);
expect(wCall.start).toHaveBeenCalledWith(wUser, conversation.id, callType, CONV_TYPE.ONEONONE, 0);
},
);

it('starts a conference call in a group conversation for proteus', async () => {
jest.spyOn(Runtime, 'isSupportingConferenceCalling').mockReturnValue(true);
const conversation = createConversation(CONVERSATION_TYPE.REGULAR, ConversationProtocol.PROTEUS);
const callType = CALL_TYPE.NORMAL;
spyOn(wCall, 'start');
return callingRepository.startCall(conversationId, conversationType, callType).then(() => {
expect(wCall.start).toHaveBeenCalledWith(wUser, conversationId.id, conversationType, callType, 0);
});
await callingRepository.startCall(conversation, callType);
expect(wCall.start).toHaveBeenCalledWith(wUser, conversation.id, callType, CONV_TYPE.CONFERENCE, 0);
});

it('starts a MLS conference call in a group conversation for MLS', async () => {
jest.spyOn(Runtime, 'isSupportingConferenceCalling').mockReturnValue(true);
const conversation = createConversation(CONVERSATION_TYPE.REGULAR, ConversationProtocol.MLS);
const callType = CALL_TYPE.NORMAL;
spyOn(wCall, 'start');
await callingRepository.startCall(conversation, callType);
expect(wCall.start).toHaveBeenCalledWith(wUser, conversation.id, callType, CONV_TYPE.CONFERENCE_MLS, 0);
});
});

Expand All @@ -102,7 +130,7 @@ describe('CallingRepository', () => {
const userId = {domain: '', id: ''};
const incomingCall = new Call(
userId,
createConversationId(),
createConversation().qualifiedId,
CONV_TYPE.CONFERENCE,
selfParticipant,
CALL_TYPE.NORMAL,
Expand All @@ -114,7 +142,7 @@ describe('CallingRepository', () => {

const activeCall = new Call(
userId,
createConversationId(),
createConversation().qualifiedId,
CONV_TYPE.CONFERENCE,
selfParticipant,
CALL_TYPE.NORMAL,
Expand All @@ -126,7 +154,7 @@ describe('CallingRepository', () => {

const declinedCall = new Call(
userId,
createConversationId(),
createConversation().qualifiedId,
CONV_TYPE.CONFERENCE,
selfParticipant,
CALL_TYPE.NORMAL,
Expand All @@ -147,9 +175,16 @@ describe('CallingRepository', () => {
it('returns cached mediastream for self user if set', () => {
const selfParticipant = createSelfParticipant();
const userId = {domain: '', id: ''};
const call = new Call(userId, createConversationId(), CONV_TYPE.CONFERENCE, selfParticipant, CALL_TYPE.NORMAL, {
currentAvailableDeviceId: mediaDevices,
} as MediaDevicesHandler);
const call = new Call(
userId,
createConversation().qualifiedId,
CONV_TYPE.CONFERENCE,
selfParticipant,
CALL_TYPE.NORMAL,
{
currentAvailableDeviceId: mediaDevices,
} as MediaDevicesHandler,
);
const source = new window.RTCAudioSource();
const audioTrack = source.createTrack();
const selfMediaStream = new MediaStream([audioTrack]);
Expand All @@ -164,14 +199,15 @@ describe('CallingRepository', () => {
});
return Promise.all(queries).then(() => {
expect(selfParticipant.getMediaStream).toHaveBeenCalledTimes(queries.length);
audioTrack.stop();
});
});

it('asks only once for mediastream when queried multiple times', () => {
const selfParticipant = createSelfParticipant();
const call = new Call(
{domain: '', id: ''},
createConversationId(),
createConversation().qualifiedId,
CONV_TYPE.CONFERENCE,
selfParticipant,
CALL_TYPE.NORMAL,
Expand All @@ -194,6 +230,7 @@ describe('CallingRepository', () => {
});
return Promise.all(queries).then(() => {
expect(callingRepository['mediaStreamHandler'].requestMediaStream).toHaveBeenCalledTimes(1);
audioTrack.stop();
});
});
});
Expand All @@ -204,9 +241,16 @@ describe('CallingRepository', () => {
spyOn(selfParticipant, 'releaseAudioStream');
spyOn(selfParticipant, 'releaseVideoStream');

const call = new Call({domain: '', id: ''}, createConversationId(), 0, selfParticipant, CALL_TYPE.NORMAL, {
currentAvailableDeviceId: mediaDevices,
} as MediaDevicesHandler);
const call = new Call(
{domain: '', id: ''},
createConversation().qualifiedId,
0,
selfParticipant,
CALL_TYPE.NORMAL,
{
currentAvailableDeviceId: mediaDevices,
} as MediaDevicesHandler,
);
spyOn(callingRepository['callState'], 'joinedCall').and.returnValue(call);
callingRepository.stopMediaSource(MediaType.AUDIO);

Expand Down Expand Up @@ -458,12 +502,12 @@ describe.skip('E2E audio call', () => {

it('calls and connect with the remote user', done => {
onCallClosed = done;
const conversationId = createConversationId();
const conversation = createConversation();
onCallConnected = () => {
expect(client['sendMessage']).toHaveBeenCalledTimes(1);
expect(client.onCallEvent).toHaveBeenCalledTimes(1);
client
.getStats(conversationId)
.getStats(conversation.qualifiedId)
?.then(extractAudioStats)
.then(audioStats => {
expect(audioStats.length).toBeGreaterThan(0);
Expand All @@ -472,16 +516,16 @@ describe.skip('E2E audio call', () => {
});

expect(client['callState'].joinedCall()).toBeDefined();
client.leaveCall(conversationId, LEAVE_CALL_REASON.MANUAL_LEAVE_BY_UI_CLICK);
client.leaveCall(conversation.qualifiedId, LEAVE_CALL_REASON.MANUAL_LEAVE_BY_UI_CLICK);
})
.catch(done.fail);
};
client.startCall(conversationId, CONV_TYPE.ONEONONE, CALL_TYPE.NORMAL).catch(done.fail);
client.startCall(conversation, CALL_TYPE.NORMAL).catch(done.fail);
});

it('answers an incoming call and connect with the remote peer', done => {
onCallClosed = done;
const conversationId = createConversationId();
const conversationId = createConversation().qualifiedId;
onCallConnected = () => {
expect(client.onCallEvent).toHaveBeenCalled();
expect(client['incomingCallCallback']).toHaveBeenCalled();
Expand Down
Loading

0 comments on commit 2db00a9

Please sign in to comment.