@webex/plugin-meetings 2.60.1-next.7 → 2.60.1-next.8

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 (54) hide show
  1. package/README.md +12 -0
  2. package/dist/breakouts/breakout.js +1 -1
  3. package/dist/breakouts/index.js +1 -1
  4. package/dist/constants.d.ts +12 -2
  5. package/dist/constants.js +15 -5
  6. package/dist/constants.js.map +1 -1
  7. package/dist/interpretation/index.js +1 -1
  8. package/dist/interpretation/siLanguage.js +1 -1
  9. package/dist/locus-info/index.d.ts +1 -1
  10. package/dist/locus-info/index.js +8 -8
  11. package/dist/locus-info/index.js.map +1 -1
  12. package/dist/meeting/index.d.ts +62 -18
  13. package/dist/meeting/index.js +679 -568
  14. package/dist/meeting/index.js.map +1 -1
  15. package/dist/meeting/request.js +25 -18
  16. package/dist/meeting/request.js.map +1 -1
  17. package/dist/meeting/util.d.ts +16 -0
  18. package/dist/meeting/util.js +71 -0
  19. package/dist/meeting/util.js.map +1 -1
  20. package/dist/meetings/index.d.ts +25 -3
  21. package/dist/meetings/index.js +83 -32
  22. package/dist/meetings/index.js.map +1 -1
  23. package/dist/reachability/index.js +11 -6
  24. package/dist/reachability/index.js.map +1 -1
  25. package/dist/reconnection-manager/index.js +3 -1
  26. package/dist/reconnection-manager/index.js.map +1 -1
  27. package/dist/roap/index.js +50 -54
  28. package/dist/roap/index.js.map +1 -1
  29. package/dist/statsAnalyzer/index.js +1 -1
  30. package/dist/statsAnalyzer/index.js.map +1 -1
  31. package/dist/statsAnalyzer/mqaUtil.js +13 -10
  32. package/dist/statsAnalyzer/mqaUtil.js.map +1 -1
  33. package/dist/webinar/index.js +1 -1
  34. package/package.json +22 -22
  35. package/src/constants.ts +13 -2
  36. package/src/locus-info/index.ts +13 -12
  37. package/src/meeting/index.ts +215 -116
  38. package/src/meeting/request.ts +7 -0
  39. package/src/meeting/util.ts +97 -0
  40. package/src/meetings/index.ts +59 -18
  41. package/src/reachability/index.ts +7 -4
  42. package/src/reconnection-manager/index.ts +1 -1
  43. package/src/roap/index.ts +49 -51
  44. package/src/statsAnalyzer/index.ts +2 -2
  45. package/src/statsAnalyzer/mqaUtil.ts +15 -14
  46. package/test/unit/spec/locus-info/index.js +53 -5
  47. package/test/unit/spec/meeting/index.js +1792 -1139
  48. package/test/unit/spec/meeting/request.js +22 -12
  49. package/test/unit/spec/meeting/utils.js +93 -0
  50. package/test/unit/spec/meetings/index.js +180 -21
  51. package/test/unit/spec/reachability/index.ts +2 -1
  52. package/test/unit/spec/reconnection-manager/index.js +1 -0
  53. package/test/unit/spec/roap/index.ts +28 -42
  54. package/test/unit/spec/stats-analyzer/index.js +415 -30
@@ -4,16 +4,19 @@ import MockWebex from '@webex/test-helper-mock-webex';
4
4
  import Meetings from '@webex/plugin-meetings';
5
5
  import MeetingRequest from '@webex/plugin-meetings/src/meeting/request';
6
6
  import uuid from 'uuid';
7
- import { merge } from 'lodash';
7
+ import {merge} from 'lodash';
8
8
  import {IP_VERSION} from '@webex/plugin-meetings/src/constants';
9
9
  import {CallDiagnosticUtils} from '@webex/internal-plugin-metrics';
10
10
 
