@webex/plugin-meetings 3.8.1 → 3.9.0-multipleLLM.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 (317) hide show
  1. package/README.md +26 -13
  2. package/dist/breakouts/breakout.js +1 -1
  3. package/dist/breakouts/index.js +1 -1
  4. package/dist/constants.js +34 -3
  5. package/dist/constants.js.map +1 -1
  6. package/dist/controls-options-manager/enums.js +1 -0
  7. package/dist/controls-options-manager/enums.js.map +1 -1
  8. package/dist/controls-options-manager/types.js.map +1 -1
  9. package/dist/controls-options-manager/util.js +26 -0
  10. package/dist/controls-options-manager/util.js.map +1 -1
  11. package/dist/interpretation/index.js +1 -1
  12. package/dist/interpretation/siLanguage.js +1 -1
  13. package/dist/locus-info/controlsUtils.js +11 -3
  14. package/dist/locus-info/controlsUtils.js.map +1 -1
  15. package/dist/locus-info/index.js +107 -95
  16. package/dist/locus-info/index.js.map +1 -1
  17. package/dist/locus-info/parser.js +4 -1
  18. package/dist/locus-info/parser.js.map +1 -1
  19. package/dist/media/index.js +2 -2
  20. package/dist/media/index.js.map +1 -1
  21. package/dist/media/properties.js +53 -5
  22. package/dist/media/properties.js.map +1 -1
  23. package/dist/meeting/brbState.js +17 -14
  24. package/dist/meeting/brbState.js.map +1 -1
  25. package/dist/meeting/in-meeting-actions.js +13 -1
  26. package/dist/meeting/in-meeting-actions.js.map +1 -1
  27. package/dist/meeting/index.js +555 -296
  28. package/dist/meeting/index.js.map +1 -1
  29. package/dist/meeting/muteState.js +2 -5
  30. package/dist/meeting/muteState.js.map +1 -1
  31. package/dist/meeting/request.js +44 -0
  32. package/dist/meeting/request.js.map +1 -1
  33. package/dist/meeting/request.type.js.map +1 -1
  34. package/dist/{rtcMetrics/constants.js → meeting/type.js} +1 -5
  35. package/dist/meeting/type.js.map +1 -0
  36. package/dist/meeting/util.js +98 -13
  37. package/dist/meeting/util.js.map +1 -1
  38. package/dist/meeting-info/meeting-info-v2.js +29 -21
  39. package/dist/meeting-info/meeting-info-v2.js.map +1 -1
  40. package/dist/meetings/index.js +18 -10
  41. package/dist/meetings/index.js.map +1 -1
  42. package/dist/member/types.js.map +1 -1
  43. package/dist/members/collection.js +13 -0
  44. package/dist/members/collection.js.map +1 -1
  45. package/dist/members/index.js +53 -29
  46. package/dist/members/index.js.map +1 -1
  47. package/dist/members/request.js +3 -3
  48. package/dist/members/request.js.map +1 -1
  49. package/dist/members/util.js +25 -8
  50. package/dist/members/util.js.map +1 -1
  51. package/dist/metrics/constants.js +3 -1
  52. package/dist/metrics/constants.js.map +1 -1
  53. package/dist/multistream/mediaRequestManager.js +1 -1
  54. package/dist/multistream/mediaRequestManager.js.map +1 -1
  55. package/dist/multistream/remoteMedia.js +34 -5
  56. package/dist/multistream/remoteMedia.js.map +1 -1
  57. package/dist/multistream/remoteMediaGroup.js +42 -2
  58. package/dist/multistream/remoteMediaGroup.js.map +1 -1
  59. package/dist/multistream/sendSlotManager.js +32 -2
  60. package/dist/multistream/sendSlotManager.js.map +1 -1
  61. package/dist/reachability/index.js +8 -13
  62. package/dist/reachability/index.js.map +1 -1
  63. package/dist/types/constants.d.ts +30 -0
  64. package/dist/types/controls-options-manager/enums.d.ts +2 -1
  65. package/dist/types/controls-options-manager/types.d.ts +4 -1
  66. package/dist/types/locus-info/index.d.ts +54 -10
  67. package/dist/types/media/properties.d.ts +21 -0
  68. package/dist/types/meeting/brbState.d.ts +0 -1
  69. package/dist/types/meeting/in-meeting-actions.d.ts +12 -0
  70. package/dist/types/meeting/index.d.ts +58 -20
  71. package/dist/types/meeting/request.d.ts +18 -1
  72. package/dist/types/meeting/request.type.d.ts +74 -0
  73. package/dist/types/meeting/type.d.ts +9 -0
  74. package/dist/types/meeting/util.d.ts +13 -3
  75. package/dist/types/meeting-info/meeting-info-v2.d.ts +6 -3
  76. package/dist/types/meetings/index.d.ts +3 -1
  77. package/dist/types/member/types.d.ts +1 -0
  78. package/dist/types/members/collection.d.ts +6 -0
  79. package/dist/types/members/index.d.ts +22 -9
  80. package/dist/types/members/request.d.ts +1 -1
  81. package/dist/types/members/util.d.ts +13 -6
  82. package/dist/types/metrics/constants.d.ts +2 -0
  83. package/dist/types/multistream/remoteMedia.d.ts +20 -1
  84. package/dist/types/multistream/remoteMediaGroup.d.ts +11 -0
  85. package/dist/types/multistream/sendSlotManager.d.ts +16 -0
  86. package/dist/types/reachability/index.d.ts +2 -2
  87. package/dist/webinar/index.js +1 -1
  88. package/package.json +24 -25
  89. package/src/constants.ts +34 -2
  90. package/src/controls-options-manager/enums.ts +1 -0
  91. package/src/controls-options-manager/types.ts +6 -1
  92. package/src/controls-options-manager/util.ts +31 -0
  93. package/src/locus-info/controlsUtils.ts +15 -0
  94. package/src/locus-info/index.ts +174 -96
  95. package/src/locus-info/parser.ts +5 -1
  96. package/src/media/index.ts +2 -2
  97. package/src/media/properties.ts +43 -0
  98. package/src/meeting/brbState.ts +13 -9
  99. package/src/meeting/in-meeting-actions.ts +25 -0
  100. package/src/meeting/index.ts +362 -75
  101. package/src/meeting/muteState.ts +2 -6
  102. package/src/meeting/request.ts +39 -0
  103. package/src/meeting/request.type.ts +64 -0
  104. package/src/meeting/type.ts +9 -0
  105. package/src/meeting/util.ts +114 -22
  106. package/src/meeting-info/meeting-info-v2.ts +24 -5
  107. package/src/meetings/index.ts +12 -5
  108. package/src/member/types.ts +1 -0
  109. package/src/members/collection.ts +11 -0
  110. package/src/members/index.ts +51 -15
  111. package/src/members/request.ts +2 -2
  112. package/src/members/util.ts +34 -6
  113. package/src/metrics/constants.ts +2 -0
  114. package/src/multistream/mediaRequestManager.ts +7 -7
  115. package/src/multistream/remoteMedia.ts +34 -4
  116. package/src/multistream/remoteMediaGroup.ts +37 -2
  117. package/src/multistream/sendSlotManager.ts +34 -2
  118. package/src/reachability/index.ts +8 -16
  119. package/test/unit/spec/controls-options-manager/util.js +58 -0
  120. package/test/unit/spec/locus-info/controlsUtils.js +52 -0
  121. package/test/unit/spec/locus-info/index.js +270 -97
  122. package/test/unit/spec/locus-info/parser.js +3 -2
  123. package/test/unit/spec/media/index.ts +107 -0
  124. package/test/unit/spec/media/properties.ts +137 -0
  125. package/test/unit/spec/meeting/brbState.ts +23 -4
  126. package/test/unit/spec/meeting/in-meeting-actions.ts +12 -0
  127. package/test/unit/spec/meeting/index.js +1194 -97
  128. package/test/unit/spec/meeting/muteState.js +32 -6
  129. package/test/unit/spec/meeting/request.js +92 -0
  130. package/test/unit/spec/meeting/utils.js +167 -17
  131. package/test/unit/spec/meeting-info/meetinginfov2.js +8 -3
  132. package/test/unit/spec/meetings/index.js +12 -1
  133. package/test/unit/spec/members/collection.js +120 -0
  134. package/test/unit/spec/members/index.js +140 -12
  135. package/test/unit/spec/members/request.js +57 -2
  136. package/test/unit/spec/members/utils.js +139 -17
  137. package/test/unit/spec/multistream/mediaRequestManager.ts +19 -6
  138. package/test/unit/spec/multistream/remoteMedia.ts +66 -2
  139. package/test/unit/spec/multistream/sendSlotManager.ts +59 -0
  140. package/test/unit/spec/reachability/index.ts +160 -9
  141. package/dist/annotation/annotation.types.d.ts +0 -42
  142. package/dist/annotation/constants.d.ts +0 -31
  143. package/dist/annotation/index.d.ts +0 -117
  144. package/dist/breakouts/breakout.d.ts +0 -8
  145. package/dist/breakouts/collection.d.ts +0 -5
  146. package/dist/breakouts/edit-lock-error.d.ts +0 -15
  147. package/dist/breakouts/events.d.ts +0 -8
  148. package/dist/breakouts/index.d.ts +0 -5
  149. package/dist/breakouts/request.d.ts +0 -22
  150. package/dist/breakouts/utils.d.ts +0 -15
  151. package/dist/common/browser-detection.d.ts +0 -9
  152. package/dist/common/collection.d.ts +0 -48
  153. package/dist/common/config.d.ts +0 -2
  154. package/dist/common/errors/captcha-error.d.ts +0 -15
  155. package/dist/common/errors/intent-to-join.d.ts +0 -16
  156. package/dist/common/errors/join-meeting.d.ts +0 -17
  157. package/dist/common/errors/media.d.ts +0 -15
  158. package/dist/common/errors/no-meeting-info.d.ts +0 -14
  159. package/dist/common/errors/parameter.d.ts +0 -15
  160. package/dist/common/errors/password-error.d.ts +0 -15
  161. package/dist/common/errors/permission.d.ts +0 -14
  162. package/dist/common/errors/reclaim-host-role-error.d.ts +0 -60
  163. package/dist/common/errors/reclaim-host-role-error.js +0 -158
  164. package/dist/common/errors/reclaim-host-role-error.js.map +0 -1
  165. package/dist/common/errors/reclaim-host-role-errors.d.ts +0 -60
  166. package/dist/common/errors/reconnection-in-progress.d.ts +0 -9
  167. package/dist/common/errors/reconnection-in-progress.js +0 -35
  168. package/dist/common/errors/reconnection-in-progress.js.map +0 -1
  169. package/dist/common/errors/reconnection.d.ts +0 -15
  170. package/dist/common/errors/stats.d.ts +0 -15
  171. package/dist/common/errors/webex-errors.d.ts +0 -81
  172. package/dist/common/errors/webex-meetings-error.d.ts +0 -20
  173. package/dist/common/events/events-scope.d.ts +0 -17
  174. package/dist/common/events/events.d.ts +0 -12
  175. package/dist/common/events/trigger-proxy.d.ts +0 -2
  176. package/dist/common/events/util.d.ts +0 -2
  177. package/dist/common/logs/logger-config.d.ts +0 -2
  178. package/dist/common/logs/logger-proxy.d.ts +0 -2
  179. package/dist/common/logs/request.d.ts +0 -34
  180. package/dist/common/queue.d.ts +0 -32
  181. package/dist/config.d.ts +0 -73
  182. package/dist/constants.d.ts +0 -952
  183. package/dist/controls-options-manager/constants.d.ts +0 -4
  184. package/dist/controls-options-manager/enums.d.ts +0 -5
  185. package/dist/controls-options-manager/index.d.ts +0 -120
  186. package/dist/controls-options-manager/types.d.ts +0 -43
  187. package/dist/controls-options-manager/util.d.ts +0 -7
  188. package/dist/index.d.ts +0 -4
  189. package/dist/interceptors/index.d.ts +0 -2
  190. package/dist/interceptors/locusRetry.d.ts +0 -27
  191. package/dist/interpretation/collection.d.ts +0 -5
  192. package/dist/interpretation/index.d.ts +0 -5
  193. package/dist/interpretation/siLanguage.d.ts +0 -5
  194. package/dist/locus-info/controlsUtils.d.ts +0 -2
  195. package/dist/locus-info/embeddedAppsUtils.d.ts +0 -2
  196. package/dist/locus-info/fullState.d.ts +0 -2
  197. package/dist/locus-info/hostUtils.d.ts +0 -2
  198. package/dist/locus-info/index.d.ts +0 -269
  199. package/dist/locus-info/infoUtils.d.ts +0 -2
  200. package/dist/locus-info/mediaSharesUtils.d.ts +0 -2
  201. package/dist/locus-info/parser.d.ts +0 -212
  202. package/dist/locus-info/selfUtils.d.ts +0 -2
  203. package/dist/media/index.d.ts +0 -32
  204. package/dist/media/properties.d.ts +0 -108
  205. package/dist/media/util.d.ts +0 -2
  206. package/dist/mediaQualityMetrics/config.d.ts +0 -233
  207. package/dist/mediaQualityMetrics/config.js +0 -513
  208. package/dist/mediaQualityMetrics/config.js.map +0 -1
  209. package/dist/meeting/effectsState.d.ts +0 -42
  210. package/dist/meeting/effectsState.js +0 -260
  211. package/dist/meeting/effectsState.js.map +0 -1
  212. package/dist/meeting/in-meeting-actions.d.ts +0 -79
  213. package/dist/meeting/index.d.ts +0 -1622
  214. package/dist/meeting/locusMediaRequest.d.ts +0 -74
  215. package/dist/meeting/muteState.d.ts +0 -116
  216. package/dist/meeting/request.d.ts +0 -257
  217. package/dist/meeting/request.type.d.ts +0 -11
  218. package/dist/meeting/state.d.ts +0 -9
  219. package/dist/meeting/util.d.ts +0 -2
  220. package/dist/meeting/voicea-meeting.d.ts +0 -16
  221. package/dist/meeting-info/collection.d.ts +0 -20
  222. package/dist/meeting-info/index.d.ts +0 -57
  223. package/dist/meeting-info/meeting-info-v2.d.ts +0 -93
  224. package/dist/meeting-info/request.d.ts +0 -22
  225. package/dist/meeting-info/util.d.ts +0 -2
  226. package/dist/meeting-info/utilv2.d.ts +0 -2
  227. package/dist/meetings/collection.d.ts +0 -23
  228. package/dist/meetings/index.d.ts +0 -296
  229. package/dist/meetings/meetings.types.d.ts +0 -4
  230. package/dist/meetings/request.d.ts +0 -27
  231. package/dist/meetings/util.d.ts +0 -18
  232. package/dist/member/index.d.ts +0 -148
  233. package/dist/member/member.types.d.ts +0 -11
  234. package/dist/member/member.types.js +0 -18
  235. package/dist/member/member.types.js.map +0 -1
  236. package/dist/member/types.d.ts +0 -32
  237. package/dist/member/util.d.ts +0 -2
  238. package/dist/members/collection.d.ts +0 -24
  239. package/dist/members/index.d.ts +0 -308
  240. package/dist/members/request.d.ts +0 -58
  241. package/dist/members/types.d.ts +0 -25
  242. package/dist/members/util.d.ts +0 -2
  243. package/dist/metrics/config.d.ts +0 -169
  244. package/dist/metrics/config.js +0 -289
  245. package/dist/metrics/config.js.map +0 -1
  246. package/dist/metrics/constants.d.ts +0 -59
  247. package/dist/metrics/index.d.ts +0 -152
  248. package/dist/multistream/mediaRequestManager.d.ts +0 -119
  249. package/dist/multistream/receiveSlot.d.ts +0 -68
  250. package/dist/multistream/receiveSlotManager.d.ts +0 -56
  251. package/dist/multistream/remoteMedia.d.ts +0 -72
  252. package/dist/multistream/remoteMediaGroup.d.ts +0 -49
  253. package/dist/multistream/remoteMediaManager.d.ts +0 -300
  254. package/dist/multistream/sendSlotManager.d.ts +0 -69
  255. package/dist/networkQualityMonitor/index.d.ts +0 -70
  256. package/dist/networkQualityMonitor/index.js +0 -226
  257. package/dist/networkQualityMonitor/index.js.map +0 -1
  258. package/dist/peer-connection-manager/index.d.ts +0 -6
  259. package/dist/peer-connection-manager/index.js +0 -671
  260. package/dist/peer-connection-manager/index.js.map +0 -1
  261. package/dist/peer-connection-manager/util.d.ts +0 -6
  262. package/dist/peer-connection-manager/util.js +0 -110
  263. package/dist/peer-connection-manager/util.js.map +0 -1
  264. package/dist/personal-meeting-room/index.d.ts +0 -47
  265. package/dist/personal-meeting-room/request.d.ts +0 -14
  266. package/dist/personal-meeting-room/util.d.ts +0 -2
  267. package/dist/reachability/clusterReachability.d.ts +0 -109
  268. package/dist/reachability/index.d.ts +0 -139
  269. package/dist/reachability/request.d.ts +0 -35
  270. package/dist/reachability/util.d.ts +0 -8
  271. package/dist/reactions/constants.d.ts +0 -3
  272. package/dist/reactions/reactions.d.ts +0 -4
  273. package/dist/reactions/reactions.type.d.ts +0 -32
  274. package/dist/reconnection-manager/index.d.ts +0 -112
  275. package/dist/recording-controller/enums.d.ts +0 -7
  276. package/dist/recording-controller/index.d.ts +0 -193
  277. package/dist/recording-controller/util.d.ts +0 -13
  278. package/dist/roap/collection.d.ts +0 -10
  279. package/dist/roap/collection.js +0 -63
  280. package/dist/roap/collection.js.map +0 -1
  281. package/dist/roap/handler.d.ts +0 -47
  282. package/dist/roap/handler.js +0 -279
  283. package/dist/roap/handler.js.map +0 -1
  284. package/dist/roap/index.d.ts +0 -116
  285. package/dist/roap/request.d.ts +0 -35
  286. package/dist/roap/state.d.ts +0 -9
  287. package/dist/roap/state.js +0 -127
  288. package/dist/roap/state.js.map +0 -1
  289. package/dist/roap/turnDiscovery.d.ts +0 -81
  290. package/dist/roap/util.d.ts +0 -2
  291. package/dist/roap/util.js +0 -76
  292. package/dist/roap/util.js.map +0 -1
  293. package/dist/rtcMetrics/constants.d.ts +0 -4
  294. package/dist/rtcMetrics/constants.js.map +0 -1
  295. package/dist/rtcMetrics/index.d.ts +0 -61
  296. package/dist/rtcMetrics/index.js +0 -197
  297. package/dist/rtcMetrics/index.js.map +0 -1
  298. package/dist/statsAnalyzer/global.d.ts +0 -118
  299. package/dist/statsAnalyzer/global.js +0 -127
  300. package/dist/statsAnalyzer/global.js.map +0 -1
  301. package/dist/statsAnalyzer/index.d.ts +0 -193
  302. package/dist/statsAnalyzer/index.js +0 -1019
  303. package/dist/statsAnalyzer/index.js.map +0 -1
  304. package/dist/statsAnalyzer/mqaUtil.d.ts +0 -22
  305. package/dist/statsAnalyzer/mqaUtil.js +0 -181
  306. package/dist/statsAnalyzer/mqaUtil.js.map +0 -1
  307. package/dist/transcription/index.d.ts +0 -64
  308. package/dist/types/common/errors/reconnection-in-progress.d.ts +0 -9
  309. package/dist/types/mediaQualityMetrics/config.d.ts +0 -241
  310. package/dist/types/networkQualityMonitor/index.d.ts +0 -70
  311. package/dist/types/rtcMetrics/constants.d.ts +0 -4
  312. package/dist/types/rtcMetrics/index.d.ts +0 -71
  313. package/dist/types/statsAnalyzer/global.d.ts +0 -36
  314. package/dist/types/statsAnalyzer/index.d.ts +0 -217
  315. package/dist/types/statsAnalyzer/mqaUtil.d.ts +0 -48
  316. package/dist/webinar/collection.d.ts +0 -16
  317. package/dist/webinar/index.d.ts +0 -5
