@webex/plugin-meetings 3.0.0-stream-classes.4 → 3.0.0-test.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.
Files changed (239) hide show
  1. package/README.md +12 -0
  2. package/dist/breakouts/breakout.js +1 -1
  3. package/dist/breakouts/index.js +1 -1
  4. package/dist/common/errors/no-meeting-info.js +51 -0
  5. package/dist/common/errors/no-meeting-info.js.map +1 -0
  6. package/dist/common/errors/reclaim-host-role-errors.js +158 -0
  7. package/dist/common/errors/reclaim-host-role-errors.js.map +1 -0
  8. package/dist/common/errors/webex-errors.js +23 -3
  9. package/dist/common/errors/webex-errors.js.map +1 -1
  10. package/dist/common/logs/request.js +5 -1
  11. package/dist/common/logs/request.js.map +1 -1
  12. package/dist/config.js +1 -1
  13. package/dist/config.js.map +1 -1
  14. package/dist/constants.js +69 -9
  15. package/dist/constants.js.map +1 -1
  16. package/dist/index.js +11 -1
  17. package/dist/index.js.map +1 -1
  18. package/dist/interceptors/index.js +15 -0
  19. package/dist/interceptors/index.js.map +1 -0
  20. package/dist/interceptors/locusRetry.js +93 -0
  21. package/dist/interceptors/locusRetry.js.map +1 -0
  22. package/dist/interpretation/index.js +16 -2
  23. package/dist/interpretation/index.js.map +1 -1
  24. package/dist/interpretation/siLanguage.js +1 -1
  25. package/dist/locus-info/index.js +40 -11
  26. package/dist/locus-info/index.js.map +1 -1
  27. package/dist/locus-info/mediaSharesUtils.js +15 -1
  28. package/dist/locus-info/mediaSharesUtils.js.map +1 -1
  29. package/dist/locus-info/parser.js +42 -21
  30. package/dist/locus-info/parser.js.map +1 -1
  31. package/dist/media/index.js +10 -6
  32. package/dist/media/index.js.map +1 -1
  33. package/dist/media/properties.js +13 -3
  34. package/dist/media/properties.js.map +1 -1
  35. package/dist/mediaQualityMetrics/config.js +135 -330
  36. package/dist/mediaQualityMetrics/config.js.map +1 -1
  37. package/dist/meeting/in-meeting-actions.js +4 -0
  38. package/dist/meeting/in-meeting-actions.js.map +1 -1
  39. package/dist/meeting/index.js +2187 -1074
  40. package/dist/meeting/index.js.map +1 -1
  41. package/dist/meeting/muteState.js +37 -25
  42. package/dist/meeting/muteState.js.map +1 -1
  43. package/dist/meeting/request.js +34 -19
  44. package/dist/meeting/request.js.map +1 -1
  45. package/dist/meeting/util.js +71 -0
  46. package/dist/meeting/util.js.map +1 -1
  47. package/dist/meeting-info/index.js +48 -23
  48. package/dist/meeting-info/index.js.map +1 -1
  49. package/dist/meeting-info/meeting-info-v2.js +25 -4
  50. package/dist/meeting-info/meeting-info-v2.js.map +1 -1
  51. package/dist/meeting-info/utilv2.js +1 -1
  52. package/dist/meeting-info/utilv2.js.map +1 -1
  53. package/dist/meetings/collection.js +17 -0
  54. package/dist/meetings/collection.js.map +1 -1
  55. package/dist/meetings/index.js +142 -57
  56. package/dist/meetings/index.js.map +1 -1
  57. package/dist/meetings/util.js +2 -6
  58. package/dist/meetings/util.js.map +1 -1
  59. package/dist/member/index.js +9 -0
  60. package/dist/member/index.js.map +1 -1
  61. package/dist/member/util.js +11 -0
  62. package/dist/member/util.js.map +1 -1
  63. package/dist/members/index.js +17 -1
  64. package/dist/members/index.js.map +1 -1
  65. package/dist/members/types.js.map +1 -1
  66. package/dist/members/util.js +15 -4
  67. package/dist/members/util.js.map +1 -1
  68. package/dist/metrics/constants.js +15 -1
  69. package/dist/metrics/constants.js.map +1 -1
  70. package/dist/multistream/mediaRequestManager.js +1 -1
  71. package/dist/multistream/mediaRequestManager.js.map +1 -1
  72. package/dist/multistream/remoteMediaGroup.js +16 -2
  73. package/dist/multistream/remoteMediaGroup.js.map +1 -1
  74. package/dist/multistream/remoteMediaManager.js +222 -73
  75. package/dist/multistream/remoteMediaManager.js.map +1 -1
  76. package/dist/multistream/sendSlotManager.js +22 -0
  77. package/dist/multistream/sendSlotManager.js.map +1 -1
  78. package/dist/reachability/clusterReachability.js +356 -0
  79. package/dist/reachability/clusterReachability.js.map +1 -0
  80. package/dist/reachability/index.js +262 -432
  81. package/dist/reachability/index.js.map +1 -1
  82. package/dist/reachability/request.js +1 -1
  83. package/dist/reachability/request.js.map +1 -1
  84. package/dist/reachability/util.js +29 -0
  85. package/dist/reachability/util.js.map +1 -0
  86. package/dist/reconnection-manager/index.js +113 -96
  87. package/dist/reconnection-manager/index.js.map +1 -1
  88. package/dist/roap/index.js +57 -25
  89. package/dist/roap/index.js.map +1 -1
  90. package/dist/roap/request.js +5 -13
  91. package/dist/roap/request.js.map +1 -1
  92. package/dist/roap/turnDiscovery.js +173 -81
  93. package/dist/roap/turnDiscovery.js.map +1 -1
  94. package/dist/rtcMetrics/index.js +68 -6
  95. package/dist/rtcMetrics/index.js.map +1 -1
  96. package/dist/statsAnalyzer/index.js +338 -289
  97. package/dist/statsAnalyzer/index.js.map +1 -1
  98. package/dist/statsAnalyzer/mqaUtil.js +296 -156
  99. package/dist/statsAnalyzer/mqaUtil.js.map +1 -1
  100. package/dist/types/common/errors/no-meeting-info.d.ts +14 -0
  101. package/dist/types/common/errors/reclaim-host-role-errors.d.ts +60 -0
  102. package/dist/types/common/errors/webex-errors.d.ts +13 -1
  103. package/dist/types/common/logs/request.d.ts +2 -0
  104. package/dist/types/config.d.ts +1 -1
  105. package/dist/types/constants.d.ts +66 -13
  106. package/dist/types/index.d.ts +1 -1
  107. package/dist/types/interceptors/index.d.ts +2 -0
  108. package/dist/types/interceptors/locusRetry.d.ts +27 -0
  109. package/dist/types/locus-info/index.d.ts +1 -1
  110. package/dist/types/locus-info/parser.d.ts +3 -2
  111. package/dist/types/mediaQualityMetrics/config.d.ts +99 -223
  112. package/dist/types/meeting/in-meeting-actions.d.ts +4 -0
  113. package/dist/types/meeting/index.d.ts +285 -34
  114. package/dist/types/meeting/locusMediaRequest.d.ts +1 -2
  115. package/dist/types/meeting/muteState.d.ts +2 -8
  116. package/dist/types/meeting/request.d.ts +4 -1
  117. package/dist/types/meeting/util.d.ts +25 -1
  118. package/dist/types/meeting-info/index.d.ts +7 -0
  119. package/dist/types/meeting-info/meeting-info-v2.d.ts +1 -0
  120. package/dist/types/meetings/collection.d.ts +9 -0
  121. package/dist/types/meetings/index.d.ts +42 -14
  122. package/dist/types/member/index.d.ts +1 -0
  123. package/dist/types/members/types.d.ts +1 -0
  124. package/dist/types/members/util.d.ts +5 -0
  125. package/dist/types/metrics/constants.d.ts +15 -0
  126. package/dist/types/multistream/mediaRequestManager.d.ts +2 -0
  127. package/dist/types/multistream/remoteMediaGroup.d.ts +2 -0
  128. package/dist/types/multistream/remoteMediaManager.d.ts +25 -1
  129. package/dist/types/multistream/sendSlotManager.d.ts +9 -0
  130. package/dist/types/reachability/clusterReachability.d.ts +109 -0
  131. package/dist/types/reachability/index.d.ts +59 -112
  132. package/dist/types/reachability/request.d.ts +1 -1
  133. package/dist/types/reachability/util.d.ts +8 -0
  134. package/dist/types/reconnection-manager/index.d.ts +10 -0
  135. package/dist/types/roap/index.d.ts +2 -1
  136. package/dist/types/roap/request.d.ts +2 -1
  137. package/dist/types/roap/turnDiscovery.d.ts +21 -4
  138. package/dist/types/rtcMetrics/index.d.ts +15 -1
  139. package/dist/types/statsAnalyzer/index.d.ts +28 -11
  140. package/dist/types/statsAnalyzer/mqaUtil.d.ts +28 -4
  141. package/dist/types/webinar/collection.d.ts +16 -0
  142. package/dist/types/webinar/index.d.ts +5 -0
  143. package/dist/webinar/collection.js +44 -0
  144. package/dist/webinar/collection.js.map +1 -0
  145. package/dist/webinar/index.js +69 -0
  146. package/dist/webinar/index.js.map +1 -0
  147. package/package.json +3 -2
  148. package/src/common/errors/no-meeting-info.ts +24 -0
  149. package/src/common/errors/reclaim-host-role-errors.ts +134 -0
  150. package/src/common/errors/webex-errors.ts +19 -2
  151. package/src/common/logs/request.ts +5 -1
  152. package/src/config.ts +1 -1
  153. package/src/constants.ts +71 -6
  154. package/src/index.ts +5 -0
  155. package/src/interceptors/index.ts +3 -0
  156. package/src/interceptors/locusRetry.ts +67 -0
  157. package/src/interpretation/index.ts +18 -1
  158. package/src/locus-info/index.ts +52 -16
  159. package/src/locus-info/mediaSharesUtils.ts +16 -0
  160. package/src/locus-info/parser.ts +47 -21
  161. package/src/media/index.ts +8 -6
  162. package/src/media/properties.ts +17 -2
  163. package/src/mediaQualityMetrics/config.ts +103 -238
  164. package/src/meeting/in-meeting-actions.ts +8 -0
  165. package/src/meeting/index.ts +1510 -529
  166. package/src/meeting/muteState.ts +34 -20
  167. package/src/meeting/request.ts +19 -1
  168. package/src/meeting/util.ts +97 -0
  169. package/src/meeting-info/index.ts +47 -20
  170. package/src/meeting-info/meeting-info-v2.ts +27 -5
  171. package/src/meeting-info/utilv2.ts +1 -1
  172. package/src/meetings/collection.ts +13 -0
  173. package/src/meetings/index.ts +112 -31
  174. package/src/meetings/util.ts +2 -8
  175. package/src/member/index.ts +9 -0
  176. package/src/member/util.ts +14 -0
  177. package/src/members/index.ts +29 -2
  178. package/src/members/types.ts +1 -0
  179. package/src/members/util.ts +15 -1
  180. package/src/metrics/constants.ts +14 -0
  181. package/src/multistream/mediaRequestManager.ts +4 -1
  182. package/src/multistream/remoteMediaGroup.ts +19 -0
  183. package/src/multistream/remoteMediaManager.ts +141 -18
  184. package/src/multistream/sendSlotManager.ts +29 -0
  185. package/src/reachability/clusterReachability.ts +320 -0
  186. package/src/reachability/index.ts +221 -382
  187. package/src/reachability/request.ts +1 -1
  188. package/src/reachability/util.ts +24 -0
  189. package/src/reconnection-manager/index.ts +87 -83
  190. package/src/roap/index.ts +60 -24
  191. package/src/roap/request.ts +3 -16
  192. package/src/roap/turnDiscovery.ts +112 -39
  193. package/src/rtcMetrics/index.ts +71 -5
  194. package/src/statsAnalyzer/index.ts +430 -427
  195. package/src/statsAnalyzer/mqaUtil.ts +317 -168
  196. package/src/webinar/collection.ts +31 -0
  197. package/src/webinar/index.ts +62 -0
  198. package/test/integration/spec/converged-space-meetings.js +7 -7
  199. package/test/integration/spec/journey.js +86 -104
  200. package/test/integration/spec/space-meeting.js +9 -9
  201. package/test/unit/spec/interceptors/locusRetry.ts +131 -0
  202. package/test/unit/spec/interpretation/index.ts +36 -3
  203. package/test/unit/spec/locus-info/index.js +205 -12
  204. package/test/unit/spec/locus-info/lib/SeqCmp.json +16 -0
  205. package/test/unit/spec/locus-info/mediaSharesUtils.ts +10 -0
  206. package/test/unit/spec/locus-info/parser.js +54 -13
  207. package/test/unit/spec/media/index.ts +20 -4
  208. package/test/unit/spec/media/properties.ts +2 -2
  209. package/test/unit/spec/meeting/in-meeting-actions.ts +4 -0
  210. package/test/unit/spec/meeting/index.js +4027 -1075
  211. package/test/unit/spec/meeting/muteState.js +219 -67
  212. package/test/unit/spec/meeting/request.js +63 -12
  213. package/test/unit/spec/meeting/utils.js +93 -0
  214. package/test/unit/spec/meeting-info/index.js +180 -61
  215. package/test/unit/spec/meeting-info/meetinginfov2.js +196 -53
  216. package/test/unit/spec/meetings/collection.js +12 -0
  217. package/test/unit/spec/meetings/index.js +619 -206
  218. package/test/unit/spec/meetings/utils.js +35 -12
  219. package/test/unit/spec/member/index.js +8 -7
  220. package/test/unit/spec/member/util.js +32 -0
  221. package/test/unit/spec/members/index.js +130 -17
  222. package/test/unit/spec/members/utils.js +26 -0
  223. package/test/unit/spec/multistream/mediaRequestManager.ts +20 -2
  224. package/test/unit/spec/multistream/remoteMediaGroup.ts +80 -1
  225. package/test/unit/spec/multistream/remoteMediaManager.ts +210 -3
  226. package/test/unit/spec/multistream/sendSlotManager.ts +50 -18
  227. package/test/unit/spec/reachability/clusterReachability.ts +279 -0
  228. package/test/unit/spec/reachability/index.ts +505 -135
  229. package/test/unit/spec/reachability/util.ts +40 -0
  230. package/test/unit/spec/reconnection-manager/index.js +74 -17
  231. package/test/unit/spec/roap/index.ts +181 -61
  232. package/test/unit/spec/roap/request.ts +27 -3
  233. package/test/unit/spec/roap/turnDiscovery.ts +362 -101
  234. package/test/unit/spec/rtcMetrics/index.ts +57 -3
  235. package/test/unit/spec/stats-analyzer/index.js +1225 -12
  236. package/test/unit/spec/webinar/collection.ts +13 -0
  237. package/test/unit/spec/webinar/index.ts +60 -0
  238. package/test/utils/integrationTestUtils.js +4 -4
  239. package/test/utils/webex-test-users.js +12 -4
