@webex/plugin-meetings 3.6.0 → 3.7.0-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.
Files changed (314) hide show
  1. package/README.md +2 -1
  2. package/dist/breakouts/breakout.js +1 -1
  3. package/dist/breakouts/index.js +1 -1
  4. package/dist/common/errors/webinar-registration-error.js +50 -0
  5. package/dist/common/errors/webinar-registration-error.js.map +1 -0
  6. package/dist/config.js +3 -1
  7. package/dist/config.js.map +1 -1
  8. package/dist/constants.js +31 -2
  9. package/dist/constants.js.map +1 -1
  10. package/dist/controls-options-manager/enums.js +1 -0
  11. package/dist/controls-options-manager/enums.js.map +1 -1
  12. package/dist/controls-options-manager/index.js +10 -3
  13. package/dist/controls-options-manager/index.js.map +1 -1
  14. package/dist/controls-options-manager/types.js.map +1 -1
  15. package/dist/controls-options-manager/util.js +12 -0
  16. package/dist/controls-options-manager/util.js.map +1 -1
  17. package/dist/index.js +7 -0
  18. package/dist/index.js.map +1 -1
  19. package/dist/interpretation/index.js +1 -1
  20. package/dist/interpretation/siLanguage.js +1 -1
  21. package/dist/locus-info/controlsUtils.js +28 -4
  22. package/dist/locus-info/controlsUtils.js.map +1 -1
  23. package/dist/locus-info/fullState.js +2 -1
  24. package/dist/locus-info/fullState.js.map +1 -1
  25. package/dist/locus-info/index.js +61 -3
  26. package/dist/locus-info/index.js.map +1 -1
  27. package/dist/locus-info/parser.js +5 -1
  28. package/dist/locus-info/parser.js.map +1 -1
  29. package/dist/meeting/in-meeting-actions.js +19 -1
  30. package/dist/meeting/in-meeting-actions.js.map +1 -1
  31. package/dist/meeting/index.js +692 -522
  32. package/dist/meeting/index.js.map +1 -1
  33. package/dist/meeting/locusMediaRequest.js +2 -6
  34. package/dist/meeting/locusMediaRequest.js.map +1 -1
  35. package/dist/meeting/muteState.js +5 -2
  36. package/dist/meeting/muteState.js.map +1 -1
  37. package/dist/meeting/request.js +21 -29
  38. package/dist/meeting/request.js.map +1 -1
  39. package/dist/meeting/util.js +97 -61
  40. package/dist/meeting/util.js.map +1 -1
  41. package/dist/meeting-info/meeting-info-v2.js +68 -17
  42. package/dist/meeting-info/meeting-info-v2.js.map +1 -1
  43. package/dist/meetings/index.js +25 -1
  44. package/dist/meetings/index.js.map +1 -1
  45. package/dist/members/index.js +3 -2
  46. package/dist/members/index.js.map +1 -1
  47. package/dist/members/util.js +9 -5
  48. package/dist/members/util.js.map +1 -1
  49. package/dist/metrics/constants.js +2 -1
  50. package/dist/metrics/constants.js.map +1 -1
  51. package/dist/multistream/remoteMedia.js +4 -0
  52. package/dist/multistream/remoteMedia.js.map +1 -1
  53. package/dist/reachability/clusterReachability.js +0 -4
  54. package/dist/reachability/clusterReachability.js.map +1 -1
  55. package/dist/reachability/index.js +433 -136
  56. package/dist/reachability/index.js.map +1 -1
  57. package/dist/{rtcMetrics/constants.js → reachability/reachability.types.js} +1 -5
  58. package/dist/reachability/reachability.types.js.map +1 -0
  59. package/dist/reachability/request.js +23 -9
  60. package/dist/reachability/request.js.map +1 -1
  61. package/dist/roap/index.js +5 -7
  62. package/dist/roap/index.js.map +1 -1
  63. package/dist/roap/request.js +45 -79
  64. package/dist/roap/request.js.map +1 -1
  65. package/dist/roap/turnDiscovery.js +3 -6
  66. package/dist/roap/turnDiscovery.js.map +1 -1
  67. package/dist/{common/errors/parameter.d.ts → types/common/errors/webinar-registration-error.d.ts} +4 -5
  68. package/dist/types/config.d.ts +2 -0
  69. package/dist/types/constants.d.ts +25 -0
  70. package/dist/types/controls-options-manager/enums.d.ts +2 -1
  71. package/dist/types/controls-options-manager/index.d.ts +2 -1
  72. package/dist/types/controls-options-manager/types.d.ts +2 -0
  73. package/dist/types/index.d.ts +2 -1
  74. package/dist/types/locus-info/index.d.ts +9 -0
  75. package/dist/types/meeting/in-meeting-actions.d.ts +18 -0
  76. package/dist/types/meeting/index.d.ts +14 -3
  77. package/dist/types/meeting/locusMediaRequest.d.ts +2 -3
  78. package/dist/types/meeting/muteState.d.ts +2 -1
  79. package/dist/types/meeting/request.d.ts +2 -2
  80. package/dist/types/meeting/util.d.ts +2 -2
  81. package/dist/types/meeting-info/meeting-info-v2.d.ts +23 -0
  82. package/dist/types/meetings/index.d.ts +10 -1
  83. package/dist/types/members/index.d.ts +2 -1
  84. package/dist/types/members/util.d.ts +3 -1
  85. package/dist/types/metrics/constants.d.ts +1 -0
  86. package/dist/types/multistream/remoteMedia.d.ts +1 -0
  87. package/dist/types/reachability/clusterReachability.d.ts +1 -10
  88. package/dist/types/reachability/index.d.ts +74 -35
  89. package/dist/types/reachability/reachability.types.d.ts +64 -0
  90. package/dist/types/reachability/request.d.ts +5 -1
  91. package/dist/types/roap/request.d.ts +1 -13
  92. package/dist/webinar/index.js +32 -19
  93. package/dist/webinar/index.js.map +1 -1
  94. package/package.json +22 -22
  95. package/src/common/errors/webinar-registration-error.ts +27 -0
  96. package/src/config.ts +2 -0
  97. package/src/constants.ts +31 -0
  98. package/src/controls-options-manager/enums.ts +1 -0
  99. package/src/controls-options-manager/index.ts +19 -2
  100. package/src/controls-options-manager/types.ts +2 -0
  101. package/src/controls-options-manager/util.ts +12 -0
  102. package/src/index.ts +2 -0
  103. package/src/locus-info/controlsUtils.ts +46 -2
  104. package/src/locus-info/fullState.ts +1 -0
  105. package/src/locus-info/index.ts +60 -0
  106. package/src/locus-info/parser.ts +8 -1
  107. package/src/meeting/in-meeting-actions.ts +37 -0
  108. package/src/meeting/index.ts +154 -22
  109. package/src/meeting/locusMediaRequest.ts +4 -8
  110. package/src/meeting/muteState.ts +6 -2
  111. package/src/meeting/request.ts +4 -11
  112. package/src/meeting/util.ts +30 -6
  113. package/src/meeting-info/meeting-info-v2.ts +51 -0
  114. package/src/meetings/index.ts +68 -40
  115. package/src/members/index.ts +4 -2
  116. package/src/members/util.ts +3 -1
  117. package/src/metrics/constants.ts +1 -0
  118. package/src/multistream/remoteMedia.ts +5 -0
  119. package/src/reachability/clusterReachability.ts +1 -14
  120. package/src/reachability/index.ts +285 -77
  121. package/src/reachability/reachability.types.ts +85 -0
  122. package/src/reachability/request.ts +55 -30
  123. package/src/roap/index.ts +4 -5
  124. package/src/roap/request.ts +32 -44
  125. package/src/roap/turnDiscovery.ts +2 -4
  126. package/src/webinar/index.ts +31 -17
  127. package/test/unit/spec/controls-options-manager/index.js +56 -32
  128. package/test/unit/spec/controls-options-manager/util.js +44 -0
  129. package/test/unit/spec/locus-info/controlsUtils.js +80 -4
  130. package/test/unit/spec/locus-info/index.js +88 -2
  131. package/test/unit/spec/meeting/in-meeting-actions.ts +18 -0
  132. package/test/unit/spec/meeting/index.js +272 -82
  133. package/test/unit/spec/meeting/locusMediaRequest.ts +18 -11
  134. package/test/unit/spec/meeting/muteState.js +8 -4
  135. package/test/unit/spec/meeting/request.js +3 -26
  136. package/test/unit/spec/meeting/utils.js +69 -14
  137. package/test/unit/spec/meeting-info/meetinginfov2.js +37 -0
  138. package/test/unit/spec/meetings/index.js +32 -1
  139. package/test/unit/spec/members/index.js +25 -2
  140. package/test/unit/spec/members/request.js +37 -3
  141. package/test/unit/spec/members/utils.js +15 -1
  142. package/test/unit/spec/multistream/remoteMedia.ts +16 -2
  143. package/test/unit/spec/reachability/index.ts +265 -1
  144. package/test/unit/spec/reachability/request.js +56 -15
  145. package/test/unit/spec/roap/index.ts +1 -1
  146. package/test/unit/spec/roap/request.ts +51 -109
  147. package/test/unit/spec/roap/turnDiscovery.ts +202 -147
  148. package/test/unit/spec/webinar/index.ts +82 -16
  149. package/dist/annotation/annotation.types.d.ts +0 -42
  150. package/dist/annotation/constants.d.ts +0 -31
  151. package/dist/annotation/index.d.ts +0 -117
  152. package/dist/breakouts/breakout.d.ts +0 -8
  153. package/dist/breakouts/collection.d.ts +0 -5
  154. package/dist/breakouts/edit-lock-error.d.ts +0 -15
  155. package/dist/breakouts/events.d.ts +0 -8
  156. package/dist/breakouts/index.d.ts +0 -5
  157. package/dist/breakouts/request.d.ts +0 -22
  158. package/dist/breakouts/utils.d.ts +0 -15
  159. package/dist/common/browser-detection.d.ts +0 -9
  160. package/dist/common/collection.d.ts +0 -48
  161. package/dist/common/config.d.ts +0 -2
  162. package/dist/common/errors/captcha-error.d.ts +0 -15
  163. package/dist/common/errors/intent-to-join.d.ts +0 -16
  164. package/dist/common/errors/join-meeting.d.ts +0 -17
  165. package/dist/common/errors/media.d.ts +0 -15
  166. package/dist/common/errors/no-meeting-info.d.ts +0 -14
  167. package/dist/common/errors/password-error.d.ts +0 -15
  168. package/dist/common/errors/permission.d.ts +0 -14
  169. package/dist/common/errors/reclaim-host-role-error.js +0 -149
  170. package/dist/common/errors/reclaim-host-role-error.js.map +0 -1
  171. package/dist/common/errors/reclaim-host-role-errors.d.ts +0 -60
  172. package/dist/common/errors/reconnection-in-progress.d.ts +0 -9
  173. package/dist/common/errors/reconnection-in-progress.js +0 -33
  174. package/dist/common/errors/reconnection-in-progress.js.map +0 -1
  175. package/dist/common/errors/reconnection.d.ts +0 -15
  176. package/dist/common/errors/stats.d.ts +0 -15
  177. package/dist/common/errors/webex-errors.d.ts +0 -93
  178. package/dist/common/errors/webex-meetings-error.d.ts +0 -20
  179. package/dist/common/events/events-scope.d.ts +0 -17
  180. package/dist/common/events/events.d.ts +0 -12
  181. package/dist/common/events/trigger-proxy.d.ts +0 -2
  182. package/dist/common/events/util.d.ts +0 -2
  183. package/dist/common/logs/logger-config.d.ts +0 -2
  184. package/dist/common/logs/logger-proxy.d.ts +0 -2
  185. package/dist/common/logs/request.d.ts +0 -36
  186. package/dist/common/queue.d.ts +0 -34
  187. package/dist/config.d.ts +0 -72
  188. package/dist/constants.d.ts +0 -1088
  189. package/dist/controls-options-manager/constants.d.ts +0 -4
  190. package/dist/controls-options-manager/enums.d.ts +0 -15
  191. package/dist/controls-options-manager/index.d.ts +0 -136
  192. package/dist/controls-options-manager/types.d.ts +0 -43
  193. package/dist/controls-options-manager/util.d.ts +0 -1
  194. package/dist/index.d.ts +0 -7
  195. package/dist/interceptors/index.d.ts +0 -2
  196. package/dist/interceptors/locusRetry.d.ts +0 -27
  197. package/dist/interpretation/collection.d.ts +0 -5
  198. package/dist/interpretation/index.d.ts +0 -5
  199. package/dist/interpretation/siLanguage.d.ts +0 -5
  200. package/dist/locus-info/controlsUtils.d.ts +0 -2
  201. package/dist/locus-info/embeddedAppsUtils.d.ts +0 -2
  202. package/dist/locus-info/fullState.d.ts +0 -2
  203. package/dist/locus-info/hostUtils.d.ts +0 -2
  204. package/dist/locus-info/index.d.ts +0 -322
  205. package/dist/locus-info/infoUtils.d.ts +0 -2
  206. package/dist/locus-info/mediaSharesUtils.d.ts +0 -2
  207. package/dist/locus-info/parser.d.ts +0 -272
  208. package/dist/locus-info/selfUtils.d.ts +0 -2
  209. package/dist/media/index.d.ts +0 -34
  210. package/dist/media/properties.d.ts +0 -93
  211. package/dist/media/util.d.ts +0 -2
  212. package/dist/mediaQualityMetrics/config.d.ts +0 -241
  213. package/dist/mediaQualityMetrics/config.js +0 -502
  214. package/dist/mediaQualityMetrics/config.js.map +0 -1
  215. package/dist/meeting/effectsState.js +0 -260
  216. package/dist/meeting/effectsState.js.map +0 -1
  217. package/dist/meeting/in-meeting-actions.d.ts +0 -167
  218. package/dist/meeting/index.d.ts +0 -1825
  219. package/dist/meeting/locusMediaRequest.d.ts +0 -74
  220. package/dist/meeting/muteState.d.ts +0 -178
  221. package/dist/meeting/request.d.ts +0 -295
  222. package/dist/meeting/request.type.d.ts +0 -11
  223. package/dist/meeting/state.d.ts +0 -9
  224. package/dist/meeting/util.d.ts +0 -119
  225. package/dist/meeting/voicea-meeting.d.ts +0 -16
  226. package/dist/meeting-info/collection.d.ts +0 -20
  227. package/dist/meeting-info/index.d.ts +0 -69
  228. package/dist/meeting-info/meeting-info-v2.d.ts +0 -123
  229. package/dist/meeting-info/request.d.ts +0 -22
  230. package/dist/meeting-info/util.d.ts +0 -2
  231. package/dist/meeting-info/utilv2.d.ts +0 -2
  232. package/dist/meetings/collection.d.ts +0 -40
  233. package/dist/meetings/index.d.ts +0 -390
  234. package/dist/meetings/meetings.types.d.ts +0 -4
  235. package/dist/meetings/request.d.ts +0 -27
  236. package/dist/meetings/util.d.ts +0 -18
  237. package/dist/member/index.d.ts +0 -160
  238. package/dist/member/member.types.js +0 -17
  239. package/dist/member/member.types.js.map +0 -1
  240. package/dist/member/types.d.ts +0 -32
  241. package/dist/member/util.d.ts +0 -2
  242. package/dist/members/collection.d.ts +0 -29
  243. package/dist/members/index.d.ts +0 -353
  244. package/dist/members/request.d.ts +0 -114
  245. package/dist/members/types.d.ts +0 -25
  246. package/dist/members/util.d.ts +0 -215
  247. package/dist/metrics/config.js +0 -276
  248. package/dist/metrics/config.js.map +0 -1
  249. package/dist/metrics/constants.d.ts +0 -70
  250. package/dist/metrics/index.d.ts +0 -45
  251. package/dist/multistream/mediaRequestManager.d.ts +0 -119
  252. package/dist/multistream/receiveSlot.d.ts +0 -68
  253. package/dist/multistream/receiveSlotManager.d.ts +0 -56
  254. package/dist/multistream/remoteMedia.d.ts +0 -72
  255. package/dist/multistream/remoteMediaGroup.d.ts +0 -49
  256. package/dist/multistream/remoteMediaManager.d.ts +0 -300
  257. package/dist/multistream/sendSlotManager.d.ts +0 -69
  258. package/dist/networkQualityMonitor/index.d.ts +0 -70
  259. package/dist/networkQualityMonitor/index.js +0 -221
  260. package/dist/networkQualityMonitor/index.js.map +0 -1
  261. package/dist/peer-connection-manager/index.js +0 -671
  262. package/dist/peer-connection-manager/index.js.map +0 -1
  263. package/dist/peer-connection-manager/util.js +0 -109
  264. package/dist/peer-connection-manager/util.js.map +0 -1
  265. package/dist/personal-meeting-room/index.d.ts +0 -47
  266. package/dist/personal-meeting-room/request.d.ts +0 -14
  267. package/dist/personal-meeting-room/util.d.ts +0 -2
  268. package/dist/reachability/clusterReachability.d.ts +0 -109
  269. package/dist/reachability/index.d.ts +0 -105
  270. package/dist/reachability/request.d.ts +0 -39
  271. package/dist/reachability/util.d.ts +0 -8
  272. package/dist/reactions/constants.d.ts +0 -3
  273. package/dist/reactions/reactions.d.ts +0 -4
  274. package/dist/reactions/reactions.type.d.ts +0 -52
  275. package/dist/reconnection-manager/index.d.ts +0 -136
  276. package/dist/recording-controller/enums.d.ts +0 -7
  277. package/dist/recording-controller/index.d.ts +0 -207
  278. package/dist/recording-controller/util.d.ts +0 -14
  279. package/dist/roap/collection.js +0 -62
  280. package/dist/roap/collection.js.map +0 -1
  281. package/dist/roap/handler.js +0 -275
  282. package/dist/roap/handler.js.map +0 -1
  283. package/dist/roap/index.d.ts +0 -86
  284. package/dist/roap/request.d.ts +0 -39
  285. package/dist/roap/state.js +0 -126
  286. package/dist/roap/state.js.map +0 -1
  287. package/dist/roap/turnDiscovery.d.ts +0 -155
  288. package/dist/roap/util.js +0 -75
  289. package/dist/roap/util.js.map +0 -1
  290. package/dist/rtcMetrics/constants.d.ts +0 -4
  291. package/dist/rtcMetrics/constants.js.map +0 -1
  292. package/dist/rtcMetrics/index.d.ts +0 -61
  293. package/dist/rtcMetrics/index.js +0 -197
  294. package/dist/rtcMetrics/index.js.map +0 -1
  295. package/dist/statsAnalyzer/global.d.ts +0 -36
  296. package/dist/statsAnalyzer/global.js +0 -126
  297. package/dist/statsAnalyzer/global.js.map +0 -1
  298. package/dist/statsAnalyzer/index.d.ts +0 -217
  299. package/dist/statsAnalyzer/index.js +0 -1013
  300. package/dist/statsAnalyzer/index.js.map +0 -1
  301. package/dist/statsAnalyzer/mqaUtil.d.ts +0 -48
  302. package/dist/statsAnalyzer/mqaUtil.js +0 -179
  303. package/dist/statsAnalyzer/mqaUtil.js.map +0 -1
  304. package/dist/transcription/index.d.ts +0 -64
  305. package/dist/types/common/errors/reconnection-in-progress.d.ts +0 -9
  306. package/dist/types/mediaQualityMetrics/config.d.ts +0 -241
  307. package/dist/types/networkQualityMonitor/index.d.ts +0 -70
  308. package/dist/types/rtcMetrics/constants.d.ts +0 -4
  309. package/dist/types/rtcMetrics/index.d.ts +0 -71
  310. package/dist/types/statsAnalyzer/global.d.ts +0 -36
  311. package/dist/types/statsAnalyzer/index.d.ts +0 -217
  312. package/dist/types/statsAnalyzer/mqaUtil.d.ts +0 -48
  313. package/dist/webinar/collection.d.ts +0 -16
  314. package/dist/webinar/index.d.ts +0 -5
