@webex/plugin-meetings 3.11.0-next.42 → 3.11.0-next.44
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/aiEnableRequest/index.js +1 -1
- package/dist/annotation/index.js +11 -2
- package/dist/annotation/index.js.map +1 -1
- package/dist/breakouts/breakout.js +1 -1
- package/dist/breakouts/index.js +1 -1
- package/dist/constants.js +3 -2
- package/dist/constants.js.map +1 -1
- package/dist/interpretation/index.js +1 -1
- package/dist/interpretation/siLanguage.js +1 -1
- package/dist/locus-info/index.js +11 -26
- package/dist/locus-info/index.js.map +1 -1
- package/dist/meeting/index.js +926 -843
- package/dist/meeting/index.js.map +1 -1
- package/dist/meeting/util.js +5 -1
- package/dist/meeting/util.js.map +1 -1
- package/dist/types/constants.d.ts +1 -0
- package/dist/types/meeting/index.d.ts +9 -1
- package/dist/webinar/index.js +209 -103
- package/dist/webinar/index.js.map +1 -1
- package/package.json +2 -2
- package/src/annotation/index.ts +21 -4
- package/src/constants.ts +1 -0
- package/src/locus-info/index.ts +8 -9
- package/src/meeting/index.ts +60 -36
- package/src/meeting/util.ts +4 -1
- package/src/webinar/index.ts +113 -4
- package/test/unit/spec/annotation/index.ts +69 -7
- package/test/unit/spec/locus-info/index.js +14 -0
- package/test/unit/spec/meeting/index.js +160 -54
- package/test/unit/spec/meeting/utils.js +5 -4
- package/test/unit/spec/webinar/index.ts +224 -36
|
@@ -7,6 +7,7 @@ import LLMChannel from '@webex/internal-plugin-llm';
|
|
|
7
7
|
|
|
8
8
|
import AnnotationService from '../../../../src/annotation/index';
|
|
9
9
|
import {ANNOTATION_RELAY_TYPES, ANNOTATION_REQUEST_TYPE, EVENT_TRIGGERS} from '../../../../src/annotation/constants';
|
|
10
|
+
import {LLM_PRACTICE_SESSION} from '../../../../src/constants';
|
|
10
11
|
|
|
11
12
|
|
|
12
13
|
describe('live-annotation', () => {
|
|
@@ -28,6 +29,7 @@ describe('live-annotation', () => {
|
|
|
28
29
|
annotationService = webex.internal.annotation;
|
|
29
30
|
annotationService.connect = sinon.stub().resolves(true);
|
|
30
31
|
annotationService.webex.internal.llm.isConnected = sinon.stub().returns(true);
|
|
32
|
+
annotationService.webex.internal.llm.getSocket = sinon.stub().returns(undefined);
|
|
31
33
|
annotationService.webex.internal.llm.getBinding = sinon.stub().returns(undefined);
|
|
32
34
|
annotationService.webex.internal.llm.getLocusUrl = sinon.stub().returns(locusUrl);
|
|
33
35
|
annotationService.approvalUrl = 'url/approval';
|
|
@@ -183,7 +185,13 @@ describe('live-annotation', () => {
|
|
|
183
185
|
|
|
184
186
|
annotationService.listenToEvents();
|
|
185
187
|
|
|
186
|
-
assert.
|
|
188
|
+
assert.calledWithExactly(spy.firstCall, 'event:relay.event', sinon.match.func, sinon.match.object);
|
|
189
|
+
assert.calledWithExactly(
|
|
190
|
+
spy.secondCall,
|
|
191
|
+
`event:relay.event:${LLM_PRACTICE_SESSION}`,
|
|
192
|
+
sinon.match.func,
|
|
193
|
+
sinon.match.object
|
|
194
|
+
);
|
|
187
195
|
});
|
|
188
196
|
|
|
189
197
|
});
|
|
@@ -226,14 +234,11 @@ describe('live-annotation', () => {
|
|
|
226
234
|
});
|
|
227
235
|
|
|
228
236
|
describe('sendStrokeData', () => {
|
|
237
|
+
let strokeData;
|
|
229
238
|
|
|
230
239
|
beforeEach(async () => {
|
|
231
240
|
annotationService.webex.internal.llm.socket = new MockWebSocket();
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
it('works on publish Stroke Data', async () => {
|
|
236
|
-
const strokeData = {
|
|
241
|
+
strokeData = {
|
|
237
242
|
content: {
|
|
238
243
|
"contentsBuffer": [{
|
|
239
244
|
"contentArray": [{
|
|
@@ -249,8 +254,11 @@ describe('live-annotation', () => {
|
|
|
249
254
|
shareInstanceId: '7fa6fe07-dcb1-41ad-973d-7bcf65fab55d',
|
|
250
255
|
encryptionKeyUrl: "encryptionKeyUrl",
|
|
251
256
|
version: '1',
|
|
252
|
-
}
|
|
257
|
+
};
|
|
258
|
+
});
|
|
259
|
+
|
|
253
260
|
|
|
261
|
+
it('works on publish Stroke Data', async () => {
|
|
254
262
|
annotationService.publishEncrypted(strokeData.content, strokeData);
|
|
255
263
|
|
|
256
264
|
const sendObject = {
|
|
@@ -283,6 +291,49 @@ describe('live-annotation', () => {
|
|
|
283
291
|
assert.calledOnceWithExactly(annotationService.webex.internal.llm.socket.send, sendObject);
|
|
284
292
|
});
|
|
285
293
|
|
|
294
|
+
it('uses the practice-session socket and binding only when the practice-session session is connected', () => {
|
|
295
|
+
const practiceSocket = new MockWebSocket();
|
|
296
|
+
|
|
297
|
+
annotationService.webex.internal.llm.isConnected.callsFake((sessionId) =>
|
|
298
|
+
sessionId === LLM_PRACTICE_SESSION
|
|
299
|
+
);
|
|
300
|
+
annotationService.webex.internal.llm.getSocket
|
|
301
|
+
.withArgs(LLM_PRACTICE_SESSION)
|
|
302
|
+
.returns(practiceSocket);
|
|
303
|
+
annotationService.webex.internal.llm.getBinding
|
|
304
|
+
.withArgs(LLM_PRACTICE_SESSION)
|
|
305
|
+
.returns('practice-binding');
|
|
306
|
+
|
|
307
|
+
annotationService.publishEncrypted(strokeData.content, strokeData);
|
|
308
|
+
|
|
309
|
+
assert.calledOnce(practiceSocket.send);
|
|
310
|
+
assert.notCalled(annotationService.webex.internal.llm.socket.send);
|
|
311
|
+
|
|
312
|
+
const sent = practiceSocket.send.getCall(0).args[0];
|
|
313
|
+
assert.equal(sent.recipients.route, 'practice-binding');
|
|
314
|
+
});
|
|
315
|
+
|
|
316
|
+
it('falls back to the default socket and binding when the practice-session socket exists but is not connected', () => {
|
|
317
|
+
const practiceSocket = new MockWebSocket();
|
|
318
|
+
|
|
319
|
+
annotationService.webex.internal.llm.isConnected.callsFake((sessionId) => !sessionId);
|
|
320
|
+
annotationService.webex.internal.llm.getSocket
|
|
321
|
+
.withArgs(LLM_PRACTICE_SESSION)
|
|
322
|
+
.returns(practiceSocket);
|
|
323
|
+
annotationService.webex.internal.llm.getBinding
|
|
324
|
+
.withArgs(LLM_PRACTICE_SESSION)
|
|
325
|
+
.returns('practice-binding');
|
|
326
|
+
annotationService.webex.internal.llm.getBinding.returns('default-binding');
|
|
327
|
+
|
|
328
|
+
annotationService.publishEncrypted(strokeData.content, strokeData);
|
|
329
|
+
|
|
330
|
+
assert.notCalled(practiceSocket.send);
|
|
331
|
+
assert.calledOnce(annotationService.webex.internal.llm.socket.send);
|
|
332
|
+
|
|
333
|
+
const sent = annotationService.webex.internal.llm.socket.send.getCall(0).args[0];
|
|
334
|
+
assert.equal(sent.recipients.route, 'default-binding');
|
|
335
|
+
});
|
|
336
|
+
|
|
286
337
|
});
|
|
287
338
|
|
|
288
339
|
|
|
@@ -441,10 +492,21 @@ describe('live-annotation', () => {
|
|
|
441
492
|
annotationService.eventDataProcessor,
|
|
442
493
|
annotationService
|
|
443
494
|
);
|
|
495
|
+
assert.calledWith(
|
|
496
|
+
llmOn,
|
|
497
|
+
`event:relay.event:${LLM_PRACTICE_SESSION}`,
|
|
498
|
+
annotationService.eventDataProcessor,
|
|
499
|
+
annotationService
|
|
500
|
+
);
|
|
444
501
|
assert.match(annotationService.hasSubscribedToEvents, true);
|
|
445
502
|
|
|
446
503
|
annotationService.deregisterEvents();
|
|
447
504
|
assert.calledWith(llmOff, 'event:relay.event', annotationService.eventDataProcessor);
|
|
505
|
+
assert.calledWith(
|
|
506
|
+
llmOff,
|
|
507
|
+
`event:relay.event:${LLM_PRACTICE_SESSION}`,
|
|
508
|
+
annotationService.eventDataProcessor
|
|
509
|
+
);
|
|
448
510
|
assert.calledWith(
|
|
449
511
|
mercuryOff,
|
|
450
512
|
'event:locus.approval_request',
|
|
@@ -934,6 +934,20 @@ describe('plugin-meetings', () => {
|
|
|
934
934
|
MEETING_REMOVED_REASON.SELF_REMOVED
|
|
935
935
|
);
|
|
936
936
|
});
|
|
937
|
+
|
|
938
|
+
// this could happen if meeting gets destroyed while we're doing some async hash tree operation like a sync
|
|
939
|
+
it('should handle MEETING_ENDED correctly when meeting is not found in the collection', () => {
|
|
940
|
+
const collectionGetStub = sinon
|
|
941
|
+
.stub(locusInfo.webex.meetings.meetingCollection, 'get')
|
|
942
|
+
.returns(null);
|
|
943
|
+
const destroyStub = sinon.stub(locusInfo.webex.meetings, 'destroy');
|
|
944
|
+
|
|
945
|
+
// simulate an update from the HashTreeParser (normally this would be triggered by incoming locus messages)
|
|
946
|
+
locusInfoUpdateCallback(MEETING_ENDED);
|
|
947
|
+
|
|
948
|
+
assert.calledOnceWithExactly(collectionGetStub, locusInfo.meetingId);
|
|
949
|
+
assert.notCalled(destroyStub);
|
|
950
|
+
});
|
|
937
951
|
});
|
|
938
952
|
});
|
|
939
953
|
|
|
@@ -267,6 +267,7 @@ describe('plugin-meetings', () => {
|
|
|
267
267
|
};
|
|
268
268
|
webex.internal.llm.isDataChannelTokenEnabled = sinon.stub().resolves(false);
|
|
269
269
|
webex.internal.llm.on = sinon.stub();
|
|
270
|
+
webex.internal.voicea.announce = sinon.stub();
|
|
270
271
|
webex.internal.newMetrics.callDiagnosticLatencies = new CallDiagnosticLatencies(
|
|
271
272
|
{},
|
|
272
273
|
{parent: webex}
|
|
@@ -6400,7 +6401,10 @@ describe('plugin-meetings', () => {
|
|
|
6400
6401
|
meeting.statsAnalyzer = {stopAnalyzer: sinon.stub().resolves()};
|
|
6401
6402
|
meeting.unsetPeerConnections = sinon.stub().returns(true);
|
|
6402
6403
|
meeting.logger.error = sinon.stub().returns(true);
|
|
6403
|
-
meeting.
|
|
6404
|
+
meeting.clearMeetingData = sinon.stub().callsFake(async () => {
|
|
6405
|
+
meeting.audio = null;
|
|
6406
|
+
meeting.video = null;
|
|
6407
|
+
});
|
|
6404
6408
|
webex.internal.voicea.off = sinon.stub().returns(true);
|
|
6405
6409
|
meeting.stopTranscription = sinon.stub();
|
|
6406
6410
|
meeting.transcription = {};
|
|
@@ -6427,9 +6431,7 @@ describe('plugin-meetings', () => {
|
|
|
6427
6431
|
assert.calledOnce(meeting.closePeerConnections);
|
|
6428
6432
|
assert.calledOnce(meeting.unsetRemoteStreams);
|
|
6429
6433
|
assert.calledOnce(meeting.unsetPeerConnections);
|
|
6430
|
-
assert.calledOnce(meeting.
|
|
6431
|
-
assert.calledOnce(meeting.annotation.deregisterEvents);
|
|
6432
|
-
assert.calledWith(webex.internal.llm.off, 'event:relay.event', meeting.processRelayEvent);
|
|
6434
|
+
assert.calledOnce(meeting.clearMeetingData);
|
|
6433
6435
|
});
|
|
6434
6436
|
|
|
6435
6437
|
it('should reset call diagnostic latencies correctly', async () => {
|
|
@@ -8430,7 +8432,10 @@ describe('plugin-meetings', () => {
|
|
|
8430
8432
|
meeting.statsAnalyzer = {stopAnalyzer: sinon.stub().resolves()};
|
|
8431
8433
|
meeting.unsetPeerConnections = sinon.stub().returns(true);
|
|
8432
8434
|
meeting.logger.error = sinon.stub().returns(true);
|
|
8433
|
-
meeting.
|
|
8435
|
+
meeting.clearMeetingData = sinon.stub().callsFake(async () => {
|
|
8436
|
+
meeting.audio = null;
|
|
8437
|
+
meeting.video = null;
|
|
8438
|
+
});
|
|
8434
8439
|
meeting.transcription = {};
|
|
8435
8440
|
meeting.stopTranscription = sinon.stub();
|
|
8436
8441
|
|
|
@@ -8456,10 +8461,7 @@ describe('plugin-meetings', () => {
|
|
|
8456
8461
|
assert.calledOnce(meeting?.closePeerConnections);
|
|
8457
8462
|
assert.calledOnce(meeting?.unsetRemoteStreams);
|
|
8458
8463
|
assert.calledOnce(meeting?.unsetPeerConnections);
|
|
8459
|
-
assert.calledOnce(meeting?.
|
|
8460
|
-
|
|
8461
|
-
assert.called(meeting.annotation.deregisterEvents);
|
|
8462
|
-
assert.calledWith(webex.internal.llm.off, 'event:relay.event', meeting.processRelayEvent);
|
|
8464
|
+
assert.calledOnce(meeting?.clearMeetingData);
|
|
8463
8465
|
});
|
|
8464
8466
|
});
|
|
8465
8467
|
|
|
@@ -12674,33 +12676,72 @@ describe('plugin-meetings', () => {
|
|
|
12674
12676
|
|
|
12675
12677
|
describe('#handleDataChannelUrlChange', () => {
|
|
12676
12678
|
let updateLLMConnectionSpy;
|
|
12679
|
+
let updatePSDataChannelSpy;
|
|
12677
12680
|
|
|
12678
12681
|
beforeEach(() => {
|
|
12679
12682
|
updateLLMConnectionSpy = sinon.spy(meeting, 'updateLLMConnection');
|
|
12683
|
+
updatePSDataChannelSpy = sinon.stub(meeting.webinar, 'updatePSDataChannel').resolves();
|
|
12684
|
+
meeting.webinar.isJoinPracticeSessionDataChannel = sinon.stub().returns(false);
|
|
12680
12685
|
});
|
|
12681
12686
|
|
|
12682
|
-
const check = (
|
|
12683
|
-
|
|
12687
|
+
const check = (
|
|
12688
|
+
url,
|
|
12689
|
+
practiceSessionDatachannelUrl,
|
|
12690
|
+
{expectedMainCalled, expectedPracticeCalled}
|
|
12691
|
+
) => {
|
|
12692
|
+
meeting.handleDataChannelUrlChange(url, practiceSessionDatachannelUrl);
|
|
12684
12693
|
|
|
12685
|
-
if (
|
|
12694
|
+
if (expectedMainCalled) {
|
|
12686
12695
|
assert.calledWith(updateLLMConnectionSpy);
|
|
12687
12696
|
} else {
|
|
12688
12697
|
assert.notCalled(updateLLMConnectionSpy);
|
|
12689
12698
|
}
|
|
12699
|
+
|
|
12700
|
+
if (expectedPracticeCalled) {
|
|
12701
|
+
assert.calledWith(updatePSDataChannelSpy);
|
|
12702
|
+
} else {
|
|
12703
|
+
assert.notCalled(updatePSDataChannelSpy);
|
|
12704
|
+
}
|
|
12690
12705
|
};
|
|
12691
12706
|
|
|
12692
12707
|
it('calls deferred updateLLMConnection if datachannelURL is set and the enableAutomaticLLM is true', () => {
|
|
12693
12708
|
meeting.config.enableAutomaticLLM = true;
|
|
12694
|
-
check('some url', true);
|
|
12709
|
+
check('some url', undefined, {expectedMainCalled: true, expectedPracticeCalled: false});
|
|
12695
12710
|
});
|
|
12696
12711
|
|
|
12697
12712
|
it('does not call updateLLMConnection if datachannelURL is undefined', () => {
|
|
12698
12713
|
meeting.config.enableAutomaticLLM = true;
|
|
12699
|
-
check(undefined,
|
|
12714
|
+
check(undefined, undefined, {
|
|
12715
|
+
expectedMainCalled: false,
|
|
12716
|
+
expectedPracticeCalled: false,
|
|
12717
|
+
});
|
|
12700
12718
|
});
|
|
12701
12719
|
|
|
12702
12720
|
it('does not call updateLLMConnection if enableAutomaticLLM is false', () => {
|
|
12703
|
-
check('some url',
|
|
12721
|
+
check('some url', 'some practice url', {
|
|
12722
|
+
expectedMainCalled: false,
|
|
12723
|
+
expectedPracticeCalled: false,
|
|
12724
|
+
});
|
|
12725
|
+
});
|
|
12726
|
+
|
|
12727
|
+
it('calls updatePSDataChannel when practice-session routing is active', () => {
|
|
12728
|
+
meeting.config.enableAutomaticLLM = true;
|
|
12729
|
+
meeting.webinar.isJoinPracticeSessionDataChannel.returns(true);
|
|
12730
|
+
|
|
12731
|
+
check('some url', 'some practice url', {
|
|
12732
|
+
expectedMainCalled: true,
|
|
12733
|
+
expectedPracticeCalled: true,
|
|
12734
|
+
});
|
|
12735
|
+
});
|
|
12736
|
+
|
|
12737
|
+
it('does not call updatePSDataChannel when the main datachannelURL is undefined', () => {
|
|
12738
|
+
meeting.config.enableAutomaticLLM = true;
|
|
12739
|
+
meeting.webinar.isJoinPracticeSessionDataChannel.returns(true);
|
|
12740
|
+
|
|
12741
|
+
check(undefined, 'some practice url', {
|
|
12742
|
+
expectedMainCalled: false,
|
|
12743
|
+
expectedPracticeCalled: false,
|
|
12744
|
+
});
|
|
12704
12745
|
});
|
|
12705
12746
|
});
|
|
12706
12747
|
|
|
@@ -12838,6 +12879,9 @@ describe('plugin-meetings', () => {
|
|
|
12838
12879
|
'event:locus.state_message',
|
|
12839
12880
|
meeting.processLocusLLMEvent
|
|
12840
12881
|
);
|
|
12882
|
+
assert.isFalse(
|
|
12883
|
+
meeting.webex.internal.llm.off.calledWithExactly('online', meeting.handleLLMOnline)
|
|
12884
|
+
);
|
|
12841
12885
|
});
|
|
12842
12886
|
it('disconnects if the data channel url has changed', async () => {
|
|
12843
12887
|
meeting.joinedWith = {state: 'JOINED'};
|
|
@@ -12887,6 +12931,9 @@ describe('plugin-meetings', () => {
|
|
|
12887
12931
|
'event:locus.state_message',
|
|
12888
12932
|
meeting.processLocusLLMEvent
|
|
12889
12933
|
);
|
|
12934
|
+
assert.isFalse(
|
|
12935
|
+
meeting.webex.internal.llm.off.calledWithExactly('online', meeting.handleLLMOnline)
|
|
12936
|
+
);
|
|
12890
12937
|
});
|
|
12891
12938
|
it('disconnects when the state is not JOINED', async () => {
|
|
12892
12939
|
meeting.joinedWith = {state: 'any other state'};
|
|
@@ -12903,8 +12950,48 @@ describe('plugin-meetings', () => {
|
|
|
12903
12950
|
});
|
|
12904
12951
|
assert.notCalled(webex.internal.llm.registerAndConnect);
|
|
12905
12952
|
assert.equal(result, undefined);
|
|
12953
|
+
assert.isFalse(
|
|
12954
|
+
meeting.webex.internal.llm.off.calledWithExactly('online', meeting.handleLLMOnline)
|
|
12955
|
+
);
|
|
12956
|
+
});
|
|
12957
|
+
it('rethrows disconnect errors during reconnect cleanup after removing relay listeners and timer', async () => {
|
|
12958
|
+
const disconnectError = new Error('disconnect failed');
|
|
12959
|
+
|
|
12960
|
+
meeting.joinedWith = {state: 'JOINED'};
|
|
12961
|
+
webex.internal.llm.isConnected.returns(true);
|
|
12962
|
+
webex.internal.llm.getLocusUrl.returns('a url');
|
|
12963
|
+
webex.internal.llm.disconnectLLM.rejects(disconnectError);
|
|
12964
|
+
|
|
12965
|
+
meeting.locusInfo = {
|
|
12966
|
+
url: 'a different url',
|
|
12967
|
+
info: {datachannelUrl: 'a datachannel url'},
|
|
12968
|
+
self: {},
|
|
12969
|
+
};
|
|
12970
|
+
|
|
12971
|
+
try {
|
|
12972
|
+
await meeting.updateLLMConnection();
|
|
12973
|
+
assert.fail('Expected updateLLMConnection to reject when disconnectLLM fails');
|
|
12974
|
+
} catch (error) {
|
|
12975
|
+
assert.equal(error, disconnectError);
|
|
12976
|
+
}
|
|
12977
|
+
|
|
12978
|
+
assert.notCalled(webex.internal.llm.registerAndConnect);
|
|
12979
|
+
assert.calledWithExactly(
|
|
12980
|
+
meeting.webex.internal.llm.off,
|
|
12981
|
+
'event:relay.event',
|
|
12982
|
+
meeting.processRelayEvent
|
|
12983
|
+
);
|
|
12984
|
+
assert.calledWithExactly(
|
|
12985
|
+
meeting.webex.internal.llm.off,
|
|
12986
|
+
'event:locus.state_message',
|
|
12987
|
+
meeting.processLocusLLMEvent
|
|
12988
|
+
);
|
|
12989
|
+
assert.isFalse(
|
|
12990
|
+
meeting.webex.internal.llm.off.calledWithExactly('online', meeting.handleLLMOnline)
|
|
12991
|
+
);
|
|
12992
|
+
assert.calledOnce(meeting.clearLLMHealthCheckTimer);
|
|
12906
12993
|
});
|
|
12907
|
-
it('
|
|
12994
|
+
it('still need connect main session data channel when PS started', async () => {
|
|
12908
12995
|
meeting.joinedWith = {state: 'JOINED'};
|
|
12909
12996
|
meeting.locusInfo = {
|
|
12910
12997
|
url: 'a url',
|
|
@@ -12920,7 +13007,7 @@ describe('plugin-meetings', () => {
|
|
|
12920
13007
|
assert.calledWithExactly(
|
|
12921
13008
|
webex.internal.llm.registerAndConnect,
|
|
12922
13009
|
'a url',
|
|
12923
|
-
'
|
|
13010
|
+
'a datachannel url',
|
|
12924
13011
|
undefined
|
|
12925
13012
|
);
|
|
12926
13013
|
});
|
|
@@ -12965,43 +13052,6 @@ describe('plugin-meetings', () => {
|
|
|
12965
13052
|
|
|
12966
13053
|
assert.notCalled(webex.internal.llm.setDatachannelToken);
|
|
12967
13054
|
});
|
|
12968
|
-
it('uses practice session token when in PS even if refreshed token exists', async () => {
|
|
12969
|
-
meeting.joinedWith = {state: 'JOINED'};
|
|
12970
|
-
|
|
12971
|
-
meeting.locusInfo = {
|
|
12972
|
-
url: 'a url',
|
|
12973
|
-
info: {
|
|
12974
|
-
datachannelUrl: 'a datachannel url',
|
|
12975
|
-
practiceSessionDatachannelUrl: 'ps-url',
|
|
12976
|
-
},
|
|
12977
|
-
self: {
|
|
12978
|
-
datachannelToken: 'locus-token',
|
|
12979
|
-
practiceSessionDatachannelToken: 'ps-token',
|
|
12980
|
-
},
|
|
12981
|
-
};
|
|
12982
|
-
|
|
12983
|
-
meeting.webinar.isJoinPracticeSessionDataChannel.returns(true);
|
|
12984
|
-
|
|
12985
|
-
webex.internal.llm.getDatachannelToken
|
|
12986
|
-
.withArgs(true)
|
|
12987
|
-
.returns('refreshed-ps-token') // refreshed practice token
|
|
12988
|
-
.withArgs(false)
|
|
12989
|
-
.returns('refreshed-normal-token'); // refreshed normal token
|
|
12990
|
-
|
|
12991
|
-
await meeting.updateLLMConnection();
|
|
12992
|
-
|
|
12993
|
-
assert.calledWithExactly(
|
|
12994
|
-
webex.internal.llm.registerAndConnect,
|
|
12995
|
-
'a url',
|
|
12996
|
-
'ps-url',
|
|
12997
|
-
'ps-token'
|
|
12998
|
-
);
|
|
12999
|
-
assert.calledWithExactly(
|
|
13000
|
-
webex.internal.llm.setDatachannelToken,
|
|
13001
|
-
'ps-token',
|
|
13002
|
-
'practiceSession'
|
|
13003
|
-
);
|
|
13004
|
-
});
|
|
13005
13055
|
|
|
13006
13056
|
it('does not pass token when data channel with jwt token is disabled', async () => {
|
|
13007
13057
|
meeting.joinedWith = {state: 'JOINED'};
|
|
@@ -13024,6 +13074,62 @@ describe('plugin-meetings', () => {
|
|
|
13024
13074
|
);
|
|
13025
13075
|
assert.calledWithExactly(webex.internal.llm.setDatachannelToken, 'token-123', 'default');
|
|
13026
13076
|
});
|
|
13077
|
+
|
|
13078
|
+
describe('#clearMeetingData', () => {
|
|
13079
|
+
beforeEach(() => {
|
|
13080
|
+
webex.internal.llm.isConnected = sinon.stub().returns(true);
|
|
13081
|
+
webex.internal.llm.disconnectLLM = sinon.stub().resolves();
|
|
13082
|
+
webex.internal.llm.off = sinon.stub();
|
|
13083
|
+
meeting.annotation.deregisterEvents = sinon.stub();
|
|
13084
|
+
meeting.clearLLMHealthCheckTimer = sinon.stub();
|
|
13085
|
+
meeting.stopTranscription = sinon.stub();
|
|
13086
|
+
meeting.transcription = {};
|
|
13087
|
+
meeting.shareStatus = 'no-share';
|
|
13088
|
+
});
|
|
13089
|
+
|
|
13090
|
+
it('disconnects llm and removes online and relay listeners during meeting data cleanup', async () => {
|
|
13091
|
+
await meeting.clearMeetingData();
|
|
13092
|
+
|
|
13093
|
+
assert.calledOnceWithExactly(webex.internal.llm.disconnectLLM, {
|
|
13094
|
+
code: 3050,
|
|
13095
|
+
reason: 'done (permanent)',
|
|
13096
|
+
});
|
|
13097
|
+
assert.calledWithExactly(webex.internal.llm.off, 'online', meeting.handleLLMOnline);
|
|
13098
|
+
assert.calledWithExactly(
|
|
13099
|
+
webex.internal.llm.off,
|
|
13100
|
+
'event:relay.event',
|
|
13101
|
+
meeting.processRelayEvent
|
|
13102
|
+
);
|
|
13103
|
+
assert.calledWithExactly(
|
|
13104
|
+
webex.internal.llm.off,
|
|
13105
|
+
'event:locus.state_message',
|
|
13106
|
+
meeting.processLocusLLMEvent
|
|
13107
|
+
);
|
|
13108
|
+
assert.calledOnce(meeting.clearLLMHealthCheckTimer);
|
|
13109
|
+
assert.calledOnce(meeting.stopTranscription);
|
|
13110
|
+
assert.calledOnce(meeting.annotation.deregisterEvents);
|
|
13111
|
+
});
|
|
13112
|
+
it('continues cleanup when disconnectLLM fails during meeting data cleanup', async () => {
|
|
13113
|
+
webex.internal.llm.disconnectLLM.rejects(new Error('disconnect failed'));
|
|
13114
|
+
|
|
13115
|
+
await meeting.clearMeetingData();
|
|
13116
|
+
|
|
13117
|
+
assert.calledWithExactly(webex.internal.llm.off, 'online', meeting.handleLLMOnline);
|
|
13118
|
+
assert.calledWithExactly(
|
|
13119
|
+
webex.internal.llm.off,
|
|
13120
|
+
'event:relay.event',
|
|
13121
|
+
meeting.processRelayEvent
|
|
13122
|
+
);
|
|
13123
|
+
assert.calledWithExactly(
|
|
13124
|
+
webex.internal.llm.off,
|
|
13125
|
+
'event:locus.state_message',
|
|
13126
|
+
meeting.processLocusLLMEvent
|
|
13127
|
+
);
|
|
13128
|
+
assert.calledOnce(meeting.clearLLMHealthCheckTimer);
|
|
13129
|
+
assert.calledOnce(meeting.stopTranscription);
|
|
13130
|
+
assert.calledOnce(meeting.annotation.deregisterEvents);
|
|
13131
|
+
});
|
|
13132
|
+
});
|
|
13027
13133
|
});
|
|
13028
13134
|
|
|
13029
13135
|
describe('#setLocus', () => {
|
|
@@ -54,8 +54,9 @@ describe('plugin-meetings', () => {
|
|
|
54
54
|
meeting.unsetPeerConnections = sinon.stub();
|
|
55
55
|
meeting.reconnectionManager = {cleanUp: sinon.stub()};
|
|
56
56
|
meeting.stopKeepAlive = sinon.stub();
|
|
57
|
-
meeting.
|
|
57
|
+
meeting.cleanupLLMConneciton = sinon.stub().resolves();
|
|
58
58
|
meeting.breakouts = {cleanUp: sinon.stub()};
|
|
59
|
+
meeting.webinar = {cleanUp: sinon.stub()};
|
|
59
60
|
meeting.annotaion = {cleanUp: sinon.stub()};
|
|
60
61
|
meeting.getWebexObject = sinon.stub().returns(webex);
|
|
61
62
|
meeting.simultaneousInterpretation = {cleanUp: sinon.stub()};
|
|
@@ -85,7 +86,7 @@ describe('plugin-meetings', () => {
|
|
|
85
86
|
assert.calledOnce(meeting.unsetPeerConnections);
|
|
86
87
|
assert.calledOnce(meeting.reconnectionManager.cleanUp);
|
|
87
88
|
assert.calledOnce(meeting.stopKeepAlive);
|
|
88
|
-
assert.
|
|
89
|
+
assert.calledOnceWithExactly(meeting.cleanupLLMConneciton, {throwOnError: false});
|
|
89
90
|
assert.calledOnce(meeting.breakouts.cleanUp);
|
|
90
91
|
assert.calledOnce(meeting.simultaneousInterpretation.cleanUp);
|
|
91
92
|
assert.calledOnce(webex.internal.device.meetingEnded);
|
|
@@ -106,7 +107,7 @@ describe('plugin-meetings', () => {
|
|
|
106
107
|
assert.calledOnce(meeting.unsetPeerConnections);
|
|
107
108
|
assert.calledOnce(meeting.reconnectionManager.cleanUp);
|
|
108
109
|
assert.calledOnce(meeting.stopKeepAlive);
|
|
109
|
-
assert.notCalled(meeting.
|
|
110
|
+
assert.notCalled(meeting.cleanupLLMConneciton);
|
|
110
111
|
assert.calledOnce(meeting.breakouts.cleanUp);
|
|
111
112
|
assert.calledOnce(meeting.simultaneousInterpretation.cleanUp);
|
|
112
113
|
assert.calledOnce(webex.internal.device.meetingEnded);
|
|
@@ -126,7 +127,7 @@ describe('plugin-meetings', () => {
|
|
|
126
127
|
assert.calledOnce(meeting.unsetPeerConnections);
|
|
127
128
|
assert.calledOnce(meeting.reconnectionManager.cleanUp);
|
|
128
129
|
assert.calledOnce(meeting.stopKeepAlive);
|
|
129
|
-
assert.notCalled(meeting.
|
|
130
|
+
assert.notCalled(meeting.cleanupLLMConneciton);
|
|
130
131
|
assert.calledOnce(meeting.breakouts.cleanUp);
|
|
131
132
|
assert.calledOnce(meeting.simultaneousInterpretation.cleanUp);
|
|
132
133
|
assert.calledOnce(webex.internal.device.meetingEnded);
|