@webex/plugin-meetings 3.0.0-beta.80 → 3.0.0-beta.82

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.
Files changed (35) hide show
  1. package/dist/breakouts/breakout.js +1 -1
  2. package/dist/breakouts/index.js +1 -1
  3. package/dist/constants.js +7 -1
  4. package/dist/constants.js.map +1 -1
  5. package/dist/controls-options-manager/enums.js +11 -2
  6. package/dist/controls-options-manager/enums.js.map +1 -1
  7. package/dist/controls-options-manager/index.js +42 -11
  8. package/dist/controls-options-manager/index.js.map +1 -1
  9. package/dist/controls-options-manager/types.js +7 -0
  10. package/dist/controls-options-manager/types.js.map +1 -0
  11. package/dist/controls-options-manager/util.js +240 -29
  12. package/dist/controls-options-manager/util.js.map +1 -1
  13. package/dist/media/index.js +5 -3
  14. package/dist/media/index.js.map +1 -1
  15. package/dist/meeting/index.js +8 -4
  16. package/dist/meeting/index.js.map +1 -1
  17. package/dist/types/constants.d.ts +5 -0
  18. package/dist/types/controls-options-manager/enums.d.ts +7 -0
  19. package/dist/types/controls-options-manager/index.d.ts +8 -0
  20. package/dist/types/controls-options-manager/types.d.ts +37 -0
  21. package/dist/types/controls-options-manager/util.d.ts +103 -9
  22. package/dist/types/media/index.d.ts +2 -0
  23. package/dist/types/meeting/index.d.ts +3 -1
  24. package/package.json +18 -18
  25. package/src/constants.ts +7 -0
  26. package/src/controls-options-manager/enums.ts +9 -0
  27. package/src/controls-options-manager/index.ts +36 -1
  28. package/src/controls-options-manager/types.ts +49 -0
  29. package/src/controls-options-manager/util.ts +221 -22
  30. package/src/media/index.ts +15 -1
  31. package/src/meeting/index.ts +7 -3
  32. package/test/unit/spec/controls-options-manager/index.js +76 -0
  33. package/test/unit/spec/controls-options-manager/util.js +317 -0
  34. package/test/unit/spec/media/index.ts +4 -0
  35. package/test/unit/spec/meeting/index.js +42 -0
@@ -1,5 +1,7 @@
1
+ import { DISPLAY_HINTS } from '@webex/plugin-meetings/src/constants';
1
2
  import ControlsOptionsUtil from '@webex/plugin-meetings/src/controls-options-manager/util';
2
3
  import { assert } from 'chai';
4
+ import sinon from 'sinon';
3
5
 
