@webex/plugin-meetings 3.11.0 → 3.12.0
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 +184 -0
- package/dist/aiEnableRequest/index.js.map +1 -0
- package/dist/aiEnableRequest/utils.js +36 -0
- package/dist/aiEnableRequest/utils.js.map +1 -0
- package/dist/annotation/index.js +14 -5
- package/dist/annotation/index.js.map +1 -1
- package/dist/breakouts/breakout.js +1 -1
- package/dist/breakouts/index.js +1 -1
- package/dist/config.js +5 -1
- package/dist/config.js.map +1 -1
- package/dist/constants.js +28 -6
- package/dist/constants.js.map +1 -1
- package/dist/hashTree/constants.js +3 -1
- package/dist/hashTree/constants.js.map +1 -1
- package/dist/hashTree/hashTree.js +18 -0
- package/dist/hashTree/hashTree.js.map +1 -1
- package/dist/hashTree/hashTreeParser.js +709 -380
- package/dist/hashTree/hashTreeParser.js.map +1 -1
- package/dist/hashTree/types.js +4 -2
- package/dist/hashTree/types.js.map +1 -1
- package/dist/hashTree/utils.js +10 -0
- package/dist/hashTree/utils.js.map +1 -1
- package/dist/index.js +11 -2
- package/dist/index.js.map +1 -1
- package/dist/interceptors/constant.js +12 -0
- package/dist/interceptors/constant.js.map +1 -0
- package/dist/interceptors/dataChannelAuthToken.js +290 -0
- package/dist/interceptors/dataChannelAuthToken.js.map +1 -0
- package/dist/interceptors/index.js +7 -0
- package/dist/interceptors/index.js.map +1 -1
- package/dist/interceptors/utils.js +27 -0
- package/dist/interceptors/utils.js.map +1 -0
- package/dist/interpretation/index.js +2 -2
- package/dist/interpretation/index.js.map +1 -1
- package/dist/interpretation/siLanguage.js +1 -1
- package/dist/locus-info/controlsUtils.js +5 -3
- package/dist/locus-info/controlsUtils.js.map +1 -1
- package/dist/locus-info/index.js +217 -79
- package/dist/locus-info/index.js.map +1 -1
- package/dist/locus-info/selfUtils.js +1 -0
- package/dist/locus-info/selfUtils.js.map +1 -1
- package/dist/locus-info/types.js.map +1 -1
- package/dist/media/MediaConnectionAwaiter.js +57 -1
- package/dist/media/MediaConnectionAwaiter.js.map +1 -1
- package/dist/media/properties.js +4 -2
- package/dist/media/properties.js.map +1 -1
- package/dist/meeting/in-meeting-actions.js +7 -1
- package/dist/meeting/in-meeting-actions.js.map +1 -1
- package/dist/meeting/index.js +1082 -861
- package/dist/meeting/index.js.map +1 -1
- package/dist/meeting/request.js +50 -0
- package/dist/meeting/request.js.map +1 -1
- package/dist/meeting/request.type.js.map +1 -1
- package/dist/meeting/util.js +133 -3
- package/dist/meeting/util.js.map +1 -1
- package/dist/meetings/index.js +100 -45
- package/dist/meetings/index.js.map +1 -1
- package/dist/member/index.js +10 -0
- package/dist/member/index.js.map +1 -1
- package/dist/member/util.js +10 -0
- package/dist/member/util.js.map +1 -1
- package/dist/metrics/constants.js +2 -1
- package/dist/metrics/constants.js.map +1 -1
- package/dist/multistream/mediaRequestManager.js +9 -60
- package/dist/multistream/mediaRequestManager.js.map +1 -1
- package/dist/multistream/remoteMediaManager.js +11 -0
- package/dist/multistream/remoteMediaManager.js.map +1 -1
- package/dist/reachability/index.js +18 -10
- package/dist/reachability/index.js.map +1 -1
- package/dist/reactions/reactions.type.js.map +1 -1
- package/dist/reconnection-manager/index.js +0 -1
- package/dist/reconnection-manager/index.js.map +1 -1
- package/dist/types/aiEnableRequest/index.d.ts +5 -0
- package/dist/types/aiEnableRequest/utils.d.ts +2 -0
- package/dist/types/config.d.ts +3 -0
- package/dist/types/constants.d.ts +23 -1
- package/dist/types/hashTree/constants.d.ts +1 -0
- package/dist/types/hashTree/hashTree.d.ts +7 -0
- package/dist/types/hashTree/hashTreeParser.d.ts +99 -14
- package/dist/types/hashTree/types.d.ts +3 -0
- package/dist/types/hashTree/utils.d.ts +6 -0
- package/dist/types/index.d.ts +1 -0
- package/dist/types/interceptors/constant.d.ts +5 -0
- package/dist/types/interceptors/dataChannelAuthToken.d.ts +43 -0
- package/dist/types/interceptors/index.d.ts +2 -1
- package/dist/types/interceptors/utils.d.ts +1 -0
- package/dist/types/locus-info/index.d.ts +21 -2
- package/dist/types/locus-info/types.d.ts +1 -0
- package/dist/types/media/MediaConnectionAwaiter.d.ts +10 -1
- package/dist/types/media/properties.d.ts +2 -1
- package/dist/types/meeting/in-meeting-actions.d.ts +6 -0
- package/dist/types/meeting/index.d.ts +38 -6
- package/dist/types/meeting/request.d.ts +16 -1
- package/dist/types/meeting/request.type.d.ts +5 -0
- package/dist/types/meeting/util.d.ts +31 -0
- package/dist/types/meetings/index.d.ts +4 -2
- package/dist/types/member/index.d.ts +1 -0
- package/dist/types/member/util.d.ts +5 -0
- package/dist/types/metrics/constants.d.ts +1 -0
- package/dist/types/multistream/mediaRequestManager.d.ts +0 -23
- package/dist/types/reactions/reactions.type.d.ts +1 -0
- package/dist/types/webinar/utils.d.ts +6 -0
- package/dist/webinar/index.js +260 -90
- package/dist/webinar/index.js.map +1 -1
- package/dist/webinar/utils.js +25 -0
- package/dist/webinar/utils.js.map +1 -0
- package/package.json +24 -23
- package/src/aiEnableRequest/README.md +84 -0
- package/src/aiEnableRequest/index.ts +170 -0
- package/src/aiEnableRequest/utils.ts +25 -0
- package/src/annotation/index.ts +27 -7
- package/src/config.ts +3 -0
- package/src/constants.ts +29 -1
- package/src/hashTree/constants.ts +1 -0
- package/src/hashTree/hashTree.ts +17 -0
- package/src/hashTree/hashTreeParser.ts +627 -249
- package/src/hashTree/types.ts +4 -0
- package/src/hashTree/utils.ts +9 -0
- package/src/index.ts +8 -1
- package/src/interceptors/constant.ts +6 -0
- package/src/interceptors/dataChannelAuthToken.ts +170 -0
- package/src/interceptors/index.ts +2 -1
- package/src/interceptors/utils.ts +16 -0
- package/src/interpretation/index.ts +2 -2
- package/src/locus-info/controlsUtils.ts +11 -0
- package/src/locus-info/index.ts +231 -61
- package/src/locus-info/selfUtils.ts +1 -0
- package/src/locus-info/types.ts +1 -0
- package/src/media/MediaConnectionAwaiter.ts +41 -1
- package/src/media/properties.ts +3 -1
- package/src/meeting/in-meeting-actions.ts +12 -0
- package/src/meeting/index.ts +205 -44
- package/src/meeting/request.ts +42 -0
- package/src/meeting/request.type.ts +6 -0
- package/src/meeting/util.ts +160 -2
- package/src/meetings/index.ts +135 -41
- package/src/member/index.ts +10 -0
- package/src/member/util.ts +12 -0
- package/src/metrics/constants.ts +1 -0
- package/src/multistream/mediaRequestManager.ts +4 -54
- package/src/multistream/remoteMediaManager.ts +13 -0
- package/src/reachability/index.ts +9 -0
- package/src/reactions/reactions.type.ts +1 -0
- package/src/reconnection-manager/index.ts +0 -1
- package/src/webinar/index.ts +162 -5
- package/src/webinar/utils.ts +16 -0
- package/test/unit/spec/aiEnableRequest/index.ts +981 -0
- package/test/unit/spec/aiEnableRequest/utils.ts +130 -0
- package/test/unit/spec/annotation/index.ts +69 -7
- package/test/unit/spec/hashTree/hashTree.ts +66 -0
- package/test/unit/spec/hashTree/hashTreeParser.ts +1869 -189
- package/test/unit/spec/interceptors/dataChannelAuthToken.ts +210 -0
- package/test/unit/spec/interceptors/utils.ts +75 -0
- package/test/unit/spec/locus-info/controlsUtils.js +29 -0
- package/test/unit/spec/locus-info/index.js +383 -46
- package/test/unit/spec/media/MediaConnectionAwaiter.ts +41 -1
- package/test/unit/spec/media/properties.ts +12 -3
- package/test/unit/spec/meeting/in-meeting-actions.ts +8 -2
- package/test/unit/spec/meeting/index.js +716 -115
- package/test/unit/spec/meeting/request.js +70 -0
- package/test/unit/spec/meeting/utils.js +438 -26
- package/test/unit/spec/meetings/index.js +652 -31
- package/test/unit/spec/member/index.js +28 -4
- package/test/unit/spec/member/util.js +65 -27
- package/test/unit/spec/multistream/mediaRequestManager.ts +2 -85
- package/test/unit/spec/multistream/remoteMediaManager.ts +30 -0
- package/test/unit/spec/reachability/index.ts +23 -0
- package/test/unit/spec/reconnection-manager/index.js +4 -8
- package/test/unit/spec/webinar/index.ts +348 -36
- package/test/unit/spec/webinar/utils.ts +39 -0
|
@@ -5,7 +5,7 @@ import {assert} from '@webex/test-helper-chai';
|
|
|
5
5
|
import MockWebex from '@webex/test-helper-mock-webex';
|
|
6
6
|
import testUtils from '../../../utils/testUtils';
|
|
7
7
|
import Meetings from '@webex/plugin-meetings';
|
|
8
|
-
import LocusInfo from '@webex/plugin-meetings/src/locus-info';
|
|
8
|
+
import LocusInfo, {createLocusFromHashTreeMessage} from '@webex/plugin-meetings/src/locus-info';
|
|
9
9
|
import SelfUtils from '@webex/plugin-meetings/src/locus-info/selfUtils';
|
|
10
10
|
import InfoUtils from '@webex/plugin-meetings/src/locus-info/infoUtils';
|
|
11
11
|
import EmbeddedAppsUtils from '@webex/plugin-meetings/src/locus-info/embeddedAppsUtils';
|
|
@@ -29,7 +29,8 @@ import {
|
|
|
29
29
|
} from '../../../../src/constants';
|
|
30
30
|
|
|
31
31
|
import {self, selfWithInactivity} from './selfConstant';
|
|
32
|
-
import {
|
|
32
|
+
import {MEETING_REMOVED_REASON} from '@webex/plugin-meetings/src/constants';
|
|
33
|
+
import LoggerProxy from '@webex/plugin-meetings/src/common/logs/logger-proxy';
|
|
33
34
|
|
|
34
35
|
describe('plugin-meetings', () => {
|
|
35
36
|
describe('LocusInfo index', () => {
|
|
@@ -106,7 +107,7 @@ describe('plugin-meetings', () => {
|
|
|
106
107
|
const createHashTreeMessage = (visibleDataSets) => ({
|
|
107
108
|
locusStateElements: [
|
|
108
109
|
{
|
|
109
|
-
htMeta: {elementId: {type: '
|
|
110
|
+
htMeta: {elementId: {type: 'metadata'}},
|
|
110
111
|
data: {visibleDataSets},
|
|
111
112
|
},
|
|
112
113
|
],
|
|
@@ -136,9 +137,13 @@ describe('plugin-meetings', () => {
|
|
|
136
137
|
HashTreeParserStub,
|
|
137
138
|
sinon.match({
|
|
138
139
|
initialLocus: {
|
|
139
|
-
locus:
|
|
140
|
+
locus: null,
|
|
140
141
|
dataSets: [],
|
|
141
142
|
},
|
|
143
|
+
metadata: {
|
|
144
|
+
htMeta: hashTreeMessage.locusStateElements[0].htMeta,
|
|
145
|
+
visibleDataSets,
|
|
146
|
+
},
|
|
142
147
|
webexRequest: sinon.match.func,
|
|
143
148
|
locusInfoUpdateCallback: sinon.match.func,
|
|
144
149
|
debugId: sinon.match.string,
|
|
@@ -169,11 +174,16 @@ describe('plugin-meetings', () => {
|
|
|
169
174
|
const visibleDataSets = ['dataset1', 'dataset2'];
|
|
170
175
|
const locus = createLocusWithVisibleDataSets(visibleDataSets);
|
|
171
176
|
const dataSets = [{name: 'dataset1', url: 'http://dataset-url.com'}];
|
|
177
|
+
const metadata = {
|
|
178
|
+
htMeta: {elementId: {type: 'metadata'}},
|
|
179
|
+
visibleDataSets,
|
|
180
|
+
};
|
|
172
181
|
|
|
173
182
|
await locusInfo.initialSetup({
|
|
174
183
|
trigger: 'join-response',
|
|
175
184
|
locus,
|
|
176
185
|
dataSets,
|
|
186
|
+
metadata,
|
|
177
187
|
});
|
|
178
188
|
|
|
179
189
|
assert.calledOnceWithExactly(
|
|
@@ -183,6 +193,7 @@ describe('plugin-meetings', () => {
|
|
|
183
193
|
locus,
|
|
184
194
|
dataSets,
|
|
185
195
|
},
|
|
196
|
+
metadata,
|
|
186
197
|
webexRequest: sinon.match.func,
|
|
187
198
|
locusInfoUpdateCallback: sinon.match.func,
|
|
188
199
|
debugId: sinon.match.string,
|
|
@@ -220,12 +231,13 @@ describe('plugin-meetings', () => {
|
|
|
220
231
|
HashTreeParserStub,
|
|
221
232
|
sinon.match({
|
|
222
233
|
initialLocus: {
|
|
223
|
-
locus:
|
|
234
|
+
locus: null,
|
|
224
235
|
dataSets: [],
|
|
225
236
|
},
|
|
226
237
|
webexRequest: sinon.match.func,
|
|
227
238
|
locusInfoUpdateCallback: sinon.match.func,
|
|
228
239
|
debugId: sinon.match.string,
|
|
240
|
+
metadata: null,
|
|
229
241
|
})
|
|
230
242
|
);
|
|
231
243
|
assert.calledOnceWithExactly(mockHashTreeParser.initializeFromGetLociResponse, locus);
|
|
@@ -249,6 +261,30 @@ describe('plugin-meetings', () => {
|
|
|
249
261
|
assert.isTrue(locusInfo.emitChange);
|
|
250
262
|
});
|
|
251
263
|
|
|
264
|
+
it('throws if called with "locus-message" and Metadata object without visibleDataSets', async () => {
|
|
265
|
+
const hashTreeMessage = {
|
|
266
|
+
locusStateElements: [
|
|
267
|
+
{
|
|
268
|
+
htMeta: {elementId: {type: 'Metadata'}},
|
|
269
|
+
data: {},
|
|
270
|
+
},
|
|
271
|
+
],
|
|
272
|
+
dataSets: [{name: 'dataset1', url: 'test-url'}],
|
|
273
|
+
};
|
|
274
|
+
try {
|
|
275
|
+
await locusInfo.initialSetup({
|
|
276
|
+
trigger: 'locus-message',
|
|
277
|
+
hashTreeMessage,
|
|
278
|
+
});
|
|
279
|
+
assert.fail('should have thrown an error');
|
|
280
|
+
} catch (error) {
|
|
281
|
+
assert.equal(
|
|
282
|
+
error.message,
|
|
283
|
+
'Metadata object with visibleDataSets is missing in the message'
|
|
284
|
+
);
|
|
285
|
+
}
|
|
286
|
+
});
|
|
287
|
+
|
|
252
288
|
describe('should setup correct locusInfoUpdateCallback when creating HashTreeParser', () => {
|
|
253
289
|
const OBJECTS_UPDATED = HashTreeParserModule.LocusInfoUpdateType.OBJECTS_UPDATED;
|
|
254
290
|
const MEETING_ENDED = HashTreeParserModule.LocusInfoUpdateType.MEETING_ENDED;
|
|
@@ -265,8 +301,8 @@ describe('plugin-meetings', () => {
|
|
|
265
301
|
hashTreeMessage: {
|
|
266
302
|
locusStateElements: [
|
|
267
303
|
{
|
|
268
|
-
htMeta: {elementId: {type: '
|
|
269
|
-
data: {visibleDataSets: ['dataset1']},
|
|
304
|
+
htMeta: {elementId: {type: 'Metadata'}},
|
|
305
|
+
data: {visibleDataSets: [{name: 'dataset1', url: 'test-url'}]},
|
|
270
306
|
},
|
|
271
307
|
],
|
|
272
308
|
dataSets: [{name: 'dataset1', url: 'test-url'}],
|
|
@@ -293,6 +329,16 @@ describe('plugin-meetings', () => {
|
|
|
293
329
|
htMeta: {elementId: {type: 'mediashare', id: 'fake-ht-mediaShare-2', version: 1}},
|
|
294
330
|
},
|
|
295
331
|
];
|
|
332
|
+
locusInfo.embeddedApps = [
|
|
333
|
+
{
|
|
334
|
+
id: 'fake-embedded-app-1',
|
|
335
|
+
htMeta: {elementId: {type: 'embeddedapp', id: 'fake-ht-embeddedApp-1', version: 1}},
|
|
336
|
+
},
|
|
337
|
+
{
|
|
338
|
+
id: 'fake-embedded-app-2',
|
|
339
|
+
htMeta: {elementId: {type: 'embeddedapp', id: 'fake-ht-embeddedApp-2', version: 1}},
|
|
340
|
+
},
|
|
341
|
+
];
|
|
296
342
|
locusInfo.meetings = {id: 'fake-meetings'};
|
|
297
343
|
locusInfo.participants = [
|
|
298
344
|
{id: 'fake-participant-1', name: 'Participant One'},
|
|
@@ -328,6 +374,16 @@ describe('plugin-meetings', () => {
|
|
|
328
374
|
htMeta: {elementId: {type: 'mediashare', id: 'fake-ht-mediaShare-2', version: 1}},
|
|
329
375
|
},
|
|
330
376
|
],
|
|
377
|
+
embeddedApps: [
|
|
378
|
+
{
|
|
379
|
+
id: 'fake-embedded-app-1',
|
|
380
|
+
htMeta: {elementId: {type: 'embeddedapp', id: 'fake-ht-embeddedApp-1', version: 1}},
|
|
381
|
+
},
|
|
382
|
+
{
|
|
383
|
+
id: 'fake-embedded-app-2',
|
|
384
|
+
htMeta: {elementId: {type: 'embeddedapp', id: 'fake-ht-embeddedApp-2', version: 1}},
|
|
385
|
+
},
|
|
386
|
+
],
|
|
331
387
|
meetings: {id: 'fake-meetings'},
|
|
332
388
|
jsSdkMeta: {removedParticipantIds: []},
|
|
333
389
|
participants: [], // empty means there were no participant updates
|
|
@@ -504,6 +560,7 @@ describe('plugin-meetings', () => {
|
|
|
504
560
|
self: {id: 'fake-self'},
|
|
505
561
|
links: {id: 'fake-links'},
|
|
506
562
|
mediaShares: expectedLocusInfo.mediaShares,
|
|
563
|
+
embeddedApps: expectedLocusInfo.embeddedApps,
|
|
507
564
|
// and now the new fields
|
|
508
565
|
...newLocus,
|
|
509
566
|
htMeta: newLocusHtMeta,
|
|
@@ -536,6 +593,7 @@ describe('plugin-meetings', () => {
|
|
|
536
593
|
self: 'new-self',
|
|
537
594
|
participants: 'new-participants',
|
|
538
595
|
mediaShares: 'new-mediaShares',
|
|
596
|
+
embeddedApps: 'new-embeddedApps',
|
|
539
597
|
},
|
|
540
598
|
},
|
|
541
599
|
],
|
|
@@ -551,6 +609,7 @@ describe('plugin-meetings', () => {
|
|
|
551
609
|
self: {id: 'fake-self'},
|
|
552
610
|
links: {id: 'fake-links'},
|
|
553
611
|
mediaShares: expectedLocusInfo.mediaShares,
|
|
612
|
+
embeddedApps: expectedLocusInfo.embeddedApps,
|
|
554
613
|
participants: [], // empty means there were no participant updates
|
|
555
614
|
jsSdkMeta: {removedParticipantIds: []}, // no participants were removed
|
|
556
615
|
...newLocus,
|
|
@@ -586,6 +645,7 @@ describe('plugin-meetings', () => {
|
|
|
586
645
|
self: {id: 'fake-self'},
|
|
587
646
|
links: {id: 'fake-links'},
|
|
588
647
|
mediaShares: expectedLocusInfo.mediaShares,
|
|
648
|
+
embeddedApps: expectedLocusInfo.embeddedApps,
|
|
589
649
|
// and now the new fields
|
|
590
650
|
...newLocus,
|
|
591
651
|
htMeta: newLocusHtMeta,
|
|
@@ -725,6 +785,39 @@ describe('plugin-meetings', () => {
|
|
|
725
785
|
});
|
|
726
786
|
});
|
|
727
787
|
|
|
788
|
+
it('should process locus update correctly when called with updated EMBEDDEDAPP objects', () => {
|
|
789
|
+
const newEmbeddedApp = {
|
|
790
|
+
id: 'new-embedded-app-3',
|
|
791
|
+
htMeta: {elementId: {type: 'embeddedapp', id: 'fake-ht-embeddedApp-3', version: 100}},
|
|
792
|
+
};
|
|
793
|
+
const updatedEmbeddedApp2 = {
|
|
794
|
+
id: 'fake-embedded-app-2',
|
|
795
|
+
someNewProp: 'newValue',
|
|
796
|
+
htMeta: {elementId: {type: 'embeddedapp', id: 'fake-ht-embeddedApp-2', version: 100}},
|
|
797
|
+
};
|
|
798
|
+
// simulate an update from the HashTreeParser (normally this would be triggered by incoming locus messages)
|
|
799
|
+
// with 1 embedded app added, 1 updated, and 1 removed
|
|
800
|
+
locusInfoUpdateCallback(OBJECTS_UPDATED, {
|
|
801
|
+
updatedObjects: [
|
|
802
|
+
{htMeta: {elementId: {type: 'embeddedapp', id: 'fake-ht-embeddedApp-1'}}, data: null},
|
|
803
|
+
{
|
|
804
|
+
htMeta: {elementId: {type: 'embeddedapp', id: 'fake-ht-embeddedApp-2'}},
|
|
805
|
+
data: updatedEmbeddedApp2,
|
|
806
|
+
},
|
|
807
|
+
{
|
|
808
|
+
htMeta: {elementId: {type: 'embeddedapp', id: 'fake-ht-embeddedApp-3'}},
|
|
809
|
+
data: newEmbeddedApp,
|
|
810
|
+
},
|
|
811
|
+
],
|
|
812
|
+
});
|
|
813
|
+
|
|
814
|
+
// check onDeltaLocus() was called with correctly updated locus info
|
|
815
|
+
assert.calledOnceWithExactly(onDeltaLocusStub, {
|
|
816
|
+
...expectedLocusInfo,
|
|
817
|
+
embeddedApps: [updatedEmbeddedApp2, newEmbeddedApp],
|
|
818
|
+
});
|
|
819
|
+
});
|
|
820
|
+
|
|
728
821
|
it('should process locus update correctly when called with a combination of various updated objects', () => {
|
|
729
822
|
const newSelf = {
|
|
730
823
|
id: 'new-self',
|
|
@@ -841,6 +934,20 @@ describe('plugin-meetings', () => {
|
|
|
841
934
|
MEETING_REMOVED_REASON.SELF_REMOVED
|
|
842
935
|
);
|
|
843
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
|
+
});
|
|
844
951
|
});
|
|
845
952
|
});
|
|
846
953
|
|
|
@@ -1076,7 +1183,7 @@ describe('plugin-meetings', () => {
|
|
|
1076
1183
|
it('should trigger the CONTROLS_POLLING_QA_CHANGED event when necessary', () => {
|
|
1077
1184
|
locusInfo.controls = {};
|
|
1078
1185
|
locusInfo.emitScoped = sinon.stub();
|
|
1079
|
-
newControls.pollingQAControl = {
|
|
1186
|
+
newControls.pollingQAControl = {enabled: true};
|
|
1080
1187
|
locusInfo.updateControls(newControls);
|
|
1081
1188
|
|
|
1082
1189
|
assert.calledWith(
|
|
@@ -1366,6 +1473,34 @@ describe('plugin-meetings', () => {
|
|
|
1366
1473
|
);
|
|
1367
1474
|
});
|
|
1368
1475
|
|
|
1476
|
+
it('should emit CONTROLS_AI_SUMMARY_NOTIFICATION_UPDATED when aiSummaryNotification changes', () => {
|
|
1477
|
+
locusInfo.emitScoped = sinon.stub();
|
|
1478
|
+
locusInfo.controls = {
|
|
1479
|
+
transcribe: {
|
|
1480
|
+
transcribing: false,
|
|
1481
|
+
caption: false,
|
|
1482
|
+
aiSummaryNotification: false,
|
|
1483
|
+
},
|
|
1484
|
+
};
|
|
1485
|
+
newControls.transcribe.transcribing = false;
|
|
1486
|
+
newControls.transcribe.caption = false;
|
|
1487
|
+
newControls.transcribe.aiSummaryNotification = true;
|
|
1488
|
+
|
|
1489
|
+
locusInfo.updateControls(newControls);
|
|
1490
|
+
|
|
1491
|
+
assert.calledWith(
|
|
1492
|
+
locusInfo.emitScoped,
|
|
1493
|
+
{
|
|
1494
|
+
file: 'locus-info',
|
|
1495
|
+
function: 'updateControls',
|
|
1496
|
+
},
|
|
1497
|
+
LOCUSINFO.EVENTS.CONTROLS_AI_SUMMARY_NOTIFICATION_UPDATED,
|
|
1498
|
+
{
|
|
1499
|
+
aiSummaryNotification: true,
|
|
1500
|
+
}
|
|
1501
|
+
);
|
|
1502
|
+
});
|
|
1503
|
+
|
|
1369
1504
|
it('should update the transcribe spoken language', () => {
|
|
1370
1505
|
locusInfo.emitScoped = sinon.stub();
|
|
1371
1506
|
locusInfo.controls = {
|
|
@@ -1631,7 +1766,6 @@ describe('plugin-meetings', () => {
|
|
|
1631
1766
|
);
|
|
1632
1767
|
});
|
|
1633
1768
|
|
|
1634
|
-
|
|
1635
1769
|
it('should call with participant display name', () => {
|
|
1636
1770
|
const failureParticipant = [
|
|
1637
1771
|
{
|
|
@@ -1656,7 +1790,7 @@ describe('plugin-meetings', () => {
|
|
|
1656
1790
|
displayName: 'Test User',
|
|
1657
1791
|
}
|
|
1658
1792
|
);
|
|
1659
|
-
})
|
|
1793
|
+
});
|
|
1660
1794
|
});
|
|
1661
1795
|
|
|
1662
1796
|
describe('#updateSelf', () => {
|
|
@@ -2457,8 +2591,8 @@ describe('plugin-meetings', () => {
|
|
|
2457
2591
|
{
|
|
2458
2592
|
isInitializing: !self,
|
|
2459
2593
|
}
|
|
2460
|
-
|
|
2461
|
-
|
|
2594
|
+
);
|
|
2595
|
+
});
|
|
2462
2596
|
|
|
2463
2597
|
const checkMeetingInfoUpdatedCalled = (expected, payload) => {
|
|
2464
2598
|
const expectedArgs = [
|
|
@@ -2923,28 +3057,28 @@ describe('plugin-meetings', () => {
|
|
|
2923
3057
|
assert.isFunction(locusParser.onDeltaAction);
|
|
2924
3058
|
});
|
|
2925
3059
|
|
|
2926
|
-
it(
|
|
3060
|
+
it('#updateLocusInfo invokes updateLocusUrl before updateMeetingInfo', () => {
|
|
2927
3061
|
const callOrder = [];
|
|
2928
|
-
sinon.stub(locusInfo,
|
|
2929
|
-
sinon.stub(locusInfo,
|
|
2930
|
-
sinon.stub(locusInfo,
|
|
2931
|
-
sinon.stub(locusInfo,
|
|
2932
|
-
sinon.stub(locusInfo,
|
|
2933
|
-
sinon.stub(locusInfo,
|
|
2934
|
-
callOrder.push(
|
|
3062
|
+
sinon.stub(locusInfo, 'updateControls');
|
|
3063
|
+
sinon.stub(locusInfo, 'updateConversationUrl');
|
|
3064
|
+
sinon.stub(locusInfo, 'updateCreated');
|
|
3065
|
+
sinon.stub(locusInfo, 'updateFullState');
|
|
3066
|
+
sinon.stub(locusInfo, 'updateHostInfo');
|
|
3067
|
+
sinon.stub(locusInfo, 'updateMeetingInfo').callsFake(() => {
|
|
3068
|
+
callOrder.push('updateMeetingInfo');
|
|
2935
3069
|
});
|
|
2936
|
-
sinon.stub(locusInfo,
|
|
2937
|
-
sinon.stub(locusInfo,
|
|
2938
|
-
sinon.stub(locusInfo,
|
|
2939
|
-
sinon.stub(locusInfo,
|
|
2940
|
-
callOrder.push(
|
|
3070
|
+
sinon.stub(locusInfo, 'updateMediaShares');
|
|
3071
|
+
sinon.stub(locusInfo, 'updateReplaces');
|
|
3072
|
+
sinon.stub(locusInfo, 'updateSelf');
|
|
3073
|
+
sinon.stub(locusInfo, 'updateLocusUrl').callsFake(() => {
|
|
3074
|
+
callOrder.push('updateLocusUrl');
|
|
2941
3075
|
});
|
|
2942
|
-
sinon.stub(locusInfo,
|
|
2943
|
-
sinon.stub(locusInfo,
|
|
2944
|
-
sinon.stub(locusInfo,
|
|
2945
|
-
sinon.stub(locusInfo,
|
|
2946
|
-
sinon.stub(locusInfo,
|
|
2947
|
-
sinon.stub(locusInfo,
|
|
3076
|
+
sinon.stub(locusInfo, 'updateAclUrl');
|
|
3077
|
+
sinon.stub(locusInfo, 'updateBasequence');
|
|
3078
|
+
sinon.stub(locusInfo, 'updateSequence');
|
|
3079
|
+
sinon.stub(locusInfo, 'updateEmbeddedApps');
|
|
3080
|
+
sinon.stub(locusInfo, 'updateLinks');
|
|
3081
|
+
sinon.stub(locusInfo, 'compareAndUpdate');
|
|
2948
3082
|
|
|
2949
3083
|
locusInfo.updateLocusInfo(locus);
|
|
2950
3084
|
|
|
@@ -3000,7 +3134,7 @@ describe('plugin-meetings', () => {
|
|
|
3000
3134
|
it('#updateLocusInfo puts the Locus DTO top level properties at the right place in LocusInfo class', () => {
|
|
3001
3135
|
// this test verifies that the top-level properties of Locus DTO are copied
|
|
3002
3136
|
// into LocusInfo class and set as top level properties too
|
|
3003
|
-
// this is important, because the code handling Locus
|
|
3137
|
+
// this is important, because the code handling Locus hash trees relies on it, see updateFromHashTree()
|
|
3004
3138
|
const info = {id: 'info id'};
|
|
3005
3139
|
const fullState = {id: 'fullState id'};
|
|
3006
3140
|
const links = {services: {id: 'service links'}, resources: {id: 'resource links'}};
|
|
@@ -3039,7 +3173,7 @@ describe('plugin-meetings', () => {
|
|
|
3039
3173
|
sandbox.stub(locusInfo, 'handleOneOnOneEvent');
|
|
3040
3174
|
sandbox.stub(locusParser, 'isNewFullLocus').returns(true);
|
|
3041
3175
|
|
|
3042
|
-
locusInfo.onFullLocus(fakeLocus, eventType);
|
|
3176
|
+
locusInfo.onFullLocus('test', fakeLocus, eventType);
|
|
3043
3177
|
|
|
3044
3178
|
assert.equal(fakeLocus, locusParser.workingCopy);
|
|
3045
3179
|
});
|
|
@@ -3060,7 +3194,7 @@ describe('plugin-meetings', () => {
|
|
|
3060
3194
|
|
|
3061
3195
|
sandbox.stub(locusParser, 'isNewFullLocus').returns(false);
|
|
3062
3196
|
|
|
3063
|
-
locusInfo.onFullLocus(fakeLocus, eventType);
|
|
3197
|
+
locusInfo.onFullLocus('test', fakeLocus, eventType);
|
|
3064
3198
|
|
|
3065
3199
|
spies.forEach((spy) => {
|
|
3066
3200
|
assert.notCalled(spy);
|
|
@@ -3210,7 +3344,11 @@ describe('plugin-meetings', () => {
|
|
|
3210
3344
|
}).then(() => {
|
|
3211
3345
|
assert.calledOnceWithExactly(meeting.meetingRequest.getLocusDTO, {url: 'oldLocusUrl'});
|
|
3212
3346
|
|
|
3213
|
-
assert.calledOnceWithExactly(
|
|
3347
|
+
assert.calledOnceWithExactly(
|
|
3348
|
+
meeting.locusInfo.onFullLocus,
|
|
3349
|
+
'classic Locus sync',
|
|
3350
|
+
fakeFullLocusDto
|
|
3351
|
+
);
|
|
3214
3352
|
assert.calledOnce(locusInfo.locusParser.resume);
|
|
3215
3353
|
});
|
|
3216
3354
|
});
|
|
@@ -3308,7 +3446,11 @@ describe('plugin-meetings', () => {
|
|
|
3308
3446
|
});
|
|
3309
3447
|
|
|
3310
3448
|
assert.notCalled(meeting.locusInfo.handleLocusDelta);
|
|
3311
|
-
assert.calledOnceWithExactly(
|
|
3449
|
+
assert.calledOnceWithExactly(
|
|
3450
|
+
meeting.locusInfo.onFullLocus,
|
|
3451
|
+
'classic Locus sync',
|
|
3452
|
+
fakeFullLocusDto
|
|
3453
|
+
);
|
|
3312
3454
|
assert.calledOnce(locusInfo.locusParser.resume);
|
|
3313
3455
|
});
|
|
3314
3456
|
});
|
|
@@ -3484,7 +3626,11 @@ describe('plugin-meetings', () => {
|
|
|
3484
3626
|
url: 'fake locus DELTA url',
|
|
3485
3627
|
});
|
|
3486
3628
|
assert.notCalled(meeting.locusInfo.handleLocusDelta);
|
|
3487
|
-
assert.calledOnceWithExactly(
|
|
3629
|
+
assert.calledOnceWithExactly(
|
|
3630
|
+
meeting.locusInfo.onFullLocus,
|
|
3631
|
+
'classic Locus sync',
|
|
3632
|
+
fakeFullLocusDto
|
|
3633
|
+
);
|
|
3488
3634
|
assert.calledOnce(locusInfo.locusParser.resume);
|
|
3489
3635
|
});
|
|
3490
3636
|
});
|
|
@@ -3856,7 +4002,7 @@ describe('plugin-meetings', () => {
|
|
|
3856
4002
|
|
|
3857
4003
|
describe('#updateLocusUrl', () => {
|
|
3858
4004
|
it('trigger LOCUS_INFO_UPDATE_URL event with isMainLocus is true as default', () => {
|
|
3859
|
-
const fakeUrl =
|
|
4005
|
+
const fakeUrl = 'https://fake.com/locus';
|
|
3860
4006
|
locusInfo.emitScoped = sinon.stub();
|
|
3861
4007
|
locusInfo.updateLocusUrl(fakeUrl);
|
|
3862
4008
|
|
|
@@ -3869,12 +4015,12 @@ describe('plugin-meetings', () => {
|
|
|
3869
4015
|
EVENTS.LOCUS_INFO_UPDATE_URL,
|
|
3870
4016
|
{
|
|
3871
4017
|
url: fakeUrl,
|
|
3872
|
-
isMainLocus: true
|
|
3873
|
-
}
|
|
4018
|
+
isMainLocus: true,
|
|
4019
|
+
}
|
|
3874
4020
|
);
|
|
3875
4021
|
});
|
|
3876
4022
|
it('trigger LOCUS_INFO_UPDATE_URL event with isMainLocus is false', () => {
|
|
3877
|
-
const fakeUrl =
|
|
4023
|
+
const fakeUrl = 'https://fake.com/locus';
|
|
3878
4024
|
locusInfo.emitScoped = sinon.stub();
|
|
3879
4025
|
locusInfo.updateLocusUrl(fakeUrl, false);
|
|
3880
4026
|
|
|
@@ -3887,8 +4033,8 @@ describe('plugin-meetings', () => {
|
|
|
3887
4033
|
EVENTS.LOCUS_INFO_UPDATE_URL,
|
|
3888
4034
|
{
|
|
3889
4035
|
url: fakeUrl,
|
|
3890
|
-
isMainLocus: false
|
|
3891
|
-
}
|
|
4036
|
+
isMainLocus: false,
|
|
4037
|
+
}
|
|
3892
4038
|
);
|
|
3893
4039
|
});
|
|
3894
4040
|
});
|
|
@@ -3940,8 +4086,8 @@ describe('plugin-meetings', () => {
|
|
|
3940
4086
|
|
|
3941
4087
|
sinon.stub(locusInfo, 'updateParticipants');
|
|
3942
4088
|
sinon.stub(locusInfo, 'isMeetingActive');
|
|
3943
|
-
|
|
3944
|
-
|
|
4089
|
+
sinon.stub(locusInfo, 'handleOneOnOneEvent');
|
|
4090
|
+
updateLocusInfoStub = sinon.stub(locusInfo, 'updateLocusInfo');
|
|
3945
4091
|
syncRequestStub = sinon.stub().resolves({body: {}});
|
|
3946
4092
|
|
|
3947
4093
|
mockMeeting.locusInfo = locusInfo;
|
|
@@ -3950,7 +4096,7 @@ describe('plugin-meetings', () => {
|
|
|
3950
4096
|
getLocusDTO: syncRequestStub,
|
|
3951
4097
|
};
|
|
3952
4098
|
|
|
3953
|
-
locusInfo.onFullLocus({
|
|
4099
|
+
locusInfo.onFullLocus('test', {
|
|
3954
4100
|
sequence: {
|
|
3955
4101
|
rangeStart: 0,
|
|
3956
4102
|
rangeEnd: 0,
|
|
@@ -4213,6 +4359,197 @@ describe('plugin-meetings', () => {
|
|
|
4213
4359
|
|
|
4214
4360
|
assert.calledOnceWithExactly(mockHashTreeParser.handleMessage, fakeHashTreeMessage);
|
|
4215
4361
|
});
|
|
4362
|
+
|
|
4363
|
+
it('ignores hash tree event when hashTreeParser is not created yet', () => {
|
|
4364
|
+
const data = {
|
|
4365
|
+
eventType: LOCUSEVENT.HASH_TREE_DATA_UPDATED,
|
|
4366
|
+
stateElementsMessage: {
|
|
4367
|
+
locusStateElements: [],
|
|
4368
|
+
dataSets: [],
|
|
4369
|
+
},
|
|
4370
|
+
};
|
|
4371
|
+
|
|
4372
|
+
const loggerSpy = sinon.spy(LoggerProxy.logger, 'info');
|
|
4373
|
+
const getTheLocusToUpdateStub = sinon.stub(locusInfo, 'getTheLocusToUpdate');
|
|
4374
|
+
|
|
4375
|
+
// Ensure we're not using hash trees
|
|
4376
|
+
assert.isUndefined(locusInfo.hashTreeParser);
|
|
4377
|
+
|
|
4378
|
+
locusInfo.parse(mockMeeting, data);
|
|
4379
|
+
|
|
4380
|
+
assert.calledWith(
|
|
4381
|
+
loggerSpy,
|
|
4382
|
+
'Locus-info:index#parse --> received locus hash tree event before hashTreeParser is created'
|
|
4383
|
+
);
|
|
4384
|
+
assert.notCalled(getTheLocusToUpdateStub);
|
|
4385
|
+
});
|
|
4386
|
+
});
|
|
4387
|
+
});
|
|
4388
|
+
|
|
4389
|
+
describe('#createLocusFromHashTreeMessage', () => {
|
|
4390
|
+
const LOCUS_URL = 'https://locus.example.com/loci/abc-123';
|
|
4391
|
+
|
|
4392
|
+
const createElement = (type, data) => ({
|
|
4393
|
+
htMeta: {elementId: {type, id: 1, version: 1}},
|
|
4394
|
+
data,
|
|
4395
|
+
});
|
|
4396
|
+
|
|
4397
|
+
it('returns locus with url and empty participants when no locusStateElements', () => {
|
|
4398
|
+
const result = createLocusFromHashTreeMessage({locusUrl: LOCUS_URL});
|
|
4399
|
+
|
|
4400
|
+
assert.deepEqual(result.locus, {participants: [], url: LOCUS_URL});
|
|
4401
|
+
assert.isUndefined(result.metadata);
|
|
4402
|
+
});
|
|
4403
|
+
|
|
4404
|
+
it('skips elements without data', () => {
|
|
4405
|
+
const result = createLocusFromHashTreeMessage({
|
|
4406
|
+
locusUrl: LOCUS_URL,
|
|
4407
|
+
locusStateElements: [{htMeta: {elementId: {type: 'Self', id: 1, version: 1}}, data: null}],
|
|
4408
|
+
});
|
|
4409
|
+
|
|
4410
|
+
assert.deepEqual(result.locus, {participants: [], url: LOCUS_URL});
|
|
4411
|
+
});
|
|
4412
|
+
|
|
4413
|
+
[
|
|
4414
|
+
{type: 'Self', locusKey: 'self', data: {id: 'self-1', state: 'JOINED'}},
|
|
4415
|
+
{type: 'Info', locusKey: 'info', data: {webExMeetingId: '123'}},
|
|
4416
|
+
{type: 'FullState', locusKey: 'fullState', data: {state: 'ACTIVE'}},
|
|
4417
|
+
{type: 'Links', locusKey: 'links', data: {resources: {}}},
|
|
4418
|
+
].forEach(({type, locusKey, data}) => {
|
|
4419
|
+
it(`maps ${type} element to locus.${locusKey}`, () => {
|
|
4420
|
+
const result = createLocusFromHashTreeMessage({
|
|
4421
|
+
locusUrl: LOCUS_URL,
|
|
4422
|
+
locusStateElements: [createElement(type, data)],
|
|
4423
|
+
});
|
|
4424
|
+
|
|
4425
|
+
assert.deepEqual(result.locus[locusKey], data);
|
|
4426
|
+
});
|
|
4427
|
+
});
|
|
4428
|
+
|
|
4429
|
+
it('pushes Participant elements to locus.participants', () => {
|
|
4430
|
+
const p1 = {id: 'p1', state: 'JOINED'};
|
|
4431
|
+
const p2 = {id: 'p2', state: 'LEFT'};
|
|
4432
|
+
|
|
4433
|
+
const result = createLocusFromHashTreeMessage({
|
|
4434
|
+
locusUrl: LOCUS_URL,
|
|
4435
|
+
locusStateElements: [createElement('Participant', p1), createElement('Participant', p2)],
|
|
4436
|
+
});
|
|
4437
|
+
|
|
4438
|
+
assert.deepEqual(result.locus.participants, [p1, p2]);
|
|
4439
|
+
});
|
|
4440
|
+
|
|
4441
|
+
it('pushes MediaShare elements to locus.mediaShares array', () => {
|
|
4442
|
+
const share1 = {name: 'whiteboard'};
|
|
4443
|
+
const share2 = {name: 'content'};
|
|
4444
|
+
|
|
4445
|
+
const result = createLocusFromHashTreeMessage({
|
|
4446
|
+
locusUrl: LOCUS_URL,
|
|
4447
|
+
locusStateElements: [
|
|
4448
|
+
createElement('MediaShare', share1),
|
|
4449
|
+
createElement('MediaShare', share2),
|
|
4450
|
+
],
|
|
4451
|
+
});
|
|
4452
|
+
|
|
4453
|
+
assert.deepEqual(result.locus.mediaShares, [share1, share2]);
|
|
4454
|
+
});
|
|
4455
|
+
|
|
4456
|
+
it('pushes EmbeddedApp elements to locus.embeddedApps array', () => {
|
|
4457
|
+
const app = {appId: 'app-1', state: 'STARTED'};
|
|
4458
|
+
|
|
4459
|
+
const result = createLocusFromHashTreeMessage({
|
|
4460
|
+
locusUrl: LOCUS_URL,
|
|
4461
|
+
locusStateElements: [createElement('EmbeddedApp', app)],
|
|
4462
|
+
});
|
|
4463
|
+
|
|
4464
|
+
assert.deepEqual(result.locus.embeddedApps, [app]);
|
|
4465
|
+
});
|
|
4466
|
+
|
|
4467
|
+
it('merges ControlEntry elements into locus.controls', () => {
|
|
4468
|
+
const control1 = {record: {recording: true}};
|
|
4469
|
+
const control2 = {lock: {locked: false}};
|
|
4470
|
+
|
|
4471
|
+
const result = createLocusFromHashTreeMessage({
|
|
4472
|
+
locusUrl: LOCUS_URL,
|
|
4473
|
+
locusStateElements: [
|
|
4474
|
+
createElement('ControlEntry', control1),
|
|
4475
|
+
createElement('ControlEntry', control2),
|
|
4476
|
+
],
|
|
4477
|
+
});
|
|
4478
|
+
|
|
4479
|
+
assert.deepEqual(result.locus.controls, {record: {recording: true}, lock: {locked: false}});
|
|
4480
|
+
});
|
|
4481
|
+
|
|
4482
|
+
it('spreads Locus element data onto top level but removes managed keys', () => {
|
|
4483
|
+
const locusData = {
|
|
4484
|
+
url: 'should-be-overridden',
|
|
4485
|
+
someTopLevelField: 'value',
|
|
4486
|
+
// these are managed by other ObjectTypes and should be removed
|
|
4487
|
+
links: {should: 'be removed'},
|
|
4488
|
+
info: {should: 'be removed'},
|
|
4489
|
+
fullState: {should: 'be removed'},
|
|
4490
|
+
self: {should: 'be removed'},
|
|
4491
|
+
participants: [{should: 'be removed'}],
|
|
4492
|
+
mediaShares: [{should: 'be removed'}],
|
|
4493
|
+
controls: {should: 'be removed'},
|
|
4494
|
+
embeddedApps: [{should: 'be removed'}],
|
|
4495
|
+
};
|
|
4496
|
+
|
|
4497
|
+
const result = createLocusFromHashTreeMessage({
|
|
4498
|
+
locusUrl: LOCUS_URL,
|
|
4499
|
+
locusStateElements: [createElement('Locus', locusData)],
|
|
4500
|
+
});
|
|
4501
|
+
|
|
4502
|
+
assert.equal(result.locus.someTopLevelField, 'value');
|
|
4503
|
+
assert.deepEqual(result.locus.participants, []);
|
|
4504
|
+
assert.isUndefined(result.locus.links);
|
|
4505
|
+
assert.isUndefined(result.locus.info);
|
|
4506
|
+
assert.isUndefined(result.locus.fullState);
|
|
4507
|
+
assert.isUndefined(result.locus.self);
|
|
4508
|
+
assert.isUndefined(result.locus.mediaShares);
|
|
4509
|
+
assert.isUndefined(result.locus.controls);
|
|
4510
|
+
assert.isUndefined(result.locus.embeddedApps);
|
|
4511
|
+
});
|
|
4512
|
+
|
|
4513
|
+
it('extracts Metadata element as metadata in the result', () => {
|
|
4514
|
+
const metadataData = {visibleDataSets: [{name: 'ds1', url: 'http://ds1.url'}]};
|
|
4515
|
+
const htMeta = {elementId: {type: 'Metadata', id: 99, version: 3}};
|
|
4516
|
+
|
|
4517
|
+
const result = createLocusFromHashTreeMessage({
|
|
4518
|
+
locusUrl: LOCUS_URL,
|
|
4519
|
+
locusStateElements: [{htMeta, data: metadataData}],
|
|
4520
|
+
});
|
|
4521
|
+
|
|
4522
|
+
assert.deepEqual(result.metadata, {...metadataData, htMeta});
|
|
4523
|
+
assert.isUndefined(result.locus.metadata);
|
|
4524
|
+
});
|
|
4525
|
+
|
|
4526
|
+
it('handles a message with multiple element types', () => {
|
|
4527
|
+
const selfData = {id: 'self-1'};
|
|
4528
|
+
const participantData = {id: 'p1'};
|
|
4529
|
+
const infoData = {webExMeetingId: '456'};
|
|
4530
|
+
|
|
4531
|
+
const result = createLocusFromHashTreeMessage({
|
|
4532
|
+
locusUrl: LOCUS_URL,
|
|
4533
|
+
locusStateElements: [
|
|
4534
|
+
createElement('Self', selfData),
|
|
4535
|
+
createElement('Participant', participantData),
|
|
4536
|
+
createElement('Info', infoData),
|
|
4537
|
+
],
|
|
4538
|
+
});
|
|
4539
|
+
|
|
4540
|
+
assert.deepEqual(result.locus.self, selfData);
|
|
4541
|
+
assert.deepEqual(result.locus.participants, [participantData]);
|
|
4542
|
+
assert.deepEqual(result.locus.info, infoData);
|
|
4543
|
+
assert.equal(result.locus.url, LOCUS_URL);
|
|
4544
|
+
});
|
|
4545
|
+
|
|
4546
|
+
it('ignores unknown element types', () => {
|
|
4547
|
+
const result = createLocusFromHashTreeMessage({
|
|
4548
|
+
locusUrl: LOCUS_URL,
|
|
4549
|
+
locusStateElements: [createElement('UnknownType', {foo: 'bar'})],
|
|
4550
|
+
});
|
|
4551
|
+
|
|
4552
|
+
assert.deepEqual(result.locus, {participants: [], url: LOCUS_URL});
|
|
4216
4553
|
});
|
|
4217
4554
|
});
|
|
4218
4555
|
});
|