@@ -1234,7 +1234,7 @@ describe('gatherReachability', () => {
1234
1234
  assert.equal(receivedEvents['done'], 1);
1235
1235
 
1236
1236
  // and that ip network detection was started
1237
- assert.calledOnceWithExactly(webex.internal.device.ipNetworkDetector.detect);
1237
+ assert.calledOnceWithExactly(webex.internal.device.ipNetworkDetector.detect, true);
1238
1238
 
1239
1239
  // finally, check the metrics - they should contain values from ipNetworkDetector
1240
1240
  assert.calledWith(Metrics.sendBehavioralMetric, 'js_sdk_reachability_completed', {
@@ -1664,6 +1664,270 @@ describe('gatherReachability', () => {
1664
1664
 
1665
1665
  assert.neverCalledWith(clusterReachabilityCtorStub);
1666
1666
  });
1667
+
1668
+ describe('fallback mechanism and multiple calls to getClusters', () => {
1669
+ let receivedEvents;
1670
+
1671
+ const mockGetClustersEmptyResult = {
1672
+ discoveryOptions: {
1673
+ ['early-call-min-clusters']: 0,
1674
+ ['report-version']: 1,
1675
+ },
1676
+ clusters: {}, // empty cluster list
1677
+ joinCookie: {id: 'cookie'},
1678
+ };
1679
+
1680
+ beforeEach(() => {
1681
+ webex.config.meetings.experimental = {
1682
+ enableTcpReachability: true,
1683
+ enableTlsReachability: true,
1684
+ };
1685
+
1686
+ receivedEvents = {
1687
+ done: 0,
1688
+ };
1689
+ });
1690
+
1691
+ it('keeps retrying if minimum required clusters are not reached', async () => {
1692
+ const reachability = new Reachability(webex);
1693
+
1694
+ reachability.on('reachability:done', () => {
1695
+ receivedEvents.done += 1;
1696
+ });
1697
+
1698
+ const mockGetClustersResult1 = {
1699
+ discoveryOptions: {
1700
+ ['early-call-min-clusters']: 2,
1701
+ ['report-version']: 1,
1702
+ },
1703
+ clusters: {
1704
+ clusterA0: {
1705
+ udp: ['udp-urlA'],
1706
+ tcp: ['tcp-urlA'],
1707
+ xtls: ['xtls-urlA'],
1708
+ isVideoMesh: false,
1709
+ },
1710
+ clusterB0: {
1711
+ udp: ['udp-urlB'],
1712
+ tcp: ['tcp-urlB'],
1713
+ xtls: ['xtls-urlB'],
1714
+ isVideoMesh: false,
1715
+ },
1716
+ },
1717
+ joinCookie: {id: 'cookie1'},
1718
+ };
1719
+ const mockGetClustersResult2 = {
1720
+ discoveryOptions: {
1721
+ ['early-call-min-clusters']: 2,
1722
+ ['report-version']: 1,
1723
+ },
1724
+ clusters: {
1725
+ clusterA1: {
1726
+ udp: ['udp-urlA'],
1727
+ tcp: ['tcp-urlA'],
1728
+ xtls: ['xtls-urlA'],
1729
+ isVideoMesh: false,
1730
+ },
1731
+ clusterB1: {
1732
+ udp: ['udp-urlB'],
1733
+ tcp: ['tcp-urlB'],
1734
+ xtls: ['xtls-urlB'],
1735
+ isVideoMesh: false,
1736
+ },
1737
+ },
1738
+ joinCookie: {id: 'cookie2'},
1739
+ };
1740
+ const mockGetClustersResult3 = {
1741
+ discoveryOptions: {
1742
+ ['early-call-min-clusters']: 1,
1743
+ ['report-version']: 1,
1744
+ },
1745
+ clusters: {
1746
+ clusterA2: {
1747
+ udp: ['udp-urlA'],
1748
+ tcp: ['tcp-urlA'],
1749
+ xtls: ['xtls-urlA'],
1750
+ isVideoMesh: false,
1751
+ },
1752
+ clusterB2: {
1753
+ udp: ['udp-urlB'],
1754
+ tcp: ['tcp-urlB'],
1755
+ xtls: ['xtls-urlB'],
1756
+ isVideoMesh: false,
1757
+ },
1758
+ },
1759
+ joinCookie: {id: 'cookie3'},
1760
+ };
1761
+
1762
+ reachability.reachabilityRequest.getClusters = sinon.stub();
1763
+ reachability.reachabilityRequest.getClusters.onCall(0).returns(mockGetClustersResult1);
1764
+ reachability.reachabilityRequest.getClusters.onCall(1).returns(mockGetClustersResult2);
1765
+
1766
+ reachability.reachabilityRequest.getClusters.onCall(2).returns(mockGetClustersResult3);
1767
+
1768
+ const resultPromise = reachability.gatherReachability('test');
1769
+
1770
+ await testUtils.flushPromises();
1771
+
1772
+ // trigger some mock result events from ClusterReachability instances,
1773
+ // but only from 1 cluster, so not enough to reach the minimum required
1774
+ mockClusterReachabilityInstances['clusterA0'].emitFakeResult('udp', {
1775
+ result: 'reachable',
1776
+ clientMediaIPs: ['1.2.3.4'],
1777
+ latencyInMilliseconds: 11,
1778
+ });
1779
+
1780
+ clock.tick(3000);
1781
+ await resultPromise;
1782
+ await testUtils.flushPromises();
1783
+
1784
+ // because the minimum was not reached, another call to getClusters should be made
1785
+ assert.calledTwice(reachability.reachabilityRequest.getClusters);
1786
+
1787
+ // simulate no results this time
1788
+
1789
+ // check that while the 2nd attempt is in progress, the join cookie is already available from the 2nd call to getClusters
1790
+ const clientMediaPreferences = await reachability.getClientMediaPreferences(
1791
+ true,
1792
+ IP_VERSION.unknown
1793
+ );
1794
+
1795
+ assert.deepEqual(clientMediaPreferences.joinCookie, mockGetClustersResult2.joinCookie);
1796
+
1797
+ clock.tick(3000);
1798
+ await testUtils.flushPromises();
1799
+
1800
+ assert.calledThrice(reachability.reachabilityRequest.getClusters);
1801
+
1802
+ await testUtils.flushPromises();
1803
+
1804
+ // this time 1 result will be enough to reach the minimum
1805
+ mockClusterReachabilityInstances['clusterA2'].emitFakeResult('udp', {
1806
+ result: 'reachable',
1807
+ clientMediaIPs: ['1.2.3.4'],
1808
+ latencyInMilliseconds: 11,
1809
+ });
1810
+ clock.tick(3000);
1811
+
1812
+ // the reachability results should include only results from the last attempt
1813
+ await checkResults(
1814
+ {
1815
+ clusterA2: {
1816
+ udp: {result: 'reachable', clientMediaIPs: ['1.2.3.4'], latencyInMilliseconds: 11},
1817
+ tcp: {result: 'unreachable'},
1818
+ xtls: {result: 'unreachable'},
1819
+ isVideoMesh: false,
1820
+ },
1821
+ clusterB2: {
1822
+ udp: {result: 'unreachable'},
1823
+ tcp: {result: 'unreachable'},
1824
+ xtls: {result: 'unreachable'},
1825
+ isVideoMesh: false,
1826
+ },
1827
+ },
1828
+ mockGetClustersResult3.joinCookie
1829
+ );
1830
+
1831
+ // wait some more time to make sure that there are no timers that fire from one of the previous checks
1832
+ clock.tick(20000);
1833
+
1834
+ // as the first 2 attempts failed and didn't reach the overall timeout, there should be only 1 done event emitted
1835
+ assert.equal(receivedEvents.done, 1);
1836
+ });
1837
+
1838
+ it('handles getClusters() returning empty list on 1st call', async () => {
1839
+ const reachability = new Reachability(webex);
1840
+
1841
+ reachability.on('reachability:done', () => {
1842
+ receivedEvents.done += 1;
1843
+ });
1844
+
1845
+ reachability.reachabilityRequest.getClusters = sinon
1846
+ .stub()
1847
+ .resolves(mockGetClustersEmptyResult);
1848
+
1849
+ const resultPromise = reachability.gatherReachability('test');
1850
+
1851
+ await testUtils.flushPromises();
1852
+
1853
+ clock.tick(3000);
1854
+ await resultPromise;
1855
+ await testUtils.flushPromises();
1856
+
1857
+ assert.calledOnce(reachability.reachabilityRequest.getClusters);
1858
+ reachability.reachabilityRequest.getClusters.resetHistory();
1859
+
1860
+ assert.equal(receivedEvents.done, 1);
1861
+ await checkResults({}, mockGetClustersEmptyResult.joinCookie);
1862
+
1863
+ // because we didn't actually test anything (we got empty cluster list from getClusters()), we should
1864
+ // not say that webex backend is unreachable
1865
+ assert.equal(await reachability.isWebexMediaBackendUnreachable(), false);
1866
+
1867
+ // wait to check that there are no other things happening
1868
+ clock.tick(20000);
1869
+ await testUtils.flushPromises();
1870
+
1871
+ assert.notCalled(reachability.reachabilityRequest.getClusters);
1872
+ assert.equal(receivedEvents.done, 1);
1873
+ });
1874
+
1875
+ it('handles getClusters() returning empty list on 2nd call', async () => {
1876
+ const reachability = new Reachability(webex);
1877
+
1878
+ reachability.on('reachability:done', () => {
1879
+ receivedEvents.done += 1;
1880
+ });
1881
+
1882
+ const mockGetClustersResult1 = {
1883
+ discoveryOptions: {
1884
+ ['early-call-min-clusters']: 2,
1885
+ ['report-version']: 1,
1886
+ },
1887
+ clusters: {
1888
+ clusterA0: {
1889
+ udp: ['udp-urlA'],
1890
+ tcp: ['tcp-urlA'],
1891
+ xtls: ['xtls-urlA'],
1892
+ isVideoMesh: false,
1893
+ },
1894
+ clusterB0: {
1895
+ udp: ['udp-urlB'],
1896
+ tcp: ['tcp-urlB'],
1897
+ xtls: ['xtls-urlB'],
1898
+ isVideoMesh: false,
1899
+ },
1900
+ },
1901
+ joinCookie: {id: 'cookie1'},
1902
+ };
1903
+
1904
+ reachability.reachabilityRequest.getClusters = sinon.stub();
1905
+ reachability.reachabilityRequest.getClusters.onCall(0).returns(mockGetClustersResult1);
1906
+ reachability.reachabilityRequest.getClusters.onCall(1).returns(mockGetClustersEmptyResult);
1907
+
1908
+ const resultPromise = reachability.gatherReachability('test');
1909
+
1910
+ await testUtils.flushPromises();
1911
+
1912
+ clock.tick(3000);
1913
+ await resultPromise;
1914
+ await testUtils.flushPromises();
1915
+
1916
+ // because the minimum was not reached, another call to getClusters should be made
1917
+ assert.calledTwice(reachability.reachabilityRequest.getClusters);
1918
+
1919
+ // the reachability results should include only results from the last attempt
1920
+ await checkResults({}, mockGetClustersEmptyResult.joinCookie);
1921
+
1922
+ // as the first 2 attempts failed and didn't reach the overall timeout, there should be only 1 done event emitted
1923
+ assert.equal(receivedEvents.done, 1);
1924
+ // because we didn't actually test anything (we got empty cluster list from getClusters()), we should
1925
+ // not say that webex backend is unreachable
1926
+ assert.equal(await reachability.isWebexMediaBackendUnreachable(), false);
1927
+ });
1928
+ });
1929
+
1930
+
1667
1931
  });
1668
1932
 
1669
1933
  describe('getReachabilityResults', () => {
@@ -35,16 +35,11 @@ describe('plugin-meetings/reachability', () => {
35
35
  });
36
36
 
37
37
  describe('#getClusters', () => {
38
+ let previousReport;
38
39
 
39
40
  beforeEach(() => {
40
41
  sinon.spy(webex.internal.newMetrics.callDiagnosticLatencies, 'measureLatency');
41
- });
42
42
 
43
- afterEach(() => {
44
- sinon.restore();
45
- });
46
-
47
- it('sends a GET request with the correct params', async () => {
48
43
  webex.request = sinon.mock().returns(Promise.resolve({
49
44
  body: {
50
45
  clusterClasses: {
@@ -57,21 +52,67 @@ describe('plugin-meetings/reachability', () => {
57
52
  }
58
53
  }));
59
54
 
60
- const res = await reachabilityRequest.getClusters(IP_VERSION.only_ipv4);
61
- const requestParams = webex.request.getCall(0).args[0];
55
+ webex.config.meetings.reachabilityGetClusterTimeout = 3000;
62
56
 
63
- assert.equal(requestParams.method, 'GET');
64
- assert.equal(requestParams.resource, `clusters`);
65
- assert.equal(requestParams.api, 'calliopeDiscovery');
66
- assert.equal(requestParams.shouldRefreshAccessToken, false);
57
+ previousReport = {
58
+ id: 'fake previous report',
59
+ }
60
+ });
61
+
62
+ afterEach(() => {
63
+ sinon.restore();
64
+ });
65
+
66
+ it('sends a POST request with the correct params when trigger is "startup"', async () => {
67
+ const res = await reachabilityRequest.getClusters('startup', IP_VERSION.only_ipv4, previousReport);
68
+ const requestParams = webex.request.getCall(0).args[0];
67
69
 
68
- assert.deepEqual(requestParams.qs, {
69
- JCSupport: 1,
70
- ipver: 4,
70
+ assert.deepEqual(requestParams, {
71
+ method: 'POST',
72
+ resource: `clusters`,
73
+ api: 'calliopeDiscovery',
74
+ shouldRefreshAccessToken: false,
75
+ timeout: 3000,
76
+ body: {
77
+ ipver: IP_VERSION.only_ipv4,
78
+ 'supported-options': {
79
+ 'report-version': 1,
80
+ 'early-call-min-clusters': true,
81
+ },
82
+ 'previous-report': previousReport,
83
+ trigger: 'startup',
84
+ },
71
85
  });
86
+
72
87
  assert.deepEqual(res.clusters.clusterId, {udp: "testUDP", isVideoMesh: true})
73
88
  assert.deepEqual(res.joinCookie, {anycastEntryPoint: "aws-eu-west-1"})
74
89
  assert.calledOnceWithExactly(webex.internal.newMetrics.callDiagnosticLatencies.measureLatency, sinon.match.func, 'internal.get.cluster.time');
75
90
  });
91
+
92
+ it('sends a POST request with the correct params when trigger is other than "startup"', async () => {
93
+ const res = await reachabilityRequest.getClusters('early-call/no-min-reached', IP_VERSION.only_ipv4, previousReport);
94
+ const requestParams = webex.request.getCall(0).args[0];
95
+
96
+ assert.deepEqual(requestParams, {
97
+ method: 'POST',
98
+ resource: `clusters`,
99
+ api: 'calliopeDiscovery',
100
+ shouldRefreshAccessToken: false,
101
+ timeout: 3000,
102
+ body: {
103
+ ipver: IP_VERSION.only_ipv4,
104
+ 'supported-options': {
105
+ 'report-version': 1,
106
+ 'early-call-min-clusters': true,
107
+ },
108
+ 'previous-report': previousReport,
109
+ trigger: 'early-call/no-min-reached',
110
+ },
111
+ });
112
+
113
+ assert.deepEqual(res.clusters.clusterId, {udp: "testUDP", isVideoMesh: true})
114
+ assert.deepEqual(res.joinCookie, {anycastEntryPoint: "aws-eu-west-1"})
115
+ assert.notCalled(webex.internal.newMetrics.callDiagnosticLatencies.measureLatency);
116
+ });
76
117
  });
77
118
  });
@@ -161,7 +161,7 @@ describe('Roap', () => {
161
161
  roapMessage: expectedRoapMessage,
162
162
  locusSelfUrl: meeting.selfUrl,
163
163
  mediaId: meeting.mediaId,
164
- meetingId: meeting.id,
164
+ isMultistream: meeting.isMultistream,
165
165
  locusMediaRequest: meeting.locusMediaRequest,
166
166
  })
167
167
  );
@@ -4,6 +4,7 @@ import {assert} from '@webex/test-helper-chai';
4
4
  import MockWebex from '@webex/test-helper-mock-webex';
5
5
  import Meetings from '@webex/plugin-meetings';
6
6
  import RoapRequest from '@webex/plugin-meetings/src/roap/request';
7
+ import MeetingUtil from '@webex/plugin-meetings/src/meeting/util';
7
8
  import {IP_VERSION, REACHABILITY} from '@webex/plugin-meetings/src/constants';
8
9
 
9
10
  describe('plugin-meetings/roap', () => {
@@ -23,6 +24,11 @@ describe('plugin-meetings/roap', () => {
23
24
  regionCode: 'WEST-COAST',
24
25
  };
25
26
 
27
+ webex.meetings.reachability = {
28
+ getReachabilityReportToAttachToRoap: sinon.stub().resolves({}),
29
+ getClientMediaPreferences: sinon.stub().resolves({}),
30
+ };
31
+
26
32
  webex.internal = {
27
33
  services: {
28
34
  get: sinon.mock().returns(locusUrl),
@@ -36,6 +42,8 @@ describe('plugin-meetings/roap', () => {
36
42
  },
37
43
  };
38
44
 
45
+ sinon.stub(MeetingUtil, 'getIpVersion').returns(IP_VERSION.ipv4_and_ipv6);
46
+
39
47
  // @ts-ignore
40
48
  roapRequest = new RoapRequest({webex});
41
49
 
@@ -74,146 +82,80 @@ describe('plugin-meetings/roap', () => {
74
82
  );
75
83
  });
76
84
 
77
- describe('#attachReachabilityData', () => {
78
- it('returns the correct reachability data', async () => {
79
- const res = await roapRequest.attachReachabilityData({});
80
-
81
- assert.deepEqual(res.localSdp, {
82
- reachability: {
83
- clusterId: {
84
- udp: {
85
- reachable: 'true',
86
- latencyInMilliseconds: '10',
87
- },
88
- tcp: {
89
- reachable: 'false',
90
- },
91
- xtls: {
92
- untested: 'true',
93
- }
94
- },
95
- },
96
- });
97
- assert.deepEqual(res.joinCookie, {
98
- anycastEntryPoint: 'aws-eu-west-1',
99
- });
100
- });
85
+ afterEach(() => {
86
+ sinon.restore();
87
+ })
101
88
 
102
- it('handles the case when reachability data does not exist', async () => {
103
- await webex.boundedStorage.del(REACHABILITY.namespace, REACHABILITY.localStorageJoinCookie);
89
+ describe('sendRoap', () => {
90
+ it('includes clientMediaPreferences and reachability in the request correctly', async () => {
91
+ const locusMediaRequest = {send: sinon.stub().resolves({body: {locus: {}}})};
104
92
 
105
- await webex.boundedStorage.del(REACHABILITY.namespace, REACHABILITY.localStorageResult);
106
- const sdp = {
107
- some: 'attribute',
93
+ const FAKE_REACHABILITY_REPORT = {
94
+ id: 'fake reachability report',
95
+ };
96
+ const FAKE_CLIENT_MEDIA_PREFERENCES = {
97
+ id: 'fake client media preferences',
108
98
  };
109
99
 
110
- const result = await roapRequest.attachReachabilityData(sdp);
111
-
112
- assert.deepEqual(result, {
113
- joinCookie: undefined,
114
- localSdp: {
115
- some: 'attribute',
116
- },
117
- });
118
- });
119
- });
120
-
121
- describe('sendRoap', () => {
122
- it('includes joinCookie in the request correctly', async () => {
123
- const locusMediaRequest = {send: sinon.stub().resolves({body: {locus: {}}})};
124
- const ipVersion = IP_VERSION.unknown;
100
+ webex.meetings.reachability.getReachabilityReportToAttachToRoap.resolves(FAKE_REACHABILITY_REPORT);
101
+ webex.meetings.reachability.getClientMediaPreferences.resolves(FAKE_CLIENT_MEDIA_PREFERENCES);
125
102
 
126
103
  await roapRequest.sendRoap({
127
104
  locusSelfUrl: locusUrl,
128
- ipVersion,
129
105
  mediaId: 'mediaId',
130
106
  roapMessage: {
131
107
  seq: 'seq',
132
108
  },
133
109
  meetingId: 'meeting-id',
110
+ isMultistream: true,
134
111
  locusMediaRequest,
135
112
  });
136
113
 
114
+ assert.calledOnceWithExactly(webex.meetings.reachability.getReachabilityReportToAttachToRoap);
115
+ assert.calledOnceWithExactly(webex.meetings.reachability.getClientMediaPreferences, true, IP_VERSION.ipv4_and_ipv6);
116
+
137
117
  const requestParams = locusMediaRequest.send.getCall(0).args[0];
138
118
  assert.deepEqual(requestParams, {
139
119
  type: 'RoapMessage',
140
120
  selfUrl: locusUrl,
141
- ipVersion,
142
- joinCookie: {
143
- anycastEntryPoint: 'aws-eu-west-1',
144
- },
121
+ clientMediaPreferences: FAKE_CLIENT_MEDIA_PREFERENCES,
145
122
  mediaId: 'mediaId',
146
123
  roapMessage: {
147
124
  seq: 'seq',
148
125
  },
149
- reachability: {
150
- clusterId: {
151
- tcp: {
152
- reachable: 'false',
153
- },
154
- udp: {
155
- latencyInMilliseconds: '10',
156
- reachable: 'true',
157
- },
158
- xtls: {
159
- untested: 'true',
160
- },
161
- },
162
- },
126
+ reachability: FAKE_REACHABILITY_REPORT,
163
127
  });
164
128
  });
165
- });
166
129
 
167
- it('calls attachReachabilityData when sendRoap', async () => {
168
- const locusMediaRequest = { send: sinon.stub().resolves({body: {locus: {}}})};
130
+ it('includes default clientMediaPreferences if calls to reachability fail', async () => {
131
+ const locusMediaRequest = {send: sinon.stub().resolves({body: {locus: {}}})};
169
132
 
170
- const newSdp = {
171
- new: 'sdp',
172
- reachability: { someResult: 'whatever' }
173
- };
174
- const ipVersion = IP_VERSION.only_ipv6;
133
+ webex.meetings.reachability.getClientMediaPreferences.rejects(new Error('fake error'));
175
134
 
176
- roapRequest.attachReachabilityData = sinon.stub().returns(
177
- Promise.resolve({
178
- localSdp: newSdp,
179
- joinCookie: {
180
- anycastEntryPoint: 'aws-eu-west-1',
135
+ await roapRequest.sendRoap({
136
+ locusSelfUrl: locusUrl,
137
+ mediaId: 'mediaId',
138
+ roapMessage: {
139
+ seq: 'seq',
181
140
  },
182
- })
183
- );
184
-
185
- await roapRequest.sendRoap({
186
- roapMessage: {
187
- seq: 1,
188
- },
189
- locusSelfUrl: 'locusSelfUrl',
190
- ipVersion,
191
- mediaId: 'mediaId',
192
- meetingId: 'meetingId',
193
- preferTranscoding: true,
194
- locusMediaRequest
195
- });
196
-
197
- const requestParams = locusMediaRequest.send.getCall(0).args[0];
141
+ meetingId: 'meeting-id',
142
+ isMultistream: true,
143
+ locusMediaRequest,
144
+ });
198
145
 
199
- assert.deepEqual(requestParams, {
200
- type: 'RoapMessage',
201
- selfUrl: 'locusSelfUrl',
202
- ipVersion,
203
- joinCookie: {
204
- anycastEntryPoint: 'aws-eu-west-1',
205
- },
206
- mediaId: 'mediaId',
207
- roapMessage: {
208
- seq: 1,
209
- },
210
- reachability: { someResult: 'whatever' },
211
- });
146
+ assert.calledOnce(webex.meetings.reachability.getClientMediaPreferences);
212
147
 
213
- assert.calledOnceWithExactly(roapRequest.attachReachabilityData, {
214
- roapMessage: {
215
- seq: 1,
216
- },
148
+ const requestParams = locusMediaRequest.send.getCall(0).args[0];
149
+ assert.deepEqual(requestParams, {
150
+ type: 'RoapMessage',
151
+ selfUrl: locusUrl,
152
+ clientMediaPreferences: {ipver: 0, joinCookie: undefined, preferTranscoding: false},
153
+ mediaId: 'mediaId',
154
+ roapMessage: {
155
+ seq: 'seq',
156
+ },
157
+ reachability: undefined,
158
+ });
217
159
  });
218
160
  });
219
161
  });