@webex/plugin-meetings 3.3.1 → 3.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (126) hide show
  1. package/dist/breakouts/breakout.js +1 -1
  2. package/dist/breakouts/index.js +7 -2
  3. package/dist/breakouts/index.js.map +1 -1
  4. package/dist/constants.js +11 -4
  5. package/dist/constants.js.map +1 -1
  6. package/dist/interpretation/index.js +1 -1
  7. package/dist/interpretation/siLanguage.js +1 -1
  8. package/dist/locus-info/selfUtils.js +0 -5
  9. package/dist/locus-info/selfUtils.js.map +1 -1
  10. package/dist/media/MediaConnectionAwaiter.js +70 -15
  11. package/dist/media/MediaConnectionAwaiter.js.map +1 -1
  12. package/dist/media/index.js +12 -0
  13. package/dist/media/index.js.map +1 -1
  14. package/dist/meeting/connectionStateHandler.js +67 -0
  15. package/dist/meeting/connectionStateHandler.js.map +1 -0
  16. package/dist/meeting/index.js +552 -357
  17. package/dist/meeting/index.js.map +1 -1
  18. package/dist/meeting/locusMediaRequest.js +7 -0
  19. package/dist/meeting/locusMediaRequest.js.map +1 -1
  20. package/dist/meeting/muteState.js +6 -1
  21. package/dist/meeting/muteState.js.map +1 -1
  22. package/dist/meeting/util.js +1 -0
  23. package/dist/meeting/util.js.map +1 -1
  24. package/dist/meeting-info/index.js +4 -4
  25. package/dist/meeting-info/index.js.map +1 -1
  26. package/dist/meeting-info/meeting-info-v2.js +2 -2
  27. package/dist/meeting-info/meeting-info-v2.js.map +1 -1
  28. package/dist/meeting-info/util.js +17 -17
  29. package/dist/meeting-info/util.js.map +1 -1
  30. package/dist/meeting-info/utilv2.js +16 -16
  31. package/dist/meeting-info/utilv2.js.map +1 -1
  32. package/dist/meetings/collection.js +1 -1
  33. package/dist/meetings/collection.js.map +1 -1
  34. package/dist/meetings/index.js +37 -33
  35. package/dist/meetings/index.js.map +1 -1
  36. package/dist/meetings/meetings.types.js +8 -0
  37. package/dist/meetings/meetings.types.js.map +1 -1
  38. package/dist/meetings/util.js +3 -2
  39. package/dist/meetings/util.js.map +1 -1
  40. package/dist/metrics/constants.js +2 -1
  41. package/dist/metrics/constants.js.map +1 -1
  42. package/dist/metrics/index.js +57 -0
  43. package/dist/metrics/index.js.map +1 -1
  44. package/dist/personal-meeting-room/index.js +1 -1
  45. package/dist/personal-meeting-room/index.js.map +1 -1
  46. package/dist/reachability/clusterReachability.js +108 -53
  47. package/dist/reachability/clusterReachability.js.map +1 -1
  48. package/dist/reachability/index.js +415 -56
  49. package/dist/reachability/index.js.map +1 -1
  50. package/dist/types/constants.d.ts +11 -3
  51. package/dist/types/media/MediaConnectionAwaiter.d.ts +24 -4
  52. package/dist/types/meeting/connectionStateHandler.d.ts +30 -0
  53. package/dist/types/meeting/index.d.ts +27 -7
  54. package/dist/types/meeting/locusMediaRequest.d.ts +2 -0
  55. package/dist/types/meeting-info/index.d.ts +3 -2
  56. package/dist/types/meeting-info/meeting-info-v2.d.ts +3 -2
  57. package/dist/types/meeting-info/util.d.ts +5 -4
  58. package/dist/types/meeting-info/utilv2.d.ts +3 -2
  59. package/dist/types/meetings/collection.d.ts +3 -2
  60. package/dist/types/meetings/index.d.ts +4 -3
  61. package/dist/types/meetings/meetings.types.d.ts +9 -0
  62. package/dist/types/metrics/constants.d.ts +1 -0
  63. package/dist/types/metrics/index.d.ts +15 -0
  64. package/dist/types/reachability/clusterReachability.d.ts +31 -3
  65. package/dist/types/reachability/index.d.ts +93 -2
  66. package/dist/webinar/index.js +1 -1
  67. package/package.json +23 -23
  68. package/src/breakouts/index.ts +7 -1
  69. package/src/constants.ts +13 -17
  70. package/src/locus-info/selfUtils.ts +0 -5
  71. package/src/media/MediaConnectionAwaiter.ts +89 -14
  72. package/src/media/index.ts +13 -0
  73. package/src/meeting/connectionStateHandler.ts +65 -0
  74. package/src/meeting/index.ts +526 -292
  75. package/src/meeting/locusMediaRequest.ts +5 -0
  76. package/src/meeting/muteState.ts +6 -1
  77. package/src/meeting/util.ts +1 -0
  78. package/src/meeting-info/index.ts +9 -6
  79. package/src/meeting-info/meeting-info-v2.ts +4 -4
  80. package/src/meeting-info/util.ts +23 -28
  81. package/src/meeting-info/utilv2.ts +18 -24
  82. package/src/meetings/collection.ts +3 -3
  83. package/src/meetings/index.ts +39 -40
  84. package/src/meetings/meetings.types.ts +11 -0
  85. package/src/meetings/util.ts +5 -4
  86. package/src/metrics/constants.ts +1 -0
  87. package/src/metrics/index.ts +44 -0
  88. package/src/personal-meeting-room/index.ts +2 -2
  89. package/src/reachability/clusterReachability.ts +86 -25
  90. package/src/reachability/index.ts +316 -27
  91. package/test/unit/spec/breakouts/index.ts +51 -32
  92. package/test/unit/spec/locus-info/selfUtils.js +25 -23
  93. package/test/unit/spec/media/MediaConnectionAwaiter.ts +131 -32
  94. package/test/unit/spec/media/index.ts +42 -27
  95. package/test/unit/spec/meeting/connectionStateHandler.ts +102 -0
  96. package/test/unit/spec/meeting/index.js +758 -179
  97. package/test/unit/spec/meeting/locusMediaRequest.ts +7 -0
  98. package/test/unit/spec/meeting/muteState.js +24 -0
  99. package/test/unit/spec/meeting-info/index.js +4 -4
  100. package/test/unit/spec/meeting-info/meetinginfov2.js +24 -28
  101. package/test/unit/spec/meeting-info/request.js +2 -2
  102. package/test/unit/spec/meeting-info/utilv2.js +41 -49
  103. package/test/unit/spec/meetings/index.js +14 -0
  104. package/test/unit/spec/metrics/index.js +126 -0
  105. package/test/unit/spec/multistream/mediaRequestManager.ts +2 -2
  106. package/test/unit/spec/personal-meeting-room/personal-meeting-room.js +2 -2
  107. package/test/unit/spec/reachability/clusterReachability.ts +116 -22
  108. package/test/unit/spec/reachability/index.ts +1153 -84
  109. package/test/unit/spec/rtcMetrics/index.ts +1 -0
  110. package/dist/mediaQualityMetrics/config.js +0 -321
  111. package/dist/mediaQualityMetrics/config.js.map +0 -1
  112. package/dist/statsAnalyzer/global.js +0 -44
  113. package/dist/statsAnalyzer/global.js.map +0 -1
  114. package/dist/statsAnalyzer/index.js +0 -1072
  115. package/dist/statsAnalyzer/index.js.map +0 -1
  116. package/dist/statsAnalyzer/mqaUtil.js +0 -368
  117. package/dist/statsAnalyzer/mqaUtil.js.map +0 -1
  118. package/dist/types/mediaQualityMetrics/config.d.ts +0 -247
  119. package/dist/types/statsAnalyzer/global.d.ts +0 -36
  120. package/dist/types/statsAnalyzer/index.d.ts +0 -217
  121. package/dist/types/statsAnalyzer/mqaUtil.d.ts +0 -48
  122. package/src/mediaQualityMetrics/config.ts +0 -255
  123. package/src/statsAnalyzer/global.ts +0 -37
  124. package/src/statsAnalyzer/index.ts +0 -1318
  125. package/src/statsAnalyzer/mqaUtil.ts +0 -463
  126. package/test/unit/spec/stats-analyzer/index.js +0 -1819