@@ -4,31 +4,40 @@ import MockWebex from '@webex/test-helper-mock-webex';
4
4
  import Meetings from '@webex/plugin-meetings';
5
5
  import MeetingRequest from '@webex/plugin-meetings/src/meeting/request';
6
6
  import uuid from 'uuid';
7
- import { merge } from 'lodash';
7
+ import {merge} from 'lodash';
8
8
  import {IP_VERSION} from '@webex/plugin-meetings/src/constants';
9
-
9
+ import {CallDiagnosticUtils} from '@webex/internal-plugin-metrics';
10
10
 
11
11
  describe('plugin-meetings', () => {
12
12
  let meetingsRequest;
13
13
  let locusDeltaRequestSpy;
14
+ let webex;
15
+ const geoHintInfoDefaults = {
16
+ countryCode: 'US',
17
+ regionCode: 'WEST-COAST',
18
+ clientAddress: '127.0.0.1',
19
+ };
20
+ let anonymizeIpSpy;
14
21
 
15
22
  beforeEach(() => {
16
- const webex = new MockWebex({
23
+ webex = new MockWebex({
17
24
  children: {
18
25
  meetings: Meetings,
19
26
  },
20
27
  });
21
28
 
22
- webex.meetings.geoHintInfo = {
23
- countryCode: 'US',
24
- regionCode: 'WEST-COAST',
25
- };
29
+ webex.meetings.geoHintInfo = {...geoHintInfoDefaults};
26
30
 
27
31
  webex.internal = {
28
32
  services: {
29
33
  get: sinon.mock().returns('locusUrl'),
30
34
  waitForCatalog: sinon.mock().returns(Promise.resolve({})),
31
35
  },
36
+ device: {
37
+ config: {
38
+ installationId: 'installationId',
39
+ },
40
+ },
32
41
  };
33
42
 
34
43
  webex.boundedStorage.get = sinon
@@ -53,6 +62,11 @@ describe('plugin-meetings', () => {
53
62
 
54
63
  meetingsRequest.request = request;
55
64
  locusDeltaRequestSpy = sinon.spy(meetingsRequest, 'locusDeltaRequest');
65
+ anonymizeIpSpy = sinon.spy(CallDiagnosticUtils, 'anonymizeIPAddress');
66
+ });
67
+
68
+ afterEach(() => {
69
+ anonymizeIpSpy.restore();
56
70
  });
57
71
 
58
72
  const checkRequest = (expectedParams) => {
@@ -173,12 +187,13 @@ describe('plugin-meetings', () => {
173
187
  });
174
188
 
175
189
  describe('#joinMeeting', () => {
176
- it('sends /call requets for join', async () => {
190
+ it('sends /call request for join', async () => {
177
191
  const locusUrl = 'locusURL';
178
192
  const deviceUrl = 'deviceUrl';
179
193
  const correlationId = 'random-uuid';
180
194
  const roapMessage = 'roap-message';
181
195
  const permissionToken = 'permission-token';
196
+ const installationId = 'installationId';
182
197
 
183
198
  await meetingsRequest.joinMeeting({
184
199
  locusUrl,
@@ -192,9 +207,43 @@ describe('plugin-meetings', () => {
192
207
  assert.equal(requestParams.method, 'POST');
193
208
  assert.equal(requestParams.uri, `${locusUrl}/participant?alternateRedirect=true`);
194
209
  assert.equal(requestParams.body.device.url, deviceUrl);
210
+ assert.equal(requestParams.body.device.installationId, installationId);
195
211
  assert.equal(requestParams.body.device.countryCode, 'US');
196
212
  assert.equal(requestParams.body.permissionToken, 'permission-token');
197
213
  assert.equal(requestParams.body.device.regionCode, 'WEST-COAST');
214
+ assert.include(requestParams.body.device.localIp, '127.0.0');
215
+
216
+ assert.calledOnceWithExactly(anonymizeIpSpy, '127.0.0.1');
217
+ });
218
+
219
+ describe('clientAddress geoHintInfo undefined', () => {
220
+ beforeEach(() => {
221
+ webex.meetings.geoHintInfo = {};
222
+ });
223
+
224
+ // reset
225
+ afterEach(() => {
226
+ webex.meetings.geoHintInfo = {...geoHintInfoDefaults};
227
+ });
228
+
229
+ it('doesnt send the clientAddress if not available as localIp', async () => {
230
+ const locusUrl = 'locusURL';
231
+ const deviceUrl = 'deviceUrl';
232
+ const correlationId = 'random-uuid';
233
+ const roapMessage = 'roap-message';
234
+ const permissionToken = 'permission-token';
235
+
236
+ await meetingsRequest.joinMeeting({
237
+ locusUrl,
238
+ deviceUrl,
239
+ correlationId,
240
+ roapMessage,
241
+ permissionToken,
242
+ });
243
+ const requestParams = meetingsRequest.request.getCall(0).args[0];
244
+
245
+ assert.equal(requestParams.body.device.localIp, undefined);
246
+ });
198
247
  });
199
248
 
200
249
  it('sends /call with meetingNumber if inviteeAddress does not exist', async () => {
@@ -329,16 +378,16 @@ describe('plugin-meetings', () => {
329
378
  correlationId,
330
379
  roapMessage,
331
380
  permissionToken,
332
- ipVersion: IP_VERSION.ipv4_and_ipv6
381
+ ipVersion: IP_VERSION.ipv4_and_ipv6,
333
382
  });
334
383
  const requestParams = meetingsRequest.request.getCall(0).args[0];
335
384
 
336
385
  assert.equal(requestParams.method, 'POST');
337
386
  assert.equal(requestParams.uri, `${locusUrl}/participant?alternateRedirect=true`);
338
387
  assert.deepEqual(requestParams.body.clientMediaPreferences, {
339
- "joinCookie": {anycastEntryPoint: "aws-eu-west-1"},
340
- "preferTranscoding": true,
341
- "ipver": 1
388
+ joinCookie: {anycastEntryPoint: 'aws-eu-west-1'},
389
+ preferTranscoding: true,
390
+ ipver: 1,
342
391
  });
343
392
  });
344
393
  });
@@ -706,6 +755,7 @@ describe('plugin-meetings', () => {
706
755
  deviceUrl: 'deviceUrl',
707
756
  resourceId: 'resourceId',
708
757
  resourceUrl: 'resourceUrl',
758
+ shareInstanceId: '12345',
709
759
  uri: 'optionsUrl',
710
760
  annotationInfo: {
711
761
  version: '1',
@@ -719,6 +769,7 @@ describe('plugin-meetings', () => {
719
769
  version: '1',
720
770
  },
721
771
  floor: {
772
+ shareInstanceId: '12345',
722
773
  beneficiary: {
723
774
  devices: [
724
775
  {
@@ -2,6 +2,7 @@ import sinon from 'sinon';
2
2
  import {assert} from '@webex/test-helper-chai';
3
3
  import Meetings from '@webex/plugin-meetings';
4
4
  import MeetingUtil from '@webex/plugin-meetings/src/meeting/util';
5
+ import {LOCAL_SHARE_ERRORS} from '@webex/plugin-meetings/src/constants';
5
6
  import LoggerProxy from '@webex/plugin-meetings/src/common/logs/logger-proxy';
6
7
  import LoggerConfig from '@webex/plugin-meetings/src/common/logs/logger-config';
7
8
  import {SELF_POLICY, IP_VERSION} from '@webex/plugin-meetings/src/constants';
@@ -1032,5 +1033,97 @@ describe('plugin-meetings', () => {
1032
1033
  });
1033
1034
  });
1034
1035
  });
1036
+
1037
+ describe('getChangeMeetingFloorErrorPayload', () => {
1038
+ [
1039
+ {
1040
+ reason: LOCAL_SHARE_ERRORS.UNDEFINED,
1041
+ expected: {
1042
+ category: 'signaling',
1043
+ errorCode: 1100,
1044
+ },
1045
+ },
1046
+ {
1047
+ reason: LOCAL_SHARE_ERRORS.DEVICE_NOT_JOINED,
1048
+ expected: {
1049
+ category: 'signaling',
1050
+ errorCode: 4050,
1051
+ },
1052
+ },
1053
+ {
1054
+ reason: LOCAL_SHARE_ERRORS.NO_MEDIA_FOR_DEVICE,
1055
+ expected: {
1056
+ category: 'media',
1057
+ errorCode: 2048,
1058
+ },
1059
+ },
1060
+ {
1061
+ reason: LOCAL_SHARE_ERRORS.NO_CONFLUENCE_ID,
1062
+ expected: {
1063
+ category: 'signaling',
1064
+ errorCode: 4064,
1065
+ },
1066
+ },
1067
+ {
1068
+ reason: LOCAL_SHARE_ERRORS.CONTENT_SHARING_DISABLED,
1069
+ expected: {
1070
+ category: 'expected',
1071
+ errorCode: 4065,
1072
+ },
1073
+ },
1074
+ {
1075
+ reason: LOCAL_SHARE_ERRORS.LOCUS_PARTICIPANT_DNE,
1076
+ expected: {
1077
+ category: 'signaling',
1078
+ errorCode: 4066,
1079
+ },
1080
+ },
1081
+ {
1082
+ reason: LOCAL_SHARE_ERRORS.CONTENT_REQUEST_WHILE_PENDING_WHITEBOARD,
1083
+ expected: {
1084
+ category: 'expected',
1085
+ errorCode: 4067,
1086
+ },
1087
+ },
1088
+ {
1089
+ reason: 'some unknown reason',
1090
+ expected: {
1091
+ category: 'signaling',
1092
+ errorCode: 1100,
1093
+ },
1094
+ },
1095
+ ].forEach(({reason, expected}) => {
1096
+ const expectedFull = {
1097
+ errorDescription: reason,
1098
+ name: 'locus.response',
1099
+ shownToUser: false,
1100
+ fatal: true,
1101
+ ...expected,
1102
+ };
1103
+ it(`returns expected when reason="${reason}"`, () => {
1104
+ const result = MeetingUtil.getChangeMeetingFloorErrorPayload(reason);
1105
+ assert.equal(result.length, 1);
1106
+
1107
+ const error = result[0];
1108
+ assert.deepEqual(error, expectedFull);
1109
+ });
1110
+ });
1111
+
1112
+ it('properly handles "includes"', () => {
1113
+ const reason = '>>> ' + LOCAL_SHARE_ERRORS.DEVICE_NOT_JOINED + ' <<<';
1114
+ const result = MeetingUtil.getChangeMeetingFloorErrorPayload(reason);
1115
+ assert.equal(result.length, 1);
1116
+
1117
+ const error = result[0];
1118
+ assert.deepEqual(error, {
1119
+ category: 'signaling',
1120
+ errorCode: 4050,
1121
+ errorDescription: reason,
1122
+ name: 'locus.response',
1123
+ shownToUser: false,
1124
+ fatal: true,
1125
+ });
1126
+ });
1127
+ });
1035
1128
  });
1036
1129
  });
@@ -25,42 +25,78 @@ describe('plugin-meetings', () => {
25
25
  });
26
26
 
27
27
  describe('#fetchMeetingInfo', () => {
28
- it('should send ca events if meetingId present', async () => {
29
- const body = {meetingKey: '1234323'};
28
+ const checkResolvedFetchMeetingInfo = async ({meetingId, sendCAevents, shouldSendCAMetrics, confIdStrProp}) => {
29
+ const body = {meetingKey: '1234323', url: 'url-123', confID: '123', meetingId: '321'};
30
+ const bodyConfIdStr = {meetingKey: '1234323', url: 'url-123', confIdStr: '123', meetingId: '321'};
30
31
 
31
32
  sinon
32
33
  .stub(MeetingInfoUtil, 'generateOptions')
33
34
  .resolves({type: 'MEETING_ID', destination: '123456'});
34
- sinon.stub(MeetingInfoRequest.prototype, 'fetchMeetingInfo').returns(Promise.resolve(body));
35
+ sinon.stub(MeetingInfoRequest.prototype, 'fetchMeetingInfo').returns(Promise.resolve(confIdStrProp ? bodyConfIdStr : body));
35
36
 
36
37
  await meetingInfo.fetchMeetingInfo('1234323', _MEETING_ID_, null, null, null, null, null, {
37
- meetingId: 'meetingId',
38
+ meetingId,
39
+ sendCAevents,
38
40
  });
39
41
 
40
42
  const submitInternalEventCalls = webex.internal.newMetrics.submitInternalEvent.getCalls();
43
+ const submitClientEventCalls = webex.internal.newMetrics.submitClientEvent.getCalls();
41
44
 
42
- assert.deepEqual(submitInternalEventCalls[0].args[0], {
43
- name: 'internal.client.meetinginfo.request',
44
- });
45
- assert.deepEqual(submitInternalEventCalls[1].args[0], {
46
- name: 'internal.client.meetinginfo.response',
47
- });
45
+ if (shouldSendCAMetrics) {
46
+ assert.deepEqual(submitInternalEventCalls[0].args[0], {
47
+ name: 'internal.client.meetinginfo.request',
48
+ });
49
+
50
+ assert.deepEqual(submitClientEventCalls[0].args[0], {
51
+ name: 'client.meetinginfo.request',
52
+ options: {
53
+ meetingId,
54
+ },
55
+ });
56
+
57
+ assert.deepEqual(submitInternalEventCalls[1].args[0], {
58
+ name: 'internal.client.meetinginfo.response',
59
+ });
60
+
61
+ assert.deepEqual(submitClientEventCalls[1].args[0], {
62
+ name: 'client.meetinginfo.response',
63
+ payload: {
64
+ identifiers: {
65
+ meetingLookupUrl: 'url-123',
66
+ },
67
+ },
68
+ options: {
69
+ meetingId,
70
+ webexConferenceIdStr: '123',
71
+ globalMeetingId: '321'
72
+ },
73
+ });
74
+ } else {
75
+ assert.notCalled(webex.internal.newMetrics.submitInternalEvent);
76
+ assert.notCalled(webex.internal.newMetrics.submitClientEvent);
77
+ }
78
+ }
79
+ it('should send ca events if meetingId present and send CA events is authorized', async () => {
80
+ checkResolvedFetchMeetingInfo({meetingId: 'meetingId', sendCAevents: true, shouldSendCAMetrics: true});
48
81
  });
49
82
 
50
- it('should not send ca events if meetingId not present', async () => {
51
- const body = {meetingKey: '1234323'};
83
+ it('should send ca events if meetingId present and send CA events is authorized and confIdStrProp is true', async () => {
84
+ checkResolvedFetchMeetingInfo({meetingId: 'meetingId', sendCAevents: true, shouldSendCAMetrics: true, confIdStrProp: true});
85
+ });
52
86
 
53
- sinon
54
- .stub(MeetingInfoUtil, 'generateOptions')
55
- .resolves({type: 'MEETING_ID', destination: '123456'});
56
- sinon.stub(MeetingInfoRequest.prototype, 'fetchMeetingInfo').returns(Promise.resolve(body));
87
+ it('should not send ca events if meetingId not present even if CA events are authorized', async () => {
88
+ checkResolvedFetchMeetingInfo({sendCAevents: true, shouldSendCAMetrics: false});
89
+ });
57
90
 
58
- await meetingInfo.fetchMeetingInfo('1234323', _MEETING_ID_, null, null, null, null, null);
91
+ it('should not send ca events if CA events are not authorized', async () => {
92
+ checkResolvedFetchMeetingInfo({meetingId: 'meetingId', shouldSendCAMetrics: false});
93
+ });
59
94
 
60
- assert.notCalled(webex.internal.newMetrics.submitInternalEvent);
95
+ it('should not send ca events if meeting id is not present and CA events are not authorized', async () => {
96
+ checkResolvedFetchMeetingInfo({shouldSendCAMetrics: false});
61
97
  });
62
98
 
63
- it('should send ca events when fails and if meetingId present', async () => {
99
+ const checkFailingFetchMeetingInfo = async ({meetingId, sendCAevents, shouldSendCAMetrics}) => {
64
100
  const reject = {
65
101
  statusCode: 403,
66
102
  body: {message: 'msg', code: 403102, data: {meetingInfo: {}}},
@@ -84,32 +120,66 @@ describe('plugin-meetings', () => {
84
120
  null,
85
121
  null,
86
122
  {
87
- meetingId: 'meetingId',
123
+ meetingId,
124
+ sendCAevents,
88
125
  }
89
126
  );
90
127
  } catch (err) {
91
128
  const submitInternalEventCalls = webex.internal.newMetrics.submitInternalEvent.getCalls();
129
+ const submitClientEventCalls = webex.internal.newMetrics.submitClientEvent.getCalls();
92
130
 
93
- assert.deepEqual(submitInternalEventCalls[0].args[0], {
94
- name: 'internal.client.meetinginfo.request',
95
- });
131
+ if(shouldSendCAMetrics) {
132
+ assert.deepEqual(submitInternalEventCalls[0].args[0], {
133
+ name: 'internal.client.meetinginfo.request',
134
+ });
96
135
 
97
- assert.calledWith(webex.internal.newMetrics.submitClientEvent, {
98
- name: 'client.meetinginfo.response',
99
- payload: {
100
- identifiers: {
101
- meetingLookupUrl: 'http://api-url.com',
136
+ assert.deepEqual(submitClientEventCalls[0].args[0], {
137
+ name: 'client.meetinginfo.request',
138
+ options: {
139
+ meetingId: 'meetingId',
102
140
  },
103
- },
104
- options: {
105
- meetingId: 'meetingId',
106
- rawError: err,
107
- },
108
- });
141
+ });
142
+
143
+ assert.deepEqual(submitInternalEventCalls[1].args[0], {
144
+ name: 'internal.client.meetinginfo.response',
145
+ });
146
+
147
+ assert.deepEqual(submitClientEventCalls[1].args[0], {
148
+ name: 'client.meetinginfo.response',
149
+ payload: {
150
+ identifiers: {
151
+ meetingLookupUrl: 'http://api-url.com',
152
+ },
153
+ },
154
+ options: {
155
+ meetingId: 'meetingId',
156
+ rawError: err,
157
+ },
158
+ });
159
+ } else {
160
+ assert.notCalled(webex.internal.newMetrics.submitInternalEvent);
161
+ assert.notCalled(webex.internal.newMetrics.submitClientEvent);
162
+ }
109
163
  }
164
+ }
165
+
166
+ it('should send ca events when fails if meetingId present and CA events are authorized', async () => {
167
+ checkFailingFetchMeetingInfo({meetingId: 'meetingId', sendCAevents: true, shouldSendCAMetrics: true})
168
+ });
169
+
170
+ it('should not send ca events when fails if meetingId present and CA events are not authorized', async () => {
171
+ checkFailingFetchMeetingInfo({meetingId: 'meetingId', shouldSendCAMetrics: false})
172
+ });
173
+
174
+ it('should not send ca events when fails if meetingId not present even if CA events are authorized', async () => {
175
+ checkFailingFetchMeetingInfo({sendCAevents: true, shouldSendCAMetrics: false})
176
+ });
177
+
178
+ it('should not send ca events when fails if meetingId not present and CA events are not authorized', async () => {
179
+ checkFailingFetchMeetingInfo({shouldSendCAMetrics: false})
110
180
  });
111
181
 
112
- it('should send ca events when in the retry as well if meetingId present', async () => {
182
+ const checkRetryFetchMeetingInfo = async ({meetingId, sendCAevents, shouldSendCAMetrics}) => {
113
183
  const reject = {
114
184
  statusCode: 403,
115
185
  body: {message: 'msg', code: 403102, data: {meetingInfo: {}}},
@@ -118,7 +188,7 @@ describe('plugin-meetings', () => {
118
188
 
119
189
  sinon
120
190
  .stub(MeetingInfoUtil, 'generateOptions')
121
- .resolves({type: 'MEETING_LINK', destination: '123456'});
191
+ .resolves({type: 'MEETING_LINK', destination: '123456', url: 'success-url-123'});
122
192
  const requestStub = sinon
123
193
  .stub(MeetingInfoRequest.prototype, 'fetchMeetingInfo')
124
194
  .rejects(reject);
@@ -133,48 +203,97 @@ describe('plugin-meetings', () => {
133
203
  null,
134
204
  null,
135
205
  {
136
- meetingId: 'meetingId',
206
+ meetingId,
207
+ sendCAevents,
137
208
  }
138
209
  );
139
210
  assert.fail('fetchMeetingInfo should have thrown, but has not done that');
140
211
  } catch (err) {
141
212
  let submitInternalEventCalls = webex.internal.newMetrics.submitInternalEvent.getCalls();
213
+ let submitClientEventCalls = webex.internal.newMetrics.submitClientlEvent.getCalls();
142
214
 
143
- assert.deepEqual(submitInternalEventCalls[0].args[0], {
144
- name: 'internal.client.meetinginfo.request',
145
- });
215
+ if(shouldSendCAMetrics) {
216
+ assert.deepEqual(submitInternalEventCalls[0].args[0], {
217
+ name: 'internal.client.meetinginfo.request',
218
+ });
146
219
 
147
- assert.calledWith(webex.internal.newMetrics.submitClientEvent, {
148
- name: 'client.meetinginfo.response',
149
- payload: {
150
- identifiers: {
151
- meetingLookupUrl: 'http://api-url.com',
152
- },
153
- },
154
- options: {
155
- meetingId: 'meetingId',
156
- rawError: err,
157
- },
158
- });
220
+ assert.deepEqual(submitClientEventCalls[0].args[0], {
221
+ name: 'client.meetinginfo.request',
222
+ });
159
223
 
160
- assert.deepEqual(submitInternalEventCalls[1].args[0], {
161
- name: 'internal.client.meetinginfo.response',
162
- });
224
+ assert.deepEqual(submitInternalEventCalls[1].args[0], {
225
+ name: 'internal.client.meetinginfo.response',
226
+ });
227
+
228
+ assert.deepEqual(submitClientEventCalls[1].args[0], {
229
+ name: 'client.meetinginfo.response',
230
+ payload: {
231
+ identifiers: {
232
+ meetingLookupUrl: 'http://api-url.com',
233
+ },
234
+ },
235
+ options: {
236
+ meetingId: 'meetingId',
237
+ rawError: err,
238
+ },
239
+ });
163
240
 
164
- assert.deepEqual(submitInternalEventCalls[2].args[0], {
165
- name: 'internal.client.meetinginfo.request',
166
- });
241
+ assert.deepEqual(submitInternalEventCalls[2].args[0], {
242
+ name: 'internal.client.meetinginfo.request',
243
+ });
244
+
245
+ assert.deepEqual(submitClientEventCalls[2].args[0], {
246
+ name: 'client.meetinginfo.request',
247
+ payload: {
248
+ identifiers: {
249
+ meetingLookupUrl: 'success-url-123',
250
+ },
251
+ },
252
+ });
253
+ } else {
254
+ assert.notCalled(webex.internal.newMetrics.submitInternalEvent);
255
+ assert.notCalled(webex.internal.newMetrics.submitClientEvent);
256
+ }
167
257
 
168
258
  requestStub.resolves({});
169
259
 
170
260
  await flushPromises();
171
261
 
172
262
  submitInternalEventCalls = webex.internal.newMetrics.submitInternalEvent.getCalls();
263
+ submitClientEventCalls = webex.internal.newMetrics.submitClientEvent.getCalls();
173
264
 
174
- assert.deepEqual(submitInternalEventCalls[3].args[0], {
175
- name: 'internal.client.meetinginfo.response',
176
- });
265
+ if(shouldSendInternalCAMetrics) {
266
+ assert.deepEqual(submitInternalEventCalls[3].args[0], {
267
+ name: 'internal.client.meetinginfo.response',
268
+ });
269
+ } else {
270
+ assert.notCalled(webex.internal.newMetrics.submitInternalEvent);
271
+ }
272
+
273
+ if(shouldSendCAMetrics) {
274
+ assert.deepEqual(submitClientEventCalls[3].args[0], {
275
+ name: 'internal.client.meetinginfo.response',
276
+ });
277
+ } else {
278
+ assert.notCalled(webex.internal.newMetrics.submitClientEvent);
279
+ }
177
280
  }
281
+ }
282
+
283
+ it('should send ca events when in the retry as well if meetingId present and CA events are authorized', async () => {
284
+ checkRetryFetchMeetingInfo({meetingId: 'meetingId', sendCAevents: true, shouldSendCAMetrics: true})
285
+ });
286
+
287
+ it('should not send ca events when in the retry as well if meetingId not present and CA events are authorized', async () => {
288
+ checkRetryFetchMeetingInfo({sendCAevents: true, shouldSendCAMetrics: false})
289
+ });
290
+
291
+ it('should not send ca events when in the retry as well if meetingId present and CA events are not authorized', async () => {
292
+ checkRetryFetchMeetingInfo({meetingId: 'meetingId', shouldSendCAMetrics: false})
293
+ });
294
+
295
+ it('should not send ca events when in the retry as well if meetingId not present and CA events are not authorized', async () => {
296
+ checkRetryFetchMeetingInfo({shouldSendCAMetrics: false})
178
297
  });
179
298
  });
180
299
  });