@webex/plugin-meetings 3.6.0 → 3.7.0-next.2

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 +4 -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 +762 -528
  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 +98 -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 +3 -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 +33 -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 +3 -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 +219 -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 +31 -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 +329 -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 +71 -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
@@ -34,12 +34,19 @@ describe('LocusMediaRequest.send()', () => {
34
34
  'wjfkm.wjfkm.*': {udp:{reachable: true}, tcp:{reachable:false}},
35
35
  '1eb65fdf-9643-417f-9974-ad72cae0e10f.59268c12-7a04-4b23-a1a1-4c74be03019a.*': {udp:{reachable: false}, tcp:{reachable:true}},
36
36
  },
37
- joinCookie: {
38
- anycastEntryPoint: 'aws-eu-west-1',
39
- clientIpAddress: 'some ip',
40
- timeShot: '2023-05-23T08:03:49Z',
41
- },
42
- ipVersion: IP_VERSION.only_ipv4,
37
+ clientMediaPreferences: {
38
+ preferTranscoding: false,
39
+ joinCookie: {
40
+ anycastEntryPoint: 'aws-eu-west-1',
41
+ clientIpAddress: 'some ip',
42
+ timeShot: '2023-05-23T08:03:49Z',
43
+ },
44
+ ipver: IP_VERSION.only_ipv4,
45
+ reachability: {
46
+ version: '1',
47
+ result: 'some fake reachability result',
48
+ }
49
+ }
43
50
  };
44
51
 
45
52
  const createExpectedRoapBody = (expectedMessageType, expectedMute:{audioMuted: boolean, videoMuted: boolean}) => {
@@ -53,12 +60,16 @@ describe('LocusMediaRequest.send()', () => {
53
60
  }
54
61
  ],
55
62
  clientMediaPreferences: {
56
- preferTranscoding: true,
63
+ preferTranscoding: false,
57
64
  ipver: 4,
58
65
  joinCookie: {
59
66
  anycastEntryPoint: 'aws-eu-west-1',
60
67
  clientIpAddress: 'some ip',
61
68
  timeShot: '2023-05-23T08:03:49Z'
69
+ },
70
+ reachability: {
71
+ version: '1',
72
+ result: 'some fake reachability result',
62
73
  }
63
74
  }
64
75
  };
@@ -87,10 +98,6 @@ describe('LocusMediaRequest.send()', () => {
87
98
  localSdp: `{"audioMuted":${expectedMute.audioMuted},"videoMuted":${expectedMute.videoMuted}}`,
88
99
  },
89
100
  ],
90
- clientMediaPreferences: {
91
- preferTranscoding: true,
92
- ipver: undefined,
93
- },
94
101
  };
95
102
 
