@webex/plugin-meetings 3.10.0 → 3.11.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (283) hide show
  1. package/dist/annotation/annotation.types.js.map +1 -1
  2. package/dist/annotation/constants.js.map +1 -1
  3. package/dist/annotation/index.js +19 -22
  4. package/dist/annotation/index.js.map +1 -1
  5. package/dist/breakouts/breakout.js +6 -6
  6. package/dist/breakouts/breakout.js.map +1 -1
  7. package/dist/breakouts/collection.js.map +1 -1
  8. package/dist/breakouts/edit-lock-error.js +9 -11
  9. package/dist/breakouts/edit-lock-error.js.map +1 -1
  10. package/dist/breakouts/events.js.map +1 -1
  11. package/dist/breakouts/index.js +126 -127
  12. package/dist/breakouts/index.js.map +1 -1
  13. package/dist/breakouts/request.js +6 -8
  14. package/dist/breakouts/request.js.map +1 -1
  15. package/dist/breakouts/utils.js.map +1 -1
  16. package/dist/common/browser-detection.js.map +1 -1
  17. package/dist/common/collection.js +1 -2
  18. package/dist/common/collection.js.map +1 -1
  19. package/dist/common/config.js.map +1 -1
  20. package/dist/common/errors/captcha-error.js +9 -11
  21. package/dist/common/errors/captcha-error.js.map +1 -1
  22. package/dist/common/errors/intent-to-join.js +10 -12
  23. package/dist/common/errors/intent-to-join.js.map +1 -1
  24. package/dist/common/errors/join-forbidden-error.js +10 -12
  25. package/dist/common/errors/join-forbidden-error.js.map +1 -1
  26. package/dist/common/errors/join-meeting.js +10 -12
  27. package/dist/common/errors/join-meeting.js.map +1 -1
  28. package/dist/common/errors/join-webinar-error.js +9 -11
  29. package/dist/common/errors/join-webinar-error.js.map +1 -1
  30. package/dist/common/errors/media.js +9 -11
  31. package/dist/common/errors/media.js.map +1 -1
  32. package/dist/common/errors/multistream-not-supported-error.js +9 -11
  33. package/dist/common/errors/multistream-not-supported-error.js.map +1 -1
  34. package/dist/common/errors/no-meeting-info.js +9 -11
  35. package/dist/common/errors/no-meeting-info.js.map +1 -1
  36. package/dist/common/errors/parameter.js +11 -14
  37. package/dist/common/errors/parameter.js.map +1 -1
  38. package/dist/common/errors/password-error.js +9 -11
  39. package/dist/common/errors/password-error.js.map +1 -1
  40. package/dist/common/errors/permission.js +9 -11
  41. package/dist/common/errors/permission.js.map +1 -1
  42. package/dist/common/errors/reclaim-host-role-errors.js +32 -38
  43. package/dist/common/errors/reclaim-host-role-errors.js.map +1 -1
  44. package/dist/common/errors/reconnection-not-started.js +5 -6
  45. package/dist/common/errors/reconnection-not-started.js.map +1 -1
  46. package/dist/common/errors/reconnection.js +9 -11
  47. package/dist/common/errors/reconnection.js.map +1 -1
  48. package/dist/common/errors/stats.js +9 -11
  49. package/dist/common/errors/stats.js.map +1 -1
  50. package/dist/common/errors/webex-errors.js +38 -27
  51. package/dist/common/errors/webex-errors.js.map +1 -1
  52. package/dist/common/errors/webex-meetings-error.js +9 -12
  53. package/dist/common/errors/webex-meetings-error.js.map +1 -1
  54. package/dist/common/events/events-scope.js +9 -10
  55. package/dist/common/events/events-scope.js.map +1 -1
  56. package/dist/common/events/events.js +9 -10
  57. package/dist/common/events/events.js.map +1 -1
  58. package/dist/common/events/trigger-proxy.js.map +1 -1
  59. package/dist/common/events/util.js.map +1 -1
  60. package/dist/common/logs/logger-config.js.map +1 -1
  61. package/dist/common/logs/logger-proxy.js.map +1 -1
  62. package/dist/common/logs/request.js +17 -17
  63. package/dist/common/logs/request.js.map +1 -1
  64. package/dist/common/queue.js +1 -2
  65. package/dist/common/queue.js.map +1 -1
  66. package/dist/config.js +2 -2
  67. package/dist/config.js.map +1 -1
  68. package/dist/constants.js +13 -8
  69. package/dist/constants.js.map +1 -1
  70. package/dist/controls-options-manager/constants.js.map +1 -1
  71. package/dist/controls-options-manager/enums.js.map +1 -1
  72. package/dist/controls-options-manager/index.js +1 -2
  73. package/dist/controls-options-manager/index.js.map +1 -1
  74. package/dist/controls-options-manager/types.js.map +1 -1
  75. package/dist/controls-options-manager/util.js +1 -2
  76. package/dist/controls-options-manager/util.js.map +1 -1
  77. package/dist/hashTree/constants.js +20 -0
  78. package/dist/hashTree/constants.js.map +1 -0
  79. package/dist/hashTree/hashTree.js +515 -0
  80. package/dist/hashTree/hashTree.js.map +1 -0
  81. package/dist/hashTree/hashTreeParser.js +1250 -0
  82. package/dist/hashTree/hashTreeParser.js.map +1 -0
  83. package/dist/hashTree/types.js +23 -0
  84. package/dist/hashTree/types.js.map +1 -0
  85. package/dist/hashTree/utils.js +59 -0
  86. package/dist/hashTree/utils.js.map +1 -0
  87. package/dist/index.js +8 -2
  88. package/dist/index.js.map +1 -1
  89. package/dist/interceptors/index.js.map +1 -1
  90. package/dist/interceptors/locusRetry.js +6 -8
  91. package/dist/interceptors/locusRetry.js.map +1 -1
  92. package/dist/interceptors/locusRouteToken.js +33 -13
  93. package/dist/interceptors/locusRouteToken.js.map +1 -1
  94. package/dist/interpretation/collection.js.map +1 -1
  95. package/dist/interpretation/index.js +1 -2
  96. package/dist/interpretation/index.js.map +1 -1
  97. package/dist/interpretation/siLanguage.js +1 -1
  98. package/dist/interpretation/siLanguage.js.map +1 -1
  99. package/dist/locus-info/controlsUtils.js +5 -3
  100. package/dist/locus-info/controlsUtils.js.map +1 -1
  101. package/dist/locus-info/embeddedAppsUtils.js.map +1 -1
  102. package/dist/locus-info/fullState.js.map +1 -1
  103. package/dist/locus-info/hostUtils.js.map +1 -1
  104. package/dist/locus-info/index.js +619 -177
  105. package/dist/locus-info/index.js.map +1 -1
  106. package/dist/locus-info/infoUtils.js.map +1 -1
  107. package/dist/locus-info/mediaSharesUtils.js.map +1 -1
  108. package/dist/locus-info/parser.js +3 -4
  109. package/dist/locus-info/parser.js.map +1 -1
  110. package/dist/locus-info/selfUtils.js.map +1 -1
  111. package/dist/locus-info/types.js +7 -0
  112. package/dist/locus-info/types.js.map +1 -0
  113. package/dist/media/MediaConnectionAwaiter.js +1 -2
  114. package/dist/media/MediaConnectionAwaiter.js.map +1 -1
  115. package/dist/media/index.js +5 -2
  116. package/dist/media/index.js.map +1 -1
  117. package/dist/media/properties.js +15 -17
  118. package/dist/media/properties.js.map +1 -1
  119. package/dist/media/util.js.map +1 -1
  120. package/dist/meeting/brbState.js +8 -9
  121. package/dist/meeting/brbState.js.map +1 -1
  122. package/dist/meeting/connectionStateHandler.js +10 -13
  123. package/dist/meeting/connectionStateHandler.js.map +1 -1
  124. package/dist/meeting/in-meeting-actions.js.map +1 -1
  125. package/dist/meeting/index.js +1632 -1535
  126. package/dist/meeting/index.js.map +1 -1
  127. package/dist/meeting/locusMediaRequest.js +13 -17
  128. package/dist/meeting/locusMediaRequest.js.map +1 -1
  129. package/dist/meeting/muteState.js +11 -12
  130. package/dist/meeting/muteState.js.map +1 -1
  131. package/dist/meeting/request.js +101 -104
  132. package/dist/meeting/request.js.map +1 -1
  133. package/dist/meeting/request.type.js.map +1 -1
  134. package/dist/meeting/state.js.map +1 -1
  135. package/dist/meeting/type.js.map +1 -1
  136. package/dist/meeting/util.js +24 -23
  137. package/dist/meeting/util.js.map +1 -1
  138. package/dist/meeting/voicea-meeting.js +3 -3
  139. package/dist/meeting/voicea-meeting.js.map +1 -1
  140. package/dist/meeting-info/collection.js +7 -10
  141. package/dist/meeting-info/collection.js.map +1 -1
  142. package/dist/meeting-info/index.js +1 -2
  143. package/dist/meeting-info/index.js.map +1 -1
  144. package/dist/meeting-info/meeting-info-v2.js +135 -146
  145. package/dist/meeting-info/meeting-info-v2.js.map +1 -1
  146. package/dist/meeting-info/request.js +1 -2
  147. package/dist/meeting-info/request.js.map +1 -1
  148. package/dist/meeting-info/util.js +36 -37
  149. package/dist/meeting-info/util.js.map +1 -1
  150. package/dist/meeting-info/utilv2.js +30 -31
  151. package/dist/meeting-info/utilv2.js.map +1 -1
  152. package/dist/meetings/collection.js +6 -8
  153. package/dist/meetings/collection.js.map +1 -1
  154. package/dist/meetings/index.js +200 -148
  155. package/dist/meetings/index.js.map +1 -1
  156. package/dist/meetings/meetings.types.js.map +1 -1
  157. package/dist/meetings/request.js +6 -8
  158. package/dist/meetings/request.js.map +1 -1
  159. package/dist/meetings/util.js +36 -30
  160. package/dist/meetings/util.js.map +1 -1
  161. package/dist/member/index.js +1 -2
  162. package/dist/member/index.js.map +1 -1
  163. package/dist/member/types.js +6 -3
  164. package/dist/member/types.js.map +1 -1
  165. package/dist/member/util.js.map +1 -1
  166. package/dist/members/collection.js +1 -2
  167. package/dist/members/collection.js.map +1 -1
  168. package/dist/members/index.js +18 -21
  169. package/dist/members/index.js.map +1 -1
  170. package/dist/members/request.js +8 -11
  171. package/dist/members/request.js.map +1 -1
  172. package/dist/members/types.js.map +1 -1
  173. package/dist/members/util.js.map +1 -1
  174. package/dist/metrics/constants.js +4 -1
  175. package/dist/metrics/constants.js.map +1 -1
  176. package/dist/metrics/index.js +3 -4
  177. package/dist/metrics/index.js.map +1 -1
  178. package/dist/multistream/mediaRequestManager.js +1 -2
  179. package/dist/multistream/mediaRequestManager.js.map +1 -1
  180. package/dist/multistream/receiveSlot.js +34 -45
  181. package/dist/multistream/receiveSlot.js.map +1 -1
  182. package/dist/multistream/receiveSlotManager.js +8 -9
  183. package/dist/multistream/receiveSlotManager.js.map +1 -1
  184. package/dist/multistream/remoteMedia.js +12 -15
  185. package/dist/multistream/remoteMedia.js.map +1 -1
  186. package/dist/multistream/remoteMediaGroup.js +1 -2
  187. package/dist/multistream/remoteMediaGroup.js.map +1 -1
  188. package/dist/multistream/remoteMediaManager.js +122 -123
  189. package/dist/multistream/remoteMediaManager.js.map +1 -1
  190. package/dist/multistream/sendSlotManager.js +29 -30
  191. package/dist/multistream/sendSlotManager.js.map +1 -1
  192. package/dist/personal-meeting-room/index.js +16 -19
  193. package/dist/personal-meeting-room/index.js.map +1 -1
  194. package/dist/personal-meeting-room/request.js +7 -10
  195. package/dist/personal-meeting-room/request.js.map +1 -1
  196. package/dist/personal-meeting-room/util.js.map +1 -1
  197. package/dist/reachability/clusterReachability.js +188 -352
  198. package/dist/reachability/clusterReachability.js.map +1 -1
  199. package/dist/reachability/index.js +206 -206
  200. package/dist/reachability/index.js.map +1 -1
  201. package/dist/reachability/reachability.types.js +14 -1
  202. package/dist/reachability/reachability.types.js.map +1 -1
  203. package/dist/reachability/reachabilityPeerConnection.js +445 -0
  204. package/dist/reachability/reachabilityPeerConnection.js.map +1 -0
  205. package/dist/reachability/request.js.map +1 -1
  206. package/dist/reachability/util.js.map +1 -1
  207. package/dist/reactions/constants.js.map +1 -1
  208. package/dist/reactions/reactions.js.map +1 -1
  209. package/dist/reactions/reactions.type.js.map +1 -1
  210. package/dist/reconnection-manager/index.js +178 -176
  211. package/dist/reconnection-manager/index.js.map +1 -1
  212. package/dist/recording-controller/enums.js.map +1 -1
  213. package/dist/recording-controller/index.js +1 -2
  214. package/dist/recording-controller/index.js.map +1 -1
  215. package/dist/recording-controller/util.js.map +1 -1
  216. package/dist/roap/index.js +12 -15
  217. package/dist/roap/index.js.map +1 -1
  218. package/dist/roap/request.js +24 -26
  219. package/dist/roap/request.js.map +1 -1
  220. package/dist/roap/turnDiscovery.js +75 -76
  221. package/dist/roap/turnDiscovery.js.map +1 -1
  222. package/dist/roap/types.js.map +1 -1
  223. package/dist/transcription/index.js +4 -5
  224. package/dist/transcription/index.js.map +1 -1
  225. package/dist/types/common/errors/webex-errors.d.ts +12 -0
  226. package/dist/types/config.d.ts +1 -0
  227. package/dist/types/constants.d.ts +27 -21
  228. package/dist/types/hashTree/constants.d.ts +8 -0
  229. package/dist/types/hashTree/hashTree.d.ts +129 -0
  230. package/dist/types/hashTree/hashTreeParser.d.ts +250 -0
  231. package/dist/types/hashTree/types.d.ts +33 -0
  232. package/dist/types/hashTree/utils.d.ts +16 -0
  233. package/dist/types/index.d.ts +2 -1
  234. package/dist/types/interceptors/locusRouteToken.d.ts +2 -0
  235. package/dist/types/locus-info/index.d.ts +98 -80
  236. package/dist/types/locus-info/types.d.ts +54 -0
  237. package/dist/types/meeting/index.d.ts +35 -9
  238. package/dist/types/meetings/index.d.ts +9 -2
  239. package/dist/types/metrics/constants.d.ts +3 -0
  240. package/dist/types/reachability/clusterReachability.d.ts +33 -84
  241. package/dist/types/reachability/reachability.types.d.ts +12 -1
  242. package/dist/types/reachability/reachabilityPeerConnection.d.ts +111 -0
  243. package/dist/webinar/collection.js +1 -2
  244. package/dist/webinar/collection.js.map +1 -1
  245. package/dist/webinar/index.js +148 -158
  246. package/dist/webinar/index.js.map +1 -1
  247. package/package.json +24 -23
  248. package/src/common/errors/webex-errors.ts +19 -0
  249. package/src/config.ts +1 -0
  250. package/src/constants.ts +15 -2
  251. package/src/hashTree/constants.ts +9 -0
  252. package/src/hashTree/hashTree.ts +463 -0
  253. package/src/hashTree/hashTreeParser.ts +1143 -0
  254. package/src/hashTree/types.ts +39 -0
  255. package/src/hashTree/utils.ts +53 -0
  256. package/src/index.ts +2 -0
  257. package/src/interceptors/locusRouteToken.ts +22 -5
  258. package/src/locus-info/controlsUtils.ts +6 -0
  259. package/src/locus-info/index.ts +641 -164
  260. package/src/locus-info/types.ts +53 -0
  261. package/src/media/index.ts +6 -0
  262. package/src/meeting/index.ts +137 -28
  263. package/src/meeting/util.ts +1 -0
  264. package/src/meetings/index.ts +119 -59
  265. package/src/meetings/util.ts +10 -9
  266. package/src/metrics/constants.ts +3 -0
  267. package/src/reachability/clusterReachability.ts +159 -330
  268. package/src/reachability/index.ts +6 -1
  269. package/src/reachability/reachability.types.ts +15 -1
  270. package/src/reachability/reachabilityPeerConnection.ts +418 -0
  271. package/test/unit/spec/hashTree/hashTree.ts +655 -0
  272. package/test/unit/spec/hashTree/hashTreeParser.ts +1524 -0
  273. package/test/unit/spec/hashTree/utils.ts +140 -0
  274. package/test/unit/spec/interceptors/locusRouteToken.ts +44 -0
  275. package/test/unit/spec/locus-info/controlsUtils.js +27 -1
  276. package/test/unit/spec/locus-info/index.js +879 -16
  277. package/test/unit/spec/media/index.ts +140 -9
  278. package/test/unit/spec/meeting/index.js +299 -94
  279. package/test/unit/spec/meeting/utils.js +78 -1
  280. package/test/unit/spec/meetings/index.js +263 -29
  281. package/test/unit/spec/meetings/utils.js +51 -1
  282. package/test/unit/spec/reachability/clusterReachability.ts +404 -137
  283. package/test/unit/spec/reachability/index.ts +3 -3