@@ -1,6 +1,6 @@
1
1
  import {assert} from '@webex/test-helper-chai';
2
2
  import sinon from 'sinon';
3
- import {ConnectionState, Event} from '@webex/internal-media-core';
3
+ import {ConnectionState, MediaConnectionEventNames} from '@webex/internal-media-core';
4
4
  import testUtils from '../../../utils/testUtils';
5
5
  import {ICE_AND_DTLS_CONNECTION_TIMEOUT} from '@webex/plugin-meetings/src/constants';
6
6
  import MediaConnectionAwaiter from '../../../../src/media/MediaConnectionAwaiter';
@@ -19,6 +19,8 @@ describe('MediaConnectionAwaiter', () => {
19
19
  off: sinon.stub(),
20
20
  getConnectionState: sinon.stub().returns(ConnectionState.New),
21
21
  getIceGatheringState: sinon.stub().returns('new'),
22
+ getIceConnectionState: sinon.stub().returns('new'),
23
+ getPeerConnectionState: sinon.stub().returns('new'),
22
24
  };
23
25
 
24
26
  mediaConnectionAwaiter = new MediaConnectionAwaiter({
@@ -52,8 +54,11 @@ describe('MediaConnectionAwaiter', () => {
52
54
  .then(() => {
53
55
  promiseResolved = true;
54
56
  })
55
- .catch(() => {
57
+ .catch((error) => {
56
58
  promiseRejected = true;
59
+
60
+ const {iceConnected} = error;
61
+ assert.equal(iceConnected, false);
57
62
  });
58
63
 
59
64
  await testUtils.flushPromises();
@@ -61,21 +66,109 @@ describe('MediaConnectionAwaiter', () => {
61
66
  assert.equal(promiseRejected, false);
62
67
 
63
68
  // check the right listener was registered
64
- assert.calledTwice(mockMC.on);
65
- assert.equal(mockMC.on.getCall(0).args[0], Event.CONNECTION_STATE_CHANGED);
66
- assert.equal(mockMC.on.getCall(1).args[0], Event.ICE_GATHERING_STATE_CHANGED);
69
+ assert.calledThrice(mockMC.on);
70
+ assert.equal(mockMC.on.getCall(0).args[0], MediaConnectionEventNames.PEER_CONNECTION_STATE_CHANGED);
71
+ assert.equal(mockMC.on.getCall(1).args[0], MediaConnectionEventNames.ICE_CONNECTION_STATE_CHANGED);
72
+ assert.equal(mockMC.on.getCall(2).args[0], MediaConnectionEventNames.ICE_GATHERING_STATE_CHANGED);
73
+ const iceGatheringListener = mockMC.on.getCall(2).args[1];
74
+
75
+ mockMC.getIceGatheringState.returns('complete');
76
+ iceGatheringListener();
77
+
78
+ await clock.tickAsync(ICE_AND_DTLS_CONNECTION_TIMEOUT);
79
+ await testUtils.flushPromises();
80
+
81
+ assert.equal(promiseResolved, false);
82
+ assert.equal(promiseRejected, true);
83
+
84
+ assert.calledThrice(mockMC.off);
85
+ });
86
+
87
+ it('rejects immediately if ice state is FAILED', async () => {
88
+ mockMC.getConnectionState.returns(ConnectionState.Connecting);
89
+ mockMC.getIceGatheringState.returns('gathering');
90
+
91
+ let promiseResolved = false;
92
+ let promiseRejected = false;
93
+
94
+ mediaConnectionAwaiter
95
+ .waitForMediaConnectionConnected()
96
+ .then(() => {
97
+ promiseResolved = true;
98
+ })
99
+ .catch((error) => {
100
+ promiseRejected = true;
101
+
102
+ const {iceConnected} = error;
103
+ assert.equal(iceConnected, false);
104
+ });
105
+
106
+ await testUtils.flushPromises();
107
+ assert.equal(promiseResolved, false);
108
+ assert.equal(promiseRejected, false);
109
+
110
+ // check the right listener was registered
111
+ assert.calledThrice(mockMC.on);
112
+ assert.equal(mockMC.on.getCall(0).args[0], MediaConnectionEventNames.PEER_CONNECTION_STATE_CHANGED);
113
+ assert.equal(mockMC.on.getCall(1).args[0], MediaConnectionEventNames.ICE_CONNECTION_STATE_CHANGED);
114
+ assert.equal(mockMC.on.getCall(2).args[0], MediaConnectionEventNames.ICE_GATHERING_STATE_CHANGED);
115
+ const iceConnectionListener = mockMC.on.getCall(1).args[1];
116
+
117
+ mockMC.getConnectionState.returns(ConnectionState.Failed);
118
+ iceConnectionListener();
119
+
120
+ await testUtils.flushPromises();
121
+
122
+ assert.equal(promiseResolved, false);
123
+ assert.equal(promiseRejected, true);
124
+
125
+ assert.calledThrice(mockMC.off);
126
+ });
127
+
128
+ it('rejects after timeout if dtls state is not connected', async () => {
129
+ mockMC.getConnectionState.returns(ConnectionState.Connecting);
130
+ mockMC.getIceGatheringState.returns('gathering');
131
+
132
+ let promiseResolved = false;
133
+ let promiseRejected = false;
134
+
135
+ mediaConnectionAwaiter
136
+ .waitForMediaConnectionConnected()
137
+ .then(() => {
138
+ promiseResolved = true;
139
+ })
140
+ .catch((error) => {
141
+ promiseRejected = true;
142
+
143
+ const {iceConnected} = error;
144
+ assert.equal(iceConnected, false);
145
+ });
146
+
147
+ await testUtils.flushPromises();
148
+ assert.equal(promiseResolved, false);
149
+ assert.equal(promiseRejected, false);
150
+
151
+ // check the right listener was registered
152
+ assert.calledThrice(mockMC.on);
153
+ assert.equal(mockMC.on.getCall(0).args[0], MediaConnectionEventNames.PEER_CONNECTION_STATE_CHANGED);
154
+ assert.equal(mockMC.on.getCall(1).args[0], MediaConnectionEventNames.ICE_CONNECTION_STATE_CHANGED);
155
+ assert.equal(mockMC.on.getCall(2).args[0], MediaConnectionEventNames.ICE_GATHERING_STATE_CHANGED);
67
156
  const listener = mockMC.on.getCall(1).args[1];
157
+ const iceConnectionListener = mockMC.on.getCall(1).args[1];
68
158
 
69
159
  mockMC.getIceGatheringState.returns('complete');
70
160
  listener();
71
161
 
162
+ mockMC.getIceConnectionState.returns('connected');
163
+ iceConnectionListener();
164
+
72
165
  await clock.tickAsync(ICE_AND_DTLS_CONNECTION_TIMEOUT);
73
166
  await testUtils.flushPromises();
74
167
 
75
168
  assert.equal(promiseResolved, false);
76
169
  assert.equal(promiseRejected, true);
77
170
 
78
- assert.calledTwice(mockMC.off);
171
+ assert.calledThrice(mockMC.off);
79
172
  });
80
173
 
81
174
  it('resolves after timeout if connection state reach connected/completed', async () => {
@@ -99,9 +192,10 @@ describe('MediaConnectionAwaiter', () => {
99
192
  assert.equal(promiseRejected, false);
100
193
 
101
194
  // check the right listener was registered
102
- assert.calledTwice(mockMC.on);
103
- assert.equal(mockMC.on.getCall(0).args[0], Event.CONNECTION_STATE_CHANGED);
104
- assert.equal(mockMC.on.getCall(1).args[0], Event.ICE_GATHERING_STATE_CHANGED);
195
+ assert.calledThrice(mockMC.on);
196
+ assert.equal(mockMC.on.getCall(0).args[0], MediaConnectionEventNames.PEER_CONNECTION_STATE_CHANGED);
197
+ assert.equal(mockMC.on.getCall(1).args[0], MediaConnectionEventNames.ICE_CONNECTION_STATE_CHANGED);
198
+ assert.equal(mockMC.on.getCall(2).args[0], MediaConnectionEventNames.ICE_GATHERING_STATE_CHANGED);
105
199
 
106
200
  mockMC.getConnectionState.returns(ConnectionState.Connected);
107
201
 
@@ -111,7 +205,7 @@ describe('MediaConnectionAwaiter', () => {
111
205
  assert.equal(promiseResolved, true);
112
206
  assert.equal(promiseRejected, false);
113
207
 
114
- assert.calledTwice(mockMC.off);
208
+ assert.calledThrice(mockMC.off);
115
209
  });
116
210
 
117
211
  it(`resolves when media connection reaches "connected" state`, async () => {
@@ -137,9 +231,10 @@ describe('MediaConnectionAwaiter', () => {
137
231
  assert.equal(promiseRejected, false);
138
232
 
139
233
  // check the right listener was registered
140
- assert.calledTwice(mockMC.on);
141
- assert.equal(mockMC.on.getCall(0).args[0], Event.CONNECTION_STATE_CHANGED);
142
- assert.equal(mockMC.on.getCall(1).args[0], Event.ICE_GATHERING_STATE_CHANGED);
234
+ assert.calledThrice(mockMC.on);
235
+ assert.equal(mockMC.on.getCall(0).args[0], MediaConnectionEventNames.PEER_CONNECTION_STATE_CHANGED);
236
+ assert.equal(mockMC.on.getCall(1).args[0], MediaConnectionEventNames.ICE_CONNECTION_STATE_CHANGED);
237
+ assert.equal(mockMC.on.getCall(2).args[0], MediaConnectionEventNames.ICE_GATHERING_STATE_CHANGED);
143
238
  const listener = mockMC.on.getCall(0).args[1];
144
239
 
145
240
  // call the listener and pretend we are now connected
@@ -151,7 +246,7 @@ describe('MediaConnectionAwaiter', () => {
151
246
  assert.equal(promiseRejected, false);
152
247
 
153
248
  // check that listener was removed
154
- assert.calledTwice(mockMC.off);
249
+ assert.calledThrice(mockMC.off);
155
250
 
156
251
  assert.calledOnce(clearTimeoutSpy);
157
252
  });
@@ -179,9 +274,10 @@ describe('MediaConnectionAwaiter', () => {
179
274
  assert.equal(promiseRejected, false);
180
275
 
181
276
  // check the right listener was registered
182
- assert.calledTwice(mockMC.on);
183
- assert.equal(mockMC.on.getCall(0).args[0], Event.CONNECTION_STATE_CHANGED);
184
- assert.equal(mockMC.on.getCall(1).args[0], Event.ICE_GATHERING_STATE_CHANGED);
277
+ assert.calledThrice(mockMC.on);
278
+ assert.equal(mockMC.on.getCall(0).args[0], MediaConnectionEventNames.PEER_CONNECTION_STATE_CHANGED);
279
+ assert.equal(mockMC.on.getCall(1).args[0], MediaConnectionEventNames.ICE_CONNECTION_STATE_CHANGED);
280
+ assert.equal(mockMC.on.getCall(2).args[0], MediaConnectionEventNames.ICE_GATHERING_STATE_CHANGED);
185
281
  const listener = mockMC.on.getCall(1).args[1];
186
282
 
187
283
  // call the listener and pretend we are now connected
@@ -197,7 +293,7 @@ describe('MediaConnectionAwaiter', () => {
197
293
  assert.equal(promiseRejected, false);
198
294
 
199
295
  // check that listener was removed
200
- assert.calledTwice(mockMC.off);
296
+ assert.calledThrice(mockMC.off);
201
297
 
202
298
  assert.neverCalledWith(clearTimeoutSpy);
203
299
  });
@@ -228,10 +324,11 @@ describe('MediaConnectionAwaiter', () => {
228
324
  assert.calledOnce(setTimeoutSpy);
229
325
 
230
326
  // check the right listener was registered
231
- assert.calledTwice(mockMC.on);
232
- assert.equal(mockMC.on.getCall(0).args[0], Event.CONNECTION_STATE_CHANGED);
233
- assert.equal(mockMC.on.getCall(1).args[0], Event.ICE_GATHERING_STATE_CHANGED);
234
- const listener = mockMC.on.getCall(1).args[1];
327
+ assert.calledThrice(mockMC.on);
328
+ assert.equal(mockMC.on.getCall(0).args[0], MediaConnectionEventNames.PEER_CONNECTION_STATE_CHANGED);
329
+ assert.equal(mockMC.on.getCall(1).args[0], MediaConnectionEventNames.ICE_CONNECTION_STATE_CHANGED);
330
+ assert.equal(mockMC.on.getCall(2).args[0], MediaConnectionEventNames.ICE_GATHERING_STATE_CHANGED);
331
+ const listener = mockMC.on.getCall(2).args[1];
235
332
 
236
333
  // call the listener and pretend we are now connected
237
334
  mockMC.getIceGatheringState.returns('complete');
@@ -249,7 +346,7 @@ describe('MediaConnectionAwaiter', () => {
249
346
  assert.equal(promiseRejected, false);
250
347
 
251
348
  // check that listener was removed
252
- assert.calledTwice(mockMC.off);
349
+ assert.calledThrice(mockMC.off);
253
350
  });
254
351
 
255
352
  it(`reject with restart timer once if gathering state is not complete`, async () => {
@@ -276,9 +373,10 @@ describe('MediaConnectionAwaiter', () => {
276
373
  assert.equal(promiseRejected, false);
277
374
 
278
375
  // check the right listener was registered
279
- assert.calledTwice(mockMC.on);
280
- assert.equal(mockMC.on.getCall(0).args[0], Event.CONNECTION_STATE_CHANGED);
281
- assert.equal(mockMC.on.getCall(1).args[0], Event.ICE_GATHERING_STATE_CHANGED);
376
+ assert.calledThrice(mockMC.on);
377
+ assert.equal(mockMC.on.getCall(0).args[0], MediaConnectionEventNames.PEER_CONNECTION_STATE_CHANGED);
378
+ assert.equal(mockMC.on.getCall(1).args[0], MediaConnectionEventNames.ICE_CONNECTION_STATE_CHANGED);
379
+ assert.equal(mockMC.on.getCall(2).args[0], MediaConnectionEventNames.ICE_GATHERING_STATE_CHANGED);
282
380
 
283
381
  await clock.tickAsync(ICE_AND_DTLS_CONNECTION_TIMEOUT * 2);
284
382
  await testUtils.flushPromises();
@@ -287,7 +385,7 @@ describe('MediaConnectionAwaiter', () => {
287
385
  assert.equal(promiseRejected, true);
288
386
 
289
387
  // check that listener was removed
290
- assert.calledTwice(mockMC.off);
388
+ assert.calledThrice(mockMC.off);
291
389
 
292
390
  assert.calledOnce(clearTimeoutSpy);
293
391
  assert.calledTwice(setTimeoutSpy);
@@ -317,11 +415,12 @@ describe('MediaConnectionAwaiter', () => {
317
415
  assert.equal(promiseRejected, false);
318
416
 
319
417
  // check the right listener was registered
320
- assert.calledTwice(mockMC.on);
321
- assert.equal(mockMC.on.getCall(0).args[0], Event.CONNECTION_STATE_CHANGED);
322
- assert.equal(mockMC.on.getCall(1).args[0], Event.ICE_GATHERING_STATE_CHANGED);
418
+ assert.calledThrice(mockMC.on);
419
+ assert.equal(mockMC.on.getCall(0).args[0], MediaConnectionEventNames.PEER_CONNECTION_STATE_CHANGED);
420
+ assert.equal(mockMC.on.getCall(1).args[0], MediaConnectionEventNames.ICE_CONNECTION_STATE_CHANGED);
421
+ assert.equal(mockMC.on.getCall(2).args[0], MediaConnectionEventNames.ICE_GATHERING_STATE_CHANGED);
323
422
  const connectionStateListener = mockMC.on.getCall(0).args[1];
324
- const iceGatheringListener = mockMC.on.getCall(1).args[1];
423
+ const iceGatheringListener = mockMC.on.getCall(2).args[1];
325
424
 
326
425
  mockMC.getIceGatheringState.returns('complete');
327
426
  iceGatheringListener();
@@ -335,7 +434,7 @@ describe('MediaConnectionAwaiter', () => {
335
434
  assert.equal(promiseRejected, false);
336
435
 
337
436
  // check that listener was removed
338
- assert.calledTwice(mockMC.off);
437
+ assert.calledThrice(mockMC.off);
339
438
 
340
439
  assert.calledTwice(clearTimeoutSpy);
341
440
  assert.calledTwice(setTimeoutSpy);
@@ -1,9 +1,8 @@
1
- import * as internalMediaModule from '@webex/internal-media-core';
1
+ import * as InternalMediaCoreModule from '@webex/internal-media-core';
2
2
  import Media from '@webex/plugin-meetings/src/media/index';
3
3
  import {assert} from '@webex/test-helper-chai';
4
4
  import sinon from 'sinon';
5
5
  import StaticConfig from '@webex/plugin-meetings/src/common/config';
6
- import {forEach} from 'lodash';
7
6
  import MockWebex from '@webex/test-helper-mock-webex';
8
7
 
9
8
  describe('createMediaConnection', () => {
@@ -17,44 +16,44 @@ describe('createMediaConnection', () => {
17
16
  id: 'roap media connection',
18
17
  };
19
18
  const fakeTrack = {
20
- id: 'any fake track'
21
- }
19
+ id: 'any fake track',
20
+ };
22
21
  const fakeAudioStream = {
23
22
  outputStream: {
24
23
  getTracks: () => {
25
24
  return [fakeTrack];
26
- }
27
- }
25
+ },
26
+ },
28
27
  };
29
28
  const fakeVideoStream = {
30
29
  outputStream: {
31
30
  getTracks: () => {
32
31
  return [fakeTrack];
33
- }
34
- }
32
+ },
33
+ },
35
34
  };
36
35
  const fakeShareVideoStream = {
37
36
  outputStream: {
38
37
  getTracks: () => {
39
38
  return [fakeTrack];
40
- }
41
- }
39
+ },
40
+ },
42
41
  };
43
42
  const fakeShareAudioStream = {
44
43
  outputStream: {
45
44
  getTracks: () => {
46
45
  return [fakeTrack];
47
- }
48
- }
46
+ },
47
+ },
49
48
  };
50
49
  afterEach(() => {
51
50
  sinon.restore();
52
- clock.uninstall()
51
+ clock.uninstall();
53
52
  });
54
53
 
55
54
  it('creates a RoapMediaConnection when multistream is disabled', () => {
56
55
  const roapMediaConnectionConstructorStub = sinon
57
- .stub(internalMediaModule, 'RoapMediaConnection')
56
+ .stub(InternalMediaCoreModule, 'RoapMediaConnection')
58
57
  .returns(fakeRoapMediaConnection);
59
58
 
60
59
  StaticConfig.set({bandwidth: {audio: 123, video: 456, startBitrate: 999}});
@@ -81,7 +80,7 @@ describe('createMediaConnection', () => {
81
80
  enableRtx: ENABLE_RTX,
82
81
  enableExtmap: ENABLE_EXTMAP,
83
82
  turnServerInfo: {
84
- url: 'turn server url',
83
+ url: 'turns:turn-server-url:443?transport=tcp',
85
84
  username: 'turn username',
86
85
  password: 'turn password',
87
86
  },
@@ -92,7 +91,12 @@ describe('createMediaConnection', () => {
92
91
  {
93
92
  iceServers: [
94
93
  {
95
- urls: 'turn server url',
94
+ urls: 'turn:turn-server-url:5004?transport=tcp',
95
+ username: 'turn username',
96
+ credential: 'turn password',
97
+ },
98
+ {
99
+ urls: 'turns:turn-server-url:443?transport=tcp',
96
100
  username: 'turn username',
97
101
  credential: 'turn password',
98
102
  },
@@ -132,7 +136,7 @@ describe('createMediaConnection', () => {
132
136
 
133
137
  it('creates a MultistreamRoapMediaConnection when multistream is enabled', () => {
134
138
  const multistreamRoapMediaConnectionConstructorStub = sinon
135
- .stub(internalMediaModule, 'MultistreamRoapMediaConnection')
139
+ .stub(InternalMediaCoreModule, 'MultistreamRoapMediaConnection')
136
140
  .returns(fakeRoapMediaConnection);
137
141
 
138
142
  Media.createMediaConnection(true, 'some debug id', webex, 'meeting id', 'correlationId', {
@@ -147,7 +151,7 @@ describe('createMediaConnection', () => {
147
151
  },
148
152
  },
149
153
  turnServerInfo: {
150
- url: 'turn server url',
154
+ url: 'turns:turn-server-url:443?transport=tcp',
151
155
  username: 'turn username',
152
156
  password: 'turn password',
153
157
  },
@@ -159,7 +163,12 @@ describe('createMediaConnection', () => {
159
163
  {
160
164
  iceServers: [
161
165
  {
162
- urls: 'turn server url',
166
+ urls: 'turn:turn-server-url:5004?transport=tcp',
167
+ username: 'turn username',
168
+ credential: 'turn password',
169
+ },
170
+ {
171
+ urls: 'turns:turn-server-url:443?transport=tcp',
163
172
  username: 'turn username',
164
173
  credential: 'turn password',
165
174
  },
@@ -172,13 +181,16 @@ describe('createMediaConnection', () => {
172
181
 
173
182
  [
174
183
  {testCase: 'turnServerInfo is undefined', turnServerInfo: undefined},
175
- {testCase: 'turnServerInfo.url is empty string', turnServerInfo: {url: '', username: 'turn username', password: 'turn password'}},
184
+ {
185
+ testCase: 'turnServerInfo.url is empty string',
186
+ turnServerInfo: {url: '', username: 'turn username', password: 'turn password'},
187
+ },
176
188
  ].forEach(({testCase, turnServerInfo}) => {
177
189
  it(`passes empty ICE servers array to MultistreamRoapMediaConnection if ${testCase} (multistream enabled)`, () => {
178
190
  const multistreamRoapMediaConnectionConstructorStub = sinon
179
- .stub(internalMediaModule, 'MultistreamRoapMediaConnection')
191
+ .stub(InternalMediaCoreModule, 'MultistreamRoapMediaConnection')
180
192
  .returns(fakeRoapMediaConnection);
181
-
193
+
182
194
  Media.createMediaConnection(true, 'debug string', webex, 'meeting id', 'correlationId', {
183
195
  mediaProperties: {
184
196
  mediaDirection: {
@@ -199,13 +211,13 @@ describe('createMediaConnection', () => {
199
211
  iceServers: [],
200
212
  },
201
213
  'meeting id'
202
- );
214
+ );
203
215
  });
204
216
  });
205
-
217
+
206
218
  it('does not pass bundlePolicy to MultistreamRoapMediaConnection if bundlePolicy is undefined', () => {
207
219
  const multistreamRoapMediaConnectionConstructorStub = sinon
208
- .stub(internalMediaModule, 'MultistreamRoapMediaConnection')
220
+ .stub(InternalMediaCoreModule, 'MultistreamRoapMediaConnection')
209
221
  .returns(fakeRoapMediaConnection);
210
222
 
211
223
  Media.createMediaConnection(true, 'debug string', webex, 'meeting id', 'correlationId', {
@@ -233,11 +245,14 @@ describe('createMediaConnection', () => {
233
245
 
234
246
  [
235
247
  {testCase: 'turnServerInfo is undefined', turnServerInfo: undefined},
236
- {testCase: 'turnServerInfo.url is empty string', turnServerInfo: {url: '', username: 'turn username', password: 'turn password'}},
248
+ {
249
+ testCase: 'turnServerInfo.url is empty string',
250
+ turnServerInfo: {url: '', username: 'turn username', password: 'turn password'},
251
+ },
237
252
  ].forEach(({testCase, turnServerInfo}) => {
238
253
  it(`passes empty ICE servers array to RoapMediaConnection if ${testCase} (multistream disabled)`, () => {
239
254
  const roapMediaConnectionConstructorStub = sinon
240
- .stub(internalMediaModule, 'RoapMediaConnection')
255
+ .stub(InternalMediaCoreModule, 'RoapMediaConnection')
241
256
  .returns(fakeRoapMediaConnection);
242
257
 
243
258
  StaticConfig.set({bandwidth: {audio: 123, video: 456, startBitrate: 999}});
@@ -0,0 +1,102 @@
1
+ import sinon from 'sinon';
2
+ import {assert} from '@webex/test-helper-chai';
3
+ import {
4
+ ConnectionStateHandler,
5
+ ConnectionStateEvent,
6
+ } from '@webex/plugin-meetings/src/meeting/connectionStateHandler';
7
+ import {ConnectionState, MediaConnectionEventNames} from '@webex/internal-media-core';
8
+
9
+ describe('ConnectionStateHandler', () => {
10
+ let connectionStateHandler: ConnectionStateHandler;
11
+ let mockMC;
12
+
13
+ beforeEach(() => {
14
+ mockMC = {
15
+ on: sinon.stub(),
16
+ off: sinon.stub(),
17
+ getConnectionState: sinon.stub().returns(ConnectionState.Connecting),
18
+ };
19
+
20
+ connectionStateHandler = new ConnectionStateHandler(mockMC);
21
+ });
22
+
23
+ describe('ConnectionStateChangedEvent', () => {
24
+ it('should emit a stateChanged event when the peer connection state changes', () => {
25
+ const spy = sinon.spy(connectionStateHandler, 'emit');
26
+
27
+ // check the right listener was registered
28
+ assert.calledTwice(mockMC.on);
29
+ assert.equal(mockMC.on.getCall(0).args[0], MediaConnectionEventNames.PEER_CONNECTION_STATE_CHANGED);
30
+ assert.equal(mockMC.on.getCall(1).args[0], MediaConnectionEventNames.ICE_CONNECTION_STATE_CHANGED);
31
+ const listener = mockMC.on.getCall(0).args[1];
32
+
33
+ listener();
34
+
35
+ assert.calledOnce(spy);
36
+ assert.calledOnceWithExactly(
37
+ connectionStateHandler.emit,
38
+ {
39
+ file: 'connectionStateHandler',
40
+ function: 'handleConnectionStateChange',
41
+ },
42
+ ConnectionStateEvent.stateChanged,
43
+ {
44
+ state: ConnectionState.Connecting,
45
+ }
46
+ );
47
+ });
48
+
49
+ it('should emit a stateChanged event when the ice connection state changes', () => {
50
+ const spy = sinon.spy(connectionStateHandler, 'emit');
51
+
52
+ // check the right listener was registered
53
+ assert.calledTwice(mockMC.on);
54
+ assert.equal(mockMC.on.getCall(0).args[0], MediaConnectionEventNames.PEER_CONNECTION_STATE_CHANGED);
55
+ assert.equal(mockMC.on.getCall(1).args[0], MediaConnectionEventNames.ICE_CONNECTION_STATE_CHANGED);
56
+ const listener = mockMC.on.getCall(1).args[1];
57
+
58
+ listener();
59
+
60
+ assert.calledOnce(spy);
61
+ assert.calledOnceWithExactly(
62
+ connectionStateHandler.emit,
63
+ {
64
+ file: 'connectionStateHandler',
65
+ function: 'handleConnectionStateChange',
66
+ },
67
+ ConnectionStateEvent.stateChanged,
68
+ {
69
+ state: ConnectionState.Connecting,
70
+ }
71
+ );
72
+ });
73
+
74
+ it('should emit a stateChanged event only once when overall connection state does not change', () => {
75
+ const spy = sinon.spy(connectionStateHandler, 'emit');
76
+
77
+ // check the right listener was registered
78
+ assert.calledTwice(mockMC.on);
79
+ assert.equal(mockMC.on.getCall(0).args[0], MediaConnectionEventNames.PEER_CONNECTION_STATE_CHANGED);
80
+ assert.equal(mockMC.on.getCall(1).args[0], MediaConnectionEventNames.ICE_CONNECTION_STATE_CHANGED);
81
+ const peerConnectionListener = mockMC.on.getCall(0).args[1];
82
+ const iceConnectionListener = mockMC.on.getCall(1).args[1];
83
+
84
+ peerConnectionListener();
85
+
86
+ iceConnectionListener();
87
+
88
+ assert.calledOnce(spy);
89
+ assert.calledOnceWithExactly(
90
+ connectionStateHandler.emit,
91
+ {
92
+ file: 'connectionStateHandler',
93
+ function: 'handleConnectionStateChange',
94
+ },
95
+ ConnectionStateEvent.stateChanged,
96
+ {
97
+ state: ConnectionState.Connecting,
98
+ }
99
+ );
100
+ });
101
+ });
102
+ });