@webex/plugin-meetings 3.12.0-next.9 → 3.12.0-task-refactor.1
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/annotation/index.js +5 -14
- 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 +2 -8
- package/dist/config.js.map +1 -1
- package/dist/constants.js +6 -29
- package/dist/constants.js.map +1 -1
- package/dist/hashTree/hashTreeParser.js +29 -1563
- package/dist/hashTree/hashTreeParser.js.map +1 -1
- package/dist/hashTree/types.js +3 -13
- package/dist/hashTree/types.js.map +1 -1
- package/dist/index.js +2 -11
- package/dist/index.js.map +1 -1
- package/dist/interceptors/index.js +0 -7
- package/dist/interceptors/index.js.map +1 -1
- package/dist/interceptors/locusRouteToken.js +5 -27
- package/dist/interceptors/locusRouteToken.js.map +1 -1
- 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 +3 -7
- package/dist/locus-info/controlsUtils.js.map +1 -1
- package/dist/locus-info/index.js +247 -642
- package/dist/locus-info/index.js.map +1 -1
- package/dist/locus-info/selfUtils.js +0 -1
- package/dist/locus-info/selfUtils.js.map +1 -1
- package/dist/locus-info/types.js.map +1 -1
- package/dist/media/MediaConnectionAwaiter.js +1 -57
- package/dist/media/MediaConnectionAwaiter.js.map +1 -1
- package/dist/media/properties.js +2 -4
- package/dist/media/properties.js.map +1 -1
- package/dist/meeting/in-meeting-actions.js +1 -7
- package/dist/meeting/in-meeting-actions.js.map +1 -1
- package/dist/meeting/index.js +1036 -1481
- package/dist/meeting/index.js.map +1 -1
- package/dist/meeting/request.js +0 -50
- package/dist/meeting/request.js.map +1 -1
- package/dist/meeting/request.type.js.map +1 -1
- package/dist/meeting/util.js +3 -133
- package/dist/meeting/util.js.map +1 -1
- package/dist/meetings/index.js +59 -142
- package/dist/meetings/index.js.map +1 -1
- package/dist/meetings/util.js +7 -11
- package/dist/meetings/util.js.map +1 -1
- package/dist/member/index.js +0 -10
- package/dist/member/index.js.map +1 -1
- package/dist/member/util.js +0 -10
- package/dist/member/util.js.map +1 -1
- package/dist/metrics/constants.js +1 -7
- package/dist/metrics/constants.js.map +1 -1
- package/dist/multistream/mediaRequestManager.js +60 -9
- package/dist/multistream/mediaRequestManager.js.map +1 -1
- package/dist/multistream/remoteMediaManager.js +0 -11
- package/dist/multistream/remoteMediaManager.js.map +1 -1
- package/dist/multistream/sendSlotManager.js +2 -116
- package/dist/multistream/sendSlotManager.js.map +1 -1
- package/dist/reachability/clusterReachability.js +18 -171
- package/dist/reachability/clusterReachability.js.map +1 -1
- package/dist/reachability/index.js +11 -21
- package/dist/reachability/index.js.map +1 -1
- package/dist/reachability/reachabilityPeerConnection.js +1 -1
- package/dist/reachability/reachabilityPeerConnection.js.map +1 -1
- package/dist/reactions/reactions.type.js.map +1 -1
- package/dist/reconnection-manager/index.js +1 -0
- package/dist/reconnection-manager/index.js.map +1 -1
- package/dist/types/common/browser-detection.d.ts +0 -1
- package/dist/types/common/events/events-scope.d.ts +0 -1
- package/dist/types/common/events/events.d.ts +0 -1
- package/dist/types/config.d.ts +0 -5
- package/dist/types/constants.d.ts +1 -24
- package/dist/types/hashTree/hashTreeParser.d.ts +11 -260
- package/dist/types/hashTree/types.d.ts +0 -20
- package/dist/types/index.d.ts +0 -1
- package/dist/types/interceptors/index.d.ts +1 -2
- package/dist/types/interceptors/locusRouteToken.d.ts +0 -2
- package/dist/types/locus-info/index.d.ts +47 -68
- package/dist/types/locus-info/types.d.ts +12 -28
- package/dist/types/media/MediaConnectionAwaiter.d.ts +1 -10
- package/dist/types/media/properties.d.ts +1 -2
- package/dist/types/meeting/in-meeting-actions.d.ts +0 -6
- package/dist/types/meeting/index.d.ts +7 -86
- package/dist/types/meeting/request.d.ts +1 -16
- package/dist/types/meeting/request.type.d.ts +0 -5
- package/dist/types/meeting/util.d.ts +0 -31
- package/dist/types/meeting-info/util.d.ts +0 -1
- package/dist/types/meeting-info/utilv2.d.ts +0 -1
- package/dist/types/meetings/index.d.ts +2 -4
- package/dist/types/member/index.d.ts +0 -1
- package/dist/types/member/types.d.ts +4 -4
- package/dist/types/member/util.d.ts +0 -5
- package/dist/types/metrics/constants.d.ts +0 -6
- package/dist/types/multistream/mediaRequestManager.d.ts +23 -0
- package/dist/types/multistream/sendSlotManager.d.ts +1 -23
- package/dist/types/reachability/clusterReachability.d.ts +3 -30
- package/dist/types/reactions/reactions.type.d.ts +0 -1
- package/dist/types/recording-controller/util.d.ts +5 -5
- package/dist/types/roap/index.d.ts +1 -1
- package/dist/webinar/index.js +163 -438
- package/dist/webinar/index.js.map +1 -1
- package/package.json +24 -26
- package/src/annotation/index.ts +7 -27
- package/src/config.ts +0 -5
- package/src/constants.ts +1 -30
- package/src/hashTree/hashTreeParser.ts +25 -1523
- package/src/hashTree/types.ts +1 -24
- package/src/index.ts +1 -8
- package/src/interceptors/index.ts +1 -2
- package/src/interceptors/locusRouteToken.ts +5 -22
- package/src/interpretation/index.ts +2 -2
- package/src/locus-info/controlsUtils.ts +0 -17
- package/src/locus-info/index.ts +213 -707
- package/src/locus-info/selfUtils.ts +0 -1
- package/src/locus-info/types.ts +12 -27
- package/src/media/MediaConnectionAwaiter.ts +1 -41
- package/src/media/properties.ts +1 -3
- package/src/meeting/in-meeting-actions.ts +0 -12
- package/src/meeting/index.ts +84 -461
- package/src/meeting/request.ts +0 -42
- package/src/meeting/request.type.ts +0 -6
- package/src/meeting/util.ts +2 -160
- package/src/meetings/index.ts +60 -180
- package/src/meetings/util.ts +9 -10
- package/src/member/index.ts +0 -10
- package/src/member/util.ts +0 -12
- package/src/metrics/constants.ts +0 -7
- package/src/multistream/mediaRequestManager.ts +54 -4
- package/src/multistream/remoteMediaManager.ts +0 -13
- package/src/multistream/sendSlotManager.ts +3 -97
- package/src/reachability/clusterReachability.ts +27 -153
- package/src/reachability/index.ts +1 -15
- package/src/reachability/reachabilityPeerConnection.ts +1 -3
- package/src/reactions/reactions.type.ts +0 -1
- package/src/reconnection-manager/index.ts +1 -0
- package/src/webinar/index.ts +6 -265
- package/test/unit/spec/annotation/index.ts +7 -69
- package/test/unit/spec/interceptors/locusRouteToken.ts +0 -44
- package/test/unit/spec/locus-info/controlsUtils.js +1 -56
- package/test/unit/spec/locus-info/index.js +90 -1457
- package/test/unit/spec/media/MediaConnectionAwaiter.ts +1 -41
- package/test/unit/spec/media/properties.ts +3 -12
- package/test/unit/spec/meeting/in-meeting-actions.ts +2 -8
- package/test/unit/spec/meeting/index.js +128 -981
- package/test/unit/spec/meeting/request.js +0 -70
- package/test/unit/spec/meeting/utils.js +26 -438
- package/test/unit/spec/meetings/index.js +33 -845
- package/test/unit/spec/meetings/utils.js +1 -51
- package/test/unit/spec/member/index.js +4 -28
- package/test/unit/spec/member/util.js +27 -65
- package/test/unit/spec/multistream/mediaRequestManager.ts +85 -2
- package/test/unit/spec/multistream/remoteMediaManager.ts +0 -30
- package/test/unit/spec/multistream/sendSlotManager.ts +36 -135
- package/test/unit/spec/reachability/clusterReachability.ts +1 -125
- package/test/unit/spec/reachability/index.ts +3 -26
- package/test/unit/spec/reconnection-manager/index.js +8 -4
- package/test/unit/spec/webinar/index.ts +37 -534
- package/dist/aiEnableRequest/index.js +0 -184
- package/dist/aiEnableRequest/index.js.map +0 -1
- package/dist/aiEnableRequest/utils.js +0 -36
- package/dist/aiEnableRequest/utils.js.map +0 -1
- package/dist/hashTree/constants.js +0 -22
- package/dist/hashTree/constants.js.map +0 -1
- package/dist/hashTree/hashTree.js +0 -533
- package/dist/hashTree/hashTree.js.map +0 -1
- package/dist/hashTree/utils.js +0 -69
- package/dist/hashTree/utils.js.map +0 -1
- package/dist/interceptors/constant.js +0 -12
- package/dist/interceptors/constant.js.map +0 -1
- package/dist/interceptors/dataChannelAuthToken.js +0 -290
- package/dist/interceptors/dataChannelAuthToken.js.map +0 -1
- package/dist/interceptors/utils.js +0 -27
- package/dist/interceptors/utils.js.map +0 -1
- package/dist/types/aiEnableRequest/index.d.ts +0 -5
- package/dist/types/aiEnableRequest/utils.d.ts +0 -2
- package/dist/types/hashTree/constants.d.ts +0 -9
- package/dist/types/hashTree/hashTree.d.ts +0 -136
- package/dist/types/hashTree/utils.d.ts +0 -22
- package/dist/types/interceptors/constant.d.ts +0 -5
- package/dist/types/interceptors/dataChannelAuthToken.d.ts +0 -43
- package/dist/types/interceptors/utils.d.ts +0 -1
- package/dist/types/webinar/utils.d.ts +0 -6
- package/dist/webinar/utils.js +0 -25
- package/dist/webinar/utils.js.map +0 -1
- package/src/aiEnableRequest/README.md +0 -84
- package/src/aiEnableRequest/index.ts +0 -170
- package/src/aiEnableRequest/utils.ts +0 -25
- package/src/hashTree/constants.ts +0 -10
- package/src/hashTree/hashTree.ts +0 -480
- package/src/hashTree/utils.ts +0 -62
- package/src/interceptors/constant.ts +0 -6
- package/src/interceptors/dataChannelAuthToken.ts +0 -170
- package/src/interceptors/utils.ts +0 -16
- package/src/webinar/utils.ts +0 -16
- package/test/unit/spec/aiEnableRequest/index.ts +0 -981
- package/test/unit/spec/aiEnableRequest/utils.ts +0 -130
- package/test/unit/spec/hashTree/hashTree.ts +0 -721
- package/test/unit/spec/hashTree/hashTreeParser.ts +0 -3670
- package/test/unit/spec/hashTree/utils.ts +0 -140
- package/test/unit/spec/interceptors/dataChannelAuthToken.ts +0 -210
- package/test/unit/spec/interceptors/utils.ts +0 -75
- package/test/unit/spec/webinar/utils.ts +0 -39
|
@@ -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
|
|
8
|
+
import LocusInfo 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,8 +29,7 @@ import {
|
|
|
29
29
|
} from '../../../../src/constants';
|
|
30
30
|
|
|
31
31
|
import {self, selfWithInactivity} from './selfConstant';
|
|
32
|
-
import {MEETING_REMOVED_REASON} from '@webex/plugin-meetings/src/constants';
|
|
33
|
-
import LoggerProxy from '@webex/plugin-meetings/src/common/logs/logger-proxy';
|
|
32
|
+
import { MEETING_REMOVED_REASON } from '@webex/plugin-meetings/src/constants';
|
|
34
33
|
|
|
35
34
|
describe('plugin-meetings', () => {
|
|
36
35
|
describe('LocusInfo index', () => {
|
|
@@ -105,10 +104,9 @@ describe('plugin-meetings', () => {
|
|
|
105
104
|
});
|
|
106
105
|
|
|
107
106
|
const createHashTreeMessage = (visibleDataSets) => ({
|
|
108
|
-
locusUrl: 'http://locus-url.com',
|
|
109
107
|
locusStateElements: [
|
|
110
108
|
{
|
|
111
|
-
htMeta: {elementId: {type: '
|
|
109
|
+
htMeta: {elementId: {type: 'self'}},
|
|
112
110
|
data: {visibleDataSets},
|
|
113
111
|
},
|
|
114
112
|
],
|
|
@@ -116,7 +114,6 @@ describe('plugin-meetings', () => {
|
|
|
116
114
|
});
|
|
117
115
|
|
|
118
116
|
const createLocusWithVisibleDataSets = (visibleDataSets) => ({
|
|
119
|
-
url: 'http://locus-url.com',
|
|
120
117
|
self: {visibleDataSets},
|
|
121
118
|
participants: [],
|
|
122
119
|
links: {
|
|
@@ -139,12 +136,8 @@ describe('plugin-meetings', () => {
|
|
|
139
136
|
HashTreeParserStub,
|
|
140
137
|
sinon.match({
|
|
141
138
|
initialLocus: {
|
|
142
|
-
locus:
|
|
143
|
-
dataSets:
|
|
144
|
-
},
|
|
145
|
-
metadata: {
|
|
146
|
-
htMeta: hashTreeMessage.locusStateElements[0].htMeta,
|
|
147
|
-
visibleDataSets,
|
|
139
|
+
locus: {self: {visibleDataSets}},
|
|
140
|
+
dataSets: [],
|
|
148
141
|
},
|
|
149
142
|
webexRequest: sinon.match.func,
|
|
150
143
|
locusInfoUpdateCallback: sinon.match.func,
|
|
@@ -176,16 +169,11 @@ describe('plugin-meetings', () => {
|
|
|
176
169
|
const visibleDataSets = ['dataset1', 'dataset2'];
|
|
177
170
|
const locus = createLocusWithVisibleDataSets(visibleDataSets);
|
|
178
171
|
const dataSets = [{name: 'dataset1', url: 'http://dataset-url.com'}];
|
|
179
|
-
const metadata = {
|
|
180
|
-
htMeta: {elementId: {type: 'metadata'}},
|
|
181
|
-
visibleDataSets,
|
|
182
|
-
};
|
|
183
172
|
|
|
184
173
|
await locusInfo.initialSetup({
|
|
185
174
|
trigger: 'join-response',
|
|
186
175
|
locus,
|
|
187
176
|
dataSets,
|
|
188
|
-
metadata,
|
|
189
177
|
});
|
|
190
178
|
|
|
191
179
|
assert.calledOnceWithExactly(
|
|
@@ -195,7 +183,6 @@ describe('plugin-meetings', () => {
|
|
|
195
183
|
locus,
|
|
196
184
|
dataSets,
|
|
197
185
|
},
|
|
198
|
-
metadata,
|
|
199
186
|
webexRequest: sinon.match.func,
|
|
200
187
|
locusInfoUpdateCallback: sinon.match.func,
|
|
201
188
|
debugId: sinon.match.string,
|
|
@@ -233,13 +220,12 @@ describe('plugin-meetings', () => {
|
|
|
233
220
|
HashTreeParserStub,
|
|
234
221
|
sinon.match({
|
|
235
222
|
initialLocus: {
|
|
236
|
-
locus:
|
|
223
|
+
locus: {self: {visibleDataSets}},
|
|
237
224
|
dataSets: [],
|
|
238
225
|
},
|
|
239
226
|
webexRequest: sinon.match.func,
|
|
240
227
|
locusInfoUpdateCallback: sinon.match.func,
|
|
241
228
|
debugId: sinon.match.string,
|
|
242
|
-
metadata: null,
|
|
243
229
|
})
|
|
244
230
|
);
|
|
245
231
|
assert.calledOnceWithExactly(mockHashTreeParser.initializeFromGetLociResponse, locus);
|
|
@@ -263,30 +249,6 @@ describe('plugin-meetings', () => {
|
|
|
263
249
|
assert.isTrue(locusInfo.emitChange);
|
|
264
250
|
});
|
|
265
251
|
|
|
266
|
-
it('throws if called with "locus-message" and Metadata object without visibleDataSets', async () => {
|
|
267
|
-
const hashTreeMessage = {
|
|
268
|
-
locusStateElements: [
|
|
269
|
-
{
|
|
270
|
-
htMeta: {elementId: {type: 'Metadata'}},
|
|
271
|
-
data: {},
|
|
272
|
-
},
|
|
273
|
-
],
|
|
274
|
-
dataSets: [{name: 'dataset1', url: 'test-url'}],
|
|
275
|
-
};
|
|
276
|
-
try {
|
|
277
|
-
await locusInfo.initialSetup({
|
|
278
|
-
trigger: 'locus-message',
|
|
279
|
-
hashTreeMessage,
|
|
280
|
-
});
|
|
281
|
-
assert.fail('should have thrown an error');
|
|
282
|
-
} catch (error) {
|
|
283
|
-
assert.equal(
|
|
284
|
-
error.message,
|
|
285
|
-
'Metadata object with visibleDataSets is missing in the message'
|
|
286
|
-
);
|
|
287
|
-
}
|
|
288
|
-
});
|
|
289
|
-
|
|
290
252
|
describe('should setup correct locusInfoUpdateCallback when creating HashTreeParser', () => {
|
|
291
253
|
const OBJECTS_UPDATED = HashTreeParserModule.LocusInfoUpdateType.OBJECTS_UPDATED;
|
|
292
254
|
const MEETING_ENDED = HashTreeParserModule.LocusInfoUpdateType.MEETING_ENDED;
|
|
@@ -301,11 +263,10 @@ describe('plugin-meetings', () => {
|
|
|
301
263
|
await locusInfo.initialSetup({
|
|
302
264
|
trigger: 'locus-message',
|
|
303
265
|
hashTreeMessage: {
|
|
304
|
-
locusUrl: 'fake-locus-url',
|
|
305
266
|
locusStateElements: [
|
|
306
267
|
{
|
|
307
|
-
htMeta: {elementId: {type: '
|
|
308
|
-
data: {visibleDataSets: [
|
|
268
|
+
htMeta: {elementId: {type: 'self'}},
|
|
269
|
+
data: {visibleDataSets: ['dataset1']},
|
|
309
270
|
},
|
|
310
271
|
],
|
|
311
272
|
dataSets: [{name: 'dataset1', url: 'test-url'}],
|
|
@@ -332,16 +293,6 @@ describe('plugin-meetings', () => {
|
|
|
332
293
|
htMeta: {elementId: {type: 'mediashare', id: 'fake-ht-mediaShare-2', version: 1}},
|
|
333
294
|
},
|
|
334
295
|
];
|
|
335
|
-
locusInfo.embeddedApps = [
|
|
336
|
-
{
|
|
337
|
-
id: 'fake-embedded-app-1',
|
|
338
|
-
htMeta: {elementId: {type: 'embeddedapp', id: 'fake-ht-embeddedApp-1', version: 1}},
|
|
339
|
-
},
|
|
340
|
-
{
|
|
341
|
-
id: 'fake-embedded-app-2',
|
|
342
|
-
htMeta: {elementId: {type: 'embeddedapp', id: 'fake-ht-embeddedApp-2', version: 1}},
|
|
343
|
-
},
|
|
344
|
-
];
|
|
345
296
|
locusInfo.meetings = {id: 'fake-meetings'};
|
|
346
297
|
locusInfo.participants = [
|
|
347
298
|
{id: 'fake-participant-1', name: 'Participant One'},
|
|
@@ -360,13 +311,6 @@ describe('plugin-meetings', () => {
|
|
|
360
311
|
locusInfo.url = 'fake-locus-url';
|
|
361
312
|
locusInfo.htMeta = {elementId: {type: 'locus', id: 'fake-ht-locus-id', version: 1}};
|
|
362
313
|
|
|
363
|
-
const createdHashTreeParser = locusInfo.hashTreeParsers.get('fake-locus-url');
|
|
364
|
-
|
|
365
|
-
assert.isDefined(createdHashTreeParser);
|
|
366
|
-
// this flag would have been set to true on the first callback triggered by initialSetup() wa called earlier
|
|
367
|
-
// it's not because we're mocking HashTreeParser, so we have to set it manually here
|
|
368
|
-
createdHashTreeParser.initializedFromHashTree = true;
|
|
369
|
-
|
|
370
314
|
// setup the default expected locus info state that each test builds upon
|
|
371
315
|
expectedLocusInfo = {
|
|
372
316
|
controls: {id: 'fake-controls'},
|
|
@@ -384,18 +328,8 @@ describe('plugin-meetings', () => {
|
|
|
384
328
|
htMeta: {elementId: {type: 'mediashare', id: 'fake-ht-mediaShare-2', version: 1}},
|
|
385
329
|
},
|
|
386
330
|
],
|
|
387
|
-
embeddedApps: [
|
|
388
|
-
{
|
|
389
|
-
id: 'fake-embedded-app-1',
|
|
390
|
-
htMeta: {elementId: {type: 'embeddedapp', id: 'fake-ht-embeddedApp-1', version: 1}},
|
|
391
|
-
},
|
|
392
|
-
{
|
|
393
|
-
id: 'fake-embedded-app-2',
|
|
394
|
-
htMeta: {elementId: {type: 'embeddedapp', id: 'fake-ht-embeddedApp-2', version: 1}},
|
|
395
|
-
},
|
|
396
|
-
],
|
|
397
331
|
meetings: {id: 'fake-meetings'},
|
|
398
|
-
jsSdkMeta: {removedParticipantIds: []
|
|
332
|
+
jsSdkMeta: {removedParticipantIds: []},
|
|
399
333
|
participants: [], // empty means there were no participant updates
|
|
400
334
|
replaces: {id: 'fake-replaces'},
|
|
401
335
|
self: {id: 'fake-self'},
|
|
@@ -424,134 +358,11 @@ describe('plugin-meetings', () => {
|
|
|
424
358
|
});
|
|
425
359
|
});
|
|
426
360
|
|
|
427
|
-
it('should process locus update correctly when called with updated SELF (webinar non-attendee)', () => {
|
|
428
|
-
const newSelf = {
|
|
429
|
-
id: 'new-self',
|
|
430
|
-
visibleDataSets: ['dataset1', 'dataset2'],
|
|
431
|
-
controls: {
|
|
432
|
-
role: {
|
|
433
|
-
roles: [
|
|
434
|
-
{type: 'PANELIST', hasRole: true},
|
|
435
|
-
{type: 'ATTENDEE', hasRole: false},
|
|
436
|
-
],
|
|
437
|
-
},
|
|
438
|
-
},
|
|
439
|
-
};
|
|
440
|
-
locusInfo.info.isWebinar = true;
|
|
441
|
-
|
|
442
|
-
// simulate an update from the HashTreeParser (normally this would be triggered by incoming locus messages)
|
|
443
|
-
locusInfoUpdateCallback(OBJECTS_UPDATED, {
|
|
444
|
-
updatedObjects: [{htMeta: {elementId: {type: 'self'}}, data: newSelf}],
|
|
445
|
-
});
|
|
446
|
-
|
|
447
|
-
// check onDeltaLocus() was called with correctly updated locus info
|
|
448
|
-
// without any participant generated
|
|
449
|
-
assert.calledOnceWithExactly(onDeltaLocusStub, {
|
|
450
|
-
...expectedLocusInfo,
|
|
451
|
-
info: {
|
|
452
|
-
...expectedLocusInfo.info,
|
|
453
|
-
isWebinar: true,
|
|
454
|
-
},
|
|
455
|
-
self: newSelf,
|
|
456
|
-
});
|
|
457
|
-
});
|
|
458
|
-
|
|
459
|
-
it('should generate a participant when called with updated SELF for webinar attendee', () => {
|
|
460
|
-
const newSelf = {
|
|
461
|
-
id: 'new-self',
|
|
462
|
-
visibleDataSets: ['dataset1', 'dataset2'],
|
|
463
|
-
controls: {
|
|
464
|
-
role: {
|
|
465
|
-
roles: [
|
|
466
|
-
{type: 'something else - should be ignored', hasRole: true},
|
|
467
|
-
{type: 'ATTENDEE', hasRole: true},
|
|
468
|
-
],
|
|
469
|
-
},
|
|
470
|
-
},
|
|
471
|
-
};
|
|
472
|
-
|
|
473
|
-
locusInfo.info.isWebinar = true;
|
|
474
|
-
|
|
475
|
-
// simulate an update from the HashTreeParser (normally this would be triggered by incoming locus messages)
|
|
476
|
-
locusInfoUpdateCallback(OBJECTS_UPDATED, {
|
|
477
|
-
updatedObjects: [{htMeta: {elementId: {type: 'self'}}, data: newSelf}],
|
|
478
|
-
});
|
|
479
|
-
|
|
480
|
-
// check onDeltaLocus() was called with correctly updated locus info
|
|
481
|
-
// that contains a participant created from self
|
|
482
|
-
assert.calledOnceWithExactly(onDeltaLocusStub, {
|
|
483
|
-
...expectedLocusInfo,
|
|
484
|
-
info: {
|
|
485
|
-
...expectedLocusInfo.info,
|
|
486
|
-
isWebinar: true,
|
|
487
|
-
},
|
|
488
|
-
self: newSelf,
|
|
489
|
-
participants: [
|
|
490
|
-
{
|
|
491
|
-
...newSelf,
|
|
492
|
-
},
|
|
493
|
-
],
|
|
494
|
-
});
|
|
495
|
-
});
|
|
496
|
-
|
|
497
|
-
it('should process locus update correctly when called with updated fullState', () => {
|
|
498
|
-
const newFullState = {
|
|
499
|
-
id: 'new-fullState',
|
|
500
|
-
visibleDataSets: ['dataset1', 'dataset2'],
|
|
501
|
-
};
|
|
502
|
-
|
|
503
|
-
// simulate an update from the HashTreeParser (normally this would be triggered by incoming locus messages)
|
|
504
|
-
locusInfoUpdateCallback(OBJECTS_UPDATED, {
|
|
505
|
-
updatedObjects: [{htMeta: {elementId: {type: 'fullState'}}, data: newFullState}],
|
|
506
|
-
});
|
|
507
|
-
|
|
508
|
-
// check onDeltaLocus() was called with correctly updated locus info
|
|
509
|
-
assert.calledOnceWithExactly(onDeltaLocusStub, {
|
|
510
|
-
...expectedLocusInfo,
|
|
511
|
-
fullState: newFullState,
|
|
512
|
-
});
|
|
513
|
-
});
|
|
514
|
-
|
|
515
|
-
it('should process locus update correctly when called with updated info', () => {
|
|
516
|
-
const newInfo = {
|
|
517
|
-
id: 'new-info',
|
|
518
|
-
visibleDataSets: ['dataset1', 'dataset2'],
|
|
519
|
-
};
|
|
520
|
-
|
|
521
|
-
// simulate an update from the HashTreeParser (normally this would be triggered by incoming locus messages)
|
|
522
|
-
locusInfoUpdateCallback(OBJECTS_UPDATED, {
|
|
523
|
-
updatedObjects: [{htMeta: {elementId: {type: 'info'}}, data: newInfo}],
|
|
524
|
-
});
|
|
525
|
-
|
|
526
|
-
// check onDeltaLocus() was called with correctly updated locus info
|
|
527
|
-
assert.calledOnceWithExactly(onDeltaLocusStub, {
|
|
528
|
-
...expectedLocusInfo,
|
|
529
|
-
info: newInfo,
|
|
530
|
-
});
|
|
531
|
-
});
|
|
532
|
-
|
|
533
|
-
it('should process locus update correctly when called with updated links', () => {
|
|
534
|
-
const newLinks = {
|
|
535
|
-
id: 'new-links',
|
|
536
|
-
visibleDataSets: ['dataset1', 'dataset2'],
|
|
537
|
-
};
|
|
538
|
-
|
|
539
|
-
// simulate an update from the HashTreeParser (normally this would be triggered by incoming locus messages)
|
|
540
|
-
locusInfoUpdateCallback(OBJECTS_UPDATED, {
|
|
541
|
-
updatedObjects: [{htMeta: {elementId: {type: 'links'}}, data: newLinks}],
|
|
542
|
-
});
|
|
543
|
-
|
|
544
|
-
// check onDeltaLocus() was called with correctly updated locus info
|
|
545
|
-
assert.calledOnceWithExactly(onDeltaLocusStub, {
|
|
546
|
-
...expectedLocusInfo,
|
|
547
|
-
links: newLinks,
|
|
548
|
-
});
|
|
549
|
-
});
|
|
550
|
-
|
|
551
361
|
it('should process locus update correctly when called with updated LOCUS object', () => {
|
|
552
362
|
// setup new updated locus that has many things missing
|
|
553
363
|
const newLocusHtMeta = {elementId: {type: 'locus', version: 42}};
|
|
554
364
|
const newLocus = {
|
|
365
|
+
conntrols: 'new-controls',
|
|
555
366
|
host: 'new-host',
|
|
556
367
|
htMeta: newLocusHtMeta,
|
|
557
368
|
};
|
|
@@ -563,67 +374,10 @@ describe('plugin-meetings', () => {
|
|
|
563
374
|
|
|
564
375
|
// check onDeltaLocus() was called with correctly updated locus info
|
|
565
376
|
assert.calledOnceWithExactly(onDeltaLocusStub, {
|
|
566
|
-
// these fields are not part of Locus object, so should keep their old values:
|
|
567
|
-
controls: {id: 'fake-controls'},
|
|
568
|
-
info: {id: 'fake-info'},
|
|
569
|
-
fullState: {id: 'fake-full-state'},
|
|
570
|
-
self: {id: 'fake-self'},
|
|
571
|
-
links: {id: 'fake-links'},
|
|
572
|
-
mediaShares: expectedLocusInfo.mediaShares,
|
|
573
|
-
embeddedApps: expectedLocusInfo.embeddedApps,
|
|
574
|
-
// and now the new fields
|
|
575
377
|
...newLocus,
|
|
576
378
|
htMeta: newLocusHtMeta,
|
|
577
379
|
participants: [], // empty means there were no participant updates
|
|
578
|
-
jsSdkMeta: {removedParticipantIds: []
|
|
579
|
-
});
|
|
580
|
-
});
|
|
581
|
-
|
|
582
|
-
// this test is checking that we cope with an edge case if Locus
|
|
583
|
-
// sends us something that they shouldn't
|
|
584
|
-
it('should process locus update correctly when called with updated LOCUS object that contains info/fullState/self/participants etc', () => {
|
|
585
|
-
// setup new updated locus that has many things missing
|
|
586
|
-
const newLocusHtMeta = {elementId: {type: 'locus', version: 42}};
|
|
587
|
-
const newLocus = {
|
|
588
|
-
host: 'new-host',
|
|
589
|
-
htMeta: newLocusHtMeta,
|
|
590
|
-
};
|
|
591
|
-
|
|
592
|
-
// simulate an update from the HashTreeParser (normally this would be triggered by incoming locus messages)
|
|
593
|
-
locusInfoUpdateCallback(OBJECTS_UPDATED, {
|
|
594
|
-
updatedObjects: [
|
|
595
|
-
{
|
|
596
|
-
htMeta: newLocusHtMeta,
|
|
597
|
-
data: {
|
|
598
|
-
...newLocus,
|
|
599
|
-
// all these fields below should be ignored and not override the existing ones in our "old" Locus
|
|
600
|
-
controls: {id: 'new-controls'},
|
|
601
|
-
info: 'new-info',
|
|
602
|
-
fullState: 'new-fullState',
|
|
603
|
-
self: 'new-self',
|
|
604
|
-
participants: 'new-participants',
|
|
605
|
-
mediaShares: 'new-mediaShares',
|
|
606
|
-
embeddedApps: 'new-embeddedApps',
|
|
607
|
-
},
|
|
608
|
-
},
|
|
609
|
-
],
|
|
610
|
-
});
|
|
611
|
-
|
|
612
|
-
// check onDeltaLocus() was called with correctly updated locus info
|
|
613
|
-
// with old values for the fields that should be ignored (like "info" or "fullState")
|
|
614
|
-
assert.calledOnceWithExactly(onDeltaLocusStub, {
|
|
615
|
-
// these fields have the "old" values:
|
|
616
|
-
controls: {id: 'fake-controls'},
|
|
617
|
-
info: {id: 'fake-info'},
|
|
618
|
-
fullState: {id: 'fake-full-state'},
|
|
619
|
-
self: {id: 'fake-self'},
|
|
620
|
-
links: {id: 'fake-links'},
|
|
621
|
-
mediaShares: expectedLocusInfo.mediaShares,
|
|
622
|
-
embeddedApps: expectedLocusInfo.embeddedApps,
|
|
623
|
-
participants: [], // empty means there were no participant updates
|
|
624
|
-
jsSdkMeta: {removedParticipantIds: [], forceReplaceMembers: false}, // no participants were removed
|
|
625
|
-
...newLocus,
|
|
626
|
-
htMeta: newLocusHtMeta,
|
|
380
|
+
jsSdkMeta: {removedParticipantIds: []}, // no participants were removed
|
|
627
381
|
});
|
|
628
382
|
});
|
|
629
383
|
|
|
@@ -648,19 +402,10 @@ describe('plugin-meetings', () => {
|
|
|
648
402
|
|
|
649
403
|
// check onDeltaLocus() was called with correctly updated locus info
|
|
650
404
|
assert.calledOnceWithExactly(onDeltaLocusStub, {
|
|
651
|
-
// these fields are not part of Locus object, so should keep their old values:
|
|
652
|
-
controls: {id: 'fake-controls'},
|
|
653
|
-
info: {id: 'fake-info'},
|
|
654
|
-
fullState: {id: 'fake-full-state'},
|
|
655
|
-
self: {id: 'fake-self'},
|
|
656
|
-
links: {id: 'fake-links'},
|
|
657
|
-
mediaShares: expectedLocusInfo.mediaShares,
|
|
658
|
-
embeddedApps: expectedLocusInfo.embeddedApps,
|
|
659
|
-
// and now the new fields
|
|
660
405
|
...newLocus,
|
|
661
406
|
htMeta: newLocusHtMeta,
|
|
662
407
|
participants: [], // empty means there were no participant updates
|
|
663
|
-
jsSdkMeta: {removedParticipantIds: []
|
|
408
|
+
jsSdkMeta: {removedParticipantIds: []}, // no participants were removed
|
|
664
409
|
});
|
|
665
410
|
});
|
|
666
411
|
|
|
@@ -748,7 +493,7 @@ describe('plugin-meetings', () => {
|
|
|
748
493
|
assert.calledOnceWithExactly(onDeltaLocusStub, {
|
|
749
494
|
...expectedLocusInfo,
|
|
750
495
|
participants: [newParticipant, updatedParticipant2],
|
|
751
|
-
jsSdkMeta: {removedParticipantIds: ['fake-participant-1']
|
|
496
|
+
jsSdkMeta: {removedParticipantIds: ['fake-participant-1']},
|
|
752
497
|
});
|
|
753
498
|
// and that the hashTreeObjectId2ParticipantId map was updated correctly
|
|
754
499
|
assert.isUndefined(locusInfo.hashTreeObjectId2ParticipantId.get('fake-ht-participant-1'));
|
|
@@ -795,39 +540,6 @@ describe('plugin-meetings', () => {
|
|
|
795
540
|
});
|
|
796
541
|
});
|
|
797
542
|
|
|
798
|
-
it('should process locus update correctly when called with updated EMBEDDEDAPP objects', () => {
|
|
799
|
-
const newEmbeddedApp = {
|
|
800
|
-
id: 'new-embedded-app-3',
|
|
801
|
-
htMeta: {elementId: {type: 'embeddedapp', id: 'fake-ht-embeddedApp-3', version: 100}},
|
|
802
|
-
};
|
|
803
|
-
const updatedEmbeddedApp2 = {
|
|
804
|
-
id: 'fake-embedded-app-2',
|
|
805
|
-
someNewProp: 'newValue',
|
|
806
|
-
htMeta: {elementId: {type: 'embeddedapp', id: 'fake-ht-embeddedApp-2', version: 100}},
|
|
807
|
-
};
|
|
808
|
-
// simulate an update from the HashTreeParser (normally this would be triggered by incoming locus messages)
|
|
809
|
-
// with 1 embedded app added, 1 updated, and 1 removed
|
|
810
|
-
locusInfoUpdateCallback(OBJECTS_UPDATED, {
|
|
811
|
-
updatedObjects: [
|
|
812
|
-
{htMeta: {elementId: {type: 'embeddedapp', id: 'fake-ht-embeddedApp-1'}}, data: null},
|
|
813
|
-
{
|
|
814
|
-
htMeta: {elementId: {type: 'embeddedapp', id: 'fake-ht-embeddedApp-2'}},
|
|
815
|
-
data: updatedEmbeddedApp2,
|
|
816
|
-
},
|
|
817
|
-
{
|
|
818
|
-
htMeta: {elementId: {type: 'embeddedapp', id: 'fake-ht-embeddedApp-3'}},
|
|
819
|
-
data: newEmbeddedApp,
|
|
820
|
-
},
|
|
821
|
-
],
|
|
822
|
-
});
|
|
823
|
-
|
|
824
|
-
// check onDeltaLocus() was called with correctly updated locus info
|
|
825
|
-
assert.calledOnceWithExactly(onDeltaLocusStub, {
|
|
826
|
-
...expectedLocusInfo,
|
|
827
|
-
embeddedApps: [updatedEmbeddedApp2, newEmbeddedApp],
|
|
828
|
-
});
|
|
829
|
-
});
|
|
830
|
-
|
|
831
543
|
it('should process locus update correctly when called with a combination of various updated objects', () => {
|
|
832
544
|
const newSelf = {
|
|
833
545
|
id: 'new-self',
|
|
@@ -873,60 +585,6 @@ describe('plugin-meetings', () => {
|
|
|
873
585
|
});
|
|
874
586
|
});
|
|
875
587
|
|
|
876
|
-
it('should process locus update correctly when called with multiple CONTROL object updates', () => {
|
|
877
|
-
const firstControl = {
|
|
878
|
-
muteOnEntry: {enabled: true},
|
|
879
|
-
lock: {locked: true, meta: {lastModified: 'YESTERDAY', modifiedBy: 'John Doe'}},
|
|
880
|
-
};
|
|
881
|
-
const secondControl = {
|
|
882
|
-
reactions: {enabled: true},
|
|
883
|
-
};
|
|
884
|
-
|
|
885
|
-
// simulate an update from the HashTreeParser (normally this would be triggered by incoming locus messages)
|
|
886
|
-
locusInfoUpdateCallback(OBJECTS_UPDATED, {
|
|
887
|
-
updatedObjects: [
|
|
888
|
-
{
|
|
889
|
-
htMeta: {elementId: {type: 'controlentry', id: 'control-1'}},
|
|
890
|
-
data: firstControl,
|
|
891
|
-
},
|
|
892
|
-
{
|
|
893
|
-
htMeta: {elementId: {type: 'controlentry', id: 'control-2'}},
|
|
894
|
-
data: secondControl,
|
|
895
|
-
},
|
|
896
|
-
],
|
|
897
|
-
});
|
|
898
|
-
|
|
899
|
-
// check onDeltaLocus() was called with correctly updated locus info
|
|
900
|
-
// all keys from both controls should be merged into the controls object
|
|
901
|
-
assert.calledOnceWithExactly(onDeltaLocusStub, {
|
|
902
|
-
...expectedLocusInfo,
|
|
903
|
-
controls: {
|
|
904
|
-
id: 'fake-controls',
|
|
905
|
-
muteOnEntry: {enabled: true},
|
|
906
|
-
lock: {locked: true, meta: {lastModified: 'YESTERDAY', modifiedBy: 'John Doe'}},
|
|
907
|
-
reactions: {enabled: true},
|
|
908
|
-
},
|
|
909
|
-
});
|
|
910
|
-
});
|
|
911
|
-
|
|
912
|
-
it('should process locus update correctly when CONTROL object is received with no data', () => {
|
|
913
|
-
// simulate an update from the HashTreeParser (normally this would be triggered by incoming locus messages)
|
|
914
|
-
locusInfoUpdateCallback(OBJECTS_UPDATED, {
|
|
915
|
-
updatedObjects: [
|
|
916
|
-
{
|
|
917
|
-
htMeta: {elementId: {type: 'controlentry', id: 'some-control-id'}},
|
|
918
|
-
data: null,
|
|
919
|
-
},
|
|
920
|
-
],
|
|
921
|
-
});
|
|
922
|
-
|
|
923
|
-
// check onDeltaLocus() was called with correctly updated locus info
|
|
924
|
-
// when data is null, it should be ignored and not change the controls
|
|
925
|
-
assert.calledOnceWithExactly(onDeltaLocusStub, {
|
|
926
|
-
...expectedLocusInfo,
|
|
927
|
-
});
|
|
928
|
-
});
|
|
929
|
-
|
|
930
588
|
it('should handle MEETING_ENDED correctly', () => {
|
|
931
589
|
const fakeMeeting = {id: 'fake-meeting-from-collection'};
|
|
932
590
|
const collectionGetStub = sinon
|
|
@@ -944,78 +602,6 @@ describe('plugin-meetings', () => {
|
|
|
944
602
|
MEETING_REMOVED_REASON.SELF_REMOVED
|
|
945
603
|
);
|
|
946
604
|
});
|
|
947
|
-
|
|
948
|
-
// this could happen if meeting gets destroyed while we're doing some async hash tree operation like a sync
|
|
949
|
-
it('should handle MEETING_ENDED correctly when meeting is not found in the collection', () => {
|
|
950
|
-
const collectionGetStub = sinon
|
|
951
|
-
.stub(locusInfo.webex.meetings.meetingCollection, 'get')
|
|
952
|
-
.returns(null);
|
|
953
|
-
const destroyStub = sinon.stub(locusInfo.webex.meetings, 'destroy');
|
|
954
|
-
|
|
955
|
-
// simulate an update from the HashTreeParser (normally this would be triggered by incoming locus messages)
|
|
956
|
-
locusInfoUpdateCallback(MEETING_ENDED);
|
|
957
|
-
|
|
958
|
-
assert.calledOnceWithExactly(collectionGetStub, locusInfo.meetingId);
|
|
959
|
-
assert.notCalled(destroyStub);
|
|
960
|
-
});
|
|
961
|
-
|
|
962
|
-
it('should set forceReplaceMembers to true on the first update for a locusUrl (initializedFromHashTree is false)', () => {
|
|
963
|
-
const createdHashTreeParser = locusInfo.hashTreeParsers.get('fake-locus-url');
|
|
964
|
-
createdHashTreeParser.initializedFromHashTree = false;
|
|
965
|
-
|
|
966
|
-
locusInfoUpdateCallback(OBJECTS_UPDATED, {
|
|
967
|
-
updatedObjects: [
|
|
968
|
-
{
|
|
969
|
-
htMeta: {elementId: {type: 'self'}},
|
|
970
|
-
data: {id: 'new-self'},
|
|
971
|
-
},
|
|
972
|
-
],
|
|
973
|
-
});
|
|
974
|
-
|
|
975
|
-
assert.calledOnce(onDeltaLocusStub);
|
|
976
|
-
assert.equal(onDeltaLocusStub.firstCall.args[0].jsSdkMeta.forceReplaceMembers, true);
|
|
977
|
-
assert.isTrue(createdHashTreeParser.initializedFromHashTree);
|
|
978
|
-
});
|
|
979
|
-
|
|
980
|
-
it('should set forceReplaceMembers to false on subsequent updates (initializedFromHashTree is true)', () => {
|
|
981
|
-
locusInfoUpdateCallback(OBJECTS_UPDATED, {
|
|
982
|
-
updatedObjects: [
|
|
983
|
-
{
|
|
984
|
-
htMeta: {elementId: {type: 'self'}},
|
|
985
|
-
data: {id: 'new-self'},
|
|
986
|
-
},
|
|
987
|
-
],
|
|
988
|
-
});
|
|
989
|
-
|
|
990
|
-
assert.calledOnce(onDeltaLocusStub);
|
|
991
|
-
assert.equal(onDeltaLocusStub.firstCall.args[0].jsSdkMeta.forceReplaceMembers, false);
|
|
992
|
-
});
|
|
993
|
-
|
|
994
|
-
it('should copy participant data to self when participant matches self identity and state is LEFT with reason MOVED', () => {
|
|
995
|
-
locusInfo.self = {id: 'fake-self', identity: 'user-123'};
|
|
996
|
-
|
|
997
|
-
locusInfoUpdateCallback(OBJECTS_UPDATED, {
|
|
998
|
-
updatedObjects: [
|
|
999
|
-
{
|
|
1000
|
-
htMeta: {elementId: {type: 'participant', id: 99}},
|
|
1001
|
-
data: {
|
|
1002
|
-
id: 'participant-matching-self',
|
|
1003
|
-
identity: 'user-123',
|
|
1004
|
-
state: 'LEFT',
|
|
1005
|
-
reason: 'MOVED',
|
|
1006
|
-
roles: ['MODERATOR'],
|
|
1007
|
-
},
|
|
1008
|
-
},
|
|
1009
|
-
],
|
|
1010
|
-
});
|
|
1011
|
-
|
|
1012
|
-
assert.calledOnce(onDeltaLocusStub);
|
|
1013
|
-
const passedLocus = onDeltaLocusStub.firstCall.args[0];
|
|
1014
|
-
|
|
1015
|
-
assert.equal(passedLocus.self.identity, 'user-123');
|
|
1016
|
-
assert.equal(passedLocus.self.state, 'LEFT');
|
|
1017
|
-
assert.equal(passedLocus.self.reason, 'MOVED');
|
|
1018
|
-
});
|
|
1019
605
|
});
|
|
1020
606
|
});
|
|
1021
607
|
|
|
@@ -1251,7 +837,7 @@ describe('plugin-meetings', () => {
|
|
|
1251
837
|
it('should trigger the CONTROLS_POLLING_QA_CHANGED event when necessary', () => {
|
|
1252
838
|
locusInfo.controls = {};
|
|
1253
839
|
locusInfo.emitScoped = sinon.stub();
|
|
1254
|
-
newControls.pollingQAControl = {enabled: true};
|
|
840
|
+
newControls.pollingQAControl = { enabled: true };
|
|
1255
841
|
locusInfo.updateControls(newControls);
|
|
1256
842
|
|
|
1257
843
|
assert.calledWith(
|
|
@@ -1513,62 +1099,6 @@ describe('plugin-meetings', () => {
|
|
|
1513
1099
|
);
|
|
1514
1100
|
});
|
|
1515
1101
|
|
|
1516
|
-
it('should update the hesiod llm id', () => {
|
|
1517
|
-
locusInfo.emitScoped = sinon.stub();
|
|
1518
|
-
locusInfo.controls = {
|
|
1519
|
-
transcribe: {
|
|
1520
|
-
transcribing: false,
|
|
1521
|
-
caption: true,
|
|
1522
|
-
hesiodLlmId: '123a-456b-789c',
|
|
1523
|
-
},
|
|
1524
|
-
};
|
|
1525
|
-
newControls.transcribe.transcribing = false;
|
|
1526
|
-
newControls.transcribe.caption = true;
|
|
1527
|
-
newControls.transcribe.hesiodLlmId = '789d-456e-123f';
|
|
1528
|
-
|
|
1529
|
-
locusInfo.updateControls(newControls);
|
|
1530
|
-
|
|
1531
|
-
assert.calledWith(
|
|
1532
|
-
locusInfo.emitScoped,
|
|
1533
|
-
{
|
|
1534
|
-
file: 'locus-info',
|
|
1535
|
-
function: 'updateControls',
|
|
1536
|
-
},
|
|
1537
|
-
LOCUSINFO.EVENTS.CONTROLS_MEETING_HESIOD_LLM_ID_UPDATED,
|
|
1538
|
-
{
|
|
1539
|
-
hesiodLlmId: '789d-456e-123f',
|
|
1540
|
-
}
|
|
1541
|
-
);
|
|
1542
|
-
});
|
|
1543
|
-
|
|
1544
|
-
it('should emit CONTROLS_AI_SUMMARY_NOTIFICATION_UPDATED when aiSummaryNotification changes', () => {
|
|
1545
|
-
locusInfo.emitScoped = sinon.stub();
|
|
1546
|
-
locusInfo.controls = {
|
|
1547
|
-
transcribe: {
|
|
1548
|
-
transcribing: false,
|
|
1549
|
-
caption: false,
|
|
1550
|
-
aiSummaryNotification: false,
|
|
1551
|
-
},
|
|
1552
|
-
};
|
|
1553
|
-
newControls.transcribe.transcribing = false;
|
|
1554
|
-
newControls.transcribe.caption = false;
|
|
1555
|
-
newControls.transcribe.aiSummaryNotification = true;
|
|
1556
|
-
|
|
1557
|
-
locusInfo.updateControls(newControls);
|
|
1558
|
-
|
|
1559
|
-
assert.calledWith(
|
|
1560
|
-
locusInfo.emitScoped,
|
|
1561
|
-
{
|
|
1562
|
-
file: 'locus-info',
|
|
1563
|
-
function: 'updateControls',
|
|
1564
|
-
},
|
|
1565
|
-
LOCUSINFO.EVENTS.CONTROLS_AI_SUMMARY_NOTIFICATION_UPDATED,
|
|
1566
|
-
{
|
|
1567
|
-
aiSummaryNotification: true,
|
|
1568
|
-
}
|
|
1569
|
-
);
|
|
1570
|
-
});
|
|
1571
|
-
|
|
1572
1102
|
it('should update the transcribe spoken language', () => {
|
|
1573
1103
|
locusInfo.emitScoped = sinon.stub();
|
|
1574
1104
|
locusInfo.controls = {
|
|
@@ -1834,6 +1364,7 @@ describe('plugin-meetings', () => {
|
|
|
1834
1364
|
);
|
|
1835
1365
|
});
|
|
1836
1366
|
|
|
1367
|
+
|
|
1837
1368
|
it('should call with participant display name', () => {
|
|
1838
1369
|
const failureParticipant = [
|
|
1839
1370
|
{
|
|
@@ -1858,7 +1389,7 @@ describe('plugin-meetings', () => {
|
|
|
1858
1389
|
displayName: 'Test User',
|
|
1859
1390
|
}
|
|
1860
1391
|
);
|
|
1861
|
-
})
|
|
1392
|
+
})
|
|
1862
1393
|
});
|
|
1863
1394
|
|
|
1864
1395
|
describe('#updateSelf', () => {
|
|
@@ -2659,8 +2190,8 @@ describe('plugin-meetings', () => {
|
|
|
2659
2190
|
{
|
|
2660
2191
|
isInitializing: !self,
|
|
2661
2192
|
}
|
|
2662
|
-
|
|
2663
|
-
|
|
2193
|
+
);
|
|
2194
|
+
});
|
|
2664
2195
|
|
|
2665
2196
|
const checkMeetingInfoUpdatedCalled = (expected, payload) => {
|
|
2666
2197
|
const expectedArgs = [
|
|
@@ -3008,359 +2539,32 @@ describe('plugin-meetings', () => {
|
|
|
3008
2539
|
|
|
3009
2540
|
const clonedApps = cloneDeep(newEmbeddedApps);
|
|
3010
2541
|
|
|
3011
|
-
locusInfo.updateEmbeddedApps(clonedApps);
|
|
3012
|
-
|
|
3013
|
-
assert.notCalled(locusInfo.emitScoped);
|
|
3014
|
-
});
|
|
3015
|
-
|
|
3016
|
-
it('emits EMBEDDED_APPS_UPDATED when apps changed', () => {
|
|
3017
|
-
locusInfo.updateEmbeddedApps(newEmbeddedApps);
|
|
3018
|
-
|
|
3019
|
-
locusInfo.emitScoped = sinon.stub();
|
|
3020
|
-
|
|
3021
|
-
const clonedApps = cloneDeep(newEmbeddedApps);
|
|
3022
|
-
|
|
3023
|
-
clonedApps[0].state = 'STOPPED';
|
|
3024
|
-
const expectedApps = EmbeddedAppsUtils.parse(clonedApps);
|
|
3025
|
-
|
|
3026
|
-
locusInfo.updateEmbeddedApps(clonedApps);
|
|
3027
|
-
|
|
3028
|
-
assert.calledWith(
|
|
3029
|
-
locusInfo.emitScoped,
|
|
3030
|
-
{
|
|
3031
|
-
file: 'locus-info',
|
|
3032
|
-
function: 'updateEmbeddedApps',
|
|
3033
|
-
},
|
|
3034
|
-
LOCUSINFO.EVENTS.EMBEDDED_APPS_UPDATED,
|
|
3035
|
-
expectedApps
|
|
3036
|
-
);
|
|
3037
|
-
});
|
|
3038
|
-
});
|
|
3039
|
-
|
|
3040
|
-
describe('#createHashTreeParser', () => {
|
|
3041
|
-
let HashTreeParserStub;
|
|
3042
|
-
|
|
3043
|
-
beforeEach(() => {
|
|
3044
|
-
HashTreeParserStub = sinon
|
|
3045
|
-
.stub(HashTreeParserModule, 'default')
|
|
3046
|
-
.returns({
|
|
3047
|
-
initializeFromMessage: sinon.stub().resolves(),
|
|
3048
|
-
initializeFromGetLociResponse: sinon.stub().resolves(),
|
|
3049
|
-
state: 'active',
|
|
3050
|
-
stop: sinon.stub(),
|
|
3051
|
-
handleMessage: sinon.stub(),
|
|
3052
|
-
});
|
|
3053
|
-
});
|
|
3054
|
-
|
|
3055
|
-
const setupParserViaInitialSetup = async (locusUrl = 'http://locus-url-A.com') => {
|
|
3056
|
-
await locusInfo.initialSetup({
|
|
3057
|
-
trigger: 'locus-message',
|
|
3058
|
-
hashTreeMessage: {
|
|
3059
|
-
locusUrl,
|
|
3060
|
-
locusStateElements: [
|
|
3061
|
-
{
|
|
3062
|
-
htMeta: {elementId: {type: 'Metadata'}},
|
|
3063
|
-
data: {visibleDataSets: [{name: 'dataset1', url: 'test-url'}]},
|
|
3064
|
-
},
|
|
3065
|
-
],
|
|
3066
|
-
dataSets: [{name: 'dataset1', url: 'test-url'}],
|
|
3067
|
-
},
|
|
3068
|
-
});
|
|
3069
|
-
};
|
|
3070
|
-
|
|
3071
|
-
it('should stop existing active parsers when creating a new one', async () => {
|
|
3072
|
-
await setupParserViaInitialSetup('http://locus-url-A.com');
|
|
3073
|
-
|
|
3074
|
-
const firstParser = locusInfo.hashTreeParsers.get('http://locus-url-A.com').parser;
|
|
3075
|
-
|
|
3076
|
-
await setupParserViaInitialSetup('http://locus-url-B.com');
|
|
3077
|
-
|
|
3078
|
-
assert.calledOnce(firstParser.stop);
|
|
3079
|
-
});
|
|
3080
|
-
|
|
3081
|
-
it('should set replacedAt on existing entries when replacedAt is provided', async () => {
|
|
3082
|
-
await setupParserViaInitialSetup('http://locus-url-A.com');
|
|
3083
|
-
|
|
3084
|
-
// Call createHashTreeParser with replacedAt via parse -> handleHashTreeParserSwitch
|
|
3085
|
-
// which calls createHashTreeParser with replacedAt from the self element
|
|
3086
|
-
locusInfo.webex.internal.device.url = 'http://device-url.com';
|
|
3087
|
-
const message = {
|
|
3088
|
-
locusUrl: 'http://locus-url-B.com',
|
|
3089
|
-
locusStateElements: [
|
|
3090
|
-
{
|
|
3091
|
-
htMeta: {elementId: {type: 'Metadata'}},
|
|
3092
|
-
data: {visibleDataSets: [{name: 'dataset1', url: 'test-url'}]},
|
|
3093
|
-
},
|
|
3094
|
-
{
|
|
3095
|
-
htMeta: {elementId: {type: 'Self'}},
|
|
3096
|
-
data: {
|
|
3097
|
-
devices: [{url: 'http://device-url.com', replaces: [{locusUrl: 'http://locus-url-A.com', replacedAt: '2026-01-01T00:00:00Z'}]}],
|
|
3098
|
-
},
|
|
3099
|
-
},
|
|
3100
|
-
],
|
|
3101
|
-
dataSets: [{name: 'dataset1', url: 'test-url'}],
|
|
3102
|
-
};
|
|
3103
|
-
|
|
3104
|
-
locusInfo.parse(mockMeeting, {
|
|
3105
|
-
eventType: LOCUSEVENT.HASH_TREE_DATA_UPDATED,
|
|
3106
|
-
stateElementsMessage: message,
|
|
3107
|
-
});
|
|
3108
|
-
|
|
3109
|
-
assert.equal(locusInfo.hashTreeParsers.get('http://locus-url-A.com').replacedAt, '2026-01-01T00:00:00Z');
|
|
3110
|
-
});
|
|
3111
|
-
|
|
3112
|
-
it('should not set replacedAt on existing entries when replacedAt is not provided', async () => {
|
|
3113
|
-
await setupParserViaInitialSetup('http://locus-url-A.com');
|
|
3114
|
-
|
|
3115
|
-
await setupParserViaInitialSetup('http://locus-url-B.com');
|
|
3116
|
-
|
|
3117
|
-
assert.isUndefined(locusInfo.hashTreeParsers.get('http://locus-url-A.com').replacedAt);
|
|
3118
|
-
});
|
|
3119
|
-
|
|
3120
|
-
it('should store the new parser in hashTreeParsers map with the correct locusUrl key', async () => {
|
|
3121
|
-
await setupParserViaInitialSetup('http://locus-url-A.com');
|
|
3122
|
-
|
|
3123
|
-
assert.isTrue(locusInfo.hashTreeParsers.has('http://locus-url-A.com'));
|
|
3124
|
-
assert.isDefined(locusInfo.hashTreeParsers.get('http://locus-url-A.com').parser);
|
|
3125
|
-
});
|
|
3126
|
-
|
|
3127
|
-
it('should clear hashTreeObjectId2ParticipantId when creating a new parser', async () => {
|
|
3128
|
-
await setupParserViaInitialSetup('http://locus-url-A.com');
|
|
3129
|
-
locusInfo.hashTreeObjectId2ParticipantId.set(1, 'participant-1');
|
|
3130
|
-
|
|
3131
|
-
await setupParserViaInitialSetup('http://locus-url-B.com');
|
|
3132
|
-
|
|
3133
|
-
assert.equal(locusInfo.hashTreeObjectId2ParticipantId.size, 0);
|
|
3134
|
-
});
|
|
3135
|
-
|
|
3136
|
-
it('should not stop already stopped parsers', async () => {
|
|
3137
|
-
await setupParserViaInitialSetup('http://locus-url-A.com');
|
|
3138
|
-
const firstParser = locusInfo.hashTreeParsers.get('http://locus-url-A.com').parser;
|
|
3139
|
-
firstParser.state = 'stopped';
|
|
3140
|
-
|
|
3141
|
-
await setupParserViaInitialSetup('http://locus-url-B.com');
|
|
3142
|
-
|
|
3143
|
-
assert.notCalled(firstParser.stop);
|
|
3144
|
-
});
|
|
3145
|
-
});
|
|
3146
|
-
|
|
3147
|
-
describe('#handleHashTreeParserSwitch', () => {
|
|
3148
|
-
const deviceUrl = 'http://device-url.com';
|
|
3149
|
-
const locusUrlA = 'http://locus-url-A.com';
|
|
3150
|
-
const locusUrlB = 'http://locus-url-B.com';
|
|
3151
|
-
|
|
3152
|
-
let HashTreeParserStub;
|
|
3153
|
-
|
|
3154
|
-
const createMockParser = (state = 'active') => ({
|
|
3155
|
-
state,
|
|
3156
|
-
stop: sinon.stub(),
|
|
3157
|
-
resume: sinon.stub(),
|
|
3158
|
-
handleMessage: sinon.stub(),
|
|
3159
|
-
});
|
|
3160
|
-
|
|
3161
|
-
const createSelfElementWithReplaces = (replacedLocusUrl, replacedAt) => ({
|
|
3162
|
-
htMeta: {elementId: {type: 'Self'}},
|
|
3163
|
-
data: {
|
|
3164
|
-
devices: [{url: deviceUrl, replaces: [{locusUrl: replacedLocusUrl, replacedAt}]}],
|
|
3165
|
-
},
|
|
3166
|
-
});
|
|
3167
|
-
|
|
3168
|
-
const createMetadataElement = () => ({
|
|
3169
|
-
htMeta: {elementId: {type: 'Metadata'}},
|
|
3170
|
-
data: {visibleDataSets: [{name: 'dataset1', url: 'test-url'}]},
|
|
3171
|
-
});
|
|
3172
|
-
|
|
3173
|
-
beforeEach(() => {
|
|
3174
|
-
locusInfo.webex.internal.device.url = deviceUrl;
|
|
3175
|
-
HashTreeParserStub = sinon
|
|
3176
|
-
.stub(HashTreeParserModule, 'default')
|
|
3177
|
-
.returns(createMockParser());
|
|
3178
|
-
});
|
|
3179
|
-
|
|
3180
|
-
it('should create a new parser when no entry exists for locusUrl and metadata has visibleDataSets', () => {
|
|
3181
|
-
// set up an existing parser for a different url
|
|
3182
|
-
locusInfo.hashTreeParsers.set(locusUrlA, {parser: createMockParser(), initializedFromHashTree: true});
|
|
3183
|
-
|
|
3184
|
-
const message = {
|
|
3185
|
-
locusUrl: locusUrlB,
|
|
3186
|
-
locusStateElements: [createMetadataElement()],
|
|
3187
|
-
dataSets: [{name: 'dataset1', url: 'test-url'}],
|
|
3188
|
-
};
|
|
3189
|
-
|
|
3190
|
-
locusInfo.parse(mockMeeting, {
|
|
3191
|
-
eventType: LOCUSEVENT.HASH_TREE_DATA_UPDATED,
|
|
3192
|
-
stateElementsMessage: message,
|
|
3193
|
-
});
|
|
3194
|
-
|
|
3195
|
-
assert.isTrue(locusInfo.hashTreeParsers.has(locusUrlB));
|
|
3196
|
-
});
|
|
3197
|
-
|
|
3198
|
-
it('should return true when no entry exists even if no metadata is available', () => {
|
|
3199
|
-
locusInfo.hashTreeParsers.set(locusUrlA, {parser: createMockParser(), initializedFromHashTree: true});
|
|
3200
|
-
const parserA = locusInfo.hashTreeParsers.get(locusUrlA).parser;
|
|
3201
|
-
|
|
3202
|
-
const message = {
|
|
3203
|
-
locusUrl: locusUrlB,
|
|
3204
|
-
locusStateElements: [],
|
|
3205
|
-
dataSets: [],
|
|
3206
|
-
};
|
|
3207
|
-
|
|
3208
|
-
locusInfo.parse(mockMeeting, {
|
|
3209
|
-
eventType: LOCUSEVENT.HASH_TREE_DATA_UPDATED,
|
|
3210
|
-
stateElementsMessage: message,
|
|
3211
|
-
});
|
|
3212
|
-
|
|
3213
|
-
// no new parser created since no metadata
|
|
3214
|
-
assert.isFalse(locusInfo.hashTreeParsers.has(locusUrlB));
|
|
3215
|
-
// the existing parser's handleMessage should NOT have been called
|
|
3216
|
-
assert.notCalled(parserA.handleMessage);
|
|
3217
|
-
});
|
|
3218
|
-
|
|
3219
|
-
it('should resume a stopped parser when replaces info is newer', () => {
|
|
3220
|
-
const parserA = createMockParser('stopped');
|
|
3221
|
-
const parserB = createMockParser('active');
|
|
3222
|
-
locusInfo.hashTreeParsers.set(locusUrlA, {parser: parserA, replacedAt: '2026-01-01T00:00:00Z', initializedFromHashTree: true});
|
|
3223
|
-
locusInfo.hashTreeParsers.set(locusUrlB, {parser: parserB, initializedFromHashTree: true});
|
|
3224
|
-
|
|
3225
|
-
const message = {
|
|
3226
|
-
locusUrl: locusUrlA,
|
|
3227
|
-
locusStateElements: [
|
|
3228
|
-
createSelfElementWithReplaces(locusUrlB, '2026-02-01T00:00:00Z'),
|
|
3229
|
-
createMetadataElement(),
|
|
3230
|
-
],
|
|
3231
|
-
dataSets: [{name: 'dataset1', url: 'test-url'}],
|
|
3232
|
-
};
|
|
3233
|
-
|
|
3234
|
-
locusInfo.parse(mockMeeting, {
|
|
3235
|
-
eventType: LOCUSEVENT.HASH_TREE_DATA_UPDATED,
|
|
3236
|
-
stateElementsMessage: message,
|
|
3237
|
-
});
|
|
3238
|
-
|
|
3239
|
-
assert.calledOnce(parserA.resume);
|
|
3240
|
-
assert.calledOnce(parserB.stop);
|
|
3241
|
-
});
|
|
3242
|
-
|
|
3243
|
-
it('should not resume a stopped parser when replaces info is not newer', () => {
|
|
3244
|
-
const parserA = createMockParser('stopped');
|
|
3245
|
-
const parserB = createMockParser('active');
|
|
3246
|
-
locusInfo.hashTreeParsers.set(locusUrlA, {parser: parserA, replacedAt: '2026-03-01T00:00:00Z', initializedFromHashTree: true});
|
|
3247
|
-
locusInfo.hashTreeParsers.set(locusUrlB, {parser: parserB, initializedFromHashTree: true});
|
|
3248
|
-
|
|
3249
|
-
const message = {
|
|
3250
|
-
locusUrl: locusUrlA,
|
|
3251
|
-
locusStateElements: [
|
|
3252
|
-
createSelfElementWithReplaces(locusUrlB, '2026-01-01T00:00:00Z'),
|
|
3253
|
-
],
|
|
3254
|
-
dataSets: [{name: 'dataset1', url: 'test-url'}],
|
|
3255
|
-
};
|
|
3256
|
-
|
|
3257
|
-
locusInfo.parse(mockMeeting, {
|
|
3258
|
-
eventType: LOCUSEVENT.HASH_TREE_DATA_UPDATED,
|
|
3259
|
-
stateElementsMessage: message,
|
|
3260
|
-
});
|
|
3261
|
-
|
|
3262
|
-
assert.notCalled(parserA.resume);
|
|
3263
|
-
assert.notCalled(parserB.stop);
|
|
3264
|
-
});
|
|
3265
|
-
|
|
3266
|
-
it('should return true for a stopped parser with no replaces info', () => {
|
|
3267
|
-
const parserA = createMockParser('stopped');
|
|
3268
|
-
locusInfo.hashTreeParsers.set(locusUrlA, {parser: parserA, initializedFromHashTree: true});
|
|
3269
|
-
|
|
3270
|
-
const message = {
|
|
3271
|
-
locusUrl: locusUrlA,
|
|
3272
|
-
locusStateElements: [],
|
|
3273
|
-
dataSets: [],
|
|
3274
|
-
};
|
|
3275
|
-
|
|
3276
|
-
locusInfo.parse(mockMeeting, {
|
|
3277
|
-
eventType: LOCUSEVENT.HASH_TREE_DATA_UPDATED,
|
|
3278
|
-
stateElementsMessage: message,
|
|
3279
|
-
});
|
|
3280
|
-
|
|
3281
|
-
assert.notCalled(parserA.resume);
|
|
3282
|
-
assert.notCalled(parserA.handleMessage);
|
|
3283
|
-
});
|
|
3284
|
-
|
|
3285
|
-
it('should return false when the entry exists and parser is active', () => {
|
|
3286
|
-
const parserA = createMockParser('active');
|
|
3287
|
-
locusInfo.hashTreeParsers.set(locusUrlA, {parser: parserA, initializedFromHashTree: true});
|
|
3288
|
-
|
|
3289
|
-
const message = {
|
|
3290
|
-
locusUrl: locusUrlA,
|
|
3291
|
-
locusStateElements: [],
|
|
3292
|
-
dataSets: [],
|
|
3293
|
-
};
|
|
3294
|
-
|
|
3295
|
-
locusInfo.parse(mockMeeting, {
|
|
3296
|
-
eventType: LOCUSEVENT.HASH_TREE_DATA_UPDATED,
|
|
3297
|
-
stateElementsMessage: message,
|
|
3298
|
-
});
|
|
3299
|
-
|
|
3300
|
-
assert.calledOnceWithExactly(parserA.handleMessage, message);
|
|
3301
|
-
});
|
|
3302
|
-
|
|
3303
|
-
it('should pass replacedAt from replaces to createHashTreeParser when creating a new parser', () => {
|
|
3304
|
-
locusInfo.hashTreeParsers.set(locusUrlA, {parser: createMockParser(), initializedFromHashTree: true});
|
|
3305
|
-
|
|
3306
|
-
const message = {
|
|
3307
|
-
locusUrl: locusUrlB,
|
|
3308
|
-
locusStateElements: [
|
|
3309
|
-
createMetadataElement(),
|
|
3310
|
-
createSelfElementWithReplaces(locusUrlA, '2026-05-01T00:00:00Z'),
|
|
3311
|
-
],
|
|
3312
|
-
dataSets: [{name: 'dataset1', url: 'test-url'}],
|
|
3313
|
-
};
|
|
3314
|
-
|
|
3315
|
-
locusInfo.parse(mockMeeting, {
|
|
3316
|
-
eventType: LOCUSEVENT.HASH_TREE_DATA_UPDATED,
|
|
3317
|
-
stateElementsMessage: message,
|
|
3318
|
-
});
|
|
2542
|
+
locusInfo.updateEmbeddedApps(clonedApps);
|
|
3319
2543
|
|
|
3320
|
-
assert.
|
|
3321
|
-
assert.equal(locusInfo.hashTreeParsers.get(locusUrlA).replacedAt, '2026-05-01T00:00:00Z');
|
|
2544
|
+
assert.notCalled(locusInfo.emitScoped);
|
|
3322
2545
|
});
|
|
3323
|
-
});
|
|
3324
|
-
|
|
3325
|
-
describe('#handleHashTreeMessage', () => {
|
|
3326
|
-
it('should call handleHashTreeParserSwitch and not call handleMessage if parser was switched', () => {
|
|
3327
|
-
const locusUrlA = 'http://locus-url-A.com';
|
|
3328
|
-
const locusUrlB = 'http://locus-url-B.com';
|
|
3329
|
-
const parserA = {state: 'stopped', handleMessage: sinon.stub(), resume: sinon.stub(), stop: sinon.stub()};
|
|
3330
|
-
locusInfo.hashTreeParsers.set(locusUrlA, {parser: parserA, initializedFromHashTree: true});
|
|
3331
|
-
|
|
3332
|
-
// message for a stopped parser without replaces -> handleHashTreeParserSwitch returns true
|
|
3333
|
-
const message = {
|
|
3334
|
-
locusUrl: locusUrlA,
|
|
3335
|
-
locusStateElements: [],
|
|
3336
|
-
dataSets: [],
|
|
3337
|
-
};
|
|
3338
2546
|
|
|
3339
|
-
|
|
3340
|
-
|
|
3341
|
-
stateElementsMessage: message,
|
|
3342
|
-
});
|
|
2547
|
+
it('emits EMBEDDED_APPS_UPDATED when apps changed', () => {
|
|
2548
|
+
locusInfo.updateEmbeddedApps(newEmbeddedApps);
|
|
3343
2549
|
|
|
3344
|
-
|
|
3345
|
-
});
|
|
2550
|
+
locusInfo.emitScoped = sinon.stub();
|
|
3346
2551
|
|
|
3347
|
-
|
|
3348
|
-
const locusUrlA = 'http://locus-url-A.com';
|
|
3349
|
-
const parserA = {state: 'active', handleMessage: sinon.stub()};
|
|
3350
|
-
locusInfo.hashTreeParsers.set(locusUrlA, {parser: parserA, initializedFromHashTree: true});
|
|
2552
|
+
const clonedApps = cloneDeep(newEmbeddedApps);
|
|
3351
2553
|
|
|
3352
|
-
|
|
3353
|
-
|
|
3354
|
-
locusStateElements: [],
|
|
3355
|
-
dataSets: [],
|
|
3356
|
-
};
|
|
2554
|
+
clonedApps[0].state = 'STOPPED';
|
|
2555
|
+
const expectedApps = EmbeddedAppsUtils.parse(clonedApps);
|
|
3357
2556
|
|
|
3358
|
-
locusInfo.
|
|
3359
|
-
eventType: LOCUSEVENT.HASH_TREE_DATA_UPDATED,
|
|
3360
|
-
stateElementsMessage: message,
|
|
3361
|
-
});
|
|
2557
|
+
locusInfo.updateEmbeddedApps(clonedApps);
|
|
3362
2558
|
|
|
3363
|
-
assert.
|
|
2559
|
+
assert.calledWith(
|
|
2560
|
+
locusInfo.emitScoped,
|
|
2561
|
+
{
|
|
2562
|
+
file: 'locus-info',
|
|
2563
|
+
function: 'updateEmbeddedApps',
|
|
2564
|
+
},
|
|
2565
|
+
LOCUSINFO.EVENTS.EMBEDDED_APPS_UPDATED,
|
|
2566
|
+
expectedApps
|
|
2567
|
+
);
|
|
3364
2568
|
});
|
|
3365
2569
|
});
|
|
3366
2570
|
|
|
@@ -3374,8 +2578,8 @@ describe('plugin-meetings', () => {
|
|
|
3374
2578
|
|
|
3375
2579
|
assert.calledWith(locusInfo.handleLocusDelta, fakeLocus, mockMeeting);
|
|
3376
2580
|
});
|
|
3377
|
-
it('
|
|
3378
|
-
const fakeLocus = {eventType: LOCUSEVENT.DIFFERENCE
|
|
2581
|
+
it('does nothing when we are using hash trees', () => {
|
|
2582
|
+
const fakeLocus = {eventType: LOCUSEVENT.DIFFERENCE};
|
|
3379
2583
|
const fakeDataSets = [{name: 'dataset1', url: 'http://test.com'}];
|
|
3380
2584
|
const responseBody = {locus: fakeLocus, dataSets: fakeDataSets};
|
|
3381
2585
|
|
|
@@ -3383,53 +2587,14 @@ describe('plugin-meetings', () => {
|
|
|
3383
2587
|
const mockHashTreeParser = {
|
|
3384
2588
|
handleLocusUpdate: sinon.stub(),
|
|
3385
2589
|
};
|
|
3386
|
-
locusInfo.
|
|
3387
|
-
parser: mockHashTreeParser,
|
|
3388
|
-
initializedFromHashTree: true,
|
|
3389
|
-
});
|
|
2590
|
+
locusInfo.hashTreeParser = mockHashTreeParser;
|
|
3390
2591
|
|
|
3391
2592
|
sinon.stub(locusInfo, 'onDeltaLocus');
|
|
3392
2593
|
|
|
3393
2594
|
locusInfo.handleLocusAPIResponse(mockMeeting, responseBody);
|
|
3394
2595
|
|
|
3395
|
-
assert.
|
|
3396
|
-
|
|
3397
|
-
|
|
3398
|
-
it('should handle unwrapped LocusDTO (without locus wrapper) when hash tree parser exists', () => {
|
|
3399
|
-
const fakeLocus = {url: 'http://locus-url.com', fullState: {state: 'ACTIVE'}};
|
|
3400
|
-
const mockHashTreeParser = {handleLocusUpdate: sinon.stub()};
|
|
3401
|
-
locusInfo.hashTreeParsers.set(fakeLocus.url, {
|
|
3402
|
-
parser: mockHashTreeParser,
|
|
3403
|
-
initializedFromHashTree: true,
|
|
3404
|
-
});
|
|
3405
|
-
|
|
3406
|
-
locusInfo.handleLocusAPIResponse(mockMeeting, fakeLocus);
|
|
3407
|
-
|
|
3408
|
-
assert.calledOnceWithExactly(mockHashTreeParser.handleLocusUpdate, {locus: fakeLocus});
|
|
3409
|
-
});
|
|
3410
|
-
|
|
3411
|
-
it('should handle unwrapped LocusDTO in classic mode (no hash tree parser)', () => {
|
|
3412
|
-
const fakeLocus = {url: 'http://locus-url.com', fullState: {state: 'ACTIVE'}};
|
|
3413
|
-
sinon.stub(locusInfo, 'handleLocusDelta');
|
|
3414
|
-
|
|
3415
|
-
locusInfo.handleLocusAPIResponse(mockMeeting, fakeLocus);
|
|
3416
|
-
|
|
3417
|
-
assert.calledOnceWithExactly(locusInfo.handleLocusDelta, fakeLocus, mockMeeting);
|
|
3418
|
-
});
|
|
3419
|
-
|
|
3420
|
-
it('should send mismatch metric when hash tree parser exists but dataSets are missing in wrapped response', () => {
|
|
3421
|
-
const fakeLocus = {url: 'http://locus-url.com'};
|
|
3422
|
-
const mockHashTreeParser = {handleLocusUpdate: sinon.stub()};
|
|
3423
|
-
locusInfo.hashTreeParsers.set(fakeLocus.url, {
|
|
3424
|
-
parser: mockHashTreeParser,
|
|
3425
|
-
initializedFromHashTree: true,
|
|
3426
|
-
});
|
|
3427
|
-
sinon.stub(locusInfo, 'sendClassicVsHashTreeMismatchMetric');
|
|
3428
|
-
|
|
3429
|
-
locusInfo.handleLocusAPIResponse(mockMeeting, {locus: fakeLocus});
|
|
3430
|
-
|
|
3431
|
-
assert.calledOnce(locusInfo.sendClassicVsHashTreeMismatchMetric);
|
|
3432
|
-
assert.calledOnce(mockHashTreeParser.handleLocusUpdate);
|
|
2596
|
+
assert.notCalled(mockHashTreeParser.handleLocusUpdate);
|
|
2597
|
+
assert.notCalled(locusInfo.onDeltaLocus);
|
|
3433
2598
|
});
|
|
3434
2599
|
});
|
|
3435
2600
|
|
|
@@ -3492,28 +2657,31 @@ describe('plugin-meetings', () => {
|
|
|
3492
2657
|
assert.isFunction(locusParser.onDeltaAction);
|
|
3493
2658
|
});
|
|
3494
2659
|
|
|
3495
|
-
it(
|
|
2660
|
+
it("#updateLocusInfo invokes updateLocusUrl before updateMeetingInfo", () => {
|
|
3496
2661
|
const callOrder = [];
|
|
3497
|
-
sinon.stub(locusInfo,
|
|
3498
|
-
sinon.stub(locusInfo,
|
|
3499
|
-
sinon.stub(locusInfo,
|
|
3500
|
-
sinon.stub(locusInfo,
|
|
3501
|
-
sinon.stub(locusInfo,
|
|
3502
|
-
sinon.stub(locusInfo,
|
|
3503
|
-
callOrder.push(
|
|
3504
|
-
});
|
|
3505
|
-
sinon.stub(locusInfo,
|
|
3506
|
-
sinon.stub(locusInfo,
|
|
3507
|
-
sinon.stub(locusInfo,
|
|
3508
|
-
sinon.stub(locusInfo,
|
|
3509
|
-
|
|
3510
|
-
|
|
3511
|
-
|
|
3512
|
-
sinon.stub(locusInfo,
|
|
3513
|
-
sinon.stub(locusInfo,
|
|
3514
|
-
sinon.stub(locusInfo,
|
|
3515
|
-
sinon.stub(locusInfo,
|
|
3516
|
-
sinon.stub(locusInfo,
|
|
2662
|
+
sinon.stub(locusInfo, "updateControls");
|
|
2663
|
+
sinon.stub(locusInfo, "updateConversationUrl");
|
|
2664
|
+
sinon.stub(locusInfo, "updateCreated");
|
|
2665
|
+
sinon.stub(locusInfo, "updateFullState");
|
|
2666
|
+
sinon.stub(locusInfo, "updateHostInfo");
|
|
2667
|
+
sinon.stub(locusInfo, "updateMeetingInfo").callsFake(() => {
|
|
2668
|
+
callOrder.push("updateMeetingInfo");
|
|
2669
|
+
});
|
|
2670
|
+
sinon.stub(locusInfo, "updateMediaShares");
|
|
2671
|
+
sinon.stub(locusInfo, "updateParticipantsUrl");
|
|
2672
|
+
sinon.stub(locusInfo, "updateReplace");
|
|
2673
|
+
sinon.stub(locusInfo, "updateSelf");
|
|
2674
|
+
sinon.stub(locusInfo, "updateLocusUrl").callsFake(() => {
|
|
2675
|
+
callOrder.push("updateLocusUrl");
|
|
2676
|
+
});
|
|
2677
|
+
sinon.stub(locusInfo, "updateAclUrl");
|
|
2678
|
+
sinon.stub(locusInfo, "updateBasequence");
|
|
2679
|
+
sinon.stub(locusInfo, "updateSequence");
|
|
2680
|
+
sinon.stub(locusInfo, "updateMemberShip");
|
|
2681
|
+
sinon.stub(locusInfo, "updateIdentifiers");
|
|
2682
|
+
sinon.stub(locusInfo, "updateEmbeddedApps");
|
|
2683
|
+
sinon.stub(locusInfo, "updateResources");
|
|
2684
|
+
sinon.stub(locusInfo, "compareAndUpdate");
|
|
3517
2685
|
|
|
3518
2686
|
locusInfo.updateLocusInfo(locus);
|
|
3519
2687
|
|
|
@@ -3536,14 +2704,17 @@ describe('plugin-meetings', () => {
|
|
|
3536
2704
|
locusInfo.updateHostInfo = sinon.stub();
|
|
3537
2705
|
locusInfo.updateMeetingInfo = sinon.stub();
|
|
3538
2706
|
locusInfo.updateMediaShares = sinon.stub();
|
|
3539
|
-
locusInfo.
|
|
2707
|
+
locusInfo.updateParticipantsUrl = sinon.stub();
|
|
2708
|
+
locusInfo.updateReplace = sinon.stub();
|
|
3540
2709
|
locusInfo.updateSelf = sinon.stub();
|
|
3541
2710
|
locusInfo.updateLocusUrl = sinon.stub();
|
|
3542
2711
|
locusInfo.updateAclUrl = sinon.stub();
|
|
3543
2712
|
locusInfo.updateBasequence = sinon.stub();
|
|
3544
2713
|
locusInfo.updateSequence = sinon.stub();
|
|
2714
|
+
locusInfo.updateMemberShip = sinon.stub();
|
|
2715
|
+
locusInfo.updateIdentifiers = sinon.stub();
|
|
3545
2716
|
locusInfo.updateEmbeddedApps = sinon.stub();
|
|
3546
|
-
locusInfo.
|
|
2717
|
+
locusInfo.updateResources = sinon.stub();
|
|
3547
2718
|
locusInfo.compareAndUpdate = sinon.stub();
|
|
3548
2719
|
|
|
3549
2720
|
locusInfo.updateLocusInfo(newLocus);
|
|
@@ -3555,49 +2726,21 @@ describe('plugin-meetings', () => {
|
|
|
3555
2726
|
assert.notCalled(locusInfo.updateHostInfo);
|
|
3556
2727
|
assert.notCalled(locusInfo.updateMeetingInfo);
|
|
3557
2728
|
assert.notCalled(locusInfo.updateMediaShares);
|
|
3558
|
-
assert.notCalled(locusInfo.
|
|
2729
|
+
assert.notCalled(locusInfo.updateParticipantsUrl);
|
|
2730
|
+
assert.notCalled(locusInfo.updateReplace);
|
|
3559
2731
|
assert.notCalled(locusInfo.updateSelf);
|
|
3560
2732
|
assert.notCalled(locusInfo.updateLocusUrl);
|
|
3561
2733
|
assert.notCalled(locusInfo.updateAclUrl);
|
|
3562
2734
|
assert.notCalled(locusInfo.updateBasequence);
|
|
3563
2735
|
assert.notCalled(locusInfo.updateSequence);
|
|
2736
|
+
assert.notCalled(locusInfo.updateMemberShip);
|
|
2737
|
+
assert.notCalled(locusInfo.updateIdentifiers);
|
|
3564
2738
|
assert.notCalled(locusInfo.updateEmbeddedApps);
|
|
3565
|
-
assert.notCalled(locusInfo.
|
|
2739
|
+
assert.notCalled(locusInfo.updateResources);
|
|
3566
2740
|
assert.notCalled(locusInfo.compareAndUpdate);
|
|
3567
2741
|
});
|
|
3568
2742
|
|
|
3569
|
-
it('#updateLocusInfo puts the Locus DTO top level properties at the right place in LocusInfo class', () => {
|
|
3570
|
-
// this test verifies that the top-level properties of Locus DTO are copied
|
|
3571
|
-
// into LocusInfo class and set as top level properties too
|
|
3572
|
-
// this is important, because the code handling Locus hash trees relies on it, see updateFromHashTree()
|
|
3573
|
-
const info = {id: 'info id'};
|
|
3574
|
-
const fullState = {id: 'fullState id'};
|
|
3575
|
-
const links = {services: {id: 'service links'}, resources: {id: 'resource links'}};
|
|
3576
|
-
const self = {id: 'self id'};
|
|
3577
|
-
const mediaShares = [{id: 'fake media share'}];
|
|
3578
|
-
|
|
3579
|
-
sinon.stub(SelfUtils, 'getSelves').returns({
|
|
3580
|
-
current: {},
|
|
3581
|
-
previous: {},
|
|
3582
|
-
updates: {},
|
|
3583
|
-
});
|
|
3584
|
-
|
|
3585
|
-
const newLocus = {
|
|
3586
|
-
info,
|
|
3587
|
-
fullState,
|
|
3588
|
-
links,
|
|
3589
|
-
self,
|
|
3590
|
-
mediaShares,
|
|
3591
|
-
};
|
|
3592
|
-
|
|
3593
|
-
locusInfo.updateLocusInfo(newLocus);
|
|
3594
2743
|
|
|
3595
|
-
assert.deepEqual(locusInfo.info, newLocus.info);
|
|
3596
|
-
assert.deepEqual(locusInfo.fullState, newLocus.fullState);
|
|
3597
|
-
assert.deepEqual(locusInfo.links, newLocus.links);
|
|
3598
|
-
assert.deepEqual(locusInfo.self, newLocus.self);
|
|
3599
|
-
assert.deepEqual(locusInfo.mediaShares, newLocus.mediaShares);
|
|
3600
|
-
});
|
|
3601
2744
|
|
|
3602
2745
|
it('onFullLocus() updates the working-copy of locus parser', () => {
|
|
3603
2746
|
const eventType = 'fakeEvent';
|
|
@@ -3608,7 +2751,7 @@ describe('plugin-meetings', () => {
|
|
|
3608
2751
|
sandbox.stub(locusInfo, 'handleOneOnOneEvent');
|
|
3609
2752
|
sandbox.stub(locusParser, 'isNewFullLocus').returns(true);
|
|
3610
2753
|
|
|
3611
|
-
locusInfo.onFullLocus(
|
|
2754
|
+
locusInfo.onFullLocus(fakeLocus, eventType);
|
|
3612
2755
|
|
|
3613
2756
|
assert.equal(fakeLocus, locusParser.workingCopy);
|
|
3614
2757
|
});
|
|
@@ -3629,7 +2772,7 @@ describe('plugin-meetings', () => {
|
|
|
3629
2772
|
|
|
3630
2773
|
sandbox.stub(locusParser, 'isNewFullLocus').returns(false);
|
|
3631
2774
|
|
|
3632
|
-
locusInfo.onFullLocus(
|
|
2775
|
+
locusInfo.onFullLocus(fakeLocus, eventType);
|
|
3633
2776
|
|
|
3634
2777
|
spies.forEach((spy) => {
|
|
3635
2778
|
assert.notCalled(spy);
|
|
@@ -3779,11 +2922,7 @@ describe('plugin-meetings', () => {
|
|
|
3779
2922
|
}).then(() => {
|
|
3780
2923
|
assert.calledOnceWithExactly(meeting.meetingRequest.getLocusDTO, {url: 'oldLocusUrl'});
|
|
3781
2924
|
|
|
3782
|
-
assert.calledOnceWithExactly(
|
|
3783
|
-
meeting.locusInfo.onFullLocus,
|
|
3784
|
-
'classic Locus sync',
|
|
3785
|
-
fakeFullLocusDto
|
|
3786
|
-
);
|
|
2925
|
+
assert.calledOnceWithExactly(meeting.locusInfo.onFullLocus, fakeFullLocusDto);
|
|
3787
2926
|
assert.calledOnce(locusInfo.locusParser.resume);
|
|
3788
2927
|
});
|
|
3789
2928
|
});
|
|
@@ -3881,11 +3020,7 @@ describe('plugin-meetings', () => {
|
|
|
3881
3020
|
});
|
|
3882
3021
|
|
|
3883
3022
|
assert.notCalled(meeting.locusInfo.handleLocusDelta);
|
|
3884
|
-
assert.calledOnceWithExactly(
|
|
3885
|
-
meeting.locusInfo.onFullLocus,
|
|
3886
|
-
'classic Locus sync',
|
|
3887
|
-
fakeFullLocusDto
|
|
3888
|
-
);
|
|
3023
|
+
assert.calledOnceWithExactly(meeting.locusInfo.onFullLocus, fakeFullLocusDto);
|
|
3889
3024
|
assert.calledOnce(locusInfo.locusParser.resume);
|
|
3890
3025
|
});
|
|
3891
3026
|
});
|
|
@@ -4061,11 +3196,7 @@ describe('plugin-meetings', () => {
|
|
|
4061
3196
|
url: 'fake locus DELTA url',
|
|
4062
3197
|
});
|
|
4063
3198
|
assert.notCalled(meeting.locusInfo.handleLocusDelta);
|
|
4064
|
-
assert.calledOnceWithExactly(
|
|
4065
|
-
meeting.locusInfo.onFullLocus,
|
|
4066
|
-
'classic Locus sync',
|
|
4067
|
-
fakeFullLocusDto
|
|
4068
|
-
);
|
|
3199
|
+
assert.calledOnceWithExactly(meeting.locusInfo.onFullLocus, fakeFullLocusDto);
|
|
4069
3200
|
assert.calledOnce(locusInfo.locusParser.resume);
|
|
4070
3201
|
});
|
|
4071
3202
|
});
|
|
@@ -4086,137 +3217,6 @@ describe('plugin-meetings', () => {
|
|
|
4086
3217
|
|
|
4087
3218
|
assert.isNull(locusInfo.mainSessionLocusCache);
|
|
4088
3219
|
});
|
|
4089
|
-
|
|
4090
|
-
it('should map participant with htMeta.elementId.id of 0 (falsy number) to hashTreeObjectId2ParticipantId', () => {
|
|
4091
|
-
const locus = {
|
|
4092
|
-
url: 'url',
|
|
4093
|
-
participants: [
|
|
4094
|
-
{
|
|
4095
|
-
id: 'participant-zero',
|
|
4096
|
-
htMeta: {elementId: {id: 0}},
|
|
4097
|
-
},
|
|
4098
|
-
],
|
|
4099
|
-
};
|
|
4100
|
-
|
|
4101
|
-
sinon.stub(locusInfo.locusParser, 'isNewFullLocus').returns(true);
|
|
4102
|
-
sinon.stub(locusInfo, 'updateLocusInfo');
|
|
4103
|
-
sinon.stub(locusInfo, 'updateParticipants');
|
|
4104
|
-
sinon.stub(locusInfo, 'isMeetingActive');
|
|
4105
|
-
sinon.stub(locusInfo, 'handleOneOnOneEvent');
|
|
4106
|
-
sinon.stub(locusInfo, 'updateEmbeddedApps');
|
|
4107
|
-
locusInfo.locusParser.workingCopy = null;
|
|
4108
|
-
|
|
4109
|
-
locusInfo.onFullLocus('test', locus);
|
|
4110
|
-
|
|
4111
|
-
assert.equal(locusInfo.hashTreeObjectId2ParticipantId.get(0), 'participant-zero');
|
|
4112
|
-
});
|
|
4113
|
-
});
|
|
4114
|
-
|
|
4115
|
-
describe('#onDeltaLocus', () => {
|
|
4116
|
-
it('should use forceReplaceMembers from jsSdkMeta when it is defined', () => {
|
|
4117
|
-
sinon.stub(locusInfo, 'mergeParticipants');
|
|
4118
|
-
sinon.stub(locusInfo, 'updateLocusInfo').returns(true);
|
|
4119
|
-
sinon.stub(locusInfo, 'updateParticipants');
|
|
4120
|
-
sinon.stub(locusInfo, 'isMeetingActive');
|
|
4121
|
-
|
|
4122
|
-
locusInfo.onDeltaLocus({
|
|
4123
|
-
participants: [],
|
|
4124
|
-
jsSdkMeta: {forceReplaceMembers: true, removedParticipantIds: []},
|
|
4125
|
-
});
|
|
4126
|
-
|
|
4127
|
-
assert.calledOnceWithExactly(locusInfo.updateParticipants, [], [], true);
|
|
4128
|
-
});
|
|
4129
|
-
|
|
4130
|
-
it('should fall back to isNeedReplaceMembers when forceReplaceMembers is not in jsSdkMeta', () => {
|
|
4131
|
-
sinon.stub(locusInfo, 'mergeParticipants');
|
|
4132
|
-
sinon.stub(locusInfo, 'updateLocusInfo').returns(true);
|
|
4133
|
-
sinon.stub(locusInfo, 'updateParticipants');
|
|
4134
|
-
sinon.stub(locusInfo, 'isMeetingActive');
|
|
4135
|
-
|
|
4136
|
-
locusInfo.onDeltaLocus({participants: []});
|
|
4137
|
-
|
|
4138
|
-
// without jsSdkMeta.forceReplaceMembers, uses ControlsUtils.isNeedReplaceMembers result (false by default)
|
|
4139
|
-
assert.calledOnceWithExactly(locusInfo.updateParticipants, [], undefined, false);
|
|
4140
|
-
});
|
|
4141
|
-
|
|
4142
|
-
it('should not call updateParticipants when updateLocusInfo returns false', () => {
|
|
4143
|
-
sinon.stub(locusInfo, 'mergeParticipants');
|
|
4144
|
-
sinon.stub(locusInfo, 'updateLocusInfo').returns(false);
|
|
4145
|
-
sinon.stub(locusInfo, 'updateParticipants');
|
|
4146
|
-
sinon.stub(locusInfo, 'isMeetingActive');
|
|
4147
|
-
|
|
4148
|
-
locusInfo.onDeltaLocus({participants: [], self: {state: 'LEFT', reason: 'MOVED'}});
|
|
4149
|
-
|
|
4150
|
-
assert.notCalled(locusInfo.updateParticipants);
|
|
4151
|
-
});
|
|
4152
|
-
|
|
4153
|
-
it('should call updateParticipants when updateLocusInfo returns true', () => {
|
|
4154
|
-
sinon.stub(locusInfo, 'mergeParticipants');
|
|
4155
|
-
sinon.stub(locusInfo, 'updateLocusInfo').returns(true);
|
|
4156
|
-
sinon.stub(locusInfo, 'updateParticipants');
|
|
4157
|
-
sinon.stub(locusInfo, 'isMeetingActive');
|
|
4158
|
-
|
|
4159
|
-
locusInfo.onDeltaLocus({participants: [{id: 'p1'}]});
|
|
4160
|
-
|
|
4161
|
-
assert.calledOnce(locusInfo.updateParticipants);
|
|
4162
|
-
});
|
|
4163
|
-
|
|
4164
|
-
[
|
|
4165
|
-
{forceReplaceMembers: true, selfInParticipants: false, expectedSelfCopied: true},
|
|
4166
|
-
{forceReplaceMembers: true, selfInParticipants: true, expectedSelfCopied: false},
|
|
4167
|
-
{forceReplaceMembers: false, selfInParticipants: false, expectedSelfCopied: false},
|
|
4168
|
-
{forceReplaceMembers: false, selfInParticipants: true, expectedSelfCopied: false},
|
|
4169
|
-
].forEach(({forceReplaceMembers, selfInParticipants, expectedSelfCopied}) => {
|
|
4170
|
-
it(`should ${expectedSelfCopied ? '' : 'not '}copy self into participants when forceReplaceMembers=${forceReplaceMembers} and self ${selfInParticipants ? 'is' : 'is not'} in participants`, () => {
|
|
4171
|
-
const self = {identity: 'selfId', state: 'JOINED', devices: [], status: {}};
|
|
4172
|
-
const participant = {identity: selfInParticipants ? 'selfId' : 'other'};
|
|
4173
|
-
const locus = {
|
|
4174
|
-
participants: [participant],
|
|
4175
|
-
self,
|
|
4176
|
-
jsSdkMeta: {forceReplaceMembers, removedParticipantIds: []},
|
|
4177
|
-
};
|
|
4178
|
-
|
|
4179
|
-
locusInfo.onDeltaLocus(locus);
|
|
4180
|
-
|
|
4181
|
-
const expectedParticipants = expectedSelfCopied ? [participant, self] : [participant];
|
|
4182
|
-
assert.deepEqual(locus.participants, expectedParticipants);
|
|
4183
|
-
});
|
|
4184
|
-
});
|
|
4185
|
-
});
|
|
4186
|
-
|
|
4187
|
-
describe('#updateLocusInfo', () => {
|
|
4188
|
-
it('should return false when self.reason is MOVED and self.state is LEFT', () => {
|
|
4189
|
-
sinon.stub(locusInfo, 'updateControls');
|
|
4190
|
-
|
|
4191
|
-
const result = locusInfo.updateLocusInfo({self: {reason: 'MOVED', state: 'LEFT'}});
|
|
4192
|
-
|
|
4193
|
-
assert.isFalse(result);
|
|
4194
|
-
assert.notCalled(locusInfo.updateControls);
|
|
4195
|
-
});
|
|
4196
|
-
|
|
4197
|
-
it('should return true when self is not in MOVED/LEFT state', () => {
|
|
4198
|
-
sinon.stub(locusInfo, 'updateControls');
|
|
4199
|
-
sinon.stub(locusInfo, 'updateConversationUrl');
|
|
4200
|
-
sinon.stub(locusInfo, 'updateCreated');
|
|
4201
|
-
sinon.stub(locusInfo, 'updateFullState');
|
|
4202
|
-
sinon.stub(locusInfo, 'updateHostInfo');
|
|
4203
|
-
sinon.stub(locusInfo, 'updateLocusUrl');
|
|
4204
|
-
sinon.stub(locusInfo, 'updateMeetingInfo');
|
|
4205
|
-
sinon.stub(locusInfo, 'updateMediaShares');
|
|
4206
|
-
sinon.stub(locusInfo, 'updateReplaces');
|
|
4207
|
-
sinon.stub(locusInfo, 'updateSelf');
|
|
4208
|
-
sinon.stub(locusInfo, 'updateAclUrl');
|
|
4209
|
-
sinon.stub(locusInfo, 'updateBasequence');
|
|
4210
|
-
sinon.stub(locusInfo, 'updateSequence');
|
|
4211
|
-
sinon.stub(locusInfo, 'updateEmbeddedApps');
|
|
4212
|
-
sinon.stub(locusInfo, 'updateLinks');
|
|
4213
|
-
sinon.stub(locusInfo, 'compareAndUpdate');
|
|
4214
|
-
|
|
4215
|
-
const result = locusInfo.updateLocusInfo({self: {state: 'JOINED'}});
|
|
4216
|
-
|
|
4217
|
-
assert.isTrue(result);
|
|
4218
|
-
assert.calledOnce(locusInfo.updateControls);
|
|
4219
|
-
});
|
|
4220
3220
|
});
|
|
4221
3221
|
|
|
4222
3222
|
describe('#getTheLocusToUpdate', () => {
|
|
@@ -4568,7 +3568,7 @@ describe('plugin-meetings', () => {
|
|
|
4568
3568
|
|
|
4569
3569
|
describe('#updateLocusUrl', () => {
|
|
4570
3570
|
it('trigger LOCUS_INFO_UPDATE_URL event with isMainLocus is true as default', () => {
|
|
4571
|
-
const fakeUrl =
|
|
3571
|
+
const fakeUrl = "https://fake.com/locus";
|
|
4572
3572
|
locusInfo.emitScoped = sinon.stub();
|
|
4573
3573
|
locusInfo.updateLocusUrl(fakeUrl);
|
|
4574
3574
|
|
|
@@ -4581,12 +3581,12 @@ describe('plugin-meetings', () => {
|
|
|
4581
3581
|
EVENTS.LOCUS_INFO_UPDATE_URL,
|
|
4582
3582
|
{
|
|
4583
3583
|
url: fakeUrl,
|
|
4584
|
-
isMainLocus: true
|
|
4585
|
-
}
|
|
3584
|
+
isMainLocus: true
|
|
3585
|
+
},
|
|
4586
3586
|
);
|
|
4587
3587
|
});
|
|
4588
3588
|
it('trigger LOCUS_INFO_UPDATE_URL event with isMainLocus is false', () => {
|
|
4589
|
-
const fakeUrl =
|
|
3589
|
+
const fakeUrl = "https://fake.com/locus";
|
|
4590
3590
|
locusInfo.emitScoped = sinon.stub();
|
|
4591
3591
|
locusInfo.updateLocusUrl(fakeUrl, false);
|
|
4592
3592
|
|
|
@@ -4599,8 +3599,8 @@ describe('plugin-meetings', () => {
|
|
|
4599
3599
|
EVENTS.LOCUS_INFO_UPDATE_URL,
|
|
4600
3600
|
{
|
|
4601
3601
|
url: fakeUrl,
|
|
4602
|
-
isMainLocus: false
|
|
4603
|
-
}
|
|
3602
|
+
isMainLocus: false
|
|
3603
|
+
},
|
|
4604
3604
|
);
|
|
4605
3605
|
});
|
|
4606
3606
|
});
|
|
@@ -4652,8 +3652,8 @@ describe('plugin-meetings', () => {
|
|
|
4652
3652
|
|
|
4653
3653
|
sinon.stub(locusInfo, 'updateParticipants');
|
|
4654
3654
|
sinon.stub(locusInfo, 'isMeetingActive');
|
|
4655
|
-
|
|
4656
|
-
|
|
3655
|
+
sinon.stub(locusInfo, 'handleOneOnOneEvent');
|
|
3656
|
+
(updateLocusInfoStub = sinon.stub(locusInfo, 'updateLocusInfo'));
|
|
4657
3657
|
syncRequestStub = sinon.stub().resolves({body: {}});
|
|
4658
3658
|
|
|
4659
3659
|
mockMeeting.locusInfo = locusInfo;
|
|
@@ -4662,7 +3662,7 @@ describe('plugin-meetings', () => {
|
|
|
4662
3662
|
getLocusDTO: syncRequestStub,
|
|
4663
3663
|
};
|
|
4664
3664
|
|
|
4665
|
-
locusInfo.onFullLocus(
|
|
3665
|
+
locusInfo.onFullLocus({
|
|
4666
3666
|
sequence: {
|
|
4667
3667
|
rangeStart: 0,
|
|
4668
3668
|
rangeEnd: 0,
|
|
@@ -4900,9 +3900,7 @@ describe('plugin-meetings', () => {
|
|
|
4900
3900
|
|
|
4901
3901
|
describe('#parse', () => {
|
|
4902
3902
|
it('handles hash tree messages correctly', () => {
|
|
4903
|
-
const fakeLocusUrl = 'http://locus-url.com';
|
|
4904
3903
|
const fakeHashTreeMessage = {
|
|
4905
|
-
locusUrl: fakeLocusUrl,
|
|
4906
3904
|
locusStateElements: [
|
|
4907
3905
|
{
|
|
4908
3906
|
htMeta: {elementId: {type: 'self'}},
|
|
@@ -4921,377 +3919,12 @@ describe('plugin-meetings', () => {
|
|
|
4921
3919
|
const mockHashTreeParser = {
|
|
4922
3920
|
handleMessage: sinon.stub(),
|
|
4923
3921
|
};
|
|
4924
|
-
locusInfo.
|
|
4925
|
-
parser: mockHashTreeParser,
|
|
4926
|
-
initializedFromHashTree: true,
|
|
4927
|
-
});
|
|
3922
|
+
locusInfo.hashTreeParser = mockHashTreeParser;
|
|
4928
3923
|
|
|
4929
3924
|
locusInfo.parse(mockMeeting, data);
|
|
4930
3925
|
|
|
4931
3926
|
assert.calledOnceWithExactly(mockHashTreeParser.handleMessage, fakeHashTreeMessage);
|
|
4932
3927
|
});
|
|
4933
|
-
|
|
4934
|
-
it('ignores hash tree event when hashTreeParser is not created yet', () => {
|
|
4935
|
-
const data = {
|
|
4936
|
-
eventType: LOCUSEVENT.HASH_TREE_DATA_UPDATED,
|
|
4937
|
-
stateElementsMessage: {
|
|
4938
|
-
locusStateElements: [],
|
|
4939
|
-
dataSets: [],
|
|
4940
|
-
},
|
|
4941
|
-
};
|
|
4942
|
-
|
|
4943
|
-
const loggerSpy = sinon.spy(LoggerProxy.logger, 'info');
|
|
4944
|
-
const getTheLocusToUpdateStub = sinon.stub(locusInfo, 'getTheLocusToUpdate');
|
|
4945
|
-
|
|
4946
|
-
// Ensure we're not using hash trees
|
|
4947
|
-
assert.equal(locusInfo.hashTreeParsers.size, 0);
|
|
4948
|
-
|
|
4949
|
-
locusInfo.parse(mockMeeting, data);
|
|
4950
|
-
|
|
4951
|
-
assert.calledWith(
|
|
4952
|
-
loggerSpy,
|
|
4953
|
-
'Locus-info:index#parse --> received locus hash tree event before hashTreeParser is created'
|
|
4954
|
-
);
|
|
4955
|
-
assert.notCalled(getTheLocusToUpdateStub);
|
|
4956
|
-
});
|
|
4957
|
-
});
|
|
4958
|
-
});
|
|
4959
|
-
|
|
4960
|
-
describe('#createLocusFromHashTreeMessage', () => {
|
|
4961
|
-
const LOCUS_URL = 'https://locus.example.com/loci/abc-123';
|
|
4962
|
-
|
|
4963
|
-
const createElement = (type, data) => ({
|
|
4964
|
-
htMeta: {elementId: {type, id: 1, version: 1}},
|
|
4965
|
-
data,
|
|
4966
|
-
});
|
|
4967
|
-
|
|
4968
|
-
it('returns locus with url and empty participants when no locusStateElements', () => {
|
|
4969
|
-
const result = createLocusFromHashTreeMessage({locusUrl: LOCUS_URL});
|
|
4970
|
-
|
|
4971
|
-
assert.deepEqual(result.locus, {participants: [], url: LOCUS_URL});
|
|
4972
|
-
assert.isUndefined(result.metadata);
|
|
4973
|
-
});
|
|
4974
|
-
|
|
4975
|
-
it('skips elements without data', () => {
|
|
4976
|
-
const result = createLocusFromHashTreeMessage({
|
|
4977
|
-
locusUrl: LOCUS_URL,
|
|
4978
|
-
locusStateElements: [{htMeta: {elementId: {type: 'Self', id: 1, version: 1}}, data: null}],
|
|
4979
|
-
});
|
|
4980
|
-
|
|
4981
|
-
assert.deepEqual(result.locus, {participants: [], url: LOCUS_URL});
|
|
4982
|
-
});
|
|
4983
|
-
|
|
4984
|
-
[
|
|
4985
|
-
{type: 'Self', locusKey: 'self', data: {id: 'self-1', state: 'JOINED'}},
|
|
4986
|
-
{type: 'Info', locusKey: 'info', data: {webExMeetingId: '123'}},
|
|
4987
|
-
{type: 'FullState', locusKey: 'fullState', data: {state: 'ACTIVE'}},
|
|
4988
|
-
{type: 'Links', locusKey: 'links', data: {resources: {}}},
|
|
4989
|
-
].forEach(({type, locusKey, data}) => {
|
|
4990
|
-
it(`maps ${type} element to locus.${locusKey}`, () => {
|
|
4991
|
-
const result = createLocusFromHashTreeMessage({
|
|
4992
|
-
locusUrl: LOCUS_URL,
|
|
4993
|
-
locusStateElements: [createElement(type, data)],
|
|
4994
|
-
});
|
|
4995
|
-
|
|
4996
|
-
assert.deepEqual(result.locus[locusKey], data);
|
|
4997
|
-
});
|
|
4998
|
-
});
|
|
4999
|
-
|
|
5000
|
-
it('pushes Participant elements to locus.participants', () => {
|
|
5001
|
-
const p1 = {id: 'p1', state: 'JOINED'};
|
|
5002
|
-
const p2 = {id: 'p2', state: 'LEFT'};
|
|
5003
|
-
|
|
5004
|
-
const result = createLocusFromHashTreeMessage({
|
|
5005
|
-
locusUrl: LOCUS_URL,
|
|
5006
|
-
locusStateElements: [createElement('Participant', p1), createElement('Participant', p2)],
|
|
5007
|
-
});
|
|
5008
|
-
|
|
5009
|
-
assert.deepEqual(result.locus.participants, [p1, p2]);
|
|
5010
|
-
});
|
|
5011
|
-
|
|
5012
|
-
it('pushes MediaShare elements to locus.mediaShares array', () => {
|
|
5013
|
-
const share1 = {name: 'whiteboard'};
|
|
5014
|
-
const share2 = {name: 'content'};
|
|
5015
|
-
|
|
5016
|
-
const result = createLocusFromHashTreeMessage({
|
|
5017
|
-
locusUrl: LOCUS_URL,
|
|
5018
|
-
locusStateElements: [
|
|
5019
|
-
createElement('MediaShare', share1),
|
|
5020
|
-
createElement('MediaShare', share2),
|
|
5021
|
-
],
|
|
5022
|
-
});
|
|
5023
|
-
|
|
5024
|
-
assert.deepEqual(result.locus.mediaShares, [share1, share2]);
|
|
5025
|
-
});
|
|
5026
|
-
|
|
5027
|
-
it('pushes EmbeddedApp elements to locus.embeddedApps array', () => {
|
|
5028
|
-
const app = {appId: 'app-1', state: 'STARTED'};
|
|
5029
|
-
|
|
5030
|
-
const result = createLocusFromHashTreeMessage({
|
|
5031
|
-
locusUrl: LOCUS_URL,
|
|
5032
|
-
locusStateElements: [createElement('EmbeddedApp', app)],
|
|
5033
|
-
});
|
|
5034
|
-
|
|
5035
|
-
assert.deepEqual(result.locus.embeddedApps, [app]);
|
|
5036
|
-
});
|
|
5037
|
-
|
|
5038
|
-
it('merges ControlEntry elements into locus.controls', () => {
|
|
5039
|
-
const control1 = {record: {recording: true}};
|
|
5040
|
-
const control2 = {lock: {locked: false}};
|
|
5041
|
-
|
|
5042
|
-
const result = createLocusFromHashTreeMessage({
|
|
5043
|
-
locusUrl: LOCUS_URL,
|
|
5044
|
-
locusStateElements: [
|
|
5045
|
-
createElement('ControlEntry', control1),
|
|
5046
|
-
createElement('ControlEntry', control2),
|
|
5047
|
-
],
|
|
5048
|
-
});
|
|
5049
|
-
|
|
5050
|
-
assert.deepEqual(result.locus.controls, {record: {recording: true}, lock: {locked: false}});
|
|
5051
|
-
});
|
|
5052
|
-
|
|
5053
|
-
it('spreads Locus element data onto top level but removes managed keys', () => {
|
|
5054
|
-
const locusData = {
|
|
5055
|
-
url: 'should-be-overridden',
|
|
5056
|
-
someTopLevelField: 'value',
|
|
5057
|
-
// these are managed by other ObjectTypes and should be removed
|
|
5058
|
-
links: {should: 'be removed'},
|
|
5059
|
-
info: {should: 'be removed'},
|
|
5060
|
-
fullState: {should: 'be removed'},
|
|
5061
|
-
self: {should: 'be removed'},
|
|
5062
|
-
participants: [{should: 'be removed'}],
|
|
5063
|
-
mediaShares: [{should: 'be removed'}],
|
|
5064
|
-
controls: {should: 'be removed'},
|
|
5065
|
-
embeddedApps: [{should: 'be removed'}],
|
|
5066
|
-
};
|
|
5067
|
-
|
|
5068
|
-
const result = createLocusFromHashTreeMessage({
|
|
5069
|
-
locusUrl: LOCUS_URL,
|
|
5070
|
-
locusStateElements: [createElement('Locus', locusData)],
|
|
5071
|
-
});
|
|
5072
|
-
|
|
5073
|
-
assert.equal(result.locus.someTopLevelField, 'value');
|
|
5074
|
-
assert.deepEqual(result.locus.participants, []);
|
|
5075
|
-
assert.isUndefined(result.locus.links);
|
|
5076
|
-
assert.isUndefined(result.locus.info);
|
|
5077
|
-
assert.isUndefined(result.locus.fullState);
|
|
5078
|
-
assert.isUndefined(result.locus.self);
|
|
5079
|
-
assert.isUndefined(result.locus.mediaShares);
|
|
5080
|
-
assert.isUndefined(result.locus.controls);
|
|
5081
|
-
assert.isUndefined(result.locus.embeddedApps);
|
|
5082
|
-
});
|
|
5083
|
-
|
|
5084
|
-
it('extracts Metadata element as metadata in the result', () => {
|
|
5085
|
-
const metadataData = {visibleDataSets: [{name: 'ds1', url: 'http://ds1.url'}]};
|
|
5086
|
-
const htMeta = {elementId: {type: 'Metadata', id: 99, version: 3}};
|
|
5087
|
-
|
|
5088
|
-
const result = createLocusFromHashTreeMessage({
|
|
5089
|
-
locusUrl: LOCUS_URL,
|
|
5090
|
-
locusStateElements: [{htMeta, data: metadataData}],
|
|
5091
|
-
});
|
|
5092
|
-
|
|
5093
|
-
assert.deepEqual(result.metadata, {...metadataData, htMeta});
|
|
5094
|
-
assert.isUndefined(result.locus.metadata);
|
|
5095
|
-
});
|
|
5096
|
-
|
|
5097
|
-
it('handles a message with multiple element types', () => {
|
|
5098
|
-
const selfData = {id: 'self-1'};
|
|
5099
|
-
const participantData = {id: 'p1'};
|
|
5100
|
-
const infoData = {webExMeetingId: '456'};
|
|
5101
|
-
|
|
5102
|
-
const result = createLocusFromHashTreeMessage({
|
|
5103
|
-
locusUrl: LOCUS_URL,
|
|
5104
|
-
locusStateElements: [
|
|
5105
|
-
createElement('Self', selfData),
|
|
5106
|
-
createElement('Participant', participantData),
|
|
5107
|
-
createElement('Info', infoData),
|
|
5108
|
-
],
|
|
5109
|
-
});
|
|
5110
|
-
|
|
5111
|
-
assert.deepEqual(result.locus.self, selfData);
|
|
5112
|
-
assert.deepEqual(result.locus.participants, [participantData]);
|
|
5113
|
-
assert.deepEqual(result.locus.info, infoData);
|
|
5114
|
-
assert.equal(result.locus.url, LOCUS_URL);
|
|
5115
|
-
});
|
|
5116
|
-
|
|
5117
|
-
it('ignores unknown element types', () => {
|
|
5118
|
-
const result = createLocusFromHashTreeMessage({
|
|
5119
|
-
locusUrl: LOCUS_URL,
|
|
5120
|
-
locusStateElements: [createElement('UnknownType', {foo: 'bar'})],
|
|
5121
|
-
});
|
|
5122
|
-
|
|
5123
|
-
assert.deepEqual(result.locus, {participants: [], url: LOCUS_URL});
|
|
5124
|
-
});
|
|
5125
|
-
});
|
|
5126
|
-
|
|
5127
|
-
describe('findMeetingForHashTreeMessage', () => {
|
|
5128
|
-
const deviceUrl = 'https://devices.example.com/device1';
|
|
5129
|
-
|
|
5130
|
-
function createMockMeetingCollection(meetings) {
|
|
5131
|
-
return {
|
|
5132
|
-
getAll: () => meetings,
|
|
5133
|
-
};
|
|
5134
|
-
}
|
|
5135
|
-
|
|
5136
|
-
function createMockMeeting(id, hashTreeParsersMap) {
|
|
5137
|
-
return {
|
|
5138
|
-
id,
|
|
5139
|
-
locusInfo: {
|
|
5140
|
-
hashTreeParsers: hashTreeParsersMap,
|
|
5141
|
-
},
|
|
5142
|
-
};
|
|
5143
|
-
}
|
|
5144
|
-
|
|
5145
|
-
function createSelfElement(devices) {
|
|
5146
|
-
return {
|
|
5147
|
-
htMeta: {elementId: {type: 'Self'}},
|
|
5148
|
-
data: {
|
|
5149
|
-
devices,
|
|
5150
|
-
},
|
|
5151
|
-
};
|
|
5152
|
-
}
|
|
5153
|
-
|
|
5154
|
-
it('returns the meeting when locusUrl matches a hashTreeParser directly', () => {
|
|
5155
|
-
const locusUrl = 'https://locus.example.com/loci/abc123';
|
|
5156
|
-
const parsersMap = new Map([[locusUrl, {state: 'active'}]]);
|
|
5157
|
-
const meeting = createMockMeeting('meeting1', parsersMap);
|
|
5158
|
-
const collection = createMockMeetingCollection({meeting1: meeting});
|
|
5159
|
-
|
|
5160
|
-
const message = {locusUrl, locusStateElements: []};
|
|
5161
|
-
|
|
5162
|
-
const result = findMeetingForHashTreeMessage(message, collection, deviceUrl);
|
|
5163
|
-
|
|
5164
|
-
assert.equal(result, meeting);
|
|
5165
|
-
});
|
|
5166
|
-
|
|
5167
|
-
it('returns undefined when no meeting matches and message has no locusStateElements', () => {
|
|
5168
|
-
const locusUrl = 'https://locus.example.com/loci/unknown';
|
|
5169
|
-
const parsersMap = new Map([['https://locus.example.com/loci/other', {state: 'active'}]]);
|
|
5170
|
-
const meeting = createMockMeeting('meeting1', parsersMap);
|
|
5171
|
-
const collection = createMockMeetingCollection({meeting1: meeting});
|
|
5172
|
-
|
|
5173
|
-
const message = {locusUrl};
|
|
5174
|
-
|
|
5175
|
-
const result = findMeetingForHashTreeMessage(message, collection, deviceUrl);
|
|
5176
|
-
|
|
5177
|
-
assert.isUndefined(result);
|
|
5178
|
-
});
|
|
5179
|
-
|
|
5180
|
-
it('returns undefined when no meeting matches and self element has no replaces', () => {
|
|
5181
|
-
const locusUrl = 'https://locus.example.com/loci/unknown';
|
|
5182
|
-
const parsersMap = new Map([['https://locus.example.com/loci/other', {state: 'active'}]]);
|
|
5183
|
-
const meeting = createMockMeeting('meeting1', parsersMap);
|
|
5184
|
-
const collection = createMockMeetingCollection({meeting1: meeting});
|
|
5185
|
-
|
|
5186
|
-
const selfElement = createSelfElement([{url: deviceUrl}]);
|
|
5187
|
-
const message = {locusUrl, locusStateElements: [selfElement]};
|
|
5188
|
-
|
|
5189
|
-
const result = findMeetingForHashTreeMessage(message, collection, deviceUrl);
|
|
5190
|
-
|
|
5191
|
-
assert.isUndefined(result);
|
|
5192
|
-
});
|
|
5193
|
-
|
|
5194
|
-
it('returns the meeting when locusUrl from replaces matches a hashTreeParser', () => {
|
|
5195
|
-
const oldLocusUrl = 'https://locus.example.com/loci/old';
|
|
5196
|
-
const newLocusUrl = 'https://locus.example.com/loci/new';
|
|
5197
|
-
const parsersMap = new Map([[oldLocusUrl, {state: 'active'}]]);
|
|
5198
|
-
const meeting = createMockMeeting('meeting1', parsersMap);
|
|
5199
|
-
const collection = createMockMeetingCollection({meeting1: meeting});
|
|
5200
|
-
|
|
5201
|
-
const selfElement = createSelfElement([
|
|
5202
|
-
{url: deviceUrl, replaces: [{locusUrl: oldLocusUrl}]},
|
|
5203
|
-
]);
|
|
5204
|
-
const message = {locusUrl: newLocusUrl, locusStateElements: [selfElement]};
|
|
5205
|
-
|
|
5206
|
-
const result = findMeetingForHashTreeMessage(message, collection, deviceUrl);
|
|
5207
|
-
|
|
5208
|
-
assert.equal(result, meeting);
|
|
5209
|
-
});
|
|
5210
|
-
|
|
5211
|
-
it('returns undefined when replaces locusUrl does not match any hashTreeParser', () => {
|
|
5212
|
-
const oldLocusUrl = 'https://locus.example.com/loci/old';
|
|
5213
|
-
const newLocusUrl = 'https://locus.example.com/loci/new';
|
|
5214
|
-
const parsersMap = new Map([
|
|
5215
|
-
['https://locus.example.com/loci/something-else', {state: 'active'}],
|
|
5216
|
-
]);
|
|
5217
|
-
const meeting = createMockMeeting('meeting1', parsersMap);
|
|
5218
|
-
const collection = createMockMeetingCollection({meeting1: meeting});
|
|
5219
|
-
|
|
5220
|
-
const selfElement = createSelfElement([
|
|
5221
|
-
{url: deviceUrl, replaces: [{locusUrl: oldLocusUrl}]},
|
|
5222
|
-
]);
|
|
5223
|
-
const message = {locusUrl: newLocusUrl, locusStateElements: [selfElement]};
|
|
5224
|
-
|
|
5225
|
-
const result = findMeetingForHashTreeMessage(message, collection, deviceUrl);
|
|
5226
|
-
|
|
5227
|
-
assert.isUndefined(result);
|
|
5228
|
-
});
|
|
5229
|
-
|
|
5230
|
-
it('returns undefined when meetingCollection is empty', () => {
|
|
5231
|
-
const collection = createMockMeetingCollection({});
|
|
5232
|
-
const message = {locusUrl: 'https://locus.example.com/loci/abc', locusStateElements: []};
|
|
5233
|
-
|
|
5234
|
-
const result = findMeetingForHashTreeMessage(message, collection, deviceUrl);
|
|
5235
|
-
|
|
5236
|
-
assert.isUndefined(result);
|
|
5237
|
-
});
|
|
5238
|
-
|
|
5239
|
-
it('checks multiple meetings and returns the correct one', () => {
|
|
5240
|
-
const targetLocusUrl = 'https://locus.example.com/loci/target';
|
|
5241
|
-
const meeting1 = createMockMeeting(
|
|
5242
|
-
'meeting1',
|
|
5243
|
-
new Map([['https://locus.example.com/loci/other', {state: 'active'}]])
|
|
5244
|
-
);
|
|
5245
|
-
const meeting2 = createMockMeeting(
|
|
5246
|
-
'meeting2',
|
|
5247
|
-
new Map([[targetLocusUrl, {state: 'active'}]])
|
|
5248
|
-
);
|
|
5249
|
-
const collection = createMockMeetingCollection({meeting1, meeting2});
|
|
5250
|
-
|
|
5251
|
-
const message = {locusUrl: targetLocusUrl, locusStateElements: []};
|
|
5252
|
-
|
|
5253
|
-
const result = findMeetingForHashTreeMessage(message, collection, deviceUrl);
|
|
5254
|
-
|
|
5255
|
-
assert.equal(result, meeting2);
|
|
5256
|
-
});
|
|
5257
|
-
|
|
5258
|
-
it('ignores devices that do not match deviceUrl when looking for replaces', () => {
|
|
5259
|
-
const oldLocusUrl = 'https://locus.example.com/loci/old';
|
|
5260
|
-
const newLocusUrl = 'https://locus.example.com/loci/new';
|
|
5261
|
-
const parsersMap = new Map([[oldLocusUrl, {state: 'active'}]]);
|
|
5262
|
-
const meeting = createMockMeeting('meeting1', parsersMap);
|
|
5263
|
-
const collection = createMockMeetingCollection({meeting1: meeting});
|
|
5264
|
-
|
|
5265
|
-
// self element has replaces, but on a different device
|
|
5266
|
-
const selfElement = createSelfElement([
|
|
5267
|
-
{url: 'https://devices.example.com/other-device', replaces: [{locusUrl: oldLocusUrl}]},
|
|
5268
|
-
]);
|
|
5269
|
-
const message = {locusUrl: newLocusUrl, locusStateElements: [selfElement]};
|
|
5270
|
-
|
|
5271
|
-
const result = findMeetingForHashTreeMessage(message, collection, deviceUrl);
|
|
5272
|
-
|
|
5273
|
-
assert.isUndefined(result);
|
|
5274
|
-
});
|
|
5275
|
-
|
|
5276
|
-
it('does not use self element if it is not of type Self', () => {
|
|
5277
|
-
const oldLocusUrl = 'https://locus.example.com/loci/old';
|
|
5278
|
-
const newLocusUrl = 'https://locus.example.com/loci/new';
|
|
5279
|
-
const parsersMap = new Map([[oldLocusUrl, {state: 'active'}]]);
|
|
5280
|
-
const meeting = createMockMeeting('meeting1', parsersMap);
|
|
5281
|
-
const collection = createMockMeetingCollection({meeting1: meeting});
|
|
5282
|
-
|
|
5283
|
-
// element has replaces data but is not of type Self
|
|
5284
|
-
const nonSelfElement = {
|
|
5285
|
-
htMeta: {elementId: {type: 'Participant'}},
|
|
5286
|
-
data: {
|
|
5287
|
-
devices: [{url: deviceUrl, replaces: [{locusUrl: oldLocusUrl}]}],
|
|
5288
|
-
},
|
|
5289
|
-
};
|
|
5290
|
-
const message = {locusUrl: newLocusUrl, locusStateElements: [nonSelfElement]};
|
|
5291
|
-
|
|
5292
|
-
const result = findMeetingForHashTreeMessage(message, collection, deviceUrl);
|
|
5293
|
-
|
|
5294
|
-
assert.isUndefined(result);
|
|
5295
3928
|
});
|
|
5296
3929
|
});
|
|
5297
3930
|
});
|