96
103
  if (sequence) {
@@ -151,7 +151,7 @@ describe('plugin-meetings', () => {
151
151
  meeting.mediaProperties.audioStream.setServerMuted = sinon.stub().callsFake((muted) => {
152
152
  meeting.mediaProperties.audioStream.userMuted = muted;
153
153
  });
154
- audio.handleServerLocalUnmuteRequired(meeting);
154
+ audio.handleServerLocalUnmuteRequired(meeting, true);
155
155
 
156
156
  await testUtils.flushPromises();
157
157
 
@@ -161,6 +161,8 @@ describe('plugin-meetings', () => {
161
161
  false,
162
162
  'localUnmuteRequired'
163
163
  );
164
+ // and unmuteAllowed was updated
165
+ assert.calledWith(meeting.mediaProperties.audioStream.setUnmuteAllowed, true);
164
166
 
165
167
  // and local unmute was sent to server
166
168
  assert.calledOnce(MeetingUtil.remoteUpdateAudioVideo);
@@ -184,7 +186,7 @@ describe('plugin-meetings', () => {
184
186
  meeting.mediaProperties.audioStream.setServerMuted = sinon.stub().callsFake((muted) => {
185
187
  meeting.mediaProperties.audioStream.userMuted = muted;
186
188
  });
187
- audio.handleServerLocalUnmuteRequired(meeting);
189
+ audio.handleServerLocalUnmuteRequired(meeting, true);
188
190
 
189
191
  await testUtils.flushPromises();
190
192
 
@@ -215,7 +217,7 @@ describe('plugin-meetings', () => {
215
217
  meeting.mediaProperties.videoStream.setServerMuted = sinon.stub().callsFake((muted) => {
216
218
  meeting.mediaProperties.videoStream.userMuted = muted;
217
219
  });
218
- video.handleServerLocalUnmuteRequired(meeting);
220
+ video.handleServerLocalUnmuteRequired(meeting, true);
219
221
 
220
222
  await testUtils.flushPromises();
221
223
 
@@ -225,6 +227,8 @@ describe('plugin-meetings', () => {
225
227
  false,
226
228
  'localUnmuteRequired'
227
229
  );
230
+ // and unmuteAllowed was updated
231
+ assert.calledWith(meeting.mediaProperties.videoStream.setUnmuteAllowed, true);
228
232
 
229
233
  // and local unmute was sent to server
230
234
  assert.calledOnce(MeetingUtil.remoteUpdateAudioVideo);
@@ -248,7 +252,7 @@ describe('plugin-meetings', () => {
248
252
  meeting.mediaProperties.videoStream.setServerMuted = sinon.stub().callsFake((muted) => {
249
253
  meeting.mediaProperties.videoStream.userMuted = muted;
250
254
  });
251
- video.handleServerLocalUnmuteRequired(meeting);
255
+ video.handleServerLocalUnmuteRequired(meeting, true);
252
256
 
253
257
  await testUtils.flushPromises();
254
258
 
@@ -196,6 +196,7 @@ describe('plugin-meetings', () => {
196
196
  const permissionToken = 'permission-token';
197
197
  const installationId = 'installationId';
198
198
  const reachability = 'reachability';
199
+ const clientMediaPreferences = 'clientMediaPreferences';
199
200
 
200
201
  await meetingsRequest.joinMeeting({
201
202
  locusUrl,
@@ -204,6 +205,7 @@ describe('plugin-meetings', () => {
204
205
  roapMessage,
205
206
  reachability,
206
207
  permissionToken,
208
+ clientMediaPreferences
207
209
  });
208
210
  const requestParams = meetingsRequest.request.getCall(0).args[0];
209
211
 
@@ -214,6 +216,7 @@ describe('plugin-meetings', () => {
214
216
  assert.equal(requestParams.body.device.countryCode, 'US');
215
217
  assert.equal(requestParams.body.permissionToken, 'permission-token');
216
218
  assert.equal(requestParams.body.device.regionCode, 'WEST-COAST');
219
+ assert.equal(requestParams.body.clientMediaPreferences, 'clientMediaPreferences');
217
220
  assert.include(requestParams.body.device.localIp, '127.0.0');
218
221
  assert.deepEqual(requestParams.body.localMedias, [
219
222
  {localSdp: '{"roapMessage":"roap-message","reachability":"reachability"}'},
@@ -386,32 +389,6 @@ describe('plugin-meetings', () => {
386
389
 
387
390
  assert.deepEqual(requestParams.body.alias, undefined);
388
391
  });
389
-
390
- it('includes joinCookie and ipver correctly', async () => {
391
- const locusUrl = 'locusURL';
392
- const deviceUrl = 'deviceUrl';
393
- const correlationId = 'random-uuid';
394
- const roapMessage = 'roap-message';
395
- const permissionToken = 'permission-token';
396
-
397
- await meetingsRequest.joinMeeting({
398
- locusUrl,
399
- deviceUrl,
400
- correlationId,
401
- roapMessage,
402
- permissionToken,
403
- ipVersion: IP_VERSION.ipv4_and_ipv6,
404
- });
405
- const requestParams = meetingsRequest.request.getCall(0).args[0];
406
-
407
- assert.equal(requestParams.method, 'POST');
408
- assert.equal(requestParams.uri, `${locusUrl}/participant?alternateRedirect=true`);
409
- assert.deepEqual(requestParams.body.clientMediaPreferences, {
410
- joinCookie: {anycastEntryPoint: 'aws-eu-west-1'},
411
- preferTranscoding: true,
412
- ipver: 1,
413
- });
414
- });
415
392
  });
416
393
 
417
394
  describe('#pstn', () => {
@@ -22,6 +22,12 @@ describe('plugin-meetings', () => {
22
22
  meetings: Meetings,
23
23
  },
24
24
  });
25
+
26
+ webex.meetings.reachability = {
27
+ getReachabilityReportToAttachToRoap: sinon.stub().resolves({}),
28
+ getClientMediaPreferences: sinon.stub().resolves({}),
29
+ };
30
+
25
31
  const logger = {
26
32
  info: sandbox.stub(),
27
33
  log: sandbox.stub(),
@@ -39,6 +45,7 @@ describe('plugin-meetings', () => {
39
45
  meeting.cleanupLocalStreams = sinon.stub().returns(Promise.resolve());
40
46
  meeting.closeRemoteStreams = sinon.stub().returns(Promise.resolve());
41
47
  meeting.closePeerConnections = sinon.stub().returns(Promise.resolve());
48
+ meeting.stopPeriodicLogUpload = sinon.stub();
42
49
 
43
50
  meeting.unsetRemoteStreams = sinon.stub();
44
51
  meeting.unsetPeerConnections = sinon.stub();
@@ -64,6 +71,7 @@ describe('plugin-meetings', () => {
64
71
  assert.calledOnce(meeting.cleanupLocalStreams);
65
72
  assert.calledOnce(meeting.closeRemoteStreams);
66
73
  assert.calledOnce(meeting.closePeerConnections);
74
+ assert.calledOnce(meeting.stopPeriodicLogUpload);
67
75
 
68
76
  assert.calledOnce(meeting.unsetRemoteStreams);
69
77
  assert.calledOnce(meeting.unsetPeerConnections);
@@ -408,17 +416,39 @@ describe('plugin-meetings', () => {
408
416
  });
409
417
 
410
418
  it('#Should call `meetingRequest.joinMeeting', async () => {
419
+ meeting.isMultistream = true;
420
+
421
+ const FAKE_REACHABILITY_REPORT = {
422
+ id: 'fake reachability report',
423
+ };
424
+ const FAKE_CLIENT_MEDIA_PREFERENCES = {
425
+ id: 'fake client media preferences',
426
+ };
427
+
428
+ webex.meetings.reachability.getReachabilityReportToAttachToRoap.resolves(FAKE_REACHABILITY_REPORT);
429
+ webex.meetings.reachability.getClientMediaPreferences.resolves(FAKE_CLIENT_MEDIA_PREFERENCES);
430
+
431
+ sinon
432
+ .stub(webex.internal.device.ipNetworkDetector, 'supportsIpV4')
433
+ .get(() => true);
434
+ sinon
435
+ .stub(webex.internal.device.ipNetworkDetector, 'supportsIpV6')
436
+ .get(() => true);
437
+
411
438
  await MeetingUtil.joinMeeting(meeting, {
412
439
  reachability: 'reachability',
413
440
  roapMessage: 'roapMessage',
414
441
  });
415
442
 
443
+ assert.calledOnceWithExactly(webex.meetings.reachability.getReachabilityReportToAttachToRoap);
444
+ assert.calledOnceWithExactly(webex.meetings.reachability.getClientMediaPreferences, meeting.isMultistream, IP_VERSION.ipv4_and_ipv6);
445
+
416
446
  assert.calledOnce(meeting.meetingRequest.joinMeeting);
417
447
  const parameter = meeting.meetingRequest.joinMeeting.getCall(0).args[0];
418
448
 
419
449
  assert.equal(parameter.inviteeAddress, 'meetingJoinUrl');
420
- assert.equal(parameter.preferTranscoding, true);
421
- assert.equal(parameter.reachability, 'reachability');
450
+ assert.equal(parameter.reachability, FAKE_REACHABILITY_REPORT);
451
+ assert.equal(parameter.clientMediaPreferences, FAKE_CLIENT_MEDIA_PREFERENCES);
422
452
  assert.equal(parameter.roapMessage, 'roapMessage');
423
453
 
424
454
  assert.calledOnce(meeting.setLocus)
@@ -445,6 +475,29 @@ describe('plugin-meetings', () => {
445
475
  });
446
476
  });
447
477
 
478
+ it('should handle failed reachability report retrieval', async () => {
479
+ webex.meetings.reachability.getReachabilityReportToAttachToRoap.rejects(
480
+ new Error('fake error')
481
+ );
482
+ await MeetingUtil.joinMeeting(meeting, {});
483
+ // Verify meeting join still proceeds
484
+ assert.calledOnce(meeting.meetingRequest.joinMeeting);
485
+ });
486
+
487
+ it('should handle failed clientMediaPreferences retrieval', async () => {
488
+ webex.meetings.reachability.getClientMediaPreferences.rejects(new Error('fake error'));
489
+ meeting.isMultistream = true;
490
+ await MeetingUtil.joinMeeting(meeting, {});
491
+ // Verify meeting join still proceeds
492
+ assert.calledOnce(meeting.meetingRequest.joinMeeting);
493
+ const parameter = meeting.meetingRequest.joinMeeting.getCall(0).args[0];
494
+ assert.deepEqual(parameter.clientMediaPreferences, {
495
+ preferTranscoding: false,
496
+ ipver: 0,
497
+ joinCookie: undefined,
498
+ });
499
+ });
500
+
448
501
  it('#Should call meetingRequest.joinMeeting with breakoutsSupported=true when passed in as true', async () => {
449
502
  await MeetingUtil.joinMeeting(meeting, {
450
503
  breakoutsSupported: true,
@@ -480,17 +533,6 @@ describe('plugin-meetings', () => {
480
533
  assert.deepEqual(parameter.deviceCapabilities, ['TEST']);
481
534
  });
482
535
 
483
- it('#Should call meetingRequest.joinMeeting with preferTranscoding=false when multistream is enabled', async () => {
484
- meeting.isMultistream = true;
485
- await MeetingUtil.joinMeeting(meeting, {});
486
-
487
- assert.calledOnce(meeting.meetingRequest.joinMeeting);
488
- const parameter = meeting.meetingRequest.joinMeeting.getCall(0).args[0];
489
-
490
- assert.equal(parameter.inviteeAddress, 'meetingJoinUrl');
491
- assert.equal(parameter.preferTranscoding, false);
492
- });
493
-
494
536
  it('#Should fallback sipUrl if meetingJoinUrl does not exists', async () => {
495
537
  meeting.meetingJoinUrl = undefined;
496
538
  meeting.sipUri = 'sipUri';
@@ -1013,7 +1055,21 @@ describe('plugin-meetings', () => {
1013
1055
  assert.equal(MeetingUtil.getIpVersion(webex), expectedOutput);
1014
1056
  });
1015
1057
 
1016
- it(`returns undefined when supportsIpV4=${supportsIpV4} and supportsIpV6=${supportsIpV6} and browser is firefox`, () => {
1058
+ it(`returns ${expectedOutput} when supportsIpV4=${supportsIpV4} and supportsIpV6=${supportsIpV6} for Firefox if config is enabled`, () => {
1059
+ sinon
1060
+ .stub(webex.internal.device.ipNetworkDetector, 'supportsIpV4')
1061
+ .get(() => supportsIpV4);
1062
+ sinon
1063
+ .stub(webex.internal.device.ipNetworkDetector, 'supportsIpV6')
1064
+ .get(() => supportsIpV6);
1065
+
1066
+ webex.config.meetings.backendIpv6NativeSupport = true;
1067
+ isBrowserStub.callsFake((name) => name === 'firefox');
1068
+
1069
+ assert.equal(MeetingUtil.getIpVersion(webex), expectedOutput);
1070
+ });
1071
+
1072
+ it(`returns undefined when supportsIpV4=${supportsIpV4} and supportsIpV6=${supportsIpV6}, config disabled and browser is firefox`, () => {
1017
1073
  sinon
1018
1074
  .stub(webex.internal.device.ipNetworkDetector, 'supportsIpV4')
1019
1075
  .get(() => supportsIpV4);
@@ -1021,6 +1077,7 @@ describe('plugin-meetings', () => {
1021
1077
  .stub(webex.internal.device.ipNetworkDetector, 'supportsIpV6')
1022
1078
  .get(() => supportsIpV6);
1023
1079
 
1080
+ webex.config.meetings.backendIpv6NativeSupport = false;
1024
1081
  isBrowserStub.callsFake((name) => name === 'firefox');
1025
1082
 
1026
1083
  assert.equal(MeetingUtil.getIpVersion(webex), undefined);
@@ -18,6 +18,7 @@ import MeetingInfo, {
18
18
  MeetingInfoV2CaptchaError,
19
19
  MeetingInfoV2AdhocMeetingError,
20
20
  MeetingInfoV2PolicyError,
21
+ MeetingInfoV2WebinarRegistrationError,
21
22
  } from '@webex/plugin-meetings/src/meeting-info/meeting-info-v2';
22
23
  import MeetingInfoUtil from '@webex/plugin-meetings/src/meeting-info/utilv2';
23
24
  import Metrics from '@webex/plugin-meetings/src/metrics';
@@ -888,6 +889,42 @@ describe('plugin-meetings', () => {
888
889
  });
889
890
  }
890
891
  );
892
+
893
+ forEach(
894
+ [
895
+ {errorCode: 403021},
896
+ {errorCode: 403022},
897
+ {errorCode: 403024},
898
+ ],
899
+ ({errorCode}) => {
900
+ it(`should throw a MeetingInfoV2WebinarRegistrationError for error code ${errorCode}`, async () => {
901
+ const message = 'a message';
902
+ const meetingInfoData = {meetingInfo: {registrationUrl: 'registrationUrl'}};
903
+
904
+ webex.request = sinon.stub().rejects({
905
+ statusCode: 403,
906
+ body: {message, code: errorCode, data: {meetingInfo: meetingInfoData}},
907
+ });
908
+ try {
909
+ await meetingInfo.createAdhocSpaceMeeting(conversationUrl, installedOrgID);
910
+ assert.fail('createAdhocSpaceMeeting should have thrown, but has not done that');
911
+ } catch (err) {
912
+ assert.instanceOf(err, MeetingInfoV2WebinarRegistrationError);
913
+ assert.deepEqual(err.message, `${message}, code=${errorCode}`);
914
+ assert.equal(err.wbxAppApiCode, errorCode);
915
+ assert.deepEqual(err.meetingInfo, meetingInfoData);
916
+
917
+ assert(Metrics.sendBehavioralMetric.calledOnce);
918
+ assert.calledWith(
919
+ Metrics.sendBehavioralMetric,
920
+ BEHAVIORAL_METRICS.WEBINAR_REGISTRATION_ERROR,
921
+ {code: errorCode}
922
+ );
923
+
924
+ }
925
+ });
926
+ }
927
+ );
891
928
  });
892
929
  });
893
930
  });
@@ -345,6 +345,22 @@ describe('plugin-meetings', () => {
345
345
  });
346
346
  });
347
347
 
348
+ describe('#_toggleIpv6BackendNativeSupport', () => {
349
+ it('should have _toggleIpv6BackendNativeSupport', () => {
350
+ assert.equal(typeof webex.meetings._toggleIpv6BackendNativeSupport, 'function');
351
+ });
352
+
353
+ describe('success', () => {
354
+ it('should update meetings config accordingly', () => {
355
+ webex.meetings._toggleIpv6BackendNativeSupport(true);
356
+ assert.equal(webex.meetings.config.backendIpv6NativeSupport, true);
357
+
358
+ webex.meetings._toggleIpv6BackendNativeSupport(false);
359
+ assert.equal(webex.meetings.config.backendIpv6NativeSupport, false);
360
+ });
361
+ });
362
+ });
363
+
348
364
  describe('Public API Contracts', () => {
349
365
  describe('#register', () => {
350
366
  it('emits an event and resolves when register succeeds', async () => {
@@ -2061,6 +2077,21 @@ describe('plugin-meetings', () => {
2061
2077
  ]);
2062
2078
  });
2063
2079
 
2080
+ it('should handle failure to get user information if scopes are insufficient', async () => {
2081
+ loggerProxySpy = sinon.spy(LoggerProxy.logger, 'error');
2082
+ Object.assign(webex.people, {
2083
+ _getMe: sinon.stub().returns(Promise.reject()),
2084
+ });
2085
+
2086
+ await webex.meetings.fetchUserPreferredWebexSite();
2087
+
2088
+ assert.equal(webex.meetings.preferredWebexSite, '');
2089
+ assert.calledOnceWithExactly(
2090
+ loggerProxySpy,
2091
+ 'Failed to retrieve user information. No preferredWebexSite will be set'
2092
+ );
2093
+ });
2094
+
2064
2095
  const setup = ({me = { type: 'validuser'}, user} = {}) => {
2065
2096
  loggerProxySpy = sinon.spy(LoggerProxy.logger, 'error');
2066
2097
  assert.deepEqual(webex.internal.services._getCatalog().getAllowedDomains(), []);
@@ -2077,7 +2108,7 @@ describe('plugin-meetings', () => {
2077
2108
 
2078
2109
  Object.assign(webex.people, {
2079
2110
  _getMe: sinon.stub().returns(Promise.resolve(me)),
2080
- });
2111
+ });
2081
2112
  };
2082
2113
 
2083
2114
  it('should not call request.getMeetingPreferences if user is a guest', async () => {
@@ -660,17 +660,20 @@ describe('plugin-meetings', () => {
660
660
  resultPromise,
661
661
  spies,
662
662
  expectedRequestingMemberId,
663
- expectedLocusUrl
663
+ expectedLocusUrl,
664
+ expectedRoles,
664
665
  ) => {
665
666
  await assert.isFulfilled(resultPromise);
666
667
  assert.calledOnceWithExactly(
667
668
  spies.generateLowerAllHandsMemberOptions,
668
669
  expectedRequestingMemberId,
669
- expectedLocusUrl
670
+ expectedLocusUrl,
671
+ expectedRoles,
670
672
  );
671
673
  assert.calledOnceWithExactly(spies.lowerAllHandsMember, {
672
674
  requestingParticipantId: expectedRequestingMemberId,
673
675
  locusUrl: expectedLocusUrl,
676
+ ...(expectedRoles !== undefined && { roles: expectedRoles })
674
677
  });
675
678
  assert.strictEqual(resultPromise, spies.lowerAllHandsMember.getCall(0).returnValue);
676
679
  };
@@ -707,6 +710,26 @@ describe('plugin-meetings', () => {
707
710
 
708
711
  await checkValid(resultPromise, spies, requestingMemberId, url1);
709
712
  });
713
+
714
+ it('should make the correct request when called with valid requestingMemberId and roles', async () => {
715
+ const requestingMemberId = 'test-member-id';
716
+ const roles = ['panelist', 'attendee'];
717
+ const { members, spies } = setup('test-locus-url');
718
+
719
+ const resultPromise = members.lowerAllHands(requestingMemberId, roles);
720
+
721
+ await checkValid(resultPromise, spies, requestingMemberId, 'test-locus-url', roles);
722
+ });
723
+
724
+ it('should handle an empty roles array correctly', async () => {
725
+ const requestingMemberId = 'test-member-id';
726
+ const roles = [];
727
+ const { members, spies } = setup('test-locus-url');
728
+
729
+ const resultPromise = members.lowerAllHands(requestingMemberId, roles);
730
+
731
+ await checkValid(resultPromise, spies, requestingMemberId, 'test-locus-url', roles);
732
+ });
710
733
  });
711
734
 
712
735
  describe('#editDisplayName', () => {
@@ -225,7 +225,7 @@ describe('plugin-meetings', () => {
225
225
  });
226
226
 
227
227
  describe('#assignRolesMember', () => {
228
- it('sends a PATCH to the locus endpoint', async () => {
228
+ it('sends a assignRolesMember PATCH to the locus endpoint', async () => {
229
229
  const locusUrl = url1;
230
230
  const memberId = 'test1';
231
231
  const roles = [
@@ -255,7 +255,7 @@ describe('plugin-meetings', () => {
255
255
  });
256
256
 
257
257
  describe('#raiseHand', () => {
258
- it('sends a PATCH to the locus endpoint', async () => {
258
+ it('sends a raiseOrLowerHandMember PATCH to the locus endpoint', async () => {
259
259
  const locusUrl = url1;
260
260
  const memberId = 'test1';
261
261
 
@@ -319,7 +319,7 @@ describe('plugin-meetings', () => {
319
319
  assert.strictEqual(result, requestResponse);
320
320
  });
321
321
 
322
- it('sends a PATCH to the locus endpoint', async () => {
322
+ it('sends a lowerAllHandsMember PATCH to the locus endpoint', async () => {
323
323
  const locusUrl = url1;
324
324
  const memberId = 'test1';
325
325
 
@@ -348,6 +348,40 @@ describe('plugin-meetings', () => {
348
348
  },
349
349
  });
350
350
  });
351
+
352
+ it('sends a lowerAllHandsMember PATCH to the locus endpoint with roles', async () => {
353
+ const locusUrl = url1;
354
+ const memberId = 'test1';
355
+ const roles = ['attendee'];
356
+
357
+ const options = {
358
+ requestingParticipantId: memberId,
359
+ locusUrl,
360
+ roles,
361
+ };
362
+
363
+ const getRequestParamsSpy = sandbox.spy(membersUtil, 'getLowerAllHandsMemberRequestParams');
364
+
365
+ await membersRequest.lowerAllHandsMember(options);
366
+
367
+ assert.calledOnceWithExactly(getRequestParamsSpy, {
368
+ requestingParticipantId: memberId,
369
+ locusUrl: url1,
370
+ roles: ['attendee'],
371
+ });
372
+
373
+ checkRequest({
374
+ method: 'PATCH',
375
+ uri: `${locusUrl}/controls`,
376
+ body: {
377
+ hand: {
378
+ raised: false,
379
+ roles: ['attendee'],
380
+ },
381
+ requestingParticipantId: memberId,
382
+ },
383
+ });
384
+ });
351
385
  });
352
386
 
353
387
  describe('#editDisplayName', () => {
@@ -101,7 +101,7 @@ describe('plugin-meetings', () => {
101
101
  });
102
102
  });
103
103
  describe('#generateLowerAllHandsMemberOptions', () => {
104
- it('returns the correct options', () => {
104
+ it('returns the correct options without roles', () => {
105
105
  const requestingParticipantId = 'test';
106
106
  const locusUrl = 'urlTest1';
107
107
 
@@ -113,6 +113,20 @@ describe('plugin-meetings', () => {
113
113
  }
114
114
  );
115
115
  });
116
+ it('returns the correct options with roles', () => {
117
+ const requestingParticipantId = 'test';
118
+ const locusUrl = 'urlTest1';
119
+ const roles = ['panelist'];
120
+
121
+ assert.deepEqual(
122
+ MembersUtil.generateLowerAllHandsMemberOptions(requestingParticipantId, locusUrl, roles),
123
+ {
124
+ requestingParticipantId,
125
+ locusUrl,
126
+ roles,
127
+ }
128
+ );
129
+ });
116
130
  });
117
131
  describe('#generateEditDisplayNameMemberOptions', () => {
118
132
  it('returns the correct options', () => {
@@ -7,7 +7,7 @@ import {RemoteMedia, RemoteMediaEvents} from '@webex/plugin-meetings/src/multist
7
7
  import {ReceiveSlotEvents} from '@webex/plugin-meetings/src/multistream/receiveSlot';
8
8
  import sinon from 'sinon';
9
9
  import {assert} from '@webex/test-helper-chai';
10
- import { forEach } from 'lodash';
10
+ import {forEach} from 'lodash';
11
11
 
12
12
  describe('RemoteMedia', () => {
13
13
  let remoteMedia;
@@ -227,12 +227,26 @@ describe('RemoteMedia', () => {
227
227
  });
228
228
 
229
229
  describe('setSizeHint()', () => {
230
-
231
230
  it('works if the receive slot is undefined', () => {
232
231
  remoteMedia.receiveSlot = undefined;
233
232
  remoteMedia.setSizeHint(100, 100);
234
233
  });
235
234
 
235
+ forEach(
236
+ [
237
+ {width: 0, height: 0},
238
+ {width: 135, height: 0},
239
+ {width: 0, height: 240},
240
+ ],
241
+ ({width, height}) => {
242
+ it(`skip updating the max fs when applied ${width}:${height}`, () => {
243
+ remoteMedia.setSizeHint(width, height);
244
+
245
+ assert.notCalled(fakeReceiveSlot.setMaxFs);
246
+ });
247
+ }
248
+ );
249
+
236
250
  forEach(
237
251
  [
238
252
  {height: 134, fs: 60},