@webex/plugin-meetings 3.12.0-next.35 → 3.12.0-next.37
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/breakouts/breakout.js +1 -1
- package/dist/breakouts/index.js +1 -1
- package/dist/constants.js +2 -4
- 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 +52 -20
- package/dist/locus-info/index.js.map +1 -1
- package/dist/locus-info/types.js +16 -0
- package/dist/locus-info/types.js.map +1 -1
- package/dist/meeting/index.js +587 -541
- package/dist/meeting/index.js.map +1 -1
- package/dist/meetings/index.js +28 -15
- package/dist/meetings/index.js.map +1 -1
- package/dist/meetings/util.js +11 -1
- package/dist/meetings/util.js.map +1 -1
- package/dist/types/constants.d.ts +0 -1
- package/dist/types/locus-info/index.d.ts +8 -1
- package/dist/types/locus-info/types.d.ts +17 -1
- package/dist/types/meeting/index.d.ts +8 -1
- package/dist/webinar/index.js +1 -1
- package/package.json +1 -1
- package/src/constants.ts +1 -2
- package/src/locus-info/index.ts +42 -8
- package/src/locus-info/types.ts +19 -1
- package/src/meeting/index.ts +28 -1
- package/src/meetings/index.ts +20 -10
- package/src/meetings/util.ts +14 -2
- package/test/unit/spec/locus-info/index.js +76 -8
- package/test/unit/spec/meeting/index.js +87 -0
- package/test/unit/spec/meetings/index.js +5 -5
- package/test/unit/spec/meetings/utils.js +13 -0
|
@@ -221,6 +221,47 @@ describe('plugin-meetings', () => {
|
|
|
221
221
|
assert.isTrue(locusInfo.emitChange);
|
|
222
222
|
});
|
|
223
223
|
|
|
224
|
+
it('calls onLocusSynced callback passed as second argument with full locus from join response', async () => {
|
|
225
|
+
const syncedLocus = {url: 'http://locus-url.com', participants: []};
|
|
226
|
+
const onLocusSynced = sinon.stub();
|
|
227
|
+
|
|
228
|
+
await locusInfo.initialSetup(
|
|
229
|
+
{
|
|
230
|
+
trigger: 'join-response',
|
|
231
|
+
locus: syncedLocus,
|
|
232
|
+
},
|
|
233
|
+
onLocusSynced
|
|
234
|
+
);
|
|
235
|
+
|
|
236
|
+
assert.calledOnceWithExactly(onLocusSynced, syncedLocus);
|
|
237
|
+
});
|
|
238
|
+
|
|
239
|
+
it('swallows onLocusSynced callback errors and logs warn', async () => {
|
|
240
|
+
const syncedLocus = {url: 'http://locus-url.com', participants: []};
|
|
241
|
+
const callbackError = new Error('onLocusSynced failed');
|
|
242
|
+
const onLocusSynced = sinon.stub().throws(callbackError);
|
|
243
|
+
const loggerWarnStub = LoggerProxy.logger.warn?.isSinonProxy
|
|
244
|
+
? LoggerProxy.logger.warn
|
|
245
|
+
: sinon.stub(LoggerProxy.logger, 'warn');
|
|
246
|
+
|
|
247
|
+
loggerWarnStub.resetHistory();
|
|
248
|
+
|
|
249
|
+
await locusInfo.initialSetup(
|
|
250
|
+
{
|
|
251
|
+
trigger: 'join-response',
|
|
252
|
+
locus: syncedLocus,
|
|
253
|
+
},
|
|
254
|
+
onLocusSynced
|
|
255
|
+
);
|
|
256
|
+
|
|
257
|
+
assert.calledOnceWithExactly(onLocusSynced, syncedLocus);
|
|
258
|
+
assert.calledOnce(loggerWarnStub);
|
|
259
|
+
assert.match(
|
|
260
|
+
loggerWarnStub.firstCall.args[0],
|
|
261
|
+
/Locus-info:index#initialSetup --> onLocusSynced callback failed/
|
|
262
|
+
);
|
|
263
|
+
});
|
|
264
|
+
|
|
224
265
|
it('should initialize the hash tree parser correctly when triggered from a get loci response containing visible datasets', async () => {
|
|
225
266
|
const visibleDataSets = ['dataset1', 'dataset2'];
|
|
226
267
|
const locus = createLocusWithVisibleDataSets(visibleDataSets);
|
|
@@ -4677,6 +4718,9 @@ describe('plugin-meetings', () => {
|
|
|
4677
4718
|
});
|
|
4678
4719
|
|
|
4679
4720
|
describe('#isMeetingActive', () => {
|
|
4721
|
+
beforeEach(() => {
|
|
4722
|
+
webex.internal.newMetrics.submitClientEvent.resetHistory();
|
|
4723
|
+
});
|
|
4680
4724
|
forEach([_CALL_, _SIP_BRIDGE_, _SPACE_SHARE_], (type) => {
|
|
4681
4725
|
describe(`type = ${type}`, () => {
|
|
4682
4726
|
it('sends client event correctly for state = inactive', () => {
|
|
@@ -4743,7 +4787,7 @@ describe('plugin-meetings', () => {
|
|
|
4743
4787
|
});
|
|
4744
4788
|
});
|
|
4745
4789
|
|
|
4746
|
-
it('sends client event correctly for state =
|
|
4790
|
+
it('sends client event correctly for state = MEETING_INACTIVE', () => {
|
|
4747
4791
|
locusInfo.getLocusPartner = sinon.stub().returns({state: MEETING_STATE.STATES.LEFT});
|
|
4748
4792
|
locusInfo.parsedLocus = {
|
|
4749
4793
|
fullState: {
|
|
@@ -4765,7 +4809,7 @@ describe('plugin-meetings', () => {
|
|
|
4765
4809
|
});
|
|
4766
4810
|
});
|
|
4767
4811
|
|
|
4768
|
-
it('
|
|
4812
|
+
it('does not send client event when state = INACTIVE and endMeetingReason = BREAKOUT_ENDED', () => {
|
|
4769
4813
|
locusInfo.getLocusPartner = sinon.stub().returns({state: MEETING_STATE.STATES.LEFT});
|
|
4770
4814
|
locusInfo.parsedLocus = {
|
|
4771
4815
|
fullState: {
|
|
@@ -4774,17 +4818,41 @@ describe('plugin-meetings', () => {
|
|
|
4774
4818
|
};
|
|
4775
4819
|
|
|
4776
4820
|
locusInfo.fullState = {
|
|
4777
|
-
|
|
4821
|
+
state: LOCUS.STATE.INACTIVE,
|
|
4822
|
+
endMeetingReason: 'BREAKOUT_ENDED',
|
|
4778
4823
|
};
|
|
4779
4824
|
|
|
4780
4825
|
locusInfo.isMeetingActive();
|
|
4781
4826
|
|
|
4782
|
-
assert.
|
|
4783
|
-
|
|
4784
|
-
|
|
4785
|
-
|
|
4827
|
+
assert.notCalled(webex.internal.newMetrics.submitClientEvent);
|
|
4828
|
+
});
|
|
4829
|
+
|
|
4830
|
+
it('sends client event correctly for state self removed', () => {
|
|
4831
|
+
locusInfo.emitScoped = sinon.stub();
|
|
4832
|
+
locusInfo.parsedLocus = {
|
|
4833
|
+
fullState: {
|
|
4834
|
+
type: _MEETING_,
|
|
4786
4835
|
},
|
|
4787
|
-
|
|
4836
|
+
self: {
|
|
4837
|
+
removed: true,
|
|
4838
|
+
}
|
|
4839
|
+
};
|
|
4840
|
+
|
|
4841
|
+
locusInfo.isMeetingActive();
|
|
4842
|
+
|
|
4843
|
+
assert.notCalled(webex.internal.newMetrics.submitClientEvent);
|
|
4844
|
+
assert.calledOnceWithExactly(
|
|
4845
|
+
locusInfo.emitScoped,
|
|
4846
|
+
{
|
|
4847
|
+
file: 'locus-info',
|
|
4848
|
+
function: 'isMeetingActive',
|
|
4849
|
+
},
|
|
4850
|
+
EVENTS.DESTROY_MEETING,
|
|
4851
|
+
{
|
|
4852
|
+
reason: MEETING_REMOVED_REASON.SELF_REMOVED,
|
|
4853
|
+
shouldLeave: false,
|
|
4854
|
+
}
|
|
4855
|
+
);
|
|
4788
4856
|
});
|
|
4789
4857
|
});
|
|
4790
4858
|
|
|
@@ -11353,6 +11353,93 @@ describe('plugin-meetings', () => {
|
|
|
11353
11353
|
});
|
|
11354
11354
|
});
|
|
11355
11355
|
|
|
11356
|
+
describe('#finalizeMeetingAfterInitialLocusSetup', () => {
|
|
11357
|
+
it('refreshes destination from synced locus when destination type is LOCUS_ID', () => {
|
|
11358
|
+
const syncedLocus = {url: 'https://locus.example.com/locus/123', info: {topic: 'x'}};
|
|
11359
|
+
|
|
11360
|
+
meeting.destinationType = DESTINATION_TYPE.LOCUS_ID;
|
|
11361
|
+
meeting.destination = {info: {topic: 'old'}};
|
|
11362
|
+
|
|
11363
|
+
meeting.finalizeMeetingAfterInitialLocusSetup(syncedLocus);
|
|
11364
|
+
|
|
11365
|
+
assert.equal(meeting.destination, syncedLocus);
|
|
11366
|
+
});
|
|
11367
|
+
|
|
11368
|
+
it('does not refresh destination when destination type is not LOCUS_ID', () => {
|
|
11369
|
+
const syncedLocus = {url: 'https://locus.example.com/locus/123', info: {topic: 'x'}};
|
|
11370
|
+
const originalDestination = {destination: 'original-destination'};
|
|
11371
|
+
|
|
11372
|
+
meeting.destinationType = DESTINATION_TYPE.CONVERSATION_URL;
|
|
11373
|
+
meeting.destination = originalDestination;
|
|
11374
|
+
|
|
11375
|
+
meeting.finalizeMeetingAfterInitialLocusSetup(syncedLocus);
|
|
11376
|
+
|
|
11377
|
+
assert.equal(meeting.destination, originalDestination);
|
|
11378
|
+
});
|
|
11379
|
+
|
|
11380
|
+
it('fetches meeting info when meetingInfo is empty and destination has info', () => {
|
|
11381
|
+
const fetchMeetingInfoStub = sinon.stub(meeting, 'fetchMeetingInfo').resolves();
|
|
11382
|
+
|
|
11383
|
+
meeting.meetingInfo = {};
|
|
11384
|
+
meeting.destination = {url: 'https://locus.example.com/locus/123', info: {topic: 'x'}};
|
|
11385
|
+
|
|
11386
|
+
meeting.finalizeMeetingAfterInitialLocusSetup({});
|
|
11387
|
+
|
|
11388
|
+
assert.calledOnceWithExactly(fetchMeetingInfoStub, {});
|
|
11389
|
+
});
|
|
11390
|
+
|
|
11391
|
+
it('does not fetch meeting info when destination has no info', () => {
|
|
11392
|
+
const fetchMeetingInfoStub = sinon.stub(meeting, 'fetchMeetingInfo').resolves();
|
|
11393
|
+
|
|
11394
|
+
meeting.meetingInfo = {};
|
|
11395
|
+
meeting.destination = {url: 'https://locus.example.com/locus/123'};
|
|
11396
|
+
|
|
11397
|
+
meeting.finalizeMeetingAfterInitialLocusSetup({});
|
|
11398
|
+
|
|
11399
|
+
assert.notCalled(fetchMeetingInfoStub);
|
|
11400
|
+
});
|
|
11401
|
+
|
|
11402
|
+
it('does not fetch meeting info when meetingInfo is already populated', () => {
|
|
11403
|
+
const fetchMeetingInfoStub = sinon.stub(meeting, 'fetchMeetingInfo').resolves();
|
|
11404
|
+
|
|
11405
|
+
meeting.meetingInfo = {meetingJoinUrl: 'https://example.com/join/abc'};
|
|
11406
|
+
meeting.destination = {url: 'https://locus.example.com/locus/123', info: {topic: 'x'}};
|
|
11407
|
+
|
|
11408
|
+
meeting.finalizeMeetingAfterInitialLocusSetup({});
|
|
11409
|
+
|
|
11410
|
+
assert.notCalled(fetchMeetingInfoStub);
|
|
11411
|
+
});
|
|
11412
|
+
|
|
11413
|
+
it('does not fetch meeting info when delayed fetch timer is already scheduled', () => {
|
|
11414
|
+
const fetchMeetingInfoStub = sinon.stub(meeting, 'fetchMeetingInfo').resolves();
|
|
11415
|
+
|
|
11416
|
+
meeting.meetingInfo = {};
|
|
11417
|
+
meeting.destination = {url: 'https://locus.example.com/locus/123', info: {topic: 'x'}};
|
|
11418
|
+
meeting.fetchMeetingInfoTimeoutId = 42;
|
|
11419
|
+
|
|
11420
|
+
meeting.finalizeMeetingAfterInitialLocusSetup({});
|
|
11421
|
+
|
|
11422
|
+
assert.notCalled(fetchMeetingInfoStub);
|
|
11423
|
+
});
|
|
11424
|
+
|
|
11425
|
+
it('swallows async fetchMeetingInfo errors and logs info', async () => {
|
|
11426
|
+
const error = new Error('fetch failed');
|
|
11427
|
+
|
|
11428
|
+
meeting.meetingInfo = {};
|
|
11429
|
+
meeting.destination = {url: 'https://locus.example.com/locus/123', info: {topic: 'x'}};
|
|
11430
|
+
sinon.stub(meeting, 'fetchMeetingInfo').returns(Promise.reject(error));
|
|
11431
|
+
const loggerInfoStub = sinon.stub(LoggerProxy.logger, 'info');
|
|
11432
|
+
|
|
11433
|
+
await meeting.finalizeMeetingAfterInitialLocusSetup({});
|
|
11434
|
+
|
|
11435
|
+
assert.calledOnce(loggerInfoStub);
|
|
11436
|
+
assert.match(
|
|
11437
|
+
loggerInfoStub.firstCall.args[0],
|
|
11438
|
+
/Meeting:index#finalizeMeetingAfterInitialLocusSetup --> deferred fetchMeetingInfo failed: fetch failed/
|
|
11439
|
+
);
|
|
11440
|
+
});
|
|
11441
|
+
});
|
|
11442
|
+
|
|
11356
11443
|
describe('#emailInput', () => {
|
|
11357
11444
|
it('should set the email input', () => {
|
|
11358
11445
|
assert.notOk(meeting.emailInput);
|
|
@@ -1489,7 +1489,7 @@ describe('plugin-meetings', () => {
|
|
|
1489
1489
|
url: url1,
|
|
1490
1490
|
},
|
|
1491
1491
|
hashTreeMessage: undefined,
|
|
1492
|
-
});
|
|
1492
|
+
}, sinon.match.func);
|
|
1493
1493
|
});
|
|
1494
1494
|
});
|
|
1495
1495
|
describe('when destroying meeting is needed', () => {
|
|
@@ -2137,7 +2137,7 @@ describe('plugin-meetings', () => {
|
|
|
2137
2137
|
},
|
|
2138
2138
|
},
|
|
2139
2139
|
hashTreeMessage: undefined,
|
|
2140
|
-
});
|
|
2140
|
+
}, sinon.match.func);
|
|
2141
2141
|
});
|
|
2142
2142
|
it('should setup the meeting from a hash tree event', async () => {
|
|
2143
2143
|
const selfData = {};
|
|
@@ -2171,7 +2171,7 @@ describe('plugin-meetings', () => {
|
|
|
2171
2171
|
info: infoData,
|
|
2172
2172
|
},
|
|
2173
2173
|
hashTreeMessage,
|
|
2174
|
-
});
|
|
2174
|
+
}, sinon.match.func);
|
|
2175
2175
|
});
|
|
2176
2176
|
|
|
2177
2177
|
it('should ignore hash tree event when created locus has INACTIVE fullState', async () => {
|
|
@@ -2251,7 +2251,7 @@ describe('plugin-meetings', () => {
|
|
|
2251
2251
|
},
|
|
2252
2252
|
},
|
|
2253
2253
|
hashTreeMessage: undefined,
|
|
2254
|
-
});
|
|
2254
|
+
}, sinon.match.func);
|
|
2255
2255
|
});
|
|
2256
2256
|
|
|
2257
2257
|
it('sends client event correctly on finally', async () => {
|
|
@@ -2327,7 +2327,7 @@ describe('plugin-meetings', () => {
|
|
|
2327
2327
|
},
|
|
2328
2328
|
},
|
|
2329
2329
|
hashTreeMessage: undefined,
|
|
2330
|
-
});
|
|
2330
|
+
}, sinon.match.func);
|
|
2331
2331
|
});
|
|
2332
2332
|
|
|
2333
2333
|
const generateFakeLocusData = (isUnifiedSpaceMeeting) => ({
|
|
@@ -238,6 +238,19 @@ describe('plugin-meetings', () => {
|
|
|
238
238
|
});
|
|
239
239
|
});
|
|
240
240
|
|
|
241
|
+
describe('#isWholeMeetingEnded', () => {
|
|
242
|
+
[
|
|
243
|
+
{description: 'state is INACTIVE with no endMeetingReason', fullState: {state: 'INACTIVE'}, expected: true},
|
|
244
|
+
{description: 'state is INACTIVE with endMeetingReason OTHER', fullState: {state: 'INACTIVE', endMeetingReason: 'SOME_OTHER_REASON'}, expected: true},
|
|
245
|
+
{description: 'state is INACTIVE with endMeetingReason BREAKOUT_ENDED', fullState: {state: 'INACTIVE', endMeetingReason: 'BREAKOUT_ENDED'}, expected: false},
|
|
246
|
+
{description: 'state is not INACTIVE', fullState: {state: 'ACTIVE', endMeetingReason: 'SOME_OTHER_REASON'}, expected: false},
|
|
247
|
+
].forEach(({description, fullState, expected}) => {
|
|
248
|
+
it(`returns ${expected} when ${description}`, () => {
|
|
249
|
+
assert.equal(MeetingsUtil.isWholeMeetingEnded(fullState), expected);
|
|
250
|
+
});
|
|
251
|
+
});
|
|
252
|
+
});
|
|
253
|
+
|
|
241
254
|
describe('#isSelfMovedOrBreakoutEnded', () => {
|
|
242
255
|
[
|
|
243
256
|
{description: 'locus is undefined', locus: undefined, expected: false},
|