@@ -306,6 +306,20 @@ describe('plugin-meetings', () => {
306
306
  );
307
307
  });
308
308
 
309
+ it('should trigger the CONTROLS_POLLING_QA_CHANGED event when necessary', () => {
310
+ locusInfo.controls = {};
311
+ locusInfo.emitScoped = sinon.stub();
312
+ newControls.pollingQAControl = { enabled: true };
313
+ locusInfo.updateControls(newControls);
314
+
315
+ assert.calledWith(
316
+ locusInfo.emitScoped,
317
+ {file: 'locus-info', function: 'updateControls'},
318
+ LOCUSINFO.EVENTS.CONTROLS_POLLING_QA_CHANGED,
319
+ {state: newControls.pollingQAControl}
320
+ );
321
+ });
322
+
309
323
  it('should keep the recording state to `IDLE`', () => {
310
324
  locusInfo.controls = {
311
325
  record: {
@@ -557,6 +571,34 @@ describe('plugin-meetings', () => {
557
571
  );
558
572
  });
559
573
 
574
+ it('should update the transcribe spoken language', () => {
575
+ locusInfo.emitScoped = sinon.stub();
576
+ locusInfo.controls = {
577
+ transcribe: {
578
+ transcribing: false,
579
+ caption: true,
580
+ spokenLanguage: 'en-US',
581
+ },
582
+ };
583
+ newControls.transcribe.transcribing = false;
584
+ newControls.transcribe.caption = true;
585
+ newControls.transcribe.spokenLanguage = 'fr';
586
+
587
+ locusInfo.updateControls(newControls);
588
+
589
+ assert.calledWith(
590
+ locusInfo.emitScoped,
591
+ {
592
+ file: 'locus-info',
593
+ function: 'updateControls',
594
+ },
595
+ LOCUSINFO.EVENTS.CONTROLS_MEETING_TRANSCRIPTION_SPOKEN_LANGUAGE_UPDATED,
596
+ {
597
+ spokenLanguage: 'fr',
598
+ }
599
+ );
600
+ });
601
+
560
602
  it('should update the manual caption state', () => {
561
603
  locusInfo.emitScoped = sinon.stub();
562
604
  locusInfo.controls = {
@@ -730,7 +772,7 @@ describe('plugin-meetings', () => {
730
772
  },
731
773
  };
732
774
  locusInfo.emitScoped = sinon.stub();
733
- locusInfo.updateParticipants({});
775
+ locusInfo.updateParticipants({}, []);
734
776
 
735
777
  // if this assertion fails, double-check the attributes used in
736
778
  // the updateParticipants function in locus-info/index.js
@@ -748,6 +790,7 @@ describe('plugin-meetings', () => {
748
790
  selfId: '2',
749
791
  hostId: '3',
750
792
  isReplace: undefined,
793
+ removedParticipantIds: [],
751
794
  }
752
795
  );
753
796
  // note: in a real use case, recordingId, selfId, and hostId would all be the same
@@ -772,7 +815,7 @@ describe('plugin-meetings', () => {
772
815
  };
773
816
 
774
817
  locusInfo.emitScoped = sinon.stub();
775
- locusInfo.updateParticipants({}, true);
818
+ locusInfo.updateParticipants({}, [], true);
776
819
 
777
820
  assert.calledWith(
778
821
  locusInfo.emitScoped,
@@ -788,43 +831,11 @@ describe('plugin-meetings', () => {
788
831
  selfId: '2',
789
832
  hostId: '3',
790
833
  isReplace: true,
834
+ removedParticipantIds: [],
791
835
  }
792
836
  );
793
837
  });
794
838
 
795
- it('should update the deltaParticipants object', () => {
796
- const prev = locusInfo.deltaParticipants;
797
-
798
- locusInfo.updateParticipantDeltas(newParticipants);
799
-
800
- assert.notEqual(locusInfo.deltaParticipants, prev);
801
- });
802
-
803
- it('should update the delta property on all changed states', () => {
804
- locusInfo.updateParticipantDeltas(newParticipants);
805
-
806
- const [exampleParticipant] = locusInfo.deltaParticipants;
807
-
808
- assert.isTrue(exampleParticipant.delta.audioStatus);
809
- assert.isTrue(exampleParticipant.delta.videoSlidesStatus);
810
- assert.isTrue(exampleParticipant.delta.videoStatus);
811
- });
812
-
813
- it('should include the person details of the changed participant', () => {
814
- locusInfo.updateParticipantDeltas(newParticipants);
815
-
816
- const [exampleParticipant] = locusInfo.deltaParticipants;
817
-
818
- assert.equal(exampleParticipant.person, newParticipants[0].person);
819
- });
820
-
821
- it('should clear deltaParticipants when no changes occured', () => {
822
- locusInfo.participants = [...newParticipants];
823
-
824
- locusInfo.updateParticipantDeltas(locusInfo.participants);
825
-
826
- assert.isTrue(locusInfo.deltaParticipants.length === 0);
827
- });
828
839
 
829
840
  it('should call with participant display name', () => {
830
841
  const failureParticipant = [
@@ -838,7 +849,7 @@ describe('plugin-meetings', () => {
838
849
  ];
839
850
 
840
851
  locusInfo.emitScoped = sinon.stub();
841
- locusInfo.updateParticipants(failureParticipant);
852
+ locusInfo.updateParticipants(failureParticipant, []);
842
853
  assert.calledWith(
843
854
  locusInfo.emitScoped,
844
855
  {
@@ -1632,6 +1643,28 @@ describe('plugin-meetings', () => {
1632
1643
  );
1633
1644
  });
1634
1645
 
1646
+ it('should trigger MEETING_INFO_UPDATED even if the roles array is empty', () => {
1647
+ const initialInfo = cloneDeep(meetingInfo);
1648
+
1649
+ const updateSelf = cloneDeep(self);
1650
+ updateSelf.controls.role.roles = [];
1651
+
1652
+ locusInfo.emitScoped = sinon.stub();
1653
+ locusInfo.updateMeetingInfo(initialInfo, updateSelf);
1654
+
1655
+ assert.calledWith(
1656
+ locusInfo.emitScoped,
1657
+ {
1658
+ file: 'locus-info',
1659
+ function: 'updateMeetingInfo',
1660
+ },
1661
+ LOCUSINFO.EVENTS.MEETING_INFO_UPDATED,
1662
+ {
1663
+ isInitializing: !self,
1664
+ }
1665
+ );
1666
+ });
1667
+
1635
1668
  const checkMeetingInfoUpdatedCalled = (expected, payload) => {
1636
1669
  const expectedArgs = [
1637
1670
  locusInfo.emitScoped,
@@ -2007,6 +2040,18 @@ describe('plugin-meetings', () => {
2007
2040
  });
2008
2041
  });
2009
2042
 
2043
+ describe('#handleLocusAPIResponse', () => {
2044
+ it('calls handleLocusDelta', () => {
2045
+ const fakeLocus = {eventType: LOCUSEVENT.DIFFERENCE};
2046
+
2047
+ sinon.stub(locusInfo, 'handleLocusDelta');
2048
+
2049
+ locusInfo.handleLocusAPIResponse(mockMeeting, {locus: fakeLocus});
2050
+
2051
+ assert.calledWith(locusInfo.handleLocusDelta, fakeLocus, mockMeeting);
2052
+ });
2053
+ });
2054
+
2010
2055
  describe('#LocusDeltaEvents', () => {
2011
2056
  const fakeMeeting = 'fakeMeeting';
2012
2057
  let sandbox = null;
@@ -2019,7 +2064,7 @@ describe('plugin-meetings', () => {
2019
2064
 
2020
2065
  fakeLocus = {
2021
2066
  meeting: true,
2022
- participants: true,
2067
+ participants: [],
2023
2068
  url: 'newLocusUrl',
2024
2069
  syncUrl: 'newSyncUrl',
2025
2070
  };
@@ -2066,6 +2111,38 @@ describe('plugin-meetings', () => {
2066
2111
  assert.isFunction(locusParser.onDeltaAction);
2067
2112
  });
2068
2113
 
2114
+ it("#updateLocusInfo invokes updateLocusUrl before updateMeetingInfo", () => {
2115
+ const callOrder = [];
2116
+ sinon.stub(locusInfo, "updateControls");
2117
+ sinon.stub(locusInfo, "updateConversationUrl");
2118
+ sinon.stub(locusInfo, "updateCreated");
2119
+ sinon.stub(locusInfo, "updateFullState");
2120
+ sinon.stub(locusInfo, "updateHostInfo");
2121
+ sinon.stub(locusInfo, "updateMeetingInfo").callsFake(() => {
2122
+ callOrder.push("updateMeetingInfo");
2123
+ });
2124
+ sinon.stub(locusInfo, "updateMediaShares");
2125
+ sinon.stub(locusInfo, "updateParticipantsUrl");
2126
+ sinon.stub(locusInfo, "updateReplace");
2127
+ sinon.stub(locusInfo, "updateSelf");
2128
+ sinon.stub(locusInfo, "updateLocusUrl").callsFake(() => {
2129
+ callOrder.push("updateLocusUrl");
2130
+ });
2131
+ sinon.stub(locusInfo, "updateAclUrl");
2132
+ sinon.stub(locusInfo, "updateBasequence");
2133
+ sinon.stub(locusInfo, "updateSequence");
2134
+ sinon.stub(locusInfo, "updateMemberShip");
2135
+ sinon.stub(locusInfo, "updateIdentifiers");
2136
+ sinon.stub(locusInfo, "updateEmbeddedApps");
2137
+ sinon.stub(locusInfo, "updateResources");
2138
+ sinon.stub(locusInfo, "compareAndUpdate");
2139
+
2140
+ locusInfo.updateLocusInfo(locus);
2141
+
2142
+ // Ensure updateLocusUrl is called before updateMeetingInfo if both are called
2143
+ assert.deepEqual(callOrder, ['updateLocusUrl', 'updateMeetingInfo']);
2144
+ });
2145
+
2069
2146
  it('#updateLocusInfo ignores breakout LEFT message', () => {
2070
2147
  const newLocus = {
2071
2148
  self: {
@@ -2117,10 +2194,11 @@ describe('plugin-meetings', () => {
2117
2194
  assert.notCalled(locusInfo.compareAndUpdate);
2118
2195
  });
2119
2196
 
2197
+
2198
+
2120
2199
  it('onFullLocus() updates the working-copy of locus parser', () => {
2121
2200
  const eventType = 'fakeEvent';
2122
2201
 
2123
- sandbox.stub(locusInfo, 'updateParticipantDeltas');
2124
2202
  sandbox.stub(locusInfo, 'updateLocusInfo');
2125
2203
  sandbox.stub(locusInfo, 'updateParticipants');
2126
2204
  sandbox.stub(locusInfo, 'isMeetingActive');
@@ -2140,7 +2218,6 @@ describe('plugin-meetings', () => {
2140
2218
  const oldWorkingCopy = locusParser.workingCopy;
2141
2219
 
2142
2220
  const spies = [
2143
- sandbox.stub(locusInfo, 'updateParticipantDeltas'),
2144
2221
  sandbox.stub(locusInfo, 'updateLocusInfo'),
2145
2222
  sandbox.stub(locusInfo, 'updateParticipants'),
2146
2223
  sandbox.stub(locusInfo, 'isMeetingActive'),
@@ -2215,7 +2292,7 @@ describe('plugin-meetings', () => {
2215
2292
 
2216
2293
  it('applyLocusDeltaData gets delta locus on DESYNC action if we have a syncUrl', () => {
2217
2294
  const {DESYNC} = LocusDeltaParser.loci;
2218
- const fakeDeltaLocus = {id: 'fake delta locus'};
2295
+ const fakeDeltaLocus = {baseSequence: {}, id: 'fake delta locus'};
2219
2296
  const meeting = {
2220
2297
  meetingRequest: {
2221
2298
  getLocusDTO: sandbox.stub().resolves({body: fakeDeltaLocus}),
@@ -2306,23 +2383,23 @@ describe('plugin-meetings', () => {
2306
2383
 
2307
2384
  it('applyLocusDeltaData handles LOCUS_URL_CHANGED action correctly', () => {
2308
2385
  const {LOCUS_URL_CHANGED} = LocusDeltaParser.loci;
2309
- const fakeDeltaLocus = {id: 'fake delta locus'};
2386
+ const fakeFullLocus = {
2387
+ url: 'new full loci url',
2388
+ };
2310
2389
  const meeting = {
2311
2390
  meetingRequest: {
2312
- getLocusDTO: sandbox.stub().resolves({body: fakeDeltaLocus}),
2391
+ getLocusDTO: sandbox.stub().resolves({body: fakeFullLocus}),
2313
2392
  },
2314
2393
  locusInfo: {
2315
2394
  handleLocusDelta: sandbox.stub(),
2316
2395
  },
2317
- locusUrl: 'current locus url',
2396
+ locusUrl: 'current BO session locus url',
2318
2397
  };
2319
2398
 
2320
- locusInfo.locusParser.workingCopy = {
2321
- syncUrl: 'current sync url',
2322
- };
2399
+ locusInfo.locusParser.workingCopy = null;
2323
2400
 
2324
2401
  locusInfo.applyLocusDeltaData(LOCUS_URL_CHANGED, fakeLocus, meeting);
2325
- assert.calledOnceWithExactly(meeting.meetingRequest.getLocusDTO, {url: 'current sync url'});
2402
+ assert.calledOnceWithExactly(meeting.meetingRequest.getLocusDTO, {url: fakeLocus.url});
2326
2403
  });
2327
2404
 
2328
2405
  describe('edge cases for sync failing', () => {
@@ -2350,25 +2427,22 @@ describe('plugin-meetings', () => {
2350
2427
  };
2351
2428
  });
2352
2429
 
2353
- it('applyLocusDeltaData gets full locus on DESYNC action if we do not have a syncUrl and destroys the meeting if that fails', () => {
2430
+ it('applyLocusDeltaData gets full locus on DESYNC action if we do not have a syncUrl and destroys the meeting if that fails', async () => {
2354
2431
  meeting.meetingRequest.getLocusDTO.rejects(new Error('fake error'));
2355
2432
 
2356
2433
  locusInfo.locusParser.workingCopy = {}; // no syncUrl
2357
2434
 
2358
- // Since we have a promise inside a function we want to test that's not returned,
2359
- // we will wait and stub it's last function to resolve this waiting promise.
2360
- return new Promise((resolve) => {
2361
- webex.meetings.destroy.callsFake(() => resolve());
2362
- locusInfo.applyLocusDeltaData(DESYNC, fakeLocus, meeting);
2363
- }).then(() => {
2364
- assert.calledOnceWithExactly(meeting.meetingRequest.getLocusDTO, {url: 'fullSyncUrl'});
2435
+ locusInfo.applyLocusDeltaData(DESYNC, fakeLocus, meeting);
2365
2436
 
2366
- assert.notCalled(meeting.locusInfo.handleLocusDelta);
2367
- assert.notCalled(meeting.locusInfo.onFullLocus);
2368
- assert.notCalled(locusInfo.locusParser.resume);
2437
+ await testUtils.flushPromises();
2369
2438
 
2370
- assert.calledOnceWithExactly(webex.meetings.destroy, meeting, 'LOCUS_DTO_SYNC_FAILED');
2371
- });
2439
+ assert.calledOnceWithExactly(meeting.meetingRequest.getLocusDTO, {url: 'fullSyncUrl'});
2440
+
2441
+ assert.notCalled(meeting.locusInfo.handleLocusDelta);
2442
+ assert.notCalled(meeting.locusInfo.onFullLocus);
2443
+ assert.notCalled(locusInfo.locusParser.resume);
2444
+
2445
+ assert.calledOnceWithExactly(webex.meetings.destroy, meeting, 'LOCUS_DTO_SYNC_FAILED');
2372
2446
  });
2373
2447
 
2374
2448
  it('applyLocusDeltaData first tries a delta sync on DESYNC action and if that fails, does a full locus sync', () => {
@@ -2405,44 +2479,67 @@ describe('plugin-meetings', () => {
2405
2479
  });
2406
2480
  });
2407
2481
 
2408
- it('applyLocusDeltaData destroys the meeting if both delta sync and full sync fail', () => {
2482
+ it('applyLocusDeltaData first tries a delta sync on DESYNC action and if that fails with 403, it does not do a full locus sync', async () => {
2483
+ const fake403Error = new Error('fake error');
2484
+ fake403Error.statusCode = 403;
2485
+
2486
+ meeting.meetingRequest.getLocusDTO.onCall(0).rejects(fake403Error);
2487
+
2488
+ locusInfo.applyLocusDeltaData(DESYNC, fakeLocus, meeting);
2489
+
2490
+ await testUtils.flushPromises();
2491
+
2492
+ assert.calledOnceWithExactly(meeting.meetingRequest.getLocusDTO, {url: 'deltaSyncUrl'});
2493
+
2494
+ assert.calledWith(sendBehavioralMetricStub, 'js_sdk_locus_delta_sync_failed', {
2495
+ correlationId: meeting.correlationId,
2496
+ url: 'deltaSyncUrl',
2497
+ reason: 'fake error',
2498
+ errorName: 'Error',
2499
+ stack: sinon.match.any,
2500
+ code: sinon.match.any,
2501
+ });
2502
+
2503
+ assert.notCalled(meeting.locusInfo.handleLocusDelta);
2504
+ assert.notCalled(meeting.locusInfo.onFullLocus);
2505
+ assert.notCalled(locusInfo.locusParser.resume);
2506
+ });
2507
+
2508
+ it('applyLocusDeltaData destroys the meeting if both delta sync and full sync fail', async () => {
2409
2509
  meeting.meetingRequest.getLocusDTO.rejects(new Error('fake error'));
2410
2510
 
2411
- // Since we have a promise inside a function we want to test that's not returned,
2412
- // we will wait and stub it's last function to resolve this waiting promise.
2413
- return new Promise((resolve) => {
2414
- webex.meetings.destroy.callsFake(() => resolve());
2415
- locusInfo.applyLocusDeltaData(DESYNC, fakeLocus, meeting);
2416
- }).then(() => {
2417
- assert.calledTwice(meeting.meetingRequest.getLocusDTO);
2511
+ locusInfo.applyLocusDeltaData(DESYNC, fakeLocus, meeting);
2418
2512
 
2419
- assert.deepEqual(meeting.meetingRequest.getLocusDTO.getCalls()[0].args, [
2420
- {url: 'deltaSyncUrl'},
2421
- ]);
2422
- assert.deepEqual(meeting.meetingRequest.getLocusDTO.getCalls()[1].args, [
2423
- {url: 'fullSyncUrl'},
2424
- ]);
2513
+ await testUtils.flushPromises();
2425
2514
 
2426
- assert.calledWith(sendBehavioralMetricStub, 'js_sdk_locus_delta_sync_failed', {
2427
- correlationId: meeting.correlationId,
2428
- url: 'deltaSyncUrl',
2429
- reason: 'fake error',
2430
- errorName: 'Error',
2431
- stack: sinon.match.any,
2432
- code: sinon.match.any,
2433
- });
2515
+ assert.calledTwice(meeting.meetingRequest.getLocusDTO);
2434
2516
 
2435
- assert.notCalled(meeting.locusInfo.handleLocusDelta);
2436
- assert.notCalled(meeting.locusInfo.onFullLocus);
2437
- assert.notCalled(locusInfo.locusParser.resume);
2517
+ assert.deepEqual(meeting.meetingRequest.getLocusDTO.getCalls()[0].args, [
2518
+ {url: 'deltaSyncUrl'},
2519
+ ]);
2520
+ assert.deepEqual(meeting.meetingRequest.getLocusDTO.getCalls()[1].args, [
2521
+ {url: 'fullSyncUrl'},
2522
+ ]);
2438
2523
 
2439
- assert.calledOnceWithExactly(webex.meetings.destroy, meeting, 'LOCUS_DTO_SYNC_FAILED');
2524
+ assert.calledWith(sendBehavioralMetricStub, 'js_sdk_locus_delta_sync_failed', {
2525
+ correlationId: meeting.correlationId,
2526
+ url: 'deltaSyncUrl',
2527
+ reason: 'fake error',
2528
+ errorName: 'Error',
2529
+ stack: sinon.match.any,
2530
+ code: sinon.match.any,
2440
2531
  });
2532
+
2533
+ assert.notCalled(meeting.locusInfo.handleLocusDelta);
2534
+ assert.notCalled(meeting.locusInfo.onFullLocus);
2535
+ assert.notCalled(locusInfo.locusParser.resume);
2536
+
2537
+ assert.calledOnceWithExactly(webex.meetings.destroy, meeting, 'LOCUS_DTO_SYNC_FAILED');
2441
2538
  });
2442
2539
  });
2443
2540
 
2444
2541
  it('onDeltaLocus handle delta data', () => {
2445
- fakeLocus.participants = {};
2542
+ fakeLocus.participants = [];
2446
2543
  const fakeBreakout = {
2447
2544
  sessionId: 'sessionId',
2448
2545
  groupId: 'groupId',
@@ -2459,17 +2556,15 @@ describe('plugin-meetings', () => {
2459
2556
  };
2460
2557
  locusInfo.updateParticipants = sinon.stub();
2461
2558
  locusInfo.onDeltaLocus(fakeLocus);
2462
- assert.calledWith(locusInfo.updateParticipants, {}, false);
2559
+ assert.calledWith(locusInfo.updateParticipants, [], undefined, false);
2463
2560
 
2464
2561
  fakeLocus.controls.breakout.sessionId = 'sessionId2';
2465
2562
  locusInfo.onDeltaLocus(fakeLocus);
2466
- assert.calledWith(locusInfo.updateParticipants, {}, true);
2563
+ assert.calledWith(locusInfo.updateParticipants, [], undefined, true);
2467
2564
  });
2468
2565
 
2469
2566
  it('onDeltaLocus merges delta participants with existing participants', () => {
2470
- const FAKE_DELTA_PARTICIPANTS = [
2471
- {id: '1111'}, {id: '2222'}
2472
- ]
2567
+ const FAKE_DELTA_PARTICIPANTS = [{id: '1111'}, {id: '2222'}];
2473
2568
  fakeLocus.participants = FAKE_DELTA_PARTICIPANTS;
2474
2569
 
2475
2570
  sinon.spy(locusInfo, 'mergeParticipants');
@@ -2477,8 +2572,86 @@ describe('plugin-meetings', () => {
2477
2572
  const existingParticipants = locusInfo.participants;
2478
2573
 
2479
2574
  locusInfo.onDeltaLocus(fakeLocus);
2480
- assert.calledOnceWithExactly(locusInfo.mergeParticipants, existingParticipants, FAKE_DELTA_PARTICIPANTS);
2481
- assert.calledWith(locusInfo.updateParticipants, FAKE_DELTA_PARTICIPANTS, false);
2575
+ assert.calledOnceWithExactly(
2576
+ locusInfo.mergeParticipants,
2577
+ existingParticipants,
2578
+ FAKE_DELTA_PARTICIPANTS
2579
+ );
2580
+ assert.calledWith(locusInfo.updateParticipants, FAKE_DELTA_PARTICIPANTS, undefined, false);
2581
+ });
2582
+
2583
+ [true, false].forEach((isDelta) =>
2584
+ it(`applyLocusDeltaData - handles empty ${
2585
+ isDelta ? 'delta' : 'full'
2586
+ } DTO in response`, async () => {
2587
+ const {DESYNC} = LocusDeltaParser.loci;
2588
+ const fakeFullLocusDto = {};
2589
+ const meeting = {
2590
+ meetingRequest: {
2591
+ getLocusDTO: sandbox.stub().resolves({body: fakeFullLocusDto}),
2592
+ },
2593
+ locusInfo: {
2594
+ onFullLocus: sandbox.stub(),
2595
+ handleLocusDelta: sandbox.stub(),
2596
+ },
2597
+ locusUrl: 'fake locus FULL url',
2598
+ };
2599
+
2600
+ sinon.stub(locusInfo.locusParser, 'resume').resolves();
2601
+
2602
+ if (isDelta) {
2603
+ locusInfo.locusParser.workingCopy = {syncUrl: 'fake locus DELTA url'};
2604
+ } else {
2605
+ locusInfo.locusParser.workingCopy = {}; // no syncUrl (to trigger FULL DTO request)
2606
+ }
2607
+
2608
+ await locusInfo.applyLocusDeltaData(DESYNC, fakeLocus, meeting);
2609
+
2610
+ await testUtils.flushPromises();
2611
+
2612
+ if (isDelta) {
2613
+ assert.calledOnceWithExactly(meeting.meetingRequest.getLocusDTO, {
2614
+ url: 'fake locus DELTA url',
2615
+ });
2616
+ } else {
2617
+ assert.calledOnceWithExactly(meeting.meetingRequest.getLocusDTO, {
2618
+ url: 'fake locus FULL url',
2619
+ });
2620
+ }
2621
+ assert.notCalled(meeting.locusInfo.handleLocusDelta);
2622
+ assert.notCalled(meeting.locusInfo.onFullLocus);
2623
+ assert.calledOnce(locusInfo.locusParser.resume);
2624
+ })
2625
+ );
2626
+
2627
+ it(`applyLocusDeltaData - handles the case when we get FULL DTO when we asked for DELTA DTO`, async () => {
2628
+ const {DESYNC} = LocusDeltaParser.loci;
2629
+ const fakeFullLocusDto = {someStuff: 'data'}; // non-empty DTO, without baseSequence
2630
+ const meeting = {
2631
+ meetingRequest: {
2632
+ getLocusDTO: sandbox.stub().resolves({body: fakeFullLocusDto}),
2633
+ },
2634
+ locusInfo: {
2635
+ onFullLocus: sandbox.stub(),
2636
+ handleLocusDelta: sandbox.stub(),
2637
+ },
2638
+ locusUrl: 'fake locus FULL url',
2639
+ };
2640
+
2641
+ sinon.stub(locusInfo.locusParser, 'resume').resolves();
2642
+
2643
+ locusInfo.locusParser.workingCopy = {syncUrl: 'fake locus DELTA url'};
2644
+
2645
+ await locusInfo.applyLocusDeltaData(DESYNC, fakeLocus, meeting);
2646
+
2647
+ await testUtils.flushPromises();
2648
+
2649
+ assert.calledOnceWithExactly(meeting.meetingRequest.getLocusDTO, {
2650
+ url: 'fake locus DELTA url',
2651
+ });
2652
+ assert.notCalled(meeting.locusInfo.handleLocusDelta);
2653
+ assert.calledOnceWithExactly(meeting.locusInfo.onFullLocus, fakeFullLocusDto);
2654
+ assert.calledOnce(locusInfo.locusParser.resume);
2482
2655
  });
2483
2656
  });
2484
2657
 
@@ -2892,10 +3065,9 @@ describe('plugin-meetings', () => {
2892
3065
  beforeEach(() => {
2893
3066
  clock = sinon.useFakeTimers();
2894
3067
 
2895
- sinon.stub(locusInfo, 'updateParticipantDeltas');
2896
3068
  sinon.stub(locusInfo, 'updateParticipants');
2897
- sinon.stub(locusInfo, 'isMeetingActive'),
2898
- sinon.stub(locusInfo, 'handleOneOnOneEvent'),
3069
+ sinon.stub(locusInfo, 'isMeetingActive');
3070
+ sinon.stub(locusInfo, 'handleOneOnOneEvent');
2899
3071
  (updateLocusInfoStub = sinon.stub(locusInfo, 'updateLocusInfo'));
2900
3072
  syncRequestStub = sinon.stub().resolves({body: {}});
2901
3073
 
@@ -2916,6 +3088,7 @@ describe('plugin-meetings', () => {
2916
3088
  id: 'test person id',
2917
3089
  },
2918
3090
  },
3091
+ participants: [],
2919
3092
  });
2920
3093
 
2921
3094
  updateLocusInfoStub.resetHistory();
@@ -253,7 +253,8 @@ describe('locus-info/parser', () => {
253
253
  });
254
254
 
255
255
  it('replaces current loci when the locus URL changes and incoming sequence is later, even when baseSequence doesn\'t match', () => {
256
- const {USE_INCOMING} = LocusDeltaParser.loci;
256
+ const {LOCUS_URL_CHANGED} = LocusDeltaParser.loci;
257
+ sandbox.stub(LocusDeltaParser, 'compare').returns(LOCUS_URL_CHANGED);
257
258
 
258
259
  parser.queue.dequeue = sandbox.stub().returns(NEW_LOCI);
259
260
  parser.onDeltaAction = sandbox.stub();
@@ -262,7 +263,7 @@ describe('locus-info/parser', () => {
262
263
 
263
264
  parser.processDeltaEvent();
264
265
 
265
- assert.equal(parser.workingCopy, NEW_LOCI);
266
+ assert.equal(parser.workingCopy, null);
266
267
  });
267
268
 
268
269
  it('does not replace current loci when the locus URL changes but incoming sequence is not later', () => {
@@ -137,6 +137,113 @@ describe('createMediaConnection', () => {
137
137
  );
138
138
  });
139
139
 
140
+ it('should set direction to sendonly for both audio and video when only send flags are true', () => {
141
+ const roapMediaConnectionConstructorStub = sinon
142
+ .stub(InternalMediaCoreModule, 'RoapMediaConnection')
143
+ .returns(fakeRoapMediaConnection);
144
+
145
+ StaticConfig.set({bandwidth: {audio: 123, video: 456, startBitrate: 999}});
146
+
147
+ const ENABLE_EXTMAP = false;
148
+ const ENABLE_RTX = true;
149
+
150
+ Media.createMediaConnection(false, 'sendonly-debug-id', 'meetingId', {
151
+ mediaProperties: {
152
+ mediaDirection: {
153
+ sendAudio: true,
154
+ receiveAudio: false,
155
+ sendVideo: true,
156
+ receiveVideo: false,
157
+ sendShare: false,
158
+ receiveShare: false,
159
+ },
160
+ audioStream: fakeAudioStream,
161
+ videoStream: fakeVideoStream,
162
+ shareVideoTrack: null,
163
+ shareAudioTrack: null,
164
+ },
165
+ remoteQualityLevel: 'HIGH',
166
+ enableRtx: ENABLE_RTX,
167
+ enableExtmap: ENABLE_EXTMAP,
168
+ turnServerInfo: undefined,
169
+ iceCandidatesTimeout: undefined,
170
+ });
171
+
172
+ assert.calledWith(
173
+ roapMediaConnectionConstructorStub,
174
+ sinon.match.any,
175
+ {
176
+ localTracks: {
177
+ audio: fakeTrack,
178
+ video: fakeTrack,
179
+ screenShareVideo: undefined,
180
+ screenShareAudio: undefined,
181
+ },
182
+ direction: {
183
+ audio: 'sendonly',
184
+ video: 'sendonly',
185
+ screenShareVideo: 'inactive',
186
+ },
187
+ remoteQualityLevel: 'HIGH',
188
+ },
189
+ 'sendonly-debug-id'
190
+ );
191
+ });
192
+
193
+ it('should set direction to recvonly for both audio and video when only receive flags are true', () => {
194
+ const roapMediaConnectionConstructorStub = sinon
195
+ .stub(InternalMediaCoreModule, 'RoapMediaConnection')
196
+ .returns(fakeRoapMediaConnection);
197
+
198
+ StaticConfig.set({bandwidth: {audio: 123, video: 456, startBitrate: 999}});
199
+
200
+ const ENABLE_EXTMAP = true;
201
+ const ENABLE_RTX = false;
202
+
203
+ Media.createMediaConnection(false, 'recvonly-debug-id', 'meetingId', {
204
+ mediaProperties: {
205
+ mediaDirection: {
206
+ sendAudio: false,
207
+ receiveAudio: true,
208
+ sendVideo: false,
209
+ receiveVideo: true,
210
+ sendShare: false,
211
+ receiveShare: false,
212
+ },
213
+ audioStream: fakeAudioStream,
214
+ videoStream: fakeVideoStream,
215
+ shareVideoTrack: null,
216
+ shareAudioTrack: null,
217
+ },
218
+ remoteQualityLevel: 'HIGH',
219
+ enableRtx: ENABLE_RTX,
220
+ enableExtmap: ENABLE_EXTMAP,
221
+ turnServerInfo: undefined,
222
+ iceCandidatesTimeout: undefined,
223
+ });
224
+
225
+ assert.calledWith(
226
+ roapMediaConnectionConstructorStub,
227
+ sinon.match.any,
228
+ {
229
+ localTracks: {
230
+ audio: fakeTrack,
231
+ video: fakeTrack,
232
+ screenShareVideo: undefined,
233
+ screenShareAudio: undefined,
234
+ },
235
+ direction: {
236
+ audio: 'recvonly',
237
+ video: 'recvonly',
238
+ screenShareVideo: 'inactive',
239
+ },
240
+ remoteQualityLevel: 'HIGH',
241
+ },
242
+ 'recvonly-debug-id'
243
+ );
244
+ });
245
+
246
+
140
247
  it('creates a MultistreamRoapMediaConnection when multistream is enabled', () => {
141
248
  const multistreamRoapMediaConnectionConstructorStub = sinon
142
249
  .stub(InternalMediaCoreModule, 'MultistreamRoapMediaConnection')