@webex/plugin-meetings 3.0.0-beta.391 → 3.0.0-beta.393
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/breakouts/breakout.js +1 -1
- package/dist/breakouts/index.js +1 -1
- package/dist/config.js +1 -0
- package/dist/config.js.map +1 -1
- package/dist/constants.js +16 -7
- package/dist/constants.js.map +1 -1
- package/dist/interpretation/index.js +1 -1
- package/dist/interpretation/siLanguage.js +1 -1
- package/dist/meeting/index.js +738 -616
- package/dist/meeting/index.js.map +1 -1
- package/dist/meeting/util.js +4 -1
- package/dist/meeting/util.js.map +1 -1
- package/dist/meeting/voicea-meeting.js +172 -0
- package/dist/meeting/voicea-meeting.js.map +1 -0
- package/dist/meeting-info/meeting-info-v2.js +9 -6
- package/dist/meeting-info/meeting-info-v2.js.map +1 -1
- package/dist/meeting-info/util.js +7 -6
- package/dist/meeting-info/util.js.map +1 -1
- package/dist/meeting-info/utilv2.js +8 -4
- package/dist/meeting-info/utilv2.js.map +1 -1
- package/dist/member/index.js +0 -1
- package/dist/member/index.js.map +1 -1
- package/dist/types/constants.d.ts +8 -2
- package/dist/types/meeting/index.d.ts +56 -12
- package/dist/types/meeting/voicea-meeting.d.ts +16 -0
- package/dist/webinar/index.js +1 -1
- package/package.json +20 -20
- package/src/config.ts +2 -4
- package/src/constants.ts +11 -2
- package/src/meeting/index.ts +320 -157
- package/src/meeting/util.ts +5 -1
- package/src/meeting/voicea-meeting.ts +122 -0
- package/src/meeting-info/meeting-info-v2.ts +5 -11
- package/src/meeting-info/util.ts +12 -9
- package/src/meeting-info/utilv2.ts +24 -14
- package/src/member/index.ts +0 -1
- package/test/integration/spec/journey.js +2 -2
- package/test/unit/spec/breakouts/breakout.ts +2 -1
- package/test/unit/spec/breakouts/index.ts +7 -4
- package/test/unit/spec/locus-info/index.js +27 -18
- package/test/unit/spec/locus-info/selfUtils.js +6 -11
- package/test/unit/spec/media/index.ts +5 -0
- package/test/unit/spec/meeting/index.js +315 -87
- package/test/unit/spec/meeting/utils.js +52 -10
- package/test/unit/spec/meeting/voicea-meeting.ts +266 -0
- package/test/unit/spec/meeting-info/meetinginfov2.js +20 -15
- package/test/unit/spec/meetings/index.js +78 -10
- package/test/unit/spec/metrics/index.js +1 -2
- package/test/unit/spec/multistream/mediaRequestManager.ts +1 -0
- package/test/unit/spec/recording-controller/index.js +0 -1
- package/test/unit/spec/roap/turnDiscovery.ts +1 -1
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
export const getSpeaker = (members, csis = []) =>
|
|
2
|
+
Object.values(members).find((member: any) => {
|
|
3
|
+
const memberCSIs = member.participant.status.csis ?? [];
|
|
4
|
+
|
|
5
|
+
return csis.some((csi) => memberCSIs.includes(csi));
|
|
6
|
+
});
|
|
7
|
+
|
|
8
|
+
export const getSpeakerFromProxyOrStore = ({csisKey, meetingMembers, transcriptData}) => {
|
|
9
|
+
let speaker = {
|
|
10
|
+
speakerId: '',
|
|
11
|
+
name: '',
|
|
12
|
+
};
|
|
13
|
+
|
|
14
|
+
let needsCaching = false;
|
|
15
|
+
|
|
16
|
+
if (csisKey && transcriptData.speakerProxy[csisKey]) {
|
|
17
|
+
speaker = transcriptData.speakerProxy[csisKey];
|
|
18
|
+
|
|
19
|
+
return {speaker, needsCaching};
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
const meetingMember: any = getSpeaker(meetingMembers, [csisKey]);
|
|
23
|
+
|
|
24
|
+
speaker = {
|
|
25
|
+
speakerId: meetingMember?.participant.person.id ?? '',
|
|
26
|
+
name: meetingMember?.participant.person.name ?? '',
|
|
27
|
+
};
|
|
28
|
+
|
|
29
|
+
needsCaching = true;
|
|
30
|
+
|
|
31
|
+
return {speaker, needsCaching};
|
|
32
|
+
};
|
|
33
|
+
|
|
34
|
+
export const processNewCaptions = ({data, meeting}) => {
|
|
35
|
+
const {transcriptId} = data;
|
|
36
|
+
const transcriptData = meeting.transcription;
|
|
37
|
+
|
|
38
|
+
if (data.isFinal) {
|
|
39
|
+
transcriptData.interimCaptions[transcriptId].forEach((interimId) => {
|
|
40
|
+
const interimTranscriptIndex = transcriptData.captions.findIndex(
|
|
41
|
+
(transcript) => transcript.id === interimId
|
|
42
|
+
);
|
|
43
|
+
|
|
44
|
+
if (interimTranscriptIndex !== -1) {
|
|
45
|
+
transcriptData.captions.splice(interimTranscriptIndex, 1);
|
|
46
|
+
}
|
|
47
|
+
});
|
|
48
|
+
delete transcriptData.interimCaptions[transcriptId];
|
|
49
|
+
const csisKey = data.transcript?.csis[0];
|
|
50
|
+
|
|
51
|
+
const {needsCaching, speaker} = getSpeakerFromProxyOrStore({
|
|
52
|
+
meetingMembers: meeting.members.membersCollection.members,
|
|
53
|
+
transcriptData,
|
|
54
|
+
csisKey,
|
|
55
|
+
});
|
|
56
|
+
|
|
57
|
+
if (needsCaching) {
|
|
58
|
+
transcriptData.speakerProxy[csisKey] = speaker;
|
|
59
|
+
}
|
|
60
|
+
const captionData = {
|
|
61
|
+
id: transcriptId,
|
|
62
|
+
isFinal: data.isFinal,
|
|
63
|
+
translations: data.translations,
|
|
64
|
+
text: data.transcript?.text,
|
|
65
|
+
currentSpokenLanguage: data.transcript?.transcript_language_code,
|
|
66
|
+
timestamp: data.timestamp,
|
|
67
|
+
speaker,
|
|
68
|
+
};
|
|
69
|
+
transcriptData.captions.push(captionData);
|
|
70
|
+
}
|
|
71
|
+
const {transcripts = []} = data;
|
|
72
|
+
const transcriptsPerCsis = new Map();
|
|
73
|
+
|
|
74
|
+
for (const transcript of transcripts) {
|
|
75
|
+
const {
|
|
76
|
+
text,
|
|
77
|
+
transcript_language_code: currentSpokenLanguage,
|
|
78
|
+
csis: [csisMember],
|
|
79
|
+
} = transcript;
|
|
80
|
+
|
|
81
|
+
const newCaption = `${transcriptsPerCsis.get(csisMember)?.text ?? ''} ${text}`.trim();
|
|
82
|
+
|
|
83
|
+
// eslint-disable-next-line camelcase
|
|
84
|
+
transcriptsPerCsis.set(csisMember, {text: newCaption, currentSpokenLanguage});
|
|
85
|
+
}
|
|
86
|
+
const interimTranscriptionIds = [];
|
|
87
|
+
|
|
88
|
+
for (const [key, value] of transcriptsPerCsis) {
|
|
89
|
+
const {needsCaching, speaker} = getSpeakerFromProxyOrStore({
|
|
90
|
+
meetingMembers: meeting.members.membersCollection.members,
|
|
91
|
+
transcriptData,
|
|
92
|
+
csisKey: key,
|
|
93
|
+
});
|
|
94
|
+
|
|
95
|
+
if (needsCaching) {
|
|
96
|
+
transcriptData.speakerProxy[key] = speaker;
|
|
97
|
+
}
|
|
98
|
+
const {speakerId} = speaker;
|
|
99
|
+
const interimId = `${transcriptId}_${speakerId}`;
|
|
100
|
+
const captionData = {
|
|
101
|
+
id: interimId,
|
|
102
|
+
isFinal: data.isFinal,
|
|
103
|
+
translations: value.translations,
|
|
104
|
+
text: value.text,
|
|
105
|
+
currentCaptionLanguage: value.currentSpokenLanguage,
|
|
106
|
+
timestamp: value?.timestamp,
|
|
107
|
+
speaker,
|
|
108
|
+
};
|
|
109
|
+
|
|
110
|
+
const interimTranscriptIndex = transcriptData.captions.findIndex(
|
|
111
|
+
(transcript) => transcript.id === interimId
|
|
112
|
+
);
|
|
113
|
+
|
|
114
|
+
if (interimTranscriptIndex !== -1) {
|
|
115
|
+
transcriptData.captions.splice(interimTranscriptIndex, 1);
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
interimTranscriptionIds.push(interimId);
|
|
119
|
+
transcriptData.captions.push(captionData);
|
|
120
|
+
}
|
|
121
|
+
transcriptData.interimCaptions[transcriptId] = interimTranscriptionIds;
|
|
122
|
+
};
|
|
@@ -204,22 +204,16 @@ export default class MeetingInfoV2 {
|
|
|
204
204
|
return invitees;
|
|
205
205
|
};
|
|
206
206
|
|
|
207
|
-
return this.webex
|
|
208
|
-
.
|
|
209
|
-
.then((conversation) => {
|
|
210
|
-
const body
|
|
211
|
-
title: string;
|
|
212
|
-
spaceUrl: string;
|
|
213
|
-
keyUrl: string;
|
|
214
|
-
kroUrl: string;
|
|
215
|
-
invitees: any[];
|
|
216
|
-
installedOrgID?: string;
|
|
217
|
-
} = {
|
|
207
|
+
return this.webex
|
|
208
|
+
.request({uri: conversationUrl, qs: {includeParticipants: true}, disableTransform: true})
|
|
209
|
+
.then(({body: conversation}) => {
|
|
210
|
+
const body = {
|
|
218
211
|
title: conversation.displayName,
|
|
219
212
|
spaceUrl: conversation.url,
|
|
220
213
|
keyUrl: conversation.encryptionKeyUrl,
|
|
221
214
|
kroUrl: conversation.kmsResourceObjectUrl,
|
|
222
215
|
invitees: getInvitees(conversation.participants?.items),
|
|
216
|
+
installedOrgID,
|
|
223
217
|
};
|
|
224
218
|
|
|
225
219
|
if (installedOrgID) {
|
package/src/meeting-info/util.ts
CHANGED
|
@@ -1,13 +1,12 @@
|
|
|
1
1
|
import url from 'url';
|
|
2
2
|
|
|
3
3
|
import btoa from 'btoa';
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
deconstructHydraId,
|
|
7
|
-
} from '@webex/common';
|
|
4
|
+
// @ts-ignore
|
|
5
|
+
import {deconstructHydraId} from '@webex/common';
|
|
8
6
|
|
|
9
7
|
import ParameterError from '../common/errors/parameter';
|
|
10
8
|
import LoggerProxy from '../common/logs/logger-proxy';
|
|
9
|
+
|
|
11
10
|
import {
|
|
12
11
|
_SIP_URI_,
|
|
13
12
|
_PERSONAL_ROOM_,
|
|
@@ -221,12 +220,16 @@ MeetingInfoUtil.generateOptions = async (from) => {
|
|
|
221
220
|
try {
|
|
222
221
|
await webex.internal.services.waitForCatalog('postauth');
|
|
223
222
|
|
|
224
|
-
const
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
223
|
+
const serviceUrl = webex.internal.services.getServiceUrlFromClusterId(
|
|
224
|
+
{
|
|
225
|
+
cluster: hydraId.cluster,
|
|
226
|
+
},
|
|
227
|
+
webex
|
|
228
|
+
);
|
|
228
229
|
|
|
229
|
-
options.destination =
|
|
230
|
+
options.destination = hydraId.destination
|
|
231
|
+
? `${serviceUrl}/conversations/${hydraId.destination}`
|
|
232
|
+
: serviceUrl;
|
|
230
233
|
} catch (e) {
|
|
231
234
|
LoggerProxy.logger.error(`Meeting-info:util#generateOptions --> ${e}`);
|
|
232
235
|
throw e;
|
|
@@ -1,9 +1,7 @@
|
|
|
1
1
|
import url from 'url';
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
deconstructHydraId,
|
|
6
|
-
} from '@webex/common';
|
|
3
|
+
// @ts-ignore
|
|
4
|
+
import {deconstructHydraId} from '@webex/common';
|
|
7
5
|
|
|
8
6
|
import {
|
|
9
7
|
_SIP_URI_,
|
|
@@ -21,6 +19,8 @@ import {
|
|
|
21
19
|
JOIN,
|
|
22
20
|
MEET,
|
|
23
21
|
MEET_M,
|
|
22
|
+
MEET_CISCO,
|
|
23
|
+
MEET_CO,
|
|
24
24
|
HTTPS_PROTOCOL,
|
|
25
25
|
UUID_REG,
|
|
26
26
|
VALID_EMAIL_ADDRESS,
|
|
@@ -68,6 +68,8 @@ MeetingInfoUtil.isMeetingLink = (value: string) => {
|
|
|
68
68
|
parsedUrl.pathname &&
|
|
69
69
|
(parsedUrl.pathname.includes(`/${MEET}`) ||
|
|
70
70
|
parsedUrl.pathname.includes(`/${MEET_M}`) ||
|
|
71
|
+
parsedUrl.pathname.includes(`/${MEET_CISCO}`) ||
|
|
72
|
+
parsedUrl.pathname.includes(`/${MEET_CO}`) ||
|
|
71
73
|
parsedUrl.pathname.includes(`/${JOIN}`));
|
|
72
74
|
|
|
73
75
|
return hostNameBool && pathNameBool;
|
|
@@ -162,7 +164,13 @@ MeetingInfoUtil.getDestinationType = async (from) => {
|
|
|
162
164
|
};
|
|
163
165
|
}
|
|
164
166
|
const options: any = {};
|
|
165
|
-
|
|
167
|
+
let hydraId;
|
|
168
|
+
|
|
169
|
+
if (webex && webex.config && webex.config.meetings && webex.config.meetings.disableHydraId) {
|
|
170
|
+
hydraId = null;
|
|
171
|
+
} else {
|
|
172
|
+
hydraId = MeetingInfoUtil.getHydraId(destination);
|
|
173
|
+
}
|
|
166
174
|
|
|
167
175
|
if (MeetingInfoUtil.isMeetingLink(destination)) {
|
|
168
176
|
LoggerProxy.logger.warn(
|
|
@@ -180,19 +188,21 @@ MeetingInfoUtil.getDestinationType = async (from) => {
|
|
|
180
188
|
} else if (MeetingInfoUtil.isConversationUrl(destination, webex)) {
|
|
181
189
|
options.type = _CONVERSATION_URL_;
|
|
182
190
|
options.destination = destination;
|
|
183
|
-
} else if (hydraId.people) {
|
|
191
|
+
} else if (hydraId && hydraId.people) {
|
|
184
192
|
options.type = _SIP_URI_;
|
|
185
193
|
|
|
186
|
-
return MeetingInfoUtil.getSipUriFromHydraPersonId(hydraId.destination, webex).then(
|
|
187
|
-
|
|
194
|
+
return MeetingInfoUtil.getSipUriFromHydraPersonId(hydraId && hydraId.destination, webex).then(
|
|
195
|
+
(res) => {
|
|
196
|
+
options.destination = res;
|
|
188
197
|
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
198
|
+
// Since hydra person ids require a unique case in which they are
|
|
199
|
+
// entirely converted to a SIP URI, we need to set a flag for detecting
|
|
200
|
+
// this type of destination.
|
|
201
|
+
options.wasHydraPerson = true;
|
|
193
202
|
|
|
194
|
-
|
|
195
|
-
|
|
203
|
+
return Promise.resolve(options);
|
|
204
|
+
}
|
|
205
|
+
);
|
|
196
206
|
} else if (hydraId.room) {
|
|
197
207
|
LoggerProxy.logger.error(
|
|
198
208
|
`Meeting-info:util#getDestinationType --> Using the space ID as a destination is no longer supported. Please refer to the [migration guide](https://github.com/webex/webex-js-sdk/wiki/Migration-to-Unified-Space-Meetings) to migrate to use the meeting ID or SIP address.`
|
package/src/member/index.ts
CHANGED
|
@@ -10,7 +10,7 @@ import {createCameraStream, createDisplayStream, createMicrophoneStream, LocalTr
|
|
|
10
10
|
|
|
11
11
|
import testUtils from '../../utils/testUtils';
|
|
12
12
|
import integrationTestUtils from '../../utils/integrationTestUtils';
|
|
13
|
-
import {EVENT_TRIGGERS} from '../../../
|
|
13
|
+
import {EVENT_TRIGGERS} from '../../../dist/constants';
|
|
14
14
|
|
|
15
15
|
require('dotenv').config();
|
|
16
16
|
|
|
@@ -239,7 +239,7 @@ skipInNode(describe)('plugin-meetings', () => {
|
|
|
239
239
|
|
|
240
240
|
// Enabled when config.enableUnifiedMeetings = true
|
|
241
241
|
xdescribe('Conversation URL', () => {
|
|
242
|
-
describe('Successful 1:1 meeting',
|
|
242
|
+
describe('Successful 1:1 meeting', () => {
|
|
243
243
|
it('Fetch meeting information with a conversation URL for a 1:1 space', async () => {
|
|
244
244
|
assert.equal(Object.keys(bob.webex.meetings.getAllMeetings()), 0);
|
|
245
245
|
assert.equal(Object.keys(chris.webex.meetings.getAllMeetings()), 0);
|
|
@@ -89,7 +89,7 @@ describe('plugin-meetings', () => {
|
|
|
89
89
|
})
|
|
90
90
|
};
|
|
91
91
|
|
|
92
|
-
sinon.stub(webex.internal.newMetrics.submitClientEvent, 'bind').returns(webex.internal.newMetrics.submitClientEvent);
|
|
92
|
+
const submitClientEventStub = sinon.stub(webex.internal.newMetrics.submitClientEvent, 'bind').returns(webex.internal.newMetrics.submitClientEvent);
|
|
93
93
|
|
|
94
94
|
let onBreakoutMoveRequestStub = sinon.stub(breakoutEvent, 'onBreakoutMoveRequest');
|
|
95
95
|
let onBreakoutMoveResponseStub = sinon.stub(breakoutEvent, 'onBreakoutMoveResponse');
|
|
@@ -105,6 +105,7 @@ describe('plugin-meetings', () => {
|
|
|
105
105
|
|
|
106
106
|
onBreakoutMoveRequestStub.restore();
|
|
107
107
|
onBreakoutMoveResponseStub.restore();
|
|
108
|
+
submitClientEventStub.restore()
|
|
108
109
|
});
|
|
109
110
|
});
|
|
110
111
|
|
|
@@ -381,7 +381,7 @@ describe('plugin-meetings', () => {
|
|
|
381
381
|
id: 'meeting-id'
|
|
382
382
|
})
|
|
383
383
|
};
|
|
384
|
-
|
|
384
|
+
const onBreakoutJoinResponseSpy = sinon.stub(breakoutEvent,'onBreakoutJoinResponse')
|
|
385
385
|
breakouts.currentBreakoutSession.sessionId = "sessionId-old";
|
|
386
386
|
breakouts.updateBreakout({
|
|
387
387
|
sessionId: 'sessionId-new',
|
|
@@ -398,7 +398,9 @@ describe('plugin-meetings', () => {
|
|
|
398
398
|
breakoutMoveId: 'breakoutMoveId',
|
|
399
399
|
});
|
|
400
400
|
|
|
401
|
-
assert.calledOnce(
|
|
401
|
+
assert.calledOnce(onBreakoutJoinResponseSpy);
|
|
402
|
+
|
|
403
|
+
onBreakoutJoinResponseSpy.restore()
|
|
402
404
|
|
|
403
405
|
});
|
|
404
406
|
|
|
@@ -408,7 +410,7 @@ describe('plugin-meetings', () => {
|
|
|
408
410
|
id: 'meeting-id'
|
|
409
411
|
})
|
|
410
412
|
};
|
|
411
|
-
|
|
413
|
+
const onBreakoutJoinResponseSpy = sinon.stub(breakoutEvent, 'onBreakoutJoinResponse');
|
|
412
414
|
breakouts.currentBreakoutSession.sessionId = "sessionId";
|
|
413
415
|
breakouts.currentBreakoutSession.groupId = "groupId";
|
|
414
416
|
breakouts.updateBreakout({
|
|
@@ -426,7 +428,8 @@ describe('plugin-meetings', () => {
|
|
|
426
428
|
breakoutMoveId: 'breakoutMoveId',
|
|
427
429
|
});
|
|
428
430
|
|
|
429
|
-
assert.notCalled(
|
|
431
|
+
assert.notCalled(onBreakoutJoinResponseSpy);
|
|
432
|
+
onBreakoutJoinResponseSpy.restore()
|
|
430
433
|
|
|
431
434
|
});
|
|
432
435
|
});
|
|
@@ -1385,7 +1385,7 @@ describe('plugin-meetings', () => {
|
|
|
1385
1385
|
function: 'updateMeetingInfo',
|
|
1386
1386
|
},
|
|
1387
1387
|
LOCUSINFO.EVENTS.MEETING_INFO_UPDATED,
|
|
1388
|
-
payload
|
|
1388
|
+
payload,
|
|
1389
1389
|
];
|
|
1390
1390
|
|
|
1391
1391
|
if (expected) {
|
|
@@ -1404,7 +1404,7 @@ describe('plugin-meetings', () => {
|
|
|
1404
1404
|
function: 'updateMeetingInfo',
|
|
1405
1405
|
},
|
|
1406
1406
|
LOCUSINFO.EVENTS.MEETING_INFO_UPDATED,
|
|
1407
|
-
payload
|
|
1407
|
+
payload,
|
|
1408
1408
|
];
|
|
1409
1409
|
|
|
1410
1410
|
if (expected) {
|
|
@@ -1426,8 +1426,7 @@ describe('plugin-meetings', () => {
|
|
|
1426
1426
|
*/
|
|
1427
1427
|
sinon.stub(locusInfo, 'emitScoped').callsFake(() => {
|
|
1428
1428
|
assert.deepEqual(mockMeeting, expectedMeeting);
|
|
1429
|
-
})
|
|
1430
|
-
|
|
1429
|
+
});
|
|
1431
1430
|
|
|
1432
1431
|
// set the info initially as locusInfo.info starts as undefined
|
|
1433
1432
|
expectedMeeting = {
|
|
@@ -1907,7 +1906,7 @@ describe('plugin-meetings', () => {
|
|
|
1907
1906
|
locusInfo.locusParser.workingCopy = {
|
|
1908
1907
|
syncUrl: 'current sync url',
|
|
1909
1908
|
};
|
|
1910
|
-
|
|
1909
|
+
|
|
1911
1910
|
locusInfo.applyLocusDeltaData(LOCUS_URL_CHANGED, fakeLocus, meeting);
|
|
1912
1911
|
assert.calledOnceWithExactly(meeting.meetingRequest.getLocusDTO, {url: 'current sync url'});
|
|
1913
1912
|
});
|
|
@@ -1970,8 +1969,12 @@ describe('plugin-meetings', () => {
|
|
|
1970
1969
|
}).then(() => {
|
|
1971
1970
|
assert.calledTwice(meeting.meetingRequest.getLocusDTO);
|
|
1972
1971
|
|
|
1973
|
-
assert.deepEqual(meeting.meetingRequest.getLocusDTO.getCalls()[0].args, [
|
|
1974
|
-
|
|
1972
|
+
assert.deepEqual(meeting.meetingRequest.getLocusDTO.getCalls()[0].args, [
|
|
1973
|
+
{url: 'deltaSyncUrl'},
|
|
1974
|
+
]);
|
|
1975
|
+
assert.deepEqual(meeting.meetingRequest.getLocusDTO.getCalls()[1].args, [
|
|
1976
|
+
{url: 'fullSyncUrl'},
|
|
1977
|
+
]);
|
|
1975
1978
|
|
|
1976
1979
|
assert.calledWith(sendBehavioralMetricStub, 'js_sdk_locus_delta_sync_failed', {
|
|
1977
1980
|
correlationId: meeting.correlationId,
|
|
@@ -1999,8 +2002,12 @@ describe('plugin-meetings', () => {
|
|
|
1999
2002
|
}).then(() => {
|
|
2000
2003
|
assert.calledTwice(meeting.meetingRequest.getLocusDTO);
|
|
2001
2004
|
|
|
2002
|
-
assert.deepEqual(meeting.meetingRequest.getLocusDTO.getCalls()[0].args, [
|
|
2003
|
-
|
|
2005
|
+
assert.deepEqual(meeting.meetingRequest.getLocusDTO.getCalls()[0].args, [
|
|
2006
|
+
{url: 'deltaSyncUrl'},
|
|
2007
|
+
]);
|
|
2008
|
+
assert.deepEqual(meeting.meetingRequest.getLocusDTO.getCalls()[1].args, [
|
|
2009
|
+
{url: 'fullSyncUrl'},
|
|
2010
|
+
]);
|
|
2004
2011
|
|
|
2005
2012
|
assert.calledWith(sendBehavioralMetricStub, 'js_sdk_locus_delta_sync_failed', {
|
|
2006
2013
|
correlationId: meeting.correlationId,
|
|
@@ -2084,7 +2091,7 @@ describe('plugin-meetings', () => {
|
|
|
2084
2091
|
|
|
2085
2092
|
locusInfo.clearMainSessionLocusCache = sinon.stub();
|
|
2086
2093
|
locusInfo.getTheLocusToUpdate(newLocus);
|
|
2087
|
-
assert.notCalled(locusInfo.clearMainSessionLocusCache)
|
|
2094
|
+
assert.notCalled(locusInfo.clearMainSessionLocusCache);
|
|
2088
2095
|
});
|
|
2089
2096
|
|
|
2090
2097
|
it('return the new locus if return to main session but no cache and do not clear main session cache', () => {
|
|
@@ -2106,7 +2113,7 @@ describe('plugin-meetings', () => {
|
|
|
2106
2113
|
|
|
2107
2114
|
locusInfo.clearMainSessionLocusCache = sinon.stub();
|
|
2108
2115
|
locusInfo.getTheLocusToUpdate(newLocus);
|
|
2109
|
-
assert.notCalled(locusInfo.clearMainSessionLocusCache)
|
|
2116
|
+
assert.notCalled(locusInfo.clearMainSessionLocusCache);
|
|
2110
2117
|
});
|
|
2111
2118
|
|
|
2112
2119
|
it('return the new locus if not return to main session and clear main session cache', () => {
|
|
@@ -2116,9 +2123,9 @@ describe('plugin-meetings', () => {
|
|
|
2116
2123
|
sessionType: 'MAIN',
|
|
2117
2124
|
},
|
|
2118
2125
|
},
|
|
2119
|
-
self: {removed: true}
|
|
2126
|
+
self: {removed: true},
|
|
2120
2127
|
};
|
|
2121
|
-
locusInfo.fullState = {state: 'ACTIVE'}
|
|
2128
|
+
locusInfo.fullState = {state: 'ACTIVE'};
|
|
2122
2129
|
locusInfo.controls = {
|
|
2123
2130
|
breakout: {
|
|
2124
2131
|
sessionType: 'MAIN',
|
|
@@ -2134,7 +2141,7 @@ describe('plugin-meetings', () => {
|
|
|
2134
2141
|
|
|
2135
2142
|
locusInfo.clearMainSessionLocusCache = sinon.stub();
|
|
2136
2143
|
const result = locusInfo.getTheLocusToUpdate(newLocus);
|
|
2137
|
-
assert.calledOnce(locusInfo.clearMainSessionLocusCache)
|
|
2144
|
+
assert.calledOnce(locusInfo.clearMainSessionLocusCache);
|
|
2138
2145
|
|
|
2139
2146
|
assert.deepEqual(result, newLocus);
|
|
2140
2147
|
});
|
|
@@ -2146,9 +2153,9 @@ describe('plugin-meetings', () => {
|
|
|
2146
2153
|
sessionType: 'MAIN',
|
|
2147
2154
|
},
|
|
2148
2155
|
},
|
|
2149
|
-
self: {removed: undefined}
|
|
2156
|
+
self: {removed: undefined},
|
|
2150
2157
|
};
|
|
2151
|
-
locusInfo.fullState = {state: 'ACTIVE'}
|
|
2158
|
+
locusInfo.fullState = {state: 'ACTIVE'};
|
|
2152
2159
|
locusInfo.controls = {
|
|
2153
2160
|
breakout: {
|
|
2154
2161
|
sessionType: 'MAIN',
|
|
@@ -2164,7 +2171,7 @@ describe('plugin-meetings', () => {
|
|
|
2164
2171
|
|
|
2165
2172
|
locusInfo.clearMainSessionLocusCache = sinon.stub();
|
|
2166
2173
|
locusInfo.getTheLocusToUpdate(newLocus);
|
|
2167
|
-
assert.notCalled(locusInfo.clearMainSessionLocusCache)
|
|
2174
|
+
assert.notCalled(locusInfo.clearMainSessionLocusCache);
|
|
2168
2175
|
});
|
|
2169
2176
|
});
|
|
2170
2177
|
|
|
@@ -2611,7 +2618,9 @@ describe('plugin-meetings', () => {
|
|
|
2611
2618
|
// send an out-of-order delta
|
|
2612
2619
|
locusInfo.handleLocusDelta(oooDelta, mockMeeting);
|
|
2613
2620
|
|
|
2614
|
-
assert.calledOnceWithExactly(sendBehavioralMetricStub, 'js_sdk_locus_delta_ooo', {
|
|
2621
|
+
assert.calledOnceWithExactly(sendBehavioralMetricStub, 'js_sdk_locus_delta_ooo', {
|
|
2622
|
+
stack: sinon.match.any,
|
|
2623
|
+
});
|
|
2615
2624
|
|
|
2616
2625
|
await clock.tickAsync(12499);
|
|
2617
2626
|
await testUtils.flushPromises();
|
|
@@ -150,8 +150,7 @@ describe('plugin-meetings', () => {
|
|
|
150
150
|
|
|
151
151
|
it('should return false if no breakouts in current', () => {
|
|
152
152
|
const current = {
|
|
153
|
-
breakoutSessions: {
|
|
154
|
-
},
|
|
153
|
+
breakoutSessions: {},
|
|
155
154
|
};
|
|
156
155
|
const previous = {
|
|
157
156
|
breakoutSessions: {
|
|
@@ -293,7 +292,7 @@ describe('plugin-meetings', () => {
|
|
|
293
292
|
const clonedSelf = cloneDeep(self);
|
|
294
293
|
|
|
295
294
|
clonedSelf.controls.audio.requestedToUnmute = true;
|
|
296
|
-
clonedSelf.controls.audio.lastModifiedRequestedToUnmute = '2023-06-16T18:25:04.369Z'
|
|
295
|
+
clonedSelf.controls.audio.lastModifiedRequestedToUnmute = '2023-06-16T18:25:04.369Z';
|
|
297
296
|
|
|
298
297
|
const {updates} = SelfUtils.getSelves(self, clonedSelf);
|
|
299
298
|
|
|
@@ -371,23 +370,18 @@ describe('plugin-meetings', () => {
|
|
|
371
370
|
const clonedSelf = cloneDeep(self);
|
|
372
371
|
|
|
373
372
|
it('get breakoutMoveId works', () => {
|
|
374
|
-
|
|
375
373
|
assert.deepEqual(SelfUtils.getReplacedBreakoutMoveId(self, deviceId), breakoutMoveId);
|
|
376
|
-
|
|
377
374
|
});
|
|
378
375
|
|
|
379
376
|
it('replaces is empty', () => {
|
|
380
|
-
|
|
381
377
|
clonedSelf.devices[0].replaces = undefined;
|
|
382
378
|
assert.deepEqual(SelfUtils.getReplacedBreakoutMoveId(clonedSelf, deviceId), null);
|
|
383
|
-
|
|
384
379
|
});
|
|
385
380
|
|
|
386
381
|
it('no self or self.devices is not array', () => {
|
|
387
|
-
|
|
388
382
|
assert.deepEqual(SelfUtils.getReplacedBreakoutMoveId(undefined, deviceId), null);
|
|
389
383
|
|
|
390
|
-
clonedSelf.devices =
|
|
384
|
+
clonedSelf.devices = {
|
|
391
385
|
url: 'https://wdm-a.wbx2.com/wdm/api/v1/devices/20eabde3-4254-48da-9a24',
|
|
392
386
|
deviceType: 'WEB',
|
|
393
387
|
mediaSessionsExternal: false,
|
|
@@ -395,10 +389,11 @@ describe('plugin-meetings', () => {
|
|
|
395
389
|
{
|
|
396
390
|
breakoutMoveId: 'e5caeb2c-ffcc-4e06-a08a-1122e7710398',
|
|
397
391
|
lastActive: '2023-05-04T07:14:32.068Z',
|
|
398
|
-
locusUrl:
|
|
392
|
+
locusUrl:
|
|
393
|
+
'https://locus-alpha-apdx.prod.meetapi.webex.com/locus/api/v1/loci/495061ca-7b3c-3b77-85ff-4e1bd58600d1',
|
|
399
394
|
replacedAt: '2023-05-04T07:16:04.905Z',
|
|
400
395
|
sessionId: 'be3147d4-c318-86d8-7611-8d24beaaca8d',
|
|
401
|
-
}
|
|
396
|
+
},
|
|
402
397
|
],
|
|
403
398
|
state: 'JOINED',
|
|
404
399
|
};
|
|
@@ -7,6 +7,10 @@ import {forEach} from 'lodash';
|
|
|
7
7
|
import MockWebex from '@webex/test-helper-mock-webex';
|
|
8
8
|
|
|
9
9
|
describe('createMediaConnection', () => {
|
|
10
|
+
let clock;
|
|
11
|
+
beforeEach(() => {
|
|
12
|
+
clock = sinon.useFakeTimers();
|
|
13
|
+
});
|
|
10
14
|
const webex = MockWebex();
|
|
11
15
|
|
|
12
16
|
const fakeRoapMediaConnection = {
|
|
@@ -45,6 +49,7 @@ describe('createMediaConnection', () => {
|
|
|
45
49
|
};
|
|
46
50
|
afterEach(() => {
|
|
47
51
|
sinon.restore();
|
|
52
|
+
clock.uninstall()
|
|
48
53
|
});
|
|
49
54
|
|
|
50
55
|
it('creates a RoapMediaConnection when multistream is disabled', () => {
|