@webex/plugin-meetings 2.60.1-next.7 → 2.60.1-next.9
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.
- package/README.md +12 -0
- package/dist/breakouts/breakout.js +1 -1
- package/dist/breakouts/index.js +1 -1
- package/dist/constants.d.ts +12 -2
- package/dist/constants.js +15 -5
- package/dist/constants.js.map +1 -1
- package/dist/interpretation/index.js +1 -1
- package/dist/interpretation/siLanguage.js +1 -1
- package/dist/locus-info/index.d.ts +1 -1
- package/dist/locus-info/index.js +8 -8
- package/dist/locus-info/index.js.map +1 -1
- package/dist/meeting/index.d.ts +62 -18
- package/dist/meeting/index.js +679 -568
- package/dist/meeting/index.js.map +1 -1
- package/dist/meeting/request.js +25 -18
- package/dist/meeting/request.js.map +1 -1
- package/dist/meeting/util.d.ts +16 -0
- package/dist/meeting/util.js +71 -0
- package/dist/meeting/util.js.map +1 -1
- package/dist/meetings/index.d.ts +25 -3
- package/dist/meetings/index.js +83 -32
- package/dist/meetings/index.js.map +1 -1
- package/dist/reachability/index.js +11 -6
- package/dist/reachability/index.js.map +1 -1
- package/dist/reconnection-manager/index.js +3 -1
- package/dist/reconnection-manager/index.js.map +1 -1
- package/dist/roap/index.js +50 -54
- package/dist/roap/index.js.map +1 -1
- package/dist/statsAnalyzer/index.js +1 -1
- package/dist/statsAnalyzer/index.js.map +1 -1
- package/dist/statsAnalyzer/mqaUtil.js +13 -10
- package/dist/statsAnalyzer/mqaUtil.js.map +1 -1
- package/dist/webinar/index.js +1 -1
- package/package.json +22 -22
- package/src/constants.ts +13 -2
- package/src/locus-info/index.ts +13 -12
- package/src/meeting/index.ts +215 -116
- package/src/meeting/request.ts +7 -0
- package/src/meeting/util.ts +97 -0
- package/src/meetings/index.ts +59 -18
- package/src/reachability/index.ts +7 -4
- package/src/reconnection-manager/index.ts +1 -1
- package/src/roap/index.ts +49 -51
- package/src/statsAnalyzer/index.ts +2 -2
- package/src/statsAnalyzer/mqaUtil.ts +15 -14
- package/test/unit/spec/locus-info/index.js +53 -5
- package/test/unit/spec/meeting/index.js +1792 -1139
- package/test/unit/spec/meeting/request.js +22 -12
- package/test/unit/spec/meeting/utils.js +93 -0
- package/test/unit/spec/meetings/index.js +180 -21
- package/test/unit/spec/reachability/index.ts +2 -1
- package/test/unit/spec/reconnection-manager/index.js +1 -0
- package/test/unit/spec/roap/index.ts +28 -42
- 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 {
|
|
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 = {
|
|
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
|
|
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
|
-
|
|
379
|
-
|
|
380
|
-
|
|
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('
|
|
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
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
1145
|
-
|
|
1146
|
-
|
|
1147
|
-
|
|
1148
|
-
|
|
1149
|
-
|
|
1150
|
-
|
|
1151
|
-
|
|
1152
|
-
|
|
1153
|
-
|
|
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: [
|
|
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
|
-
{
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
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
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
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 = {
|