4
6
  describe('plugin-meetings', () => {
5
7
  describe('controls-option-manager tests', () => {
@@ -8,6 +10,8 @@ describe('plugin-meetings', () => {
8
10
  let locusInfo;
9
11
 
10
12
  beforeEach(() => {
13
+ sinon.restore();
14
+
11
15
  locusInfo = {
12
16
  parsedLocus: {
13
17
  info: {
@@ -16,6 +20,319 @@ describe('plugin-meetings', () => {
16
20
  },
17
21
  };
18
22
  });
23
+
24
+ describe('hasHints()', () => {
25
+ it('should return true if all hints are found', () => {
26
+ const hints = ['EXAMPLE_HINT_A', 'EXAMPLE_HINT_B']
27
+
28
+ locusInfo.parsedLocus.info.userDisplayHints.push(...hints);
29
+
30
+ assert.isTrue(ControlsOptionsUtil.hasHints({requiredHints: hints, displayHints: hints}));
31
+ });
32
+
33
+ it('should return false if all hints are not found', () => {
34
+ const hints = ['EXAMPLE_HINT_A', 'EXAMPLE_HINT_B']
35
+
36
+ locusInfo.parsedLocus.info.userDisplayHints.push(...hints);
37
+
38
+ assert.isFalse(ControlsOptionsUtil.hasHints({requiredHints: hints, displayHints: []}));
39
+ });
40
+ });
41
+
42
+ describe('canUpdateAudio()', () => {
43
+ beforeEach(() => {
44
+ ControlsOptionsUtil.hasHints = sinon.stub().returns(true);
45
+ });
46
+
47
+ it('should call hasHints() with proper hints when `muted` is true', () => {
48
+ ControlsOptionsUtil.canUpdateAudio({properties: {muted: true}}, [])
49
+
50
+ assert.calledWith(ControlsOptionsUtil.hasHints, {
51
+ requiredHints: [DISPLAY_HINTS.MUTE_ALL],
52
+ displayHints: [],
53
+ });
54
+ });
55
+
56
+ it('should call hasHints() with proper hints when `muted` is false', () => {
57
+ ControlsOptionsUtil.canUpdateAudio({properties: {muted: false}}, [])
58
+
59
+ assert.calledWith(ControlsOptionsUtil.hasHints, {
60
+ requiredHints: [DISPLAY_HINTS.UNMUTE_ALL],
61
+ displayHints: [],
62
+ });
63
+ });
64
+
65
+ it('should call hasHints() with proper hints when `disallowUnmute` is true', () => {
66
+ ControlsOptionsUtil.canUpdateAudio({properties: {disallowUnmute: true}}, [])
67
+
68
+ assert.calledWith(ControlsOptionsUtil.hasHints, {
69
+ requiredHints: [DISPLAY_HINTS.ENABLE_HARD_MUTE],
70
+ displayHints: [],
71
+ });
72
+ });
73
+
74
+ it('should call hasHints() with proper hints when `disallowUnmute` is false', () => {
75
+ ControlsOptionsUtil.canUpdateAudio({properties: {disallowUnmute: false}}, [])
76
+
77
+ assert.calledWith(ControlsOptionsUtil.hasHints, {
78
+ requiredHints: [DISPLAY_HINTS.DISABLE_HARD_MUTE],
79
+ displayHints: [],
80
+ });
81
+ });
82
+
83
+ it('should call hasHints() with proper hints when `muteOnEntry` is true', () => {
84
+ ControlsOptionsUtil.canUpdateAudio({properties: {muteOnEntry: true}}, [])
85
+
86
+ assert.calledWith(ControlsOptionsUtil.hasHints, {
87
+ requiredHints: [DISPLAY_HINTS.ENABLE_MUTE_ON_ENTRY],
88
+ displayHints: [],
89
+ });
90
+ });
91
+
92
+ it('should call hasHints() with proper hints when `muteOnEntry` is false', () => {
93
+ ControlsOptionsUtil.canUpdateAudio({properties: {muteOnEntry: false}}, [])
94
+
95
+ assert.calledWith(ControlsOptionsUtil.hasHints, {
96
+ requiredHints: [DISPLAY_HINTS.DISABLE_MUTE_ON_ENTRY],
97
+ displayHints: [],
98
+ });
99
+ });
100
+
101
+ it('should call hasHints() with all properties after negotiating hints', () => {
102
+ const properties = {
103
+ muted: true,
104
+ disallowUnmute: true,
105
+ muteOnEntry: true,
106
+ };
107
+
108
+ ControlsOptionsUtil.canUpdateAudio({properties}, []);
109
+
110
+ assert.calledWith(ControlsOptionsUtil.hasHints, {
111
+ requiredHints: [
112
+ DISPLAY_HINTS.MUTE_ALL,
113
+ DISPLAY_HINTS.ENABLE_HARD_MUTE,
114
+ DISPLAY_HINTS.ENABLE_MUTE_ON_ENTRY,
115
+ ],
116
+ displayHints: [],
117
+ });
118
+ });
119
+
120
+ it('should return the resolution of hasHints()', () => {
121
+ const expected = 'example-return-value'
122
+ ControlsOptionsUtil.hasHints = sinon.stub().returns(expected);
123
+
124
+ const results = ControlsOptionsUtil.canUpdateAudio({properties: {}}, []);
125
+
126
+ assert.calledOnce(ControlsOptionsUtil.hasHints);
127
+ assert.equal(results, expected);
128
+ });
129
+ });
130
+
131
+ describe('canUpdateReactions()', () => {
132
+ beforeEach(() => {
133
+ ControlsOptionsUtil.hasHints = sinon.stub().returns(true);
134
+ });
135
+
136
+ it('should call hasHints() with proper hints when `enabled` is true', () => {
137
+ ControlsOptionsUtil.canUpdateReactions({properties: {enabled: true}}, [])
138
+
139
+ assert.calledWith(ControlsOptionsUtil.hasHints, {
140
+ requiredHints: [DISPLAY_HINTS.ENABLE_REACTIONS],
141
+ displayHints: [],
142
+ });
143
+ });
144
+
145
+ it('should call hasHints() with proper hints when `enabled` is false', () => {
146
+ ControlsOptionsUtil.canUpdateReactions({properties: {enabled: false}}, [])
147
+
148
+ assert.calledWith(ControlsOptionsUtil.hasHints, {
149
+ requiredHints: [DISPLAY_HINTS.DISABLE_REACTIONS],
150
+ displayHints: [],
151
+ });
152
+ });
153
+
154
+ it('should call hasHints() with proper hints when `showDisplayNameWithReactions` is true', () => {
155
+ ControlsOptionsUtil.canUpdateReactions({properties: {showDisplayNameWithReactions: true}}, [])
156
+
157
+ assert.calledWith(ControlsOptionsUtil.hasHints, {
158
+ requiredHints: [DISPLAY_HINTS.ENABLE_SHOW_DISPLAY_NAME],
159
+ displayHints: [],
160
+ });
161
+ });
162
+
163
+ it('should call hasHints() with proper hints when `showDisplayNameWithReactions` is false', () => {
164
+ ControlsOptionsUtil.canUpdateReactions({properties: {showDisplayNameWithReactions: false}}, [])
165
+
166
+ assert.calledWith(ControlsOptionsUtil.hasHints, {
167
+ requiredHints: [DISPLAY_HINTS.DISABLE_SHOW_DISPLAY_NAME],
168
+ displayHints: [],
169
+ });
170
+ });
171
+
172
+ it('should call hasHints() with all properties after negotiating hints', () => {
173
+ const properties = {
174
+ enabled: true,
175
+ showDisplayNameWithReactions: true,
176
+ };
177
+
178
+ ControlsOptionsUtil.canUpdateReactions({properties}, []);
179
+
180
+ assert.calledWith(ControlsOptionsUtil.hasHints, {
181
+ requiredHints: [
182
+ DISPLAY_HINTS.ENABLE_REACTIONS,
183
+ DISPLAY_HINTS.ENABLE_SHOW_DISPLAY_NAME,
184
+ ],
185
+ displayHints: [],
186
+ });
187
+ });
188
+
189
+ it('should return the resolution of hasHints()', () => {
190
+ const expected = 'example-return-value'
191
+ ControlsOptionsUtil.hasHints = sinon.stub().returns(expected);
192
+
193
+ const results = ControlsOptionsUtil.canUpdateReactions({properties: {}}, []);
194
+
195
+ assert.calledOnce(ControlsOptionsUtil.hasHints);
196
+ assert.equal(results, expected);
197
+ });
198
+ });
199
+
200
+ describe('canUpdateShareControl()', () => {
201
+ beforeEach(() => {
202
+ ControlsOptionsUtil.hasHints = sinon.stub().returns(true);
203
+ });
204
+
205
+ it('should call hasHints() with proper hints', () => {
206
+ ControlsOptionsUtil.canUpdateShareControl([])
207
+
208
+ assert.calledWith(ControlsOptionsUtil.hasHints, {
209
+ requiredHints: [DISPLAY_HINTS.SHARE_CONTROL],
210
+ displayHints: [],
211
+ });
212
+ });
213
+
214
+ it('should return the resolution of hasHints()', () => {
215
+ const expected = 'example-return-value'
216
+ ControlsOptionsUtil.hasHints = sinon.stub().returns(expected);
217
+
218
+ const results = ControlsOptionsUtil.canUpdateShareControl([]);
219
+
220
+ assert.calledOnce(ControlsOptionsUtil.hasHints);
221
+ assert.equal(results, expected);
222
+ });
223
+ });
224
+
225
+ describe('canUpdateViewTheParticipantsList()', () => {
226
+ beforeEach(() => {
227
+ ControlsOptionsUtil.hasHints = sinon.stub().returns(true);
228
+ });
229
+
230
+ it('should call hasHints() with proper hints when `enabled` is true', () => {
231
+ ControlsOptionsUtil.canUpdateViewTheParticipantsList({properties: {enabled: true}}, [])
232
+
233
+ assert.calledWith(ControlsOptionsUtil.hasHints, {
234
+ requiredHints: [DISPLAY_HINTS.ENABLE_VIEW_THE_PARTICIPANT_LIST],
235
+ displayHints: [],
236
+ });
237
+ });
238
+
239
+ it('should call hasHints() with proper hints when `enabled` is false', () => {
240
+ ControlsOptionsUtil.canUpdateViewTheParticipantsList({properties: {enabled: false}}, [])
241
+
242
+ assert.calledWith(ControlsOptionsUtil.hasHints, {
243
+ requiredHints: [DISPLAY_HINTS.DISABLE_VIEW_THE_PARTICIPANT_LIST],
244
+ displayHints: [],
245
+ });
246
+ });
247
+
248
+ it('should return the resolution of hasHints()', () => {
249
+ const expected = 'example-return-value'
250
+ ControlsOptionsUtil.hasHints = sinon.stub().returns(expected);
251
+
252
+ const results = ControlsOptionsUtil.canUpdateViewTheParticipantsList({properties: {}}, []);
253
+
254
+ assert.calledOnce(ControlsOptionsUtil.hasHints);
255
+ assert.equal(results, expected);
256
+ });
257
+ });
258
+
259
+ describe('canUpdate()', () => {
260
+ const displayHints = [];
261
+ let spies;
262
+
263
+ beforeEach(() => {
264
+ // spies = {
265
+ // canUpdateAudio: sinon.spy(ControlsOptionsUtil, 'canUpdateAudio'),
266
+ // canUpdateReactions: sinon.spy(ControlsOptionsUtil, 'canUpdateReactions'),
267
+ // canUpdateShareControl: sinon.spy(ControlsOptionsUtil, 'canUpdateShareControl'),
268
+ // canUpdateViewTheParticipantsList: sinon.spy(ControlsOptionsUtil, 'canUpdateViewTheParticipantsList'),
269
+ // }
270
+ ControlsOptionsUtil.canUpdateAudio = sinon.stub().returns(true);
271
+ ControlsOptionsUtil.canUpdateReactions = sinon.stub().returns(true);
272
+ ControlsOptionsUtil.canUpdateShareControl = sinon.stub().returns(true);
273
+ ControlsOptionsUtil.canUpdateViewTheParticipantsList = sinon.stub().returns(true);
274
+ });
275
+
276
+ it('should only call canUpdateAudio() if the scope is audio', () => {
277
+ const control = { scope: 'audio' };
278
+
279
+ const results = ControlsOptionsUtil.canUpdate(control, displayHints);
280
+
281
+ assert.calledWith(ControlsOptionsUtil.canUpdateAudio, control, displayHints);
282
+ assert.callCount(ControlsOptionsUtil.canUpdateReactions, 0);
283
+ assert.callCount(ControlsOptionsUtil.canUpdateShareControl, 0);
284
+ assert.callCount(ControlsOptionsUtil.canUpdateViewTheParticipantsList, 0);
285
+ assert.isTrue(results);
286
+ });
287
+
288
+ it('should only call canUpdateReactions() if the scope is reactions', () => {
289
+ const control = { scope: 'reactions' };
290
+
291
+ const results = ControlsOptionsUtil.canUpdate(control, displayHints);
292
+
293
+ assert.callCount(ControlsOptionsUtil.canUpdateAudio, 0);
294
+ assert.calledWith(ControlsOptionsUtil.canUpdateReactions, control, displayHints);
295
+ assert.callCount(ControlsOptionsUtil.canUpdateShareControl, 0);
296
+ assert.callCount(ControlsOptionsUtil.canUpdateViewTheParticipantsList, 0);
297
+ assert.isTrue(results);
298
+ });
299
+
300
+ it('should only call canUpdateShareControl() if the scope is shareControl', () => {
301
+ const control = { scope: 'shareControl' };
302
+
303
+ const results = ControlsOptionsUtil.canUpdate(control, displayHints);
304
+
305
+ assert.callCount(ControlsOptionsUtil.canUpdateAudio, 0);
306
+ assert.callCount(ControlsOptionsUtil.canUpdateReactions, 0);
307
+ assert.calledWith(ControlsOptionsUtil.canUpdateShareControl, displayHints);
308
+ assert.callCount(ControlsOptionsUtil.canUpdateViewTheParticipantsList, 0);
309
+ assert.isTrue(results);
310
+ });
311
+
312
+ it('should only call canUpdateViewTheParticipantsList() if the scope is viewTheParticipantList', () => {
313
+ const control = { scope: 'viewTheParticipantList' };
314
+
315
+ const results = ControlsOptionsUtil.canUpdate(control, displayHints);
316
+
317
+ assert.callCount(ControlsOptionsUtil.canUpdateAudio, 0);
318
+ assert.callCount(ControlsOptionsUtil.canUpdateReactions, 0);
319
+ assert.callCount(ControlsOptionsUtil.canUpdateShareControl, 0);
320
+ assert.calledWith(ControlsOptionsUtil.canUpdateViewTheParticipantsList, control, displayHints);
321
+ assert.isTrue(results);
322
+ });
323
+
324
+ it('should return false when the provided control scope is not supported', () => {
325
+ const control = { scope: 'invalid' };
326
+
327
+ const results = ControlsOptionsUtil.canUpdate(control, displayHints);
328
+
329
+ assert.callCount(ControlsOptionsUtil.canUpdateAudio, 0);
330
+ assert.callCount(ControlsOptionsUtil.canUpdateReactions, 0);
331
+ assert.callCount(ControlsOptionsUtil.canUpdateShareControl, 0);
332
+ assert.callCount(ControlsOptionsUtil.canUpdateViewTheParticipantsList, 0);
333
+ assert.isFalse(results);
334
+ });
335
+ });
19
336
 
20
337
  describe('canUserSetMuteOnEntry', () => {
21
338
  it('can set mute on entry enable', () => {
@@ -119,6 +119,7 @@ describe('createMediaConnection', () => {
119
119
  username: 'turn username',
120
120
  password: 'turn password',
121
121
  },
122
+ bundlePolicy: 'max-bundle',
122
123
  });
123
124
  assert.calledOnce(multistreamRoapMediaConnectionConstructorStub);
124
125
  assert.calledWith(
@@ -133,6 +134,7 @@ describe('createMediaConnection', () => {
133
134
  ],
134
135
  enableMainAudio: true,
135
136
  enableMainVideo: true,
137
+ bundlePolicy: 'max-bundle',
136
138
  },
137
139
  'some debug id'
138
140
  );
@@ -168,6 +170,7 @@ describe('createMediaConnection', () => {
168
170
  iceServers: [],
169
171
  enableMainAudio,
170
172
  enableMainVideo,
173
+ bundlePolicy: undefined,
171
174
  },
172
175
  'some debug id'
173
176
  );
@@ -198,6 +201,7 @@ describe('createMediaConnection', () => {
198
201
  iceServers: [],
199
202
  enableMainAudio: true,
200
203
  enableMainVideo: true,
204
+ bundlePolicy: undefined,
201
205
  },
202
206
  'debug string'
203
207
  );
@@ -1484,6 +1484,48 @@ describe('plugin-meetings', () => {
1484
1484
  });
1485
1485
  });
1486
1486
  });
1487
+
1488
+ it('should pass bundlePolicy to createMediaConnection', async () => {
1489
+ const FAKE_TURN_URL = 'turns:webex.com:3478';
1490
+ const FAKE_TURN_USER = 'some-turn-username';
1491
+ const FAKE_TURN_PASSWORD = 'some-password';
1492
+
1493
+ meeting.meetingState = 'ACTIVE';
1494
+ Media.createMediaConnection.resetHistory();
1495
+
1496
+ meeting.roap.doTurnDiscovery = sinon.stub().resolves({
1497
+ turnServerInfo: {
1498
+ url: FAKE_TURN_URL,
1499
+ username: FAKE_TURN_USER,
1500
+ password: FAKE_TURN_PASSWORD,
1501
+ },
1502
+ turnServerSkippedReason: undefined,
1503
+ });
1504
+ const media = meeting.addMedia({
1505
+ mediaSettings: {},
1506
+ bundlePolicy: 'bundlePolicy-value',
1507
+ });
1508
+
1509
+ assert.exists(media);
1510
+ await media;
1511
+ assert.calledOnce(meeting.roap.doTurnDiscovery);
1512
+ assert.calledWith(meeting.roap.doTurnDiscovery, meeting, false);
1513
+ assert.calledOnce(Media.createMediaConnection);
1514
+ assert.calledWith(
1515
+ Media.createMediaConnection,
1516
+ false,
1517
+ meeting.getMediaConnectionDebugId(),
1518
+ sinon.match({
1519
+ turnServerInfo: {
1520
+ url: FAKE_TURN_URL,
1521
+ username: FAKE_TURN_USER,
1522
+ password: FAKE_TURN_PASSWORD,
1523
+ },
1524
+ bundlePolicy: 'bundlePolicy-value',
1525
+ })
1526
+ );
1527
+ assert.calledOnce(fakeMediaConnection.initiateOffer);
1528
+ });
1487
1529
  });
1488
1530
  describe('#acknowledge', () => {
1489
1531
  it('should have #acknowledge', () => {