@@ -97,6 +97,7 @@ import PermissionError from '../../../../src/common/errors/permission';
97
97
  import JoinWebinarError from '../../../../src/common/errors/join-webinar-error';
98
98
  import IntentToJoinError from '../../../../src/common/errors/intent-to-join';
99
99
  import MultistreamNotSupportedError from '../../../../src/common/errors/multistream-not-supported-error';
100
+ import {SdpResponseTimeoutError} from '@webex/plugin-meetings/src/common/errors/webex-errors';
100
101
  import testUtils from '../../../utils/testUtils';
101
102
  import {
102
103
  MeetingInfoV2CaptchaError,
@@ -132,11 +133,15 @@ describe('plugin-meetings', () => {
132
133
  debug: () => {},
133
134
  };
134
135
 
136
+ let fakeClock;
137
+
135
138
  beforeEach(() => {
136
139
  sinon.stub(Metrics, 'sendBehavioralMetric');
140
+ fakeClock = sinon.useFakeTimers();
137
141
  });
138
142
  afterEach(() => {
139
143
  sinon.restore();
144
+ fakeClock.restore();
140
145
  });
141
146
 
142
147
  before(() => {
@@ -1002,6 +1007,35 @@ describe('plugin-meetings', () => {
1002
1007
  );
1003
1008
  });
1004
1009
 
1010
+ it('should call leave() if addMediaInternal() fails ', async () => {
1011
+ const addMediaError = new Error('fake addMedia error');
1012
+ addMediaError.name = 'TypeError';
1013
+
1014
+ const rejectError = {
1015
+ error: {
1016
+ body: {
1017
+ errorCode: 2729,
1018
+ message: 'fake addMedia error',
1019
+ name: 'TypeError'
1020
+ }
1021
+ }
1022
+ };
1023
+ meeting.addMediaInternal.rejects(addMediaError);
1024
+ sinon.stub(meeting, 'leave').resolves();
1025
+
1026
+ await assert.isRejected(
1027
+ meeting.joinWithMedia({
1028
+ joinOptions,
1029
+ mediaOptions,
1030
+ }),
1031
+ rejectError
1032
+ );
1033
+
1034
+ assert.calledOnce(meeting.join);
1035
+ assert.calledOnce(meeting.addMediaInternal);
1036
+ assert.calledOnce(Metrics.sendBehavioralMetric);
1037
+ });
1038
+
1005
1039
  it('should not call leave() if addMediaInternal() fails the first time and succeeds the second time and should only call join() once', async () => {
1006
1040
  const addMediaError = new Error('fake addMedia error');
1007
1041
  const leaveStub = sinon.stub(meeting, 'leave');
@@ -1329,6 +1363,25 @@ describe('plugin-meetings', () => {
1329
1363
  });
1330
1364
  });
1331
1365
 
1366
+ describe('#update hesiod llm id', () => {
1367
+ beforeEach(() => {
1368
+ webex.internal.voicea.onCaptionServiceIdUpdate = sinon.stub();
1369
+ });
1370
+ afterEach(() => {
1371
+ // Restore the original methods after each test
1372
+ sinon.restore();
1373
+ });
1374
+ it('should call voicea.onCaptionServiceIdUpdate when joined', async () => {
1375
+ meeting.joinedWith = {state: 'JOINED'};
1376
+ await meeting.locusInfo.emitScoped(
1377
+ {function: 'test', file: 'test'},
1378
+ LOCUSINFO.EVENTS.CONTROLS_MEETING_HESIOD_LLM_ID_UPDATED,
1379
+ {hesiodLlmId: '123a-456b-789c'}
1380
+ );
1381
+ assert.calledWith(webex.internal.voicea.onCaptionServiceIdUpdate, '123a-456b-789c');
1382
+ });
1383
+ });
1384
+
1332
1385
  describe('#update spoken language', () => {
1333
1386
  beforeEach(() => {
1334
1387
  webex.internal.voicea.onSpokenLanguageUpdate = sinon.stub();
@@ -1848,7 +1901,7 @@ describe('plugin-meetings', () => {
1848
1901
  setCorrelationIdSpy = sinon.spy(meeting, 'setCorrelationId');
1849
1902
  meeting.setLocus = sinon.stub().returns(true);
1850
1903
  webex.meetings.registered = true;
1851
- meeting.updateLLMConnection = sinon.stub().returns(Promise.resolve());
1904
+ sinon.stub(meeting, 'updateLLMConnection').returns(Promise.resolve());
1852
1905
  });
1853
1906
 
1854
1907
  describe('successful', () => {
@@ -1999,18 +2052,15 @@ describe('plugin-meetings', () => {
1999
2052
 
2000
2053
  // Assert that client.locus.join.response error event is not sent from this function, it is now emitted from MeetingUtil.joinMeeting
2001
2054
  assert.calledOnce(webex.internal.newMetrics.submitClientEvent);
2002
- assert.calledWithMatch(
2003
- webex.internal.newMetrics.submitClientEvent,
2004
- {
2005
- name: 'client.call.initiated',
2006
- payload: {
2007
- trigger: 'user-interaction',
2008
- isRoapCallEnabled: true,
2009
- pstnAudioType: undefined
2010
- },
2011
- options: {meetingId: meeting.id},
2012
- }
2013
- );
2055
+ assert.calledWithMatch(webex.internal.newMetrics.submitClientEvent, {
2056
+ name: 'client.call.initiated',
2057
+ payload: {
2058
+ trigger: 'user-interaction',
2059
+ isRoapCallEnabled: true,
2060
+ pstnAudioType: undefined,
2061
+ },
2062
+ options: {meetingId: meeting.id},
2063
+ });
2014
2064
  });
2015
2065
  });
2016
2066
  it('should fail if password is required', async () => {
@@ -2042,7 +2092,7 @@ describe('plugin-meetings', () => {
2042
2092
  const defer = new Defer();
2043
2093
 
2044
2094
  meeting.config.enableAutomaticLLM = true;
2045
- meeting.updateLLMConnection = sinon.stub().returns(defer.promise);
2095
+ meeting.updateLLMConnection.returns(defer.promise);
2046
2096
 
2047
2097
  const result = await meeting.join();
2048
2098
 
@@ -2053,7 +2103,7 @@ describe('plugin-meetings', () => {
2053
2103
 
2054
2104
  it('should call updateLLMConnection as part of joining if config value is set', async () => {
2055
2105
  meeting.config.enableAutomaticLLM = true;
2056
- meeting.updateLLMConnection = sinon.stub().resolves();
2106
+ meeting.updateLLMConnection.resolves();
2057
2107
 
2058
2108
  await meeting.join();
2059
2109
 
@@ -2061,7 +2111,7 @@ describe('plugin-meetings', () => {
2061
2111
  });
2062
2112
 
2063
2113
  it('should not call updateLLMConnection as part of joining if config value is not set', async () => {
2064
- meeting.updateLLMConnection = sinon.stub().resolves();
2114
+ meeting.updateLLMConnection.resolves();
2065
2115
  await meeting.join();
2066
2116
 
2067
2117
  assert.notCalled(meeting.updateLLMConnection);
@@ -2071,7 +2121,7 @@ describe('plugin-meetings', () => {
2071
2121
  const defer = new Defer();
2072
2122
 
2073
2123
  meeting.config.enableAutomaticLLM = true;
2074
- meeting.updateLLMConnection = sinon.stub().returns(defer.promise);
2124
+ meeting.updateLLMConnection.returns(defer.promise);
2075
2125
 
2076
2126
  const result = await meeting.join();
2077
2127
 
@@ -2097,6 +2147,111 @@ describe('plugin-meetings', () => {
2097
2147
  ]);
2098
2148
  }
2099
2149
  });
2150
+
2151
+ it('handles Locus LLM events', async () => {
2152
+ const locusInfoParseStub = sinon.stub(meeting.locusInfo, 'parse');
2153
+ sinon.stub(meeting, 'isJoined').returns(true);
2154
+
2155
+ // Set up llm.on stub to capture the registered listener when updateLLMConnection is called
2156
+ let locusLLMEventListener;
2157
+ meeting.webex.internal.llm.on = sinon.stub().callsFake((eventName, callback) => {
2158
+ if (eventName === 'event:locus.state_message') {
2159
+ locusLLMEventListener = callback;
2160
+ }
2161
+ });
2162
+ meeting.webex.internal.llm.off = sinon.stub();
2163
+
2164
+ // we need the real meeting.updateLLMConnection not the mock
2165
+ meeting.updateLLMConnection.restore();
2166
+
2167
+ // Call updateLLMConnection to register the listener
2168
+ await meeting.updateLLMConnection();
2169
+
2170
+ // Verify the listener was registered and we captured it
2171
+ assert.isDefined(locusLLMEventListener, 'LLM event listener should be registered');
2172
+
2173
+ // Now trigger the event
2174
+ const eventData = {
2175
+ eventType: 'locus.state_message',
2176
+ stateElementsMessage: {
2177
+ header: {messageId: 'msg-1'},
2178
+ elements: [],
2179
+ },
2180
+ };
2181
+
2182
+ locusLLMEventListener({data: eventData});
2183
+
2184
+ assert.calledOnceWithExactly(locusInfoParseStub, meeting, eventData);
2185
+ });
2186
+
2187
+ it('UpdateLLMConnection sends a metric if not connected after timeout', async () => {
2188
+ sinon.stub(meeting, 'isJoined').returns(true);
2189
+ sinon.stub(meeting.webex.internal.llm, 'isConnected').returns(false);
2190
+ sinon.stub(meeting.webex.internal.llm, 'hasEverConnected').value(true);
2191
+ sinon.stub(meeting.webex.internal.llm, 'registerAndConnect').resolves({});
2192
+
2193
+ // Restore the real updateLLMConnection
2194
+ meeting.updateLLMConnection.restore();
2195
+
2196
+ // Call updateLLMConnection to start the timer
2197
+ await meeting.updateLLMConnection();
2198
+
2199
+ // Fast forward time by 3 minutes
2200
+ fakeClock.tick(3 * 60 * 1000);
2201
+
2202
+ assert.calledWith(
2203
+ Metrics.sendBehavioralMetric,
2204
+ BEHAVIORAL_METRICS.LLM_HEALTHCHECK_FAILURE,
2205
+ {
2206
+ correlation_id: meeting.correlationId,
2207
+ hasEverConnected: true,
2208
+ }
2209
+ );
2210
+ });
2211
+
2212
+ it('clears the LLM health check timer when disconnecting LLM', async () => {
2213
+ const isJoinedStub = sinon.stub(meeting, 'isJoined');
2214
+ sinon.stub(meeting.webex.internal.llm, 'isConnected');
2215
+ sinon.stub(meeting.webex.internal.llm, 'disconnectLLM').resolves();
2216
+ sinon.stub(meeting.webex.internal.llm, 'registerAndConnect').resolves({});
2217
+ sinon
2218
+ .stub(meeting.webex.internal.llm, 'getLocusUrl')
2219
+ .returns('https://locus1.example.com');
2220
+ sinon
2221
+ .stub(meeting.webex.internal.llm, 'getDatachannelUrl')
2222
+ .returns('https://datachannel1.example.com');
2223
+
2224
+ // Restore the real updateLLMConnection
2225
+ meeting.updateLLMConnection.restore();
2226
+
2227
+ // First, connect LLM and start the timer
2228
+ isJoinedStub.returns(true);
2229
+ meeting.webex.internal.llm.isConnected.returns(false);
2230
+ await meeting.updateLLMConnection();
2231
+
2232
+ // Verify timer was started
2233
+ assert.exists(meeting.llmHealthCheckTimer);
2234
+
2235
+ // Now simulate that we're no longer joined
2236
+ isJoinedStub.returns(false);
2237
+ meeting.webex.internal.llm.isConnected.returns(true);
2238
+
2239
+ await meeting.updateLLMConnection();
2240
+
2241
+ assert.calledOnce(meeting.webex.internal.llm.disconnectLLM);
2242
+
2243
+ // Verify the timer was cleared (should be undefined)
2244
+ assert.isUndefined(meeting.llmHealthCheckTimer);
2245
+
2246
+ // Fast forward time to ensure no metric is sent
2247
+ Metrics.sendBehavioralMetric.resetHistory();
2248
+ fakeClock.tick(3 * 60 * 1000);
2249
+
2250
+ assert.neverCalledWith(
2251
+ Metrics.sendBehavioralMetric,
2252
+ BEHAVIORAL_METRICS.LLM_HEALTHCHECK_FAILURE
2253
+ );
2254
+ });
2100
2255
  });
2101
2256
 
2102
2257
  describe('refreshPermissionToken', () => {
@@ -2679,7 +2834,11 @@ describe('plugin-meetings', () => {
2679
2834
  // simulate timeout waiting for the SDP answer that never comes
2680
2835
  await clock.tickAsync(ROAP_OFFER_ANSWER_EXCHANGE_TIMEOUT);
2681
2836
 
2682
- await assert.isRejected(result);
2837
+ await assert.isRejected(
2838
+ result,
2839
+ SdpResponseTimeoutError,
2840
+ 'Timed out waiting for REMOTE SDP ANSWER'
2841
+ );
2683
2842
 
2684
2843
  assert.calledOnceWithExactly(getErrorPayloadForClientErrorCodeStub, {
2685
2844
  clientErrorCode: 2007,
@@ -4087,7 +4246,7 @@ describe('plugin-meetings', () => {
4087
4246
  member2: {isInMeeting: false, isInLobby: true},
4088
4247
  member3: {isInMeeting: false, isInLobby: false},
4089
4248
  member4: {isInMeeting: true, isInLobby: false},
4090
- }
4249
+ },
4091
4250
  };
4092
4251
  sinon.stub(meeting, 'getMembers').returns({membersCollection: fakeMembersCollection});
4093
4252
  const fakeData = {intervalMetadata: {}};
@@ -4747,6 +4906,7 @@ describe('plugin-meetings', () => {
4747
4906
  id: 'fake locus from mocked join request',
4748
4907
  locusUrl: 'fake locus url',
4749
4908
  mediaId: 'fake media id',
4909
+ locus: {fullState: {}},
4750
4910
  });
4751
4911
  sinon.stub(meeting.meetingRequest, 'joinMeeting').resolves({
4752
4912
  headers: {
@@ -6739,7 +6899,7 @@ describe('plugin-meetings', () => {
6739
6899
  // Verify pstnCorrelationId was set
6740
6900
  assert.exists(meeting.pstnCorrelationId);
6741
6901
  assert.notEqual(meeting.pstnCorrelationId, meeting.correlationId);
6742
- const firstPstnCorrelationId = meeting.pstnCorrelationId
6902
+ const firstPstnCorrelationId = meeting.pstnCorrelationId;
6743
6903
 
6744
6904
  meeting.meetingRequest.dialIn.resetHistory();
6745
6905
 
@@ -6814,15 +6974,19 @@ describe('plugin-meetings', () => {
6814
6974
  assert.equal(e, error);
6815
6975
 
6816
6976
  // Verify behavioral metric was sent with dial_in_correlation_id
6817
- assert.calledWith(Metrics.sendBehavioralMetric, BEHAVIORAL_METRICS.ADD_DIAL_IN_FAILURE, {
6818
- correlation_id: meeting.correlationId,
6819
- dial_in_url: meeting.dialInUrl,
6820
- dial_in_correlation_id: sinon.match.string,
6821
- locus_id: meeting.locusUrl.split('/').pop(),
6822
- client_url: meeting.deviceUrl,
6823
- reason: error.error.message,
6824
- stack: error.stack,
6825
- });
6977
+ assert.calledWith(
6978
+ Metrics.sendBehavioralMetric,
6979
+ BEHAVIORAL_METRICS.ADD_DIAL_IN_FAILURE,
6980
+ {
6981
+ correlation_id: meeting.correlationId,
6982
+ dial_in_url: meeting.dialInUrl,
6983
+ dial_in_correlation_id: sinon.match.string,
6984
+ locus_id: meeting.locusUrl.split('/').pop(),
6985
+ client_url: meeting.deviceUrl,
6986
+ reason: error.error.message,
6987
+ stack: error.stack,
6988
+ }
6989
+ );
6826
6990
 
6827
6991
  // Verify pstnCorrelationId was cleared after error
6828
6992
  assert.equal(meeting.pstnCorrelationId, undefined);
@@ -6841,15 +7005,19 @@ describe('plugin-meetings', () => {
6841
7005
  assert.equal(e, error);
6842
7006
 
6843
7007
  // Verify behavioral metric was sent with dial_out_correlation_id
6844
- assert.calledWith(Metrics.sendBehavioralMetric, BEHAVIORAL_METRICS.ADD_DIAL_OUT_FAILURE, {
6845
- correlation_id: meeting.correlationId,
6846
- dial_out_url: meeting.dialOutUrl,
6847
- dial_out_correlation_id: sinon.match.string,
6848
- locus_id: meeting.locusUrl.split('/').pop(),
6849
- client_url: meeting.deviceUrl,
6850
- reason: error.error.message,
6851
- stack: error.stack,
6852
- });
7008
+ assert.calledWith(
7009
+ Metrics.sendBehavioralMetric,
7010
+ BEHAVIORAL_METRICS.ADD_DIAL_OUT_FAILURE,
7011
+ {
7012
+ correlation_id: meeting.correlationId,
7013
+ dial_out_url: meeting.dialOutUrl,
7014
+ dial_out_correlation_id: sinon.match.string,
7015
+ locus_id: meeting.locusUrl.split('/').pop(),
7016
+ client_url: meeting.deviceUrl,
7017
+ reason: error.error.message,
7018
+ stack: error.stack,
7019
+ }
7020
+ );
6853
7021
 
6854
7022
  // Verify pstnCorrelationId was cleared after error
6855
7023
  assert.equal(meeting.pstnCorrelationId, undefined);
@@ -6894,7 +7062,7 @@ describe('plugin-meetings', () => {
6894
7062
 
6895
7063
  // Verify that pstnCorrelationId is still cleared even when no phone connection is active
6896
7064
  assert.equal(meeting.pstnCorrelationId, undefined);
6897
- // And verify no disconnect was attempted
7065
+ // And verify no disconnect was attempted
6898
7066
  assert.notCalled(MeetingUtil.disconnectPhoneAudio);
6899
7067
  });
6900
7068
  });
@@ -10568,7 +10736,7 @@ describe('plugin-meetings', () => {
10568
10736
  describe('#setUpLocusUrlListener', () => {
10569
10737
  it('listens to the locus url update event', (done) => {
10570
10738
  const newLocusUrl = 'newLocusUrl/12345';
10571
- const payload = {url: newLocusUrl}
10739
+ const payload = {url: newLocusUrl};
10572
10740
 
10573
10741
  meeting.members = {locusUrlUpdate: sinon.stub().returns(Promise.resolve(test1))};
10574
10742
  meeting.recordingController = {setLocusUrl: sinon.stub().returns(undefined)};
@@ -10611,7 +10779,7 @@ describe('plugin-meetings', () => {
10611
10779
  });
10612
10780
  it('update mainLocusUrl for controlsOptionManager if payload.isMainLocus as true', (done) => {
10613
10781
  const newLocusUrl = 'newLocusUrl/12345';
10614
- const payload = {url: newLocusUrl, isMainLocus: true}
10782
+ const payload = {url: newLocusUrl, isMainLocus: true};
10615
10783
 
10616
10784
  meeting.controlsOptionsManager = {setLocusUrl: sinon.stub().returns(undefined)};
10617
10785
 
@@ -10843,7 +11011,9 @@ describe('plugin-meetings', () => {
10843
11011
  meeting.meetingRequest.changeMeetingFloor = sinon.stub().returns(Promise.resolve());
10844
11012
  (meeting.deviceUrl = 'deviceUrl.com'), (meeting.localShareInstanceId = '1234-5678');
10845
11013
  webex.internal.newMetrics.callDiagnosticLatencies.saveTimestamp = sinon.stub();
10846
- webex.internal.newMetrics.callDiagnosticLatencies.getShareDuration = sinon.stub().returns(1000);
11014
+ webex.internal.newMetrics.callDiagnosticLatencies.getShareDuration = sinon
11015
+ .stub()
11016
+ .returns(1000);
10847
11017
  });
10848
11018
  it('should call changeMeetingFloor()', async () => {
10849
11019
  meeting.screenShareFloorState = 'GRANTED';
@@ -11494,8 +11664,10 @@ describe('plugin-meetings', () => {
11494
11664
  canShareWhiteBoardSpy = sinon.spy(MeetingUtil, 'canShareWhiteBoard');
11495
11665
  canMoveToLobbySpy = sinon.spy(MeetingUtil, 'canMoveToLobby');
11496
11666
  showAutoEndMeetingWarningSpy = sinon.spy(MeetingUtil, 'showAutoEndMeetingWarning');
11497
- isSpokenLanguageAutoDetectionEnabledSpy = sinon.spy(MeetingUtil, 'isSpokenLanguageAutoDetectionEnabled');
11498
-
11667
+ isSpokenLanguageAutoDetectionEnabledSpy = sinon.spy(
11668
+ MeetingUtil,
11669
+ 'isSpokenLanguageAutoDetectionEnabled'
11670
+ );
11499
11671
  });
11500
11672
 
11501
11673
  afterEach(() => {
@@ -12277,16 +12449,26 @@ describe('plugin-meetings', () => {
12277
12449
  assert.notCalled(webex.internal.llm.disconnectLLM);
12278
12450
  assert.calledWith(webex.internal.llm.registerAndConnect, 'a url', 'a datachannel url');
12279
12451
  assert.equal(result, 'something');
12280
- assert.calledOnceWithExactly(
12452
+ assert.calledWithExactly(
12281
12453
  meeting.webex.internal.llm.off,
12282
12454
  'event:relay.event',
12283
12455
  meeting.processRelayEvent
12284
12456
  );
12285
- assert.calledOnceWithExactly(
12457
+ assert.calledWithExactly(
12458
+ meeting.webex.internal.llm.off,
12459
+ 'event:locus.state_message',
12460
+ meeting.processLocusLLMEvent
12461
+ );
12462
+ assert.calledWithExactly(
12286
12463
  meeting.webex.internal.llm.on,
12287
12464
  'event:relay.event',
12288
12465
  meeting.processRelayEvent
12289
12466
  );
12467
+ assert.calledWithExactly(
12468
+ meeting.webex.internal.llm.on,
12469
+ 'event:locus.state_message',
12470
+ meeting.processLocusLLMEvent
12471
+ );
12290
12472
  });
12291
12473
 
12292
12474
  it('disconnects if first if the locus url has changed', async () => {
@@ -12314,15 +12496,25 @@ describe('plugin-meetings', () => {
12314
12496
  'event:relay.event',
12315
12497
  meeting.processRelayEvent
12316
12498
  );
12317
- assert.calledTwice(meeting.webex.internal.llm.off);
12318
- assert.calledOnceWithExactly(
12499
+ assert.calledWithExactly(
12500
+ meeting.webex.internal.llm.off,
12501
+ 'event:locus.state_message',
12502
+ meeting.processLocusLLMEvent
12503
+ );
12504
+ assert.callCount(meeting.webex.internal.llm.off, 4);
12505
+ assert.calledWithExactly(
12319
12506
  meeting.webex.internal.llm.on,
12320
12507
  'event:relay.event',
12321
12508
  meeting.processRelayEvent
12322
12509
  );
12510
+ assert.calledWithExactly(
12511
+ meeting.webex.internal.llm.on,
12512
+ 'event:locus.state_message',
12513
+ meeting.processLocusLLMEvent
12514
+ );
12323
12515
  });
12324
12516
 
12325
- it('disconnects if first if the data channel url has changed', async () => {
12517
+ it('disconnects it first if the data channel url has changed', async () => {
12326
12518
  meeting.joinedWith = {state: 'JOINED'};
12327
12519
  webex.internal.llm.isConnected.returns(true);
12328
12520
  webex.internal.llm.getLocusUrl.returns('a url');
@@ -12347,12 +12539,21 @@ describe('plugin-meetings', () => {
12347
12539
  'event:relay.event',
12348
12540
  meeting.processRelayEvent
12349
12541
  );
12350
- assert.calledTwice(meeting.webex.internal.llm.off);
12351
- assert.calledOnceWithExactly(
12542
+ assert.calledWithExactly(
12543
+ meeting.webex.internal.llm.off,
12544
+ 'event:locus.state_message',
12545
+ meeting.processLocusLLMEvent
12546
+ );
12547
+ assert.calledWithExactly(
12352
12548
  meeting.webex.internal.llm.on,
12353
12549
  'event:relay.event',
12354
12550
  meeting.processRelayEvent
12355
12551
  );
12552
+ assert.calledWithExactly(
12553
+ meeting.webex.internal.llm.on,
12554
+ 'event:locus.state_message',
12555
+ meeting.processLocusLLMEvent
12556
+ );
12356
12557
  });
12357
12558
 
12358
12559
  it('disconnects when the state is not JOINED', async () => {
@@ -12367,11 +12568,16 @@ describe('plugin-meetings', () => {
12367
12568
  assert.calledWith(webex.internal.llm.disconnectLLM, undefined);
12368
12569
  assert.notCalled(webex.internal.llm.registerAndConnect);
12369
12570
  assert.equal(result, undefined);
12370
- assert.calledOnceWithExactly(
12571
+ assert.calledWithExactly(
12371
12572
  meeting.webex.internal.llm.off,
12372
12573
  'event:relay.event',
12373
12574
  meeting.processRelayEvent
12374
12575
  );
12576
+ assert.calledWithExactly(
12577
+ meeting.webex.internal.llm.off,
12578
+ 'event:locus.state_message',
12579
+ meeting.processLocusLLMEvent
12580
+ );
12375
12581
  });
12376
12582
 
12377
12583
  it('connect ps data channel if ps started in webinar', async () => {
@@ -12397,22 +12603,22 @@ describe('plugin-meetings', () => {
12397
12603
  });
12398
12604
 
12399
12605
  it('should read the locus object, set on the meeting and return null', () => {
12606
+ const dataSets = {someFakeStuff: 'dataSet'};
12607
+
12400
12608
  meeting.setLocus({
12401
12609
  mediaConnections: [test1],
12402
12610
  locusUrl: url1,
12403
12611
  locusId: uuid1,
12404
12612
  selfId: uuid2,
12405
12613
  mediaId: uuid3,
12406
- host: {id: uuid4},
12614
+ locus: {host: {id: uuid4}},
12615
+ dataSets,
12407
12616
  });
12408
12617
  assert.calledOnce(meeting.locusInfo.initialSetup);
12409
12618
  assert.calledWith(meeting.locusInfo.initialSetup, {
12410
- mediaConnections: [test1],
12411
- locusUrl: url1,
12412
- locusId: uuid1,
12413
- selfId: uuid2,
12414
- mediaId: uuid3,
12415
- host: {id: uuid4},
12619
+ trigger: 'join-response',
12620
+ locus: {host: {id: uuid4}},
12621
+ dataSets,
12416
12622
  });
12417
12623
  assert.equal(meeting.mediaConnections, test1);
12418
12624
  assert.equal(meeting.locusUrl, url1);
@@ -12502,7 +12708,9 @@ describe('plugin-meetings', () => {
12502
12708
  meeting.meetingRequest.changeMeetingFloor = sinon.stub().returns(Promise.resolve());
12503
12709
  meeting.deviceUrl = 'deviceUrl.com';
12504
12710
  webex.internal.newMetrics.callDiagnosticLatencies.saveTimestamp = sinon.stub();
12505
- webex.internal.newMetrics.callDiagnosticLatencies.getShareDuration = sinon.stub().returns(1000);
12711
+ webex.internal.newMetrics.callDiagnosticLatencies.getShareDuration = sinon
12712
+ .stub()
12713
+ .returns(1000);
12506
12714
  webex.internal.newMetrics.submitClientEvent = sinon.stub();
12507
12715
  });
12508
12716
  it('should stop the whiteboard share', async () => {
@@ -12606,7 +12814,9 @@ describe('plugin-meetings', () => {
12606
12814
  meeting.deviceUrl = 'my-web-url';
12607
12815
  meeting.locusInfo.info = {isWebinar: false};
12608
12816
  webex.internal.newMetrics.callDiagnosticLatencies.saveTimestamp = sinon.stub();
12609
- webex.internal.newMetrics.callDiagnosticLatencies.getShareDuration = sinon.stub().returns(1500);
12817
+ webex.internal.newMetrics.callDiagnosticLatencies.getShareDuration = sinon
12818
+ .stub()
12819
+ .returns(1500);
12610
12820
  webex.internal.newMetrics.submitClientEvent = sinon.stub();
12611
12821
  });
12612
12822
 
@@ -12855,8 +13065,8 @@ describe('plugin-meetings', () => {
12855
13065
 
12856
13066
  shareStatus =
12857
13067
  meeting.webinar.selfIsAttendee || meeting.guest
12858
- ? SHARE_STATUS.REMOTE_SHARE_ACTIVE
12859
- : SHARE_STATUS.WHITEBOARD_SHARE_ACTIVE;
13068
+ ? SHARE_STATUS.REMOTE_SHARE_ACTIVE
13069
+ : SHARE_STATUS.WHITEBOARD_SHARE_ACTIVE;
12860
13070
  }
12861
13071
 
12862
13072
  if (eventTrigger.member) {
@@ -13802,32 +14012,32 @@ describe('plugin-meetings', () => {
13802
14012
  });
13803
14013
  });
13804
14014
 
13805
- describe('handleShareVideoStreamMuteStateChange', () => {
13806
- it('should emit MEETING_SHARE_VIDEO_MUTE_STATE_CHANGE event with correct fields', () => {
13807
- meeting.isMultistream = true;
13808
- meeting.statsAnalyzer = {shareVideoEncoderImplementation: 'OpenH264'};
13809
- meeting.mediaProperties.shareVideoStream = {
13810
- getSettings: sinon.stub().returns({displaySurface: 'monitor', frameRate: 30}),
13811
- };
14015
+ describe('handleShareVideoStreamMuteStateChange', () => {
14016
+ it('should emit MEETING_SHARE_VIDEO_MUTE_STATE_CHANGE event with correct fields', () => {
14017
+ meeting.isMultistream = true;
14018
+ meeting.statsAnalyzer = {shareVideoEncoderImplementation: 'OpenH264'};
14019
+ meeting.mediaProperties.shareVideoStream = {
14020
+ getSettings: sinon.stub().returns({displaySurface: 'monitor', frameRate: 30}),
14021
+ };
13812
14022
 
13813
- meeting.handleShareVideoStreamMuteStateChange(true);
14023
+ meeting.handleShareVideoStreamMuteStateChange(true);
13814
14024
 
13815
- assert.calledOnceWithExactly(
13816
- Metrics.sendBehavioralMetric,
13817
- BEHAVIORAL_METRICS.MEETING_SHARE_VIDEO_MUTE_STATE_CHANGE,
13818
- {
13819
- correlationId: meeting.correlationId,
13820
- muted: true,
13821
- encoderImplementation: 'OpenH264',
13822
- displaySurface: 'monitor',
13823
- isMultistream: true,
13824
- frameRate: 30,
13825
- }
13826
- );
14025
+ assert.calledOnceWithExactly(
14026
+ Metrics.sendBehavioralMetric,
14027
+ BEHAVIORAL_METRICS.MEETING_SHARE_VIDEO_MUTE_STATE_CHANGE,
14028
+ {
14029
+ correlationId: meeting.correlationId,
14030
+ muted: true,
14031
+ encoderImplementation: 'OpenH264',
14032
+ displaySurface: 'monitor',
14033
+ isMultistream: true,
14034
+ frameRate: 30,
14035
+ }
14036
+ );
14037
+ });
13827
14038
  });
13828
14039
  });
13829
14040
  });
13830
- });
13831
14041
 
13832
14042
  describe('#startKeepAlive', () => {
13833
14043
  let clock;
@@ -15026,11 +15236,9 @@ describe('plugin-meetings', () => {
15026
15236
  assert.exists(unsetStagePromise.then);
15027
15237
  await unsetStagePromise;
15028
15238
 
15029
- assert.calledOnceWithExactly(
15030
- meeting.meetingRequest.synchronizeStage,
15031
- locusUrl,
15032
- {overrideDefault: false}
15033
- );
15239
+ assert.calledOnceWithExactly(meeting.meetingRequest.synchronizeStage, locusUrl, {
15240
+ overrideDefault: false,
15241
+ });
15034
15242
  });
15035
15243
  });
15036
15244
 
@@ -15055,7 +15263,7 @@ describe('plugin-meetings', () => {
15055
15263
  meeting.meetingInfo.siteFullUrl,
15056
15264
  meeting.locusId,
15057
15265
  meetingUuid,
15058
- displayName,
15266
+ displayName
15059
15267
  );
15060
15268
  });
15061
15269
  });
@@ -15102,10 +15310,7 @@ describe('plugin-meetings', () => {
15102
15310
  assert.exists(cancelSipCallOutPromise.then);
15103
15311
  await cancelSipCallOutPromise;
15104
15312
 
15105
- assert.calledOnceWithExactly(
15106
- meeting.meetingRequest.cancelSipCallOut,
15107
- participantId
15108
- );
15313
+ assert.calledOnceWithExactly(meeting.meetingRequest.cancelSipCallOut, participantId);
15109
15314
  });
15110
15315
  });
15111
15316
  });