@webex/plugin-meetings 3.8.0-web-workers-keepalive.1 → 3.8.1-next.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/breakouts/breakout.js +1 -1
- package/dist/breakouts/index.js +70 -6
- package/dist/breakouts/index.js.map +1 -1
- package/dist/common/errors/webex-errors.js +12 -2
- package/dist/common/errors/webex-errors.js.map +1 -1
- package/dist/config.js +4 -1
- package/dist/config.js.map +1 -1
- package/dist/constants.js +22 -123
- package/dist/constants.js.map +1 -1
- package/dist/controls-options-manager/enums.js +2 -0
- package/dist/controls-options-manager/enums.js.map +1 -1
- package/dist/controls-options-manager/types.js.map +1 -1
- package/dist/controls-options-manager/util.js +52 -0
- package/dist/controls-options-manager/util.js.map +1 -1
- package/dist/interpretation/index.js +1 -1
- package/dist/interpretation/siLanguage.js +1 -1
- package/dist/locus-info/controlsUtils.js +30 -10
- package/dist/locus-info/controlsUtils.js.map +1 -1
- package/dist/locus-info/index.js +83 -12
- package/dist/locus-info/index.js.map +1 -1
- package/dist/locus-info/selfUtils.js +432 -418
- package/dist/locus-info/selfUtils.js.map +1 -1
- package/dist/media/index.js +17 -17
- package/dist/media/index.js.map +1 -1
- package/dist/media/properties.js +94 -6
- package/dist/media/properties.js.map +1 -1
- package/dist/meeting/brbState.js +9 -2
- package/dist/meeting/brbState.js.map +1 -1
- package/dist/meeting/in-meeting-actions.js +17 -1
- package/dist/meeting/in-meeting-actions.js.map +1 -1
- package/dist/meeting/index.js +568 -328
- package/dist/meeting/index.js.map +1 -1
- package/dist/meeting/locusMediaRequest.js +0 -17
- package/dist/meeting/locusMediaRequest.js.map +1 -1
- package/dist/meeting/muteState.js +4 -4
- package/dist/meeting/muteState.js.map +1 -1
- package/dist/meeting/request.js +30 -0
- package/dist/meeting/request.js.map +1 -1
- package/dist/meeting/request.type.js.map +1 -1
- package/dist/meeting/util.js +9 -1
- package/dist/meeting/util.js.map +1 -1
- package/dist/meeting-info/meeting-info-v2.js +19 -13
- package/dist/meeting-info/meeting-info-v2.js.map +1 -1
- package/dist/meeting-info/utilv2.js +5 -1
- package/dist/meeting-info/utilv2.js.map +1 -1
- package/dist/meetings/index.js +76 -0
- package/dist/meetings/index.js.map +1 -1
- package/dist/meetings/util.js +14 -0
- package/dist/meetings/util.js.map +1 -1
- package/dist/member/index.js +45 -9
- package/dist/member/index.js.map +1 -1
- package/dist/member/types.js +3 -0
- package/dist/member/types.js.map +1 -1
- package/dist/member/util.js +335 -356
- package/dist/member/util.js.map +1 -1
- package/dist/members/collection.js.map +1 -1
- package/dist/members/index.js +137 -29
- package/dist/members/index.js.map +1 -1
- package/dist/members/request.js +38 -0
- package/dist/members/request.js.map +1 -1
- package/dist/members/util.js +36 -1
- package/dist/members/util.js.map +1 -1
- package/dist/metrics/constants.js +1 -0
- package/dist/metrics/constants.js.map +1 -1
- package/dist/reachability/clusterReachability.js +23 -31
- package/dist/reachability/clusterReachability.js.map +1 -1
- package/dist/reachability/index.js +42 -2
- package/dist/reachability/index.js.map +1 -1
- package/dist/reconnection-manager/index.js +2 -2
- package/dist/reconnection-manager/index.js.map +1 -1
- package/dist/roap/index.js.map +1 -1
- package/dist/roap/turnDiscovery.js +45 -27
- package/dist/roap/turnDiscovery.js.map +1 -1
- package/dist/roap/types.js +17 -0
- package/dist/roap/types.js.map +1 -0
- package/dist/types/common/errors/webex-errors.d.ts +7 -1
- package/dist/types/config.d.ts +2 -0
- package/dist/types/constants.d.ts +15 -85
- package/dist/types/controls-options-manager/enums.d.ts +3 -1
- package/dist/types/controls-options-manager/types.d.ts +7 -1
- package/dist/types/locus-info/index.d.ts +3 -3
- package/dist/types/locus-info/selfUtils.d.ts +216 -1
- package/dist/types/media/properties.d.ts +15 -0
- package/dist/types/meeting/in-meeting-actions.d.ts +16 -0
- package/dist/types/meeting/index.d.ts +35 -1
- package/dist/types/meeting/muteState.d.ts +0 -1
- package/dist/types/meeting/request.d.ts +12 -1
- package/dist/types/meeting/request.type.d.ts +6 -0
- package/dist/types/meeting/util.d.ts +3 -1
- package/dist/types/meeting-info/meeting-info-v2.d.ts +2 -1
- package/dist/types/meetings/index.d.ts +28 -0
- package/dist/types/member/index.d.ts +20 -6
- package/dist/types/member/types.d.ts +73 -14
- package/dist/types/member/util.d.ts +156 -1
- package/dist/types/members/collection.d.ts +6 -5
- package/dist/types/members/index.d.ts +32 -43
- package/dist/types/members/request.d.ts +26 -0
- package/dist/types/members/util.d.ts +27 -0
- package/dist/types/metrics/constants.d.ts +1 -0
- package/dist/types/reachability/clusterReachability.d.ts +2 -6
- package/dist/types/reachability/index.d.ts +8 -0
- package/dist/types/roap/index.d.ts +3 -2
- package/dist/types/roap/turnDiscovery.d.ts +5 -17
- package/dist/types/roap/types.d.ts +16 -0
- package/dist/webinar/index.js +1 -1
- package/package.json +24 -23
- package/src/breakouts/index.ts +69 -0
- package/src/common/errors/webex-errors.ts +8 -1
- package/src/config.ts +2 -0
- package/src/constants.ts +23 -90
- package/src/controls-options-manager/enums.ts +2 -0
- package/src/controls-options-manager/types.ts +11 -1
- package/src/controls-options-manager/util.ts +62 -0
- package/src/locus-info/controlsUtils.ts +48 -12
- package/src/locus-info/index.ts +88 -13
- package/src/locus-info/selfUtils.ts +496 -442
- package/src/media/index.ts +23 -21
- package/src/media/properties.ts +96 -0
- package/src/meeting/brbState.ts +11 -2
- package/src/meeting/in-meeting-actions.ts +32 -0
- package/src/meeting/index.ts +356 -87
- package/src/meeting/locusMediaRequest.ts +0 -18
- package/src/meeting/muteState.ts +4 -4
- package/src/meeting/request.ts +36 -1
- package/src/meeting/request.type.ts +7 -0
- package/src/meeting/util.ts +9 -1
- package/src/meeting-info/meeting-info-v2.ts +7 -2
- package/src/meeting-info/utilv2.ts +5 -0
- package/src/meetings/index.ts +76 -0
- package/src/meetings/util.ts +18 -0
- package/src/member/index.ts +57 -22
- package/src/member/types.ts +82 -16
- package/src/member/util.ts +357 -353
- package/src/members/collection.ts +4 -3
- package/src/members/index.ts +137 -18
- package/src/members/request.ts +44 -0
- package/src/members/util.ts +43 -1
- package/src/metrics/constants.ts +1 -0
- package/src/reachability/clusterReachability.ts +26 -25
- package/src/reachability/index.ts +55 -1
- package/src/reconnection-manager/index.ts +2 -2
- package/src/roap/index.ts +3 -7
- package/src/roap/turnDiscovery.ts +34 -39
- package/src/roap/types.ts +23 -0
- package/test/unit/spec/breakouts/index.ts +167 -95
- package/test/unit/spec/controls-options-manager/util.js +120 -0
- package/test/unit/spec/locus-info/controlsUtils.js +131 -9
- package/test/unit/spec/locus-info/index.js +195 -73
- package/test/unit/spec/locus-info/selfUtils.js +98 -24
- package/test/unit/spec/media/index.ts +150 -18
- package/test/unit/spec/media/properties.ts +130 -0
- package/test/unit/spec/meeting/brbState.ts +40 -2
- package/test/unit/spec/meeting/in-meeting-actions.ts +19 -4
- package/test/unit/spec/meeting/index.js +553 -36
- package/test/unit/spec/meeting/locusMediaRequest.ts +0 -30
- package/test/unit/spec/meeting/muteState.js +73 -2
- package/test/unit/spec/meeting/request.js +32 -1
- package/test/unit/spec/meeting/utils.js +79 -33
- package/test/unit/spec/meeting-info/meetinginfov2.js +41 -0
- package/test/unit/spec/meeting-info/utilv2.js +19 -0
- package/test/unit/spec/meetings/index.js +68 -1
- package/test/unit/spec/members/index.js +304 -78
- package/test/unit/spec/members/request.js +68 -22
- package/test/unit/spec/members/utils.js +75 -0
- package/test/unit/spec/reachability/clusterReachability.ts +41 -55
- package/test/unit/spec/reachability/index.ts +89 -0
- package/test/unit/spec/reconnection-manager/index.js +4 -4
- package/test/unit/spec/roap/turnDiscovery.ts +110 -28
@@ -32,58 +32,7 @@ sinon.assert.expose(chai.assert, {prefix: ''});
|
|
32
32
|
describe('plugin-meetings', () => {
|
33
33
|
let webex;
|
34
34
|
let url1;
|
35
|
-
|
36
|
-
test1: {
|
37
|
-
namespace: 'Meetings',
|
38
|
-
participant: {
|
39
|
-
state: 'JOINED',
|
40
|
-
type: 'USER',
|
41
|
-
person: {
|
42
|
-
id: '6eb08f8b-bf69-3251-a126-b161bead2d21',
|
43
|
-
phoneNumber: '+18578675309',
|
44
|
-
isExternal: true,
|
45
|
-
primaryDisplayString: '+18578675309',
|
46
|
-
},
|
47
|
-
devices: [
|
48
|
-
{
|
49
|
-
url: 'https://fakeURL.com',
|
50
|
-
deviceType: 'SIP',
|
51
|
-
state: 'JOINED',
|
52
|
-
intents: [null],
|
53
|
-
correlationId: '1234',
|
54
|
-
provisionalUrl: 'dialout:///fake',
|
55
|
-
isSparkPstn: true,
|
56
|
-
},
|
57
|
-
{
|
58
|
-
url: 'dialout:///fakeagain',
|
59
|
-
deviceType: 'PROVISIONAL',
|
60
|
-
state: 'JOINED',
|
61
|
-
intents: [null],
|
62
|
-
correlationId: '4321',
|
63
|
-
isVideoCallback: false,
|
64
|
-
clientUrl: 'https://fakeURL',
|
65
|
-
provisionalType: 'DIAL_OUT_ONLY',
|
66
|
-
dialingStatus: 'SUCCESS',
|
67
|
-
},
|
68
|
-
],
|
69
|
-
status: {
|
70
|
-
audioStatus: 'SENDRECV',
|
71
|
-
videoStatus: 'INACTIVE',
|
72
|
-
},
|
73
|
-
id: 'abc-123-abc-123',
|
74
|
-
guest: true,
|
75
|
-
resourceGuest: false,
|
76
|
-
moderator: false,
|
77
|
-
panelist: false,
|
78
|
-
moveToLobbyNotAllowed: true,
|
79
|
-
deviceUrl: 'https://fakeDeviceurl',
|
80
|
-
},
|
81
|
-
id: 'abc-123-abc-123',
|
82
|
-
status: 'IN_MEETING',
|
83
|
-
type: 'MEETING',
|
84
|
-
isModerator: false,
|
85
|
-
},
|
86
|
-
};
|
35
|
+
let fakeMembersCollection;
|
87
36
|
|
88
37
|
describe('members', () => {
|
89
38
|
const sandbox = sinon.createSandbox();
|
@@ -92,6 +41,65 @@ describe('plugin-meetings', () => {
|
|
92
41
|
let membersRequestSpy;
|
93
42
|
|
94
43
|
beforeEach(() => {
|
44
|
+
fakeMembersCollection = {
|
45
|
+
test1: {
|
46
|
+
associatedUsers: new Set(),
|
47
|
+
namespace: 'Meetings',
|
48
|
+
participant: {
|
49
|
+
state: 'JOINED',
|
50
|
+
type: 'USER',
|
51
|
+
person: {
|
52
|
+
id: '6eb08f8b-bf69-3251-a126-b161bead2d21',
|
53
|
+
phoneNumber: '+18578675309',
|
54
|
+
isExternal: true,
|
55
|
+
primaryDisplayString: '+18578675309',
|
56
|
+
},
|
57
|
+
devices: [
|
58
|
+
{
|
59
|
+
url: 'https://fakeURL.com',
|
60
|
+
deviceType: 'SIP',
|
61
|
+
state: 'JOINED',
|
62
|
+
intents: [null],
|
63
|
+
correlationId: '1234',
|
64
|
+
provisionalUrl: 'dialout:///fake',
|
65
|
+
isSparkPstn: true,
|
66
|
+
},
|
67
|
+
{
|
68
|
+
url: 'dialout:///fakeagain',
|
69
|
+
deviceType: 'PROVISIONAL',
|
70
|
+
state: 'JOINED',
|
71
|
+
intents: [null],
|
72
|
+
correlationId: '4321',
|
73
|
+
isVideoCallback: false,
|
74
|
+
clientUrl: 'https://fakeURL',
|
75
|
+
provisionalType: 'DIAL_OUT_ONLY',
|
76
|
+
dialingStatus: 'SUCCESS',
|
77
|
+
},
|
78
|
+
],
|
79
|
+
status: {
|
80
|
+
audioStatus: 'SENDRECV',
|
81
|
+
videoStatus: 'INACTIVE',
|
82
|
+
},
|
83
|
+
id: 'test1',
|
84
|
+
guest: true,
|
85
|
+
resourceGuest: false,
|
86
|
+
moderator: false,
|
87
|
+
panelist: false,
|
88
|
+
moveToLobbyNotAllowed: true,
|
89
|
+
deviceUrl: 'https://fakeDeviceurl',
|
90
|
+
url: 'fake participant url for test1',
|
91
|
+
},
|
92
|
+
id: 'test1',
|
93
|
+
status: 'IN_MEETING',
|
94
|
+
type: 'USER',
|
95
|
+
isModerator: false,
|
96
|
+
isHost: false,
|
97
|
+
isSelf: false,
|
98
|
+
isContentSharing: false,
|
99
|
+
pairedWith: {},
|
100
|
+
},
|
101
|
+
};
|
102
|
+
|
95
103
|
webex = new MockWebex({
|
96
104
|
children: {
|
97
105
|
meetings: Meetings,
|
@@ -120,9 +128,9 @@ describe('plugin-meetings', () => {
|
|
120
128
|
meeting = {
|
121
129
|
request: sinon.mock().returns(Promise.resolve()),
|
122
130
|
locusInfo: {
|
123
|
-
sequence: {}
|
124
|
-
}
|
125
|
-
}
|
131
|
+
sequence: {},
|
132
|
+
},
|
133
|
+
};
|
126
134
|
|
127
135
|
createMembers = (options) => new Members({locusUrl: options.url, meeting}, {parent: webex});
|
128
136
|
});
|
@@ -157,6 +165,17 @@ describe('plugin-meetings', () => {
|
|
157
165
|
|
158
166
|
assert.isRejected(members.addMember({email: 'test@cisco.com'}));
|
159
167
|
});
|
168
|
+
|
169
|
+
it('should accept valid SIP email addresses', async () => {
|
170
|
+
sandbox.spy(MembersUtil, 'isInvalidInvitee');
|
171
|
+
|
172
|
+
const members = createMembers({url: true});
|
173
|
+
|
174
|
+
await members.addMember({email: 'sip:test@cisco.com'});
|
175
|
+
|
176
|
+
assert.calledOnce(MembersUtil.isInvalidInvitee);
|
177
|
+
assert.isFalse(MembersUtil.isInvalidInvitee({email: 'sip:test@cisco.com'}), 'SIP email should be valid');
|
178
|
+
});
|
160
179
|
});
|
161
180
|
|
162
181
|
describe('#admitMembers', () => {
|
@@ -280,6 +299,110 @@ describe('plugin-meetings', () => {
|
|
280
299
|
}
|
281
300
|
);
|
282
301
|
});
|
302
|
+
|
303
|
+
describe('handles members with paired devices correctly', () => {
|
304
|
+
const runCheck = (propsForUpdate, expectedPropsOnPairedMember) => {
|
305
|
+
const members = createMembers({url: url1});
|
306
|
+
|
307
|
+
const DEVICE_PARTICIPANT_URL = 'fake participant url for test2';
|
308
|
+
|
309
|
+
members.membersCollection.setAll(fakeMembersCollection);
|
310
|
+
|
311
|
+
// simulate a locus update with a member that has a paired device
|
312
|
+
members.locusParticipantsUpdate({
|
313
|
+
...propsForUpdate,
|
314
|
+
participants: [
|
315
|
+
{
|
316
|
+
id: 'test1',
|
317
|
+
type: 'USER',
|
318
|
+
person: {},
|
319
|
+
devices: [
|
320
|
+
{
|
321
|
+
intents: [
|
322
|
+
{
|
323
|
+
type: 'OBSERVE',
|
324
|
+
associatedWith: DEVICE_PARTICIPANT_URL,
|
325
|
+
},
|
326
|
+
],
|
327
|
+
},
|
328
|
+
],
|
329
|
+
},
|
330
|
+
{
|
331
|
+
id: 'test2',
|
332
|
+
type: 'RESOURCE_ROOM',
|
333
|
+
person: {},
|
334
|
+
devices: [
|
335
|
+
{
|
336
|
+
state: 'JOINED',
|
337
|
+
intents: [null],
|
338
|
+
},
|
339
|
+
],
|
340
|
+
url: DEVICE_PARTICIPANT_URL,
|
341
|
+
},
|
342
|
+
],
|
343
|
+
});
|
344
|
+
|
345
|
+
let member = members.membersCollection.get('test1');
|
346
|
+
assert.isDefined(member.pairedWith);
|
347
|
+
assert.strictEqual(member.pairedWith.participantUrl, DEVICE_PARTICIPANT_URL);
|
348
|
+
assert.strictEqual(member.pairedWith.memberId, 'test2');
|
349
|
+
|
350
|
+
let pairedDeviceMember = members.membersCollection.get('test2');
|
351
|
+
assert(pairedDeviceMember.associatedUsers.has(member.id));
|
352
|
+
assert.strictEqual(pairedDeviceMember.associatedUser, member.id);
|
353
|
+
assert.strictEqual(pairedDeviceMember.associatedUsers.size, 1);
|
354
|
+
|
355
|
+
assert.strictEqual(
|
356
|
+
pairedDeviceMember.isPairedWithSelf,
|
357
|
+
expectedPropsOnPairedMember.isPairedWithSelf
|
358
|
+
);
|
359
|
+
assert.strictEqual(pairedDeviceMember.isHost, expectedPropsOnPairedMember.isHost);
|
360
|
+
|
361
|
+
// now simulate the user and paired device leaving the meeting
|
362
|
+
members.locusParticipantsUpdate({
|
363
|
+
...propsForUpdate,
|
364
|
+
participants: [
|
365
|
+
{
|
366
|
+
id: 'test1',
|
367
|
+
type: 'USER',
|
368
|
+
person: {},
|
369
|
+
devices: [],
|
370
|
+
},
|
371
|
+
{
|
372
|
+
id: 'test2',
|
373
|
+
type: 'RESOURCE_ROOM',
|
374
|
+
person: {},
|
375
|
+
devices: [],
|
376
|
+
},
|
377
|
+
],
|
378
|
+
});
|
379
|
+
|
380
|
+
// and check that all the relevant properties were reset
|
381
|
+
member = members.membersCollection.get('test1');
|
382
|
+
assert.isDefined(member.pairedWith);
|
383
|
+
assert.isUndefined(member.pairedWith.participantUrl);
|
384
|
+
assert.isUndefined(member.pairedWith.memberId);
|
385
|
+
|
386
|
+
pairedDeviceMember = members.membersCollection.get('test2');
|
387
|
+
assert.strictEqual(pairedDeviceMember.associatedUser, null);
|
388
|
+
assert.strictEqual(pairedDeviceMember.associatedUsers.size, 0);
|
389
|
+
|
390
|
+
assert.strictEqual(pairedDeviceMember.isPairedWithSelf, false);
|
391
|
+
assert.strictEqual(pairedDeviceMember.isHost, false);
|
392
|
+
};
|
393
|
+
|
394
|
+
it('sets the right properties when a member has a paired device', () => {
|
395
|
+
runCheck({}, {isPairedWithSelf: false, isHost: false});
|
396
|
+
});
|
397
|
+
|
398
|
+
it('sets the right properties when a member has a paired device (isSelf)', () => {
|
399
|
+
runCheck({selfId: 'test1'}, {isPairedWithSelf: true, isHost: false});
|
400
|
+
});
|
401
|
+
|
402
|
+
it('sets the right properties when a member has a paired device (isHost)', () => {
|
403
|
+
runCheck({hostId: 'test1'}, {isPairedWithSelf: false, isHost: true});
|
404
|
+
});
|
405
|
+
});
|
283
406
|
});
|
284
407
|
describe('#sendDialPadKey', () => {
|
285
408
|
it('should throw a rejection when calling sendDialPadKey with no tones', async () => {
|
@@ -342,6 +465,32 @@ describe('plugin-meetings', () => {
|
|
342
465
|
});
|
343
466
|
});
|
344
467
|
|
468
|
+
describe('#cancelSIPInvite', () => {
|
469
|
+
const memberId = uuid.v4();
|
470
|
+
it('should invoke cancelSIPInviteOptions from MembersUtil when cancelSIPInvite is called with valid params', async () => {
|
471
|
+
sandbox.spy(MembersUtil, 'cancelSIPInviteOptions');
|
472
|
+
|
473
|
+
const members = createMembers({url: url1});
|
474
|
+
|
475
|
+
await members.cancelSIPInvite({memberId});
|
476
|
+
assert.calledOnce(MembersUtil.cancelSIPInviteOptions);
|
477
|
+
});
|
478
|
+
|
479
|
+
it('should throw a rejection if there is no locus url', async () => {
|
480
|
+
const members = createMembers({url: false});
|
481
|
+
|
482
|
+
assert.isRejected(members.cancelSIPInvite({memberId}));
|
483
|
+
});
|
484
|
+
|
485
|
+
it('should throw a rejection if memberId is not provided', async () => {
|
486
|
+
const members = createMembers({url: url1});
|
487
|
+
|
488
|
+
assert.isRejected(members.cancelSIPInvite({}));
|
489
|
+
assert.isRejected(members.cancelSIPInvite({memberId: null}));
|
490
|
+
assert.isRejected(members.cancelSIPInvite({memberId: undefined}));
|
491
|
+
});
|
492
|
+
});
|
493
|
+
|
345
494
|
describe('#assignRoles', () => {
|
346
495
|
const fakeRoles = [
|
347
496
|
{type: 'PRESENTER', hasRole: true},
|
@@ -349,7 +498,7 @@ describe('plugin-meetings', () => {
|
|
349
498
|
{type: 'COHOST', hasRole: true},
|
350
499
|
];
|
351
500
|
|
352
|
-
const resolvedValue =
|
501
|
+
const resolvedValue = 'it worked';
|
353
502
|
|
354
503
|
const genericMessage = 'Generic error from the API';
|
355
504
|
|
@@ -364,9 +513,13 @@ describe('plugin-meetings', () => {
|
|
364
513
|
};
|
365
514
|
|
366
515
|
if (errorCode) {
|
367
|
-
spies.assignRolesMember = sandbox
|
516
|
+
spies.assignRolesMember = sandbox
|
517
|
+
.stub(members.membersRequest, 'assignRolesMember')
|
518
|
+
.rejects({body: {errorCode}, message: genericMessage});
|
368
519
|
} else {
|
369
|
-
spies.assignRolesMember = sandbox
|
520
|
+
spies.assignRolesMember = sandbox
|
521
|
+
.stub(members.membersRequest, 'assignRolesMember')
|
522
|
+
.resolves(resolvedValue);
|
370
523
|
}
|
371
524
|
|
372
525
|
return {members, spies};
|
@@ -378,7 +531,15 @@ describe('plugin-meetings', () => {
|
|
378
531
|
assert.notCalled(spies.assignRolesMember);
|
379
532
|
};
|
380
533
|
|
381
|
-
const checkError = async (
|
534
|
+
const checkError = async (
|
535
|
+
error,
|
536
|
+
expectedMemberId,
|
537
|
+
expectedRoles,
|
538
|
+
expectedLocusUrl,
|
539
|
+
resultPromise,
|
540
|
+
expectedMessage,
|
541
|
+
spies
|
542
|
+
) => {
|
382
543
|
await assert.isRejected(resultPromise, error, expectedMessage);
|
383
544
|
assert.calledOnceWithExactly(
|
384
545
|
spies.generateRoleAssignmentMemberOptions,
|
@@ -423,7 +584,7 @@ describe('plugin-meetings', () => {
|
|
423
584
|
await checkInvalid(
|
424
585
|
resultPromise,
|
425
586
|
'The member id must be defined to assign the roles to a member.',
|
426
|
-
spies
|
587
|
+
spies
|
427
588
|
);
|
428
589
|
});
|
429
590
|
|
@@ -435,7 +596,7 @@ describe('plugin-meetings', () => {
|
|
435
596
|
await checkInvalid(
|
436
597
|
resultPromise,
|
437
598
|
'The associated locus url for this meetings members object must be defined.',
|
438
|
-
spies
|
599
|
+
spies
|
439
600
|
);
|
440
601
|
});
|
441
602
|
|
@@ -452,7 +613,7 @@ describe('plugin-meetings', () => {
|
|
452
613
|
url1,
|
453
614
|
resultPromise,
|
454
615
|
'Non converged meetings, PSTN or SIP users in converged meetings are not supported currently.',
|
455
|
-
spies
|
616
|
+
spies
|
456
617
|
);
|
457
618
|
});
|
458
619
|
|
@@ -469,7 +630,7 @@ describe('plugin-meetings', () => {
|
|
469
630
|
url1,
|
470
631
|
resultPromise,
|
471
632
|
'Reclaim Host Role Not Allowed For Other Participants. Participants cannot claim host role in PMR meeting, space instant meeting or escalated instant meeting. However, the original host still can reclaim host role when it manually makes another participant to be the host.',
|
472
|
-
spies
|
633
|
+
spies
|
473
634
|
);
|
474
635
|
});
|
475
636
|
|
@@ -486,7 +647,7 @@ describe('plugin-meetings', () => {
|
|
486
647
|
url1,
|
487
648
|
resultPromise,
|
488
649
|
'Host Key Not Specified Or Matched. The original host can reclaim the host role without entering the host key. However, any other person who claims the host role must enter the host key to get it.',
|
489
|
-
spies
|
650
|
+
spies
|
490
651
|
);
|
491
652
|
});
|
492
653
|
|
@@ -503,7 +664,7 @@ describe('plugin-meetings', () => {
|
|
503
664
|
url1,
|
504
665
|
resultPromise,
|
505
666
|
'Participant Having Host Role Already. Participant who sends request to reclaim host role has already a host role.',
|
506
|
-
spies
|
667
|
+
spies
|
507
668
|
);
|
508
669
|
});
|
509
670
|
|
@@ -520,7 +681,7 @@ describe('plugin-meetings', () => {
|
|
520
681
|
url1,
|
521
682
|
resultPromise,
|
522
683
|
genericMessage,
|
523
|
-
spies
|
684
|
+
spies
|
524
685
|
);
|
525
686
|
});
|
526
687
|
|
@@ -530,13 +691,7 @@ describe('plugin-meetings', () => {
|
|
530
691
|
|
531
692
|
const resultPromise = members.assignRoles(memberId, fakeRoles);
|
532
693
|
|
533
|
-
await checkValid(
|
534
|
-
resultPromise,
|
535
|
-
spies,
|
536
|
-
memberId,
|
537
|
-
fakeRoles,
|
538
|
-
url1,
|
539
|
-
);
|
694
|
+
await checkValid(resultPromise, spies, memberId, fakeRoles, url1);
|
540
695
|
});
|
541
696
|
});
|
542
697
|
|
@@ -661,19 +816,19 @@ describe('plugin-meetings', () => {
|
|
661
816
|
spies,
|
662
817
|
expectedRequestingMemberId,
|
663
818
|
expectedLocusUrl,
|
664
|
-
expectedRoles
|
819
|
+
expectedRoles
|
665
820
|
) => {
|
666
821
|
await assert.isFulfilled(resultPromise);
|
667
822
|
assert.calledOnceWithExactly(
|
668
823
|
spies.generateLowerAllHandsMemberOptions,
|
669
824
|
expectedRequestingMemberId,
|
670
825
|
expectedLocusUrl,
|
671
|
-
expectedRoles
|
826
|
+
expectedRoles
|
672
827
|
);
|
673
828
|
assert.calledOnceWithExactly(spies.lowerAllHandsMember, {
|
674
829
|
requestingParticipantId: expectedRequestingMemberId,
|
675
830
|
locusUrl: expectedLocusUrl,
|
676
|
-
...(expectedRoles !== undefined && {
|
831
|
+
...(expectedRoles !== undefined && {roles: expectedRoles}),
|
677
832
|
});
|
678
833
|
assert.strictEqual(resultPromise, spies.lowerAllHandsMember.getCall(0).returnValue);
|
679
834
|
};
|
@@ -714,7 +869,7 @@ describe('plugin-meetings', () => {
|
|
714
869
|
it('should make the correct request when called with valid requestingMemberId and roles', async () => {
|
715
870
|
const requestingMemberId = 'test-member-id';
|
716
871
|
const roles = ['panelist', 'attendee'];
|
717
|
-
const {
|
872
|
+
const {members, spies} = setup('test-locus-url');
|
718
873
|
|
719
874
|
const resultPromise = members.lowerAllHands(requestingMemberId, roles);
|
720
875
|
|
@@ -724,7 +879,7 @@ describe('plugin-meetings', () => {
|
|
724
879
|
it('should handle an empty roles array correctly', async () => {
|
725
880
|
const requestingMemberId = 'test-member-id';
|
726
881
|
const roles = [];
|
727
|
-
const {
|
882
|
+
const {members, spies} = setup('test-locus-url');
|
728
883
|
|
729
884
|
const resultPromise = members.lowerAllHands(requestingMemberId, roles);
|
730
885
|
|
@@ -977,5 +1132,76 @@ describe('plugin-meetings', () => {
|
|
977
1132
|
);
|
978
1133
|
});
|
979
1134
|
});
|
1135
|
+
|
1136
|
+
describe('#moveToLobby', () => {
|
1137
|
+
const setup = (locusUrl) => {
|
1138
|
+
const members = createMembers({url: locusUrl});
|
1139
|
+
|
1140
|
+
const spies = {
|
1141
|
+
getMoveMemberToLobbyRequestBody: sandbox.spy(
|
1142
|
+
MembersUtil,
|
1143
|
+
'getMoveMemberToLobbyRequestBody'
|
1144
|
+
),
|
1145
|
+
moveToLobbyMember: sandbox.spy(members.membersRequest, 'moveToLobbyMember'),
|
1146
|
+
};
|
1147
|
+
|
1148
|
+
return {members, spies};
|
1149
|
+
};
|
1150
|
+
|
1151
|
+
const checkInvalid = async (resultPromise, expectedMessage, spies) => {
|
1152
|
+
await assert.isRejected(resultPromise, ParameterError, expectedMessage);
|
1153
|
+
assert.notCalled(spies.getMoveMemberToLobbyRequestBody);
|
1154
|
+
assert.notCalled(spies.moveToLobbyMember);
|
1155
|
+
};
|
1156
|
+
|
1157
|
+
const checkValid = async (resultPromise, spies, expectedMemberId, expectedLocusUrl) => {
|
1158
|
+
await assert.isFulfilled(resultPromise);
|
1159
|
+
assert.calledOnceWithExactly(spies.getMoveMemberToLobbyRequestBody, expectedMemberId);
|
1160
|
+
assert.calledOnceWithExactly(
|
1161
|
+
spies.moveToLobbyMember,
|
1162
|
+
{
|
1163
|
+
locusUrl: expectedLocusUrl,
|
1164
|
+
memberId: expectedMemberId,
|
1165
|
+
},
|
1166
|
+
{
|
1167
|
+
moveToLobby: {participantIds: [expectedMemberId]},
|
1168
|
+
}
|
1169
|
+
);
|
1170
|
+
assert.strictEqual(resultPromise, spies.moveToLobbyMember.getCall(0).returnValue);
|
1171
|
+
};
|
1172
|
+
|
1173
|
+
it('should not make a request if there is no member id', async () => {
|
1174
|
+
const {members, spies} = setup(url1);
|
1175
|
+
|
1176
|
+
const resultPromise = members.moveToLobby();
|
1177
|
+
|
1178
|
+
await checkInvalid(
|
1179
|
+
resultPromise,
|
1180
|
+
'The member id must be defined to move the member to lobby.',
|
1181
|
+
spies
|
1182
|
+
);
|
1183
|
+
});
|
1184
|
+
|
1185
|
+
it('should not make a request if there is no locus url', async () => {
|
1186
|
+
const {members, spies} = setup();
|
1187
|
+
|
1188
|
+
const resultPromise = members.moveToLobby(uuid.v4());
|
1189
|
+
|
1190
|
+
await checkInvalid(
|
1191
|
+
resultPromise,
|
1192
|
+
'The associated locus url for this meetings members object must be defined.',
|
1193
|
+
spies
|
1194
|
+
);
|
1195
|
+
});
|
1196
|
+
|
1197
|
+
it('should make the correct request when called with valid memberId and locusUrl', async () => {
|
1198
|
+
const memberId = uuid.v4();
|
1199
|
+
const {members, spies} = setup(url1);
|
1200
|
+
|
1201
|
+
const resultPromise = members.moveToLobby(memberId);
|
1202
|
+
|
1203
|
+
await checkValid(resultPromise, spies, memberId, url1);
|
1204
|
+
});
|
1205
|
+
});
|
980
1206
|
});
|
981
1207
|
});
|
@@ -9,7 +9,7 @@ import Meetings from '@webex/plugin-meetings';
|
|
9
9
|
import MembersRequest from '@webex/plugin-meetings/src/members/request';
|
10
10
|
import membersUtil from '@webex/plugin-meetings/src/members/util';
|
11
11
|
import ParameterError from '@webex/plugin-meetings/src/common/errors/parameter';
|
12
|
-
import {
|
12
|
+
import {merge} from 'lodash';
|
13
13
|
|
14
14
|
const {assert} = chai;
|
15
15
|
|
@@ -65,10 +65,7 @@ describe('plugin-meetings', () => {
|
|
65
65
|
|
66
66
|
const checkRequest = (expectedParams) => {
|
67
67
|
assert.calledOnceWithExactly(locusDeltaRequestSpy, expectedParams);
|
68
|
-
assert.calledOnceWithExactly(
|
69
|
-
membersRequest.request,
|
70
|
-
merge(expectedParams, {body: {sequence}})
|
71
|
-
);
|
68
|
+
assert.calledOnceWithExactly(membersRequest.request, merge(expectedParams, {body: {sequence}}));
|
72
69
|
};
|
73
70
|
|
74
71
|
describe('members request library', () => {
|
@@ -98,8 +95,8 @@ describe('plugin-meetings', () => {
|
|
98
95
|
},
|
99
96
|
device: {
|
100
97
|
url,
|
101
|
-
}
|
102
|
-
}
|
98
|
+
},
|
99
|
+
},
|
103
100
|
});
|
104
101
|
});
|
105
102
|
});
|
@@ -120,9 +117,9 @@ describe('plugin-meetings', () => {
|
|
120
117
|
uri: url1,
|
121
118
|
body: {
|
122
119
|
alertIfActive: undefined,
|
123
|
-
invitees: [{address: '+18578675309'}]
|
124
|
-
}
|
125
|
-
})
|
120
|
+
invitees: [{address: '+18578675309'}],
|
121
|
+
},
|
122
|
+
});
|
126
123
|
});
|
127
124
|
});
|
128
125
|
|
@@ -133,16 +130,16 @@ describe('plugin-meetings', () => {
|
|
133
130
|
memberIds: ['1', '2'],
|
134
131
|
};
|
135
132
|
|
136
|
-
await membersRequest.admitMember(options)
|
133
|
+
await membersRequest.admitMember(options);
|
137
134
|
|
138
135
|
checkRequest({
|
139
136
|
method: 'PUT',
|
140
137
|
uri: 'https://example.com/12345/controls',
|
141
138
|
body: {
|
142
139
|
admit: {
|
143
|
-
participantIds: options.memberIds
|
144
|
-
}
|
145
|
-
}
|
140
|
+
participantIds: options.memberIds,
|
141
|
+
},
|
142
|
+
},
|
146
143
|
});
|
147
144
|
});
|
148
145
|
});
|
@@ -160,7 +157,7 @@ describe('plugin-meetings', () => {
|
|
160
157
|
method: 'PUT',
|
161
158
|
uri: 'https://example.com/12345/participant/member1/leave',
|
162
159
|
body: {
|
163
|
-
reason: undefined
|
160
|
+
reason: undefined,
|
164
161
|
},
|
165
162
|
});
|
166
163
|
});
|
@@ -224,6 +221,29 @@ describe('plugin-meetings', () => {
|
|
224
221
|
});
|
225
222
|
});
|
226
223
|
|
224
|
+
describe('#cancelSIPInvite', () => {
|
225
|
+
const memberId = uuid.v4();
|
226
|
+
it('sends a PUT to the locus endpoint', async () => {
|
227
|
+
const options = {
|
228
|
+
invitee: {
|
229
|
+
memberId,
|
230
|
+
},
|
231
|
+
locusUrl: url1,
|
232
|
+
};
|
233
|
+
|
234
|
+
await membersRequest.cancelSIPInvite(options);
|
235
|
+
|
236
|
+
checkRequest({
|
237
|
+
method: 'PUT',
|
238
|
+
uri: url1,
|
239
|
+
body: {
|
240
|
+
actionType: 'REMOVE',
|
241
|
+
invitees: [{address: memberId}],
|
242
|
+
},
|
243
|
+
});
|
244
|
+
});
|
245
|
+
});
|
246
|
+
|
227
247
|
describe('#assignRolesMember', () => {
|
228
248
|
it('sends a assignRolesMember PATCH to the locus endpoint', async () => {
|
229
249
|
const locusUrl = url1;
|
@@ -247,9 +267,9 @@ describe('plugin-meetings', () => {
|
|
247
267
|
uri: `${locusUrl}/participant/${memberId}/controls`,
|
248
268
|
body: {
|
249
269
|
role: {
|
250
|
-
roles
|
251
|
-
}
|
252
|
-
}
|
270
|
+
roles,
|
271
|
+
},
|
272
|
+
},
|
253
273
|
});
|
254
274
|
});
|
255
275
|
});
|
@@ -272,9 +292,9 @@ describe('plugin-meetings', () => {
|
|
272
292
|
uri: `${locusUrl}/participant/${memberId}/controls`,
|
273
293
|
body: {
|
274
294
|
hand: {
|
275
|
-
raised: true
|
276
|
-
}
|
277
|
-
}
|
295
|
+
raised: true,
|
296
|
+
},
|
297
|
+
},
|
278
298
|
});
|
279
299
|
});
|
280
300
|
});
|
@@ -406,7 +426,33 @@ describe('plugin-meetings', () => {
|
|
406
426
|
body: {
|
407
427
|
aliasValue,
|
408
428
|
requestingParticipantId,
|
409
|
-
}
|
429
|
+
},
|
430
|
+
});
|
431
|
+
});
|
432
|
+
});
|
433
|
+
|
434
|
+
describe('#moveToLobby', () => {
|
435
|
+
it('sends a moveToLobbyMember PATCH to the locus endpoint', async () => {
|
436
|
+
const locusUrl = url1;
|
437
|
+
const memberId = 'test1';
|
438
|
+
const options = {
|
439
|
+
locusUrl: locusUrl,
|
440
|
+
memberId,
|
441
|
+
};
|
442
|
+
const body = {
|
443
|
+
moveToLobby: {participantIds: [memberId]},
|
444
|
+
};
|
445
|
+
|
446
|
+
const getRequestParamsSpy = sandbox.spy(membersUtil, 'getMoveMemberToLobbyRequestParams');
|
447
|
+
|
448
|
+
await membersRequest.moveToLobbyMember(options, body);
|
449
|
+
|
450
|
+
assert.calledOnceWithExactly(getRequestParamsSpy, options, body);
|
451
|
+
|
452
|
+
checkRequest({
|
453
|
+
method: 'PATCH',
|
454
|
+
uri: `${locusUrl}/participant/${memberId}/controls`,
|
455
|
+
body: {moveToLobby: {participantIds: [memberId]}},
|
410
456
|
});
|
411
457
|
});
|
412
458
|
});
|