11
-
12
11
  describe('plugin-meetings', () => {
13
12
  let meetingsRequest;
14
13
  let locusDeltaRequestSpy;
15
14
  let webex;
16
- const geoHintInfoDefaults = {countryCode: 'US', regionCode: 'WEST-COAST', clientAddress: '127.0.0.1'};
15
+ const geoHintInfoDefaults = {
16
+ countryCode: 'US',
17
+ regionCode: 'WEST-COAST',
18
+ clientAddress: '127.0.0.1',
19
+ };
17
20
  let anonymizeIpSpy;
18
21
 
19
22
  beforeEach(() => {
@@ -30,6 +33,11 @@ describe('plugin-meetings', () => {
30
33
  get: sinon.mock().returns('locusUrl'),
31
34
  waitForCatalog: sinon.mock().returns(Promise.resolve({})),
32
35
  },
36
+ device: {
37
+ config: {
38
+ installationId: 'installationId',
39
+ },
40
+ },
33
41
  };
34
42
 
35
43
  webex.boundedStorage.get = sinon
@@ -179,12 +187,13 @@ describe('plugin-meetings', () => {
179
187
  });
180
188
 
181
189
  describe('#joinMeeting', () => {
182
- it('sends /call requets for join', async () => {
190
+ it('sends /call request for join', async () => {
183
191
  const locusUrl = 'locusURL';
184
192
  const deviceUrl = 'deviceUrl';
185
193
  const correlationId = 'random-uuid';
186
194
  const roapMessage = 'roap-message';
187
195
  const permissionToken = 'permission-token';
196
+ const installationId = 'installationId';
188
197
 
189
198
  await meetingsRequest.joinMeeting({
190
199
  locusUrl,
@@ -198,6 +207,7 @@ describe('plugin-meetings', () => {
198
207
  assert.equal(requestParams.method, 'POST');
199
208
  assert.equal(requestParams.uri, `${locusUrl}/participant?alternateRedirect=true`);
200
209
  assert.equal(requestParams.body.device.url, deviceUrl);
210
+ assert.equal(requestParams.body.device.installationId, installationId);
201
211
  assert.equal(requestParams.body.device.countryCode, 'US');
202
212
  assert.equal(requestParams.body.permissionToken, 'permission-token');
203
213
  assert.equal(requestParams.body.device.regionCode, 'WEST-COAST');
@@ -210,7 +220,7 @@ describe('plugin-meetings', () => {
210
220
  beforeEach(() => {
211
221
  webex.meetings.geoHintInfo = {};
212
222
  });
213
-
223
+
214
224
  // reset
215
225
  afterEach(() => {
216
226
  webex.meetings.geoHintInfo = {...geoHintInfoDefaults};
@@ -222,7 +232,7 @@ describe('plugin-meetings', () => {
222
232
  const correlationId = 'random-uuid';
223
233
  const roapMessage = 'roap-message';
224
234
  const permissionToken = 'permission-token';
225
-
235
+
226
236
  await meetingsRequest.joinMeeting({
227
237
  locusUrl,
228
238
  deviceUrl,
@@ -231,10 +241,10 @@ describe('plugin-meetings', () => {
231
241
  permissionToken,
232
242
  });
233
243
  const requestParams = meetingsRequest.request.getCall(0).args[0];
234
-
244
+
235
245
  assert.equal(requestParams.body.device.localIp, undefined);
236
246
  });
237
- })
247
+ });
238
248
 
239
249
  it('sends /call with meetingNumber if inviteeAddress does not exist', async () => {
240
250
  const deviceUrl = 'deviceUrl';
@@ -368,16 +378,16 @@ describe('plugin-meetings', () => {
368
378
  correlationId,
369
379
  roapMessage,
370
380
  permissionToken,
371
- ipVersion: IP_VERSION.ipv4_and_ipv6
381
+ ipVersion: IP_VERSION.ipv4_and_ipv6,
372
382
  });
373
383
  const requestParams = meetingsRequest.request.getCall(0).args[0];
374
384
 
375
385
  assert.equal(requestParams.method, 'POST');
376
386
  assert.equal(requestParams.uri, `${locusUrl}/participant?alternateRedirect=true`);
377
387
  assert.deepEqual(requestParams.body.clientMediaPreferences, {
378
- "joinCookie": {anycastEntryPoint: "aws-eu-west-1"},
379
- "preferTranscoding": true,
380
- "ipver": 1
388
+ joinCookie: {anycastEntryPoint: 'aws-eu-west-1'},
389
+ preferTranscoding: true,
390
+ ipver: 1,
381
391
  });
382
392
  });
383
393
  });
@@ -2,6 +2,7 @@ import sinon from 'sinon';
2
2
  import {assert} from '@webex/test-helper-chai';
3
3
  import Meetings from '@webex/plugin-meetings';
4
4
  import MeetingUtil from '@webex/plugin-meetings/src/meeting/util';
5
+ import {LOCAL_SHARE_ERRORS} from '@webex/plugin-meetings/src/constants';
5
6
  import LoggerProxy from '@webex/plugin-meetings/src/common/logs/logger-proxy';
6
7
  import LoggerConfig from '@webex/plugin-meetings/src/common/logs/logger-config';
7
8
  import {SELF_POLICY, IP_VERSION} from '@webex/plugin-meetings/src/constants';
@@ -1032,5 +1033,97 @@ describe('plugin-meetings', () => {
1032
1033
  });
1033
1034
  });
1034
1035
  });
1036
+
1037
+ describe('getChangeMeetingFloorErrorPayload', () => {
1038
+ [
1039
+ {
1040
+ reason: LOCAL_SHARE_ERRORS.UNDEFINED,
1041
+ expected: {
1042
+ category: 'signaling',
1043
+ errorCode: 1100,
1044
+ },
1045
+ },
1046
+ {
1047
+ reason: LOCAL_SHARE_ERRORS.DEVICE_NOT_JOINED,
1048
+ expected: {
1049
+ category: 'signaling',
1050
+ errorCode: 4050,
1051
+ },
1052
+ },
1053
+ {
1054
+ reason: LOCAL_SHARE_ERRORS.NO_MEDIA_FOR_DEVICE,
1055
+ expected: {
1056
+ category: 'media',
1057
+ errorCode: 2048,
1058
+ },
1059
+ },
1060
+ {
1061
+ reason: LOCAL_SHARE_ERRORS.NO_CONFLUENCE_ID,
1062
+ expected: {
1063
+ category: 'signaling',
1064
+ errorCode: 4064,
1065
+ },
1066
+ },
1067
+ {
1068
+ reason: LOCAL_SHARE_ERRORS.CONTENT_SHARING_DISABLED,
1069
+ expected: {
1070
+ category: 'expected',
1071
+ errorCode: 4065,
1072
+ },
1073
+ },
1074
+ {
1075
+ reason: LOCAL_SHARE_ERRORS.LOCUS_PARTICIPANT_DNE,
1076
+ expected: {
1077
+ category: 'signaling',
1078
+ errorCode: 4066,
1079
+ },
1080
+ },
1081
+ {
1082
+ reason: LOCAL_SHARE_ERRORS.CONTENT_REQUEST_WHILE_PENDING_WHITEBOARD,
1083
+ expected: {
1084
+ category: 'expected',
1085
+ errorCode: 4067,
1086
+ },
1087
+ },
1088
+ {
1089
+ reason: 'some unknown reason',
1090
+ expected: {
1091
+ category: 'signaling',
1092
+ errorCode: 1100,
1093
+ },
1094
+ },
1095
+ ].forEach(({reason, expected}) => {
1096
+ const expectedFull = {
1097
+ errorDescription: reason,
1098
+ name: 'locus.response',
1099
+ shownToUser: false,
1100
+ fatal: true,
1101
+ ...expected,
1102
+ };
1103
+ it(`returns expected when reason="${reason}"`, () => {
1104
+ const result = MeetingUtil.getChangeMeetingFloorErrorPayload(reason);
1105
+ assert.equal(result.length, 1);
1106
+
1107
+ const error = result[0];
1108
+ assert.deepEqual(error, expectedFull);
1109
+ });
1110
+ });
1111
+
1112
+ it('properly handles "includes"', () => {
1113
+ const reason = '>>> ' + LOCAL_SHARE_ERRORS.DEVICE_NOT_JOINED + ' <<<';
1114
+ const result = MeetingUtil.getChangeMeetingFloorErrorPayload(reason);
1115
+ assert.equal(result.length, 1);
1116
+
1117
+ const error = result[0];
1118
+ assert.deepEqual(error, {
1119
+ category: 'signaling',
1120
+ errorCode: 4050,
1121
+ errorDescription: reason,
1122
+ name: 'locus.response',
1123
+ shownToUser: false,
1124
+ fatal: true,
1125
+ });
1126
+ });
1127
+ });
1035
1128
  });
1036
1129
  });
@@ -17,7 +17,7 @@ import StaticConfig from '@webex/plugin-meetings/src/common/config';
17
17
  import TriggerProxy from '@webex/plugin-meetings/src/common/events/trigger-proxy';
18
18
  import LoggerProxy from '@webex/plugin-meetings/src/common/logs/logger-proxy';
19
19
  import LoggerConfig from '@webex/plugin-meetings/src/common/logs/logger-config';
20
- import Meeting from '@webex/plugin-meetings/src/meeting';
20
+ import Meeting, {CallStateForMetrics} from '@webex/plugin-meetings/src/meeting';
21
21
  import MeetingUtil from '@webex/plugin-meetings/src/meeting/util';
22
22
  import Meetings from '@webex/plugin-meetings/src/meetings';
23
23
  import MeetingCollection from '@webex/plugin-meetings/src/meetings/collection';
@@ -240,6 +240,19 @@ describe('plugin-meetings', () => {
240
240
  });
241
241
  });
242
242
 
243
+ describe('#_toggleTcpReachability', () => {
244
+ it('should have _toggleTcpReachability', () => {
245
+ assert.equal(typeof webex.meetings._toggleTcpReachability, 'function');
246
+ });
247
+
248
+ describe('success', () => {
249
+ it('should update meetings to do TCP reachability', () => {
250
+ webex.meetings._toggleTcpReachability(true);
251
+ assert.equal(webex.meetings.config.experimental.enableTcpReachability, true);
252
+ });
253
+ });
254
+ });
255
+
243
256
  describe('Public API Contracts', () => {
244
257
  describe('#register', () => {
245
258
  it('emits an event and resolves when register succeeds', async () => {
@@ -559,10 +572,10 @@ describe('plugin-meetings', () => {
559
572
  });
560
573
  });
561
574
  });
562
- describe('destroy non active locus meetings', () => {
575
+ describe('when destroying meeting is needed', () => {
563
576
  let destroySpy;
564
577
 
565
- const meetingCollectionMeetings = {
578
+ const meetingCollectionMeetings = {
566
579
  stillValidLocusMeeting: {
567
580
  locusUrl: 'still-valid-locus-url',
568
581
  sendCallAnalyzerMetrics: sinon.stub(),
@@ -583,21 +596,46 @@ describe('plugin-meetings', () => {
583
596
 
584
597
  beforeEach(() => {
585
598
  destroySpy = sinon.spy(webex.meetings, 'destroy');
586
- webex.meetings.meetingCollection.getAll = sinon.stub().returns(meetingCollectionMeetings);
599
+ webex.meetings.meetingCollection.getAll = sinon
600
+ .stub()
601
+ .returns(meetingCollectionMeetings);
587
602
  webex.meetings.request.getActiveMeetings = sinon.stub().returns(
588
603
  Promise.resolve({
589
- loci: [
590
- {url: 'still-valid-locus-url'}
591
- ],
604
+ loci: [{url: 'still-valid-locus-url'}],
592
605
  })
593
606
  );
594
607
  MeetingUtil.cleanUp = sinon.stub().returns(Promise.resolve());
595
608
  });
596
- it('destroy only non active locus meetings and keep active locus meetings and any other non-locus meeting', async () => {
609
+
610
+ it('destroy any meeting that has no active locus url if keepOnlyLocusMeetings is not defined', async () => {
597
611
  await webex.meetings.syncMeetings();
598
612
  assert.calledOnce(webex.meetings.request.getActiveMeetings);
599
613
  assert.calledOnce(webex.meetings.meetingCollection.getAll);
600
614
  assert.calledWith(destroySpy, meetingCollectionMeetings.noLongerValidLocusMeeting);
615
+ assert.calledWith(destroySpy, meetingCollectionMeetings.otherNonLocusMeeting1);
616
+ assert.calledWith(destroySpy, meetingCollectionMeetings.otherNonLocusMeeting2);
617
+ assert.callCount(destroySpy, 3);
618
+
619
+ assert.callCount(MeetingUtil.cleanUp, 3);
620
+ });
621
+
622
+ it('destroy any meeting that has no active locus url if keepOnlyLocusMeetings === true', async () => {
623
+ await webex.meetings.syncMeetings({keepOnlyLocusMeetings: true});
624
+ assert.calledOnce(webex.meetings.request.getActiveMeetings);
625
+ assert.calledOnce(webex.meetings.meetingCollection.getAll);
626
+ assert.calledWith(destroySpy, meetingCollectionMeetings.noLongerValidLocusMeeting);
627
+ assert.calledWith(destroySpy, meetingCollectionMeetings.otherNonLocusMeeting1);
628
+ assert.calledWith(destroySpy, meetingCollectionMeetings.otherNonLocusMeeting2);
629
+ assert.callCount(destroySpy, 3);
630
+
631
+ assert.callCount(MeetingUtil.cleanUp, 3);
632
+ });
633
+
634
+ it('destroy any LOCUS meetings that have no active locus url if keepOnlyLocusMeetings === false', async () => {
635
+ await webex.meetings.syncMeetings({keepOnlyLocusMeetings: false});
636
+ assert.calledOnce(webex.meetings.request.getActiveMeetings);
637
+ assert.calledOnce(webex.meetings.meetingCollection.getAll);
638
+ assert.calledWith(destroySpy, meetingCollectionMeetings.noLongerValidLocusMeeting);
601
639
  assert.callCount(destroySpy, 1);
602
640
 
603
641
  assert.calledOnce(MeetingUtil.cleanUp);
@@ -680,6 +718,41 @@ describe('plugin-meetings', () => {
680
718
  );
681
719
  });
682
720
 
721
+ it('calls createMeeting, pass the meeting info param and returns its promise', async () => {
722
+ const meetingInfo = {};
723
+ await checkCallCreateMeeting(
724
+ [test1, test2, FAKE_USE_RANDOM_DELAY, {}, correlationId, true, undefined, meetingInfo],
725
+ [test1, test2, FAKE_USE_RANDOM_DELAY, {}, {correlationId}, true, meetingInfo]
726
+ );
727
+ });
728
+
729
+ it('calls createMeeting, pass the meeting info and meetingLookupURL param and returns its promise', async () => {
730
+ const meetingInfo = {};
731
+ await checkCallCreateMeeting(
732
+ [
733
+ test1,
734
+ test2,
735
+ FAKE_USE_RANDOM_DELAY,
736
+ {},
737
+ correlationId,
738
+ true,
739
+ undefined,
740
+ meetingInfo,
741
+ 'meetingLookupURL',
742
+ ],
743
+ [
744
+ test1,
745
+ test2,
746
+ FAKE_USE_RANDOM_DELAY,
747
+ {},
748
+ {correlationId},
749
+ true,
750
+ meetingInfo,
751
+ 'meetingLookupURL',
752
+ ]
753
+ );
754
+ });
755
+
683
756
  it('calls createMeeting when failOnMissingMeetinginfo is undefined and returns its promise', async () => {
684
757
  await checkCallCreateMeeting(
685
758
  [test1, test2, FAKE_USE_RANDOM_DELAY, {}, correlationId, undefined],
@@ -1135,23 +1208,35 @@ describe('plugin-meetings', () => {
1135
1208
  type,
1136
1209
  extraParams = {},
1137
1210
  expectedMeetingData = {},
1138
- sendCAevents = false
1211
+ sendCAevents = false,
1212
+ injectMeetingInfo = false
1139
1213
  ) => {
1140
- assert.calledOnce(webex.meetings.meetingInfo.fetchMeetingInfo);
1214
+ if (injectMeetingInfo) {
1215
+ assert.notCalled(webex.meetings.meetingInfo.fetchMeetingInfo);
1216
+ } else {
1217
+ assert.calledOnce(webex.meetings.meetingInfo.fetchMeetingInfo);
1218
+ }
1219
+
1141
1220
  assert.calledOnce(MeetingsUtil.getMeetingAddedType);
1142
1221
  assert.notCalled(setTimeoutSpy);
1143
1222
  assert.callCount(TriggerProxy.trigger, 5);
1144
- assert.calledWith(
1145
- webex.meetings.meetingInfo.fetchMeetingInfo,
1146
- destination,
1147
- type,
1148
- null,
1149
- null,
1150
- undefined,
1151
- undefined,
1152
- extraParams,
1153
- {meetingId: meeting.id, sendCAevents}
1154
- );
1223
+
1224
+ if (injectMeetingInfo) {
1225
+ assert.notCalled(webex.meetings.meetingInfo.fetchMeetingInfo);
1226
+ } else {
1227
+ assert.calledWith(
1228
+ webex.meetings.meetingInfo.fetchMeetingInfo,
1229
+ destination,
1230
+ type,
1231
+ null,
1232
+ null,
1233
+ undefined,
1234
+ undefined,
1235
+ extraParams,
1236
+ {meetingId: meeting.id, sendCAevents}
1237
+ );
1238
+ }
1239
+
1155
1240
  assert.calledWith(MeetingsUtil.getMeetingAddedType, 'test type');
1156
1241
 
1157
1242
  if (expectedMeetingData.permissionToken) {
@@ -1169,6 +1254,12 @@ describe('plugin-meetings', () => {
1169
1254
  expectedMeetingData.callStateForMetrics
1170
1255
  );
1171
1256
  }
1257
+ if (expectedMeetingData.meetingLookupUrl) {
1258
+ assert.equal(
1259
+ meeting.meetingInfo.meetingLookupUrl,
1260
+ expectedMeetingData.meetingLookupUrl
1261
+ );
1262
+ }
1172
1263
  assert.equal(meeting.destination, destination);
1173
1264
  assert.equal(meeting.destinationType, type);
1174
1265
  assert.calledWith(
@@ -1210,6 +1301,72 @@ describe('plugin-meetings', () => {
1210
1301
  );
1211
1302
  });
1212
1303
 
1304
+ it('accepts injected meeting info', async () => {
1305
+ const meetingInfo = {
1306
+ permissionToken: 'PT',
1307
+ meetingJoinUrl: 'meetingJoinUrl',
1308
+ };
1309
+
1310
+ const meeting = await webex.meetings.createMeeting(
1311
+ 'test destination',
1312
+ 'test type',
1313
+ false,
1314
+ {},
1315
+ undefined,
1316
+ false,
1317
+ meetingInfo
1318
+ );
1319
+
1320
+ const expectedMeetingData = {
1321
+ ...meetingInfo,
1322
+ correlationId: meeting.id,
1323
+ };
1324
+
1325
+ checkCreateWithoutDelay(
1326
+ meeting,
1327
+ 'test destination',
1328
+ 'test type',
1329
+ {},
1330
+ expectedMeetingData,
1331
+ false,
1332
+ true
1333
+ );
1334
+ });
1335
+
1336
+ it('accepts injected meeting info with meeting lookup url', async () => {
1337
+ const meetingInfo = {
1338
+ permissionToken: 'PT',
1339
+ meetingJoinUrl: 'meetingJoinUrl',
1340
+ };
1341
+
1342
+ const meeting = await webex.meetings.createMeeting(
1343
+ 'test destination',
1344
+ 'test type',
1345
+ false,
1346
+ {},
1347
+ undefined,
1348
+ false,
1349
+ meetingInfo,
1350
+ 'meetingLookupUrl'
1351
+ );
1352
+
1353
+ const expectedMeetingData = {
1354
+ ...meetingInfo,
1355
+ meetingLookupUrl: 'meetingLookupUrl',
1356
+ correlationId: meeting.id,
1357
+ };
1358
+
1359
+ checkCreateWithoutDelay(
1360
+ meeting,
1361
+ 'test destination',
1362
+ 'test type',
1363
+ {},
1364
+ expectedMeetingData,
1365
+ false,
1366
+ true
1367
+ );
1368
+ });
1369
+
1213
1370
  [undefined, FAKE_INFO_EXTRA_PARAMS].forEach((infoExtraParams) => {
1214
1371
  const infoExtraParamsProvided = infoExtraParams !== undefined;
1215
1372
 
@@ -1303,6 +1460,8 @@ describe('plugin-meetings', () => {
1303
1460
 
1304
1461
  // When timer expires
1305
1462
  clock.tick(FAKE_TIME_TO_START);
1463
+ await testUtils.flushPromises();
1464
+
1306
1465
  assert.calledWith(
1307
1466
  webex.meetings.meetingInfo.fetchMeetingInfo,
1308
1467
  FAKE_LOCUS_MEETING,
@@ -210,9 +210,10 @@ describe('gatherReachability', () => {
210
210
  xtls: ['xtls1.1', 'xtls1.2'],
211
211
  isVideoMesh: false,
212
212
  });
213
+ // cluster 2 is video mesh, so we should not do TCP reachability on it
213
214
  assert.calledWith(clusterReachabilityCtorStub, 'cluster 2', {
214
215
  udp: ['udp2.1', 'udp2.2'],
215
- tcp: ['tcp2.1', 'tcp2.2'],
216
+ tcp: [],
216
217
  xtls: ['xtls2.1', 'xtls2.2'],
217
218
  isVideoMesh: true,
218
219
  });
@@ -81,6 +81,7 @@ describe('plugin-meetings', () => {
81
81
  await rm.reconnect();
82
82
 
83
83
  assert.calledOnce(rm.webex.meetings.syncMeetings);
84
+ assert.calledWith(rm.webex.meetings.syncMeetings, {keepOnlyLocusMeetings: false});
84
85
  });
85
86
 
86
87
  it('does not sync meetings if it is an unverified guest', async () => {
@@ -82,49 +82,35 @@ describe('Roap', () => {
82
82
  sinon.restore();
83
83
  });
84
84
 
85
- [
86
- {reconnect: true, turnDiscoverySkipped: false, expectEmptyMediaId: false},
87
- {reconnect: true, turnDiscoverySkipped: true, expectEmptyMediaId: true},
88
- {reconnect: false, turnDiscoverySkipped: false, expectEmptyMediaId: false},
89
- {reconnect: false, turnDiscoverySkipped: true, expectEmptyMediaId: false},
90
- ].forEach(({reconnect, turnDiscoverySkipped, expectEmptyMediaId}) =>
91
- it(`sends roap OFFER with ${expectEmptyMediaId ? 'empty ' : ''}mediaId when ${
92
- reconnect ? '' : 'not '
93
- }reconnecting and TURN discovery is ${
94
- turnDiscoverySkipped ? 'skipped' : 'not skipped'
95
- }`, async () => {
96
- roap.turnDiscovery.isSkipped.resolves(turnDiscoverySkipped);
97
-
98
- await roap.sendRoapMediaRequest({
99
- meeting,
100
- sdp: 'sdp',
101
- reconnect,
102
- seq: 2,
103
- tieBreaker: 4294967294,
104
- });
85
+ it(`sends roap OFFER`, async () => {
86
+ await roap.sendRoapMediaRequest({
87
+ meeting,
88
+ sdp: 'sdp',
89
+ seq: 2,
90
+ tieBreaker: 4294967294,
91
+ });
92
+
93
+ const expectedRoapMessage = {
94
+ messageType: 'OFFER',
95
+ sdps: ['sdp'],
96
+ version: '2',
97
+ seq: 2,
98
+ tieBreaker: 4294967294,
99
+ headers: ['includeAnswerInHttpResponse', 'noOkInTransaction'],
100
+ };
105
101
 
106
- const expectedRoapMessage = {
107
- messageType: 'OFFER',
108
- sdps: ['sdp'],
109
- version: '2',
110
- seq: 2,
111
- tieBreaker: 4294967294,
112
- headers: ['includeAnswerInHttpResponse', 'noOkInTransaction'],
113
- };
114
-
115
- assert.calledOnce(sendRoapStub);
116
- assert.calledWith(
117
- sendRoapStub,
118
- sinon.match({
119
- roapMessage: expectedRoapMessage,
120
- locusSelfUrl: meeting.selfUrl,
121
- mediaId: expectEmptyMediaId ? '' : meeting.mediaId,
122
- meetingId: meeting.id,
123
- locusMediaRequest: meeting.locusMediaRequest,
124
- })
125
- );
126
- })
127
- );
102
+ assert.calledOnce(sendRoapStub);
103
+ assert.calledWith(
104
+ sendRoapStub,
105
+ sinon.match({
106
+ roapMessage: expectedRoapMessage,
107
+ locusSelfUrl: meeting.selfUrl,
108
+ mediaId: meeting.mediaId,
109
+ meetingId: meeting.id,
110
+ locusMediaRequest: meeting.locusMediaRequest,
111
+ })
112
+ );
113
+ });
128
114
 
129
115
  it('reads SDP answer from the http response', async () => {
130
116
  const roapAnswer = {