@webex/plugin-meetings 3.0.0-beta.34 → 3.0.0-beta.35
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/dist/breakouts/breakout.js +1 -1
- package/dist/breakouts/index.js +1 -1
- package/dist/constants.js +2 -1
- package/dist/constants.js.map +1 -1
- package/dist/meeting/request.js +135 -85
- package/dist/meeting/request.js.map +1 -1
- package/dist/reachability/index.js +25 -17
- package/dist/reachability/index.js.map +1 -1
- package/dist/reachability/request.js +12 -5
- package/dist/reachability/request.js.map +1 -1
- package/dist/roap/request.js +114 -83
- package/dist/roap/request.js.map +1 -1
- package/dist/types/constants.d.ts +2 -1
- package/dist/types/meeting/request.d.ts +10 -0
- package/dist/types/reachability/request.d.ts +5 -3
- package/dist/types/roap/request.d.ts +6 -3
- package/package.json +18 -18
- package/src/constants.ts +2 -1
- package/src/meeting/request.ts +35 -1
- package/src/reachability/index.ts +12 -4
- package/src/reachability/request.ts +10 -5
- package/src/roap/request.ts +93 -78
- package/test/unit/spec/meeting/request.js +27 -0
- package/test/unit/spec/reachability/index.ts +18 -7
- package/test/unit/spec/reachability/request.js +66 -0
- package/test/unit/spec/roap/request.ts +187 -84
package/src/meeting/request.ts
CHANGED
|
@@ -23,10 +23,10 @@ import {
|
|
|
23
23
|
PARTICIPANT,
|
|
24
24
|
PROVISIONAL_TYPE_DIAL_IN,
|
|
25
25
|
PROVISIONAL_TYPE_DIAL_OUT,
|
|
26
|
+
REACHABILITY,
|
|
26
27
|
SEND_DTMF_ENDPOINT,
|
|
27
28
|
_SLIDES_,
|
|
28
29
|
} from '../constants';
|
|
29
|
-
import {Reaction} from '../reactions/reactions.type';
|
|
30
30
|
import {SendReactionOptions, ToggleReactionsOptions} from './request.type';
|
|
31
31
|
|
|
32
32
|
/**
|
|
@@ -35,6 +35,11 @@ import {SendReactionOptions, ToggleReactionsOptions} from './request.type';
|
|
|
35
35
|
export default class MeetingRequest extends StatelessWebexPlugin {
|
|
36
36
|
changeVideoLayoutDebounced: any;
|
|
37
37
|
|
|
38
|
+
/**
|
|
39
|
+
* Constructor
|
|
40
|
+
* @param {Object} attrs
|
|
41
|
+
* @param {Object} options
|
|
42
|
+
*/
|
|
38
43
|
constructor(attrs: any, options: any) {
|
|
39
44
|
super(attrs, options);
|
|
40
45
|
this.changeVideoLayoutDebounced = debounce(this.changeVideoLayout, 2000, {
|
|
@@ -43,6 +48,32 @@ export default class MeetingRequest extends StatelessWebexPlugin {
|
|
|
43
48
|
});
|
|
44
49
|
}
|
|
45
50
|
|
|
51
|
+
/**
|
|
52
|
+
* Returns joinCookie from boundedStorage if present.
|
|
53
|
+
* @returns {Object} joinCookie
|
|
54
|
+
*/
|
|
55
|
+
private getJoinCookie = async () => {
|
|
56
|
+
// @ts-ignore
|
|
57
|
+
const joinCookieRaw = await this.webex.boundedStorage
|
|
58
|
+
.get(REACHABILITY.namespace, REACHABILITY.localStorageJoinCookie)
|
|
59
|
+
.catch(() => {});
|
|
60
|
+
|
|
61
|
+
if (joinCookieRaw) {
|
|
62
|
+
try {
|
|
63
|
+
const joinCookie = JSON.parse(joinCookieRaw);
|
|
64
|
+
if (joinCookie) {
|
|
65
|
+
return joinCookie;
|
|
66
|
+
}
|
|
67
|
+
} catch (e) {
|
|
68
|
+
LoggerProxy.logger.error(
|
|
69
|
+
`MeetingRequest#constructor --> Error in parsing join cookie data: ${e}`
|
|
70
|
+
);
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
return null;
|
|
75
|
+
};
|
|
76
|
+
|
|
46
77
|
/**
|
|
47
78
|
* Make a network request to join a meeting
|
|
48
79
|
* @param {Object} options
|
|
@@ -99,6 +130,8 @@ export default class MeetingRequest extends StatelessWebexPlugin {
|
|
|
99
130
|
|
|
100
131
|
let url = '';
|
|
101
132
|
|
|
133
|
+
const joinCookie = await this.getJoinCookie();
|
|
134
|
+
|
|
102
135
|
const body: any = {
|
|
103
136
|
asResourceOccupant,
|
|
104
137
|
device: {
|
|
@@ -115,6 +148,7 @@ export default class MeetingRequest extends StatelessWebexPlugin {
|
|
|
115
148
|
supportsNativeLobby: 1,
|
|
116
149
|
clientMediaPreferences: {
|
|
117
150
|
preferTranscoding: preferTranscoding ?? true,
|
|
151
|
+
joinCookie,
|
|
118
152
|
},
|
|
119
153
|
};
|
|
120
154
|
|
|
@@ -63,11 +63,13 @@ export default class Reachability {
|
|
|
63
63
|
|
|
64
64
|
// Remove stored reachability results to ensure no stale data
|
|
65
65
|
// @ts-ignore
|
|
66
|
-
await this.webex.boundedStorage.del(this.namespace, REACHABILITY.
|
|
66
|
+
await this.webex.boundedStorage.del(this.namespace, REACHABILITY.localStorageResult);
|
|
67
|
+
// @ts-ignore
|
|
68
|
+
await this.webex.boundedStorage.del(this.namespace, REACHABILITY.localStorageJoinCookie);
|
|
67
69
|
|
|
68
70
|
// Fetch clusters and measure latency
|
|
69
71
|
try {
|
|
70
|
-
const clusters = await this.reachabilityRequest.getClusters();
|
|
72
|
+
const {clusters, joinCookie} = await this.reachabilityRequest.getClusters();
|
|
71
73
|
|
|
72
74
|
// Perform Reachability Check
|
|
73
75
|
const results = await this.performReachabilityCheck(clusters);
|
|
@@ -75,9 +77,15 @@ export default class Reachability {
|
|
|
75
77
|
// @ts-ignore
|
|
76
78
|
await this.webex.boundedStorage.put(
|
|
77
79
|
this.namespace,
|
|
78
|
-
REACHABILITY.
|
|
80
|
+
REACHABILITY.localStorageResult,
|
|
79
81
|
JSON.stringify(results)
|
|
80
82
|
);
|
|
83
|
+
// @ts-ignore
|
|
84
|
+
await this.webex.boundedStorage.put(
|
|
85
|
+
this.namespace,
|
|
86
|
+
REACHABILITY.localStorageJoinCookie,
|
|
87
|
+
JSON.stringify(joinCookie)
|
|
88
|
+
);
|
|
81
89
|
|
|
82
90
|
LoggerProxy.logger.log(
|
|
83
91
|
'Reachability:index#gatherReachability --> Reachability checks completed'
|
|
@@ -103,7 +111,7 @@ export default class Reachability {
|
|
|
103
111
|
let reachable = false;
|
|
104
112
|
// @ts-ignore
|
|
105
113
|
const reachabilityData = await this.webex.boundedStorage
|
|
106
|
-
.get(this.namespace, REACHABILITY.
|
|
114
|
+
.get(this.namespace, REACHABILITY.localStorageResult)
|
|
107
115
|
.catch(() => {});
|
|
108
116
|
|
|
109
117
|
if (reachabilityData) {
|
|
@@ -28,21 +28,23 @@ class ReachabilityRequest {
|
|
|
28
28
|
}
|
|
29
29
|
|
|
30
30
|
/**
|
|
31
|
-
*
|
|
31
|
+
* Gets the cluster information
|
|
32
32
|
*
|
|
33
|
-
* @param {boolean} includeVideoMesh whether to include the video mesh clusters in the result or not
|
|
34
33
|
* @returns {Promise}
|
|
35
34
|
*/
|
|
36
|
-
getClusters = (): Promise<ClusterList> =>
|
|
35
|
+
getClusters = (): Promise<{clusters: ClusterList; joinCookie: any}> =>
|
|
37
36
|
this.webex
|
|
38
37
|
.request({
|
|
39
38
|
method: HTTP_VERBS.GET,
|
|
40
39
|
shouldRefreshAccessToken: false,
|
|
41
40
|
api: API.CALLIOPEDISCOVERY,
|
|
42
41
|
resource: RESOURCE.CLUSTERS,
|
|
42
|
+
qs: {
|
|
43
|
+
JCSupport: 1,
|
|
44
|
+
},
|
|
43
45
|
})
|
|
44
46
|
.then((res) => {
|
|
45
|
-
const {clusters} = res.body;
|
|
47
|
+
const {clusters, joinCookie} = res.body;
|
|
46
48
|
|
|
47
49
|
Object.keys(clusters).forEach((key) => {
|
|
48
50
|
clusters[key].isVideoMesh = res.body.clusterClasses?.hybridMedia?.includes(key);
|
|
@@ -52,7 +54,10 @@ class ReachabilityRequest {
|
|
|
52
54
|
`Reachability:request#getClusters --> get clusters successful:${JSON.stringify(clusters)}`
|
|
53
55
|
);
|
|
54
56
|
|
|
55
|
-
return
|
|
57
|
+
return {
|
|
58
|
+
clusters,
|
|
59
|
+
joinCookie,
|
|
60
|
+
};
|
|
56
61
|
});
|
|
57
62
|
|
|
58
63
|
/**
|
package/src/roap/request.ts
CHANGED
|
@@ -12,14 +12,16 @@ import {eventType} from '../metrics/config';
|
|
|
12
12
|
*/
|
|
13
13
|
export default class RoapRequest extends StatelessWebexPlugin {
|
|
14
14
|
/**
|
|
15
|
-
*
|
|
15
|
+
* Returns reachability data.
|
|
16
16
|
* @param {Object} localSdp
|
|
17
|
-
* @returns {
|
|
17
|
+
* @returns {Object}
|
|
18
18
|
*/
|
|
19
|
-
async
|
|
19
|
+
async attachReachabilityData(localSdp) {
|
|
20
|
+
let joinCookie;
|
|
21
|
+
|
|
20
22
|
// @ts-ignore
|
|
21
23
|
const reachabilityData = await this.webex.boundedStorage
|
|
22
|
-
.get(REACHABILITY.namespace, REACHABILITY.
|
|
24
|
+
.get(REACHABILITY.namespace, REACHABILITY.localStorageResult)
|
|
23
25
|
.catch(() => {});
|
|
24
26
|
|
|
25
27
|
if (reachabilityData) {
|
|
@@ -37,7 +39,22 @@ export default class RoapRequest extends StatelessWebexPlugin {
|
|
|
37
39
|
}
|
|
38
40
|
}
|
|
39
41
|
|
|
40
|
-
|
|
42
|
+
// @ts-ignore
|
|
43
|
+
const joinCookieRaw = await this.webex.boundedStorage
|
|
44
|
+
.get(REACHABILITY.namespace, REACHABILITY.localStorageJoinCookie)
|
|
45
|
+
.catch(() => {});
|
|
46
|
+
|
|
47
|
+
if (joinCookieRaw) {
|
|
48
|
+
try {
|
|
49
|
+
joinCookie = JSON.parse(joinCookieRaw);
|
|
50
|
+
} catch (e) {
|
|
51
|
+
LoggerProxy.logger.error(
|
|
52
|
+
`MeetingRequest#constructor --> Error in parsing join cookie data: ${e}`
|
|
53
|
+
);
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
return {localSdp, joinCookie};
|
|
41
58
|
}
|
|
42
59
|
|
|
43
60
|
/**
|
|
@@ -53,7 +70,7 @@ export default class RoapRequest extends StatelessWebexPlugin {
|
|
|
53
70
|
* @param {Boolean} options.preferTranscoding
|
|
54
71
|
* @returns {Promise} returns the response/failure of the request
|
|
55
72
|
*/
|
|
56
|
-
sendRoap(options: {
|
|
73
|
+
async sendRoap(options: {
|
|
57
74
|
roapMessage: any;
|
|
58
75
|
locusSelfUrl: string;
|
|
59
76
|
mediaId: string;
|
|
@@ -69,6 +86,14 @@ export default class RoapRequest extends StatelessWebexPlugin {
|
|
|
69
86
|
LoggerProxy.logger.info('Roap:request#sendRoap --> Race Condition /call mediaID not present');
|
|
70
87
|
}
|
|
71
88
|
|
|
89
|
+
const {localSdp: localSdpWithReachabilityData, joinCookie} = await this.attachReachabilityData({
|
|
90
|
+
roapMessage,
|
|
91
|
+
// eslint-disable-next-line no-warning-comments
|
|
92
|
+
// TODO: check whats the need for video and audiomute
|
|
93
|
+
audioMuted: !!options.audioMuted,
|
|
94
|
+
videoMuted: !!options.videoMuted,
|
|
95
|
+
});
|
|
96
|
+
|
|
72
97
|
const mediaUrl = `${locusSelfUrl}/${MEDIA}`;
|
|
73
98
|
// @ts-ignore
|
|
74
99
|
const deviceUrl = this.webex.internal.device.url;
|
|
@@ -79,79 +104,69 @@ export default class RoapRequest extends StatelessWebexPlugin {
|
|
|
79
104
|
|
|
80
105
|
Metrics.postEvent({event: eventType.MEDIA_REQUEST, meetingId});
|
|
81
106
|
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
// @ts-ignore
|
|
98
|
-
deviceType: this.config.meetings.deviceType,
|
|
99
|
-
},
|
|
100
|
-
correlationId,
|
|
101
|
-
localMedias: [
|
|
102
|
-
{
|
|
103
|
-
localSdp: JSON.stringify(sdpWithReachability),
|
|
104
|
-
mediaId: options.mediaId,
|
|
105
|
-
},
|
|
106
|
-
],
|
|
107
|
-
clientMediaPreferences: {
|
|
108
|
-
preferTranscoding: options.preferTranscoding ?? true,
|
|
109
|
-
},
|
|
107
|
+
// @ts-ignore
|
|
108
|
+
return this.request({
|
|
109
|
+
uri: mediaUrl,
|
|
110
|
+
method: HTTP_VERBS.PUT,
|
|
111
|
+
body: {
|
|
112
|
+
device: {
|
|
113
|
+
url: deviceUrl,
|
|
114
|
+
// @ts-ignore
|
|
115
|
+
deviceType: this.config.meetings.deviceType,
|
|
116
|
+
},
|
|
117
|
+
correlationId,
|
|
118
|
+
localMedias: [
|
|
119
|
+
{
|
|
120
|
+
localSdp: JSON.stringify(localSdpWithReachabilityData),
|
|
121
|
+
mediaId: options.mediaId,
|
|
110
122
|
},
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
roapMessage,
|
|
149
|
-
null,
|
|
150
|
-
2
|
|
151
|
-
)} + '\\n mediaId:'${options.mediaId}`
|
|
152
|
-
);
|
|
153
|
-
throw err;
|
|
123
|
+
],
|
|
124
|
+
clientMediaPreferences: {
|
|
125
|
+
preferTranscoding: options.preferTranscoding ?? true,
|
|
126
|
+
joinCookie,
|
|
127
|
+
},
|
|
128
|
+
},
|
|
129
|
+
})
|
|
130
|
+
.then((res) => {
|
|
131
|
+
Metrics.postEvent({event: eventType.MEDIA_RESPONSE, meetingId});
|
|
132
|
+
|
|
133
|
+
// always it will be the first mediaConnection Object
|
|
134
|
+
const mediaConnections =
|
|
135
|
+
res.body.mediaConnections &&
|
|
136
|
+
res.body.mediaConnections.length > 0 &&
|
|
137
|
+
res.body.mediaConnections[0];
|
|
138
|
+
|
|
139
|
+
LoggerProxy.logger.debug(
|
|
140
|
+
`Roap:request#sendRoap --> response:${JSON.stringify(
|
|
141
|
+
mediaConnections,
|
|
142
|
+
null,
|
|
143
|
+
2
|
|
144
|
+
)}'\n StatusCode:'${res.statusCode}`
|
|
145
|
+
);
|
|
146
|
+
const {locus} = res.body;
|
|
147
|
+
|
|
148
|
+
locus.roapSeq = options.roapMessage.seq;
|
|
149
|
+
|
|
150
|
+
return {
|
|
151
|
+
locus,
|
|
152
|
+
...(mediaConnections && {mediaConnections: res.body.mediaConnections}),
|
|
153
|
+
};
|
|
154
|
+
})
|
|
155
|
+
.catch((err) => {
|
|
156
|
+
Metrics.postEvent({
|
|
157
|
+
event: eventType.MEDIA_RESPONSE,
|
|
158
|
+
meetingId,
|
|
159
|
+
data: {error: Metrics.parseLocusError(err, true)},
|
|
154
160
|
});
|
|
155
|
-
|
|
161
|
+
LoggerProxy.logger.error(`Roap:request#sendRoap --> Error:${JSON.stringify(err, null, 2)}`);
|
|
162
|
+
LoggerProxy.logger.error(
|
|
163
|
+
`Roap:request#sendRoapRequest --> errorBody:${JSON.stringify(
|
|
164
|
+
roapMessage,
|
|
165
|
+
null,
|
|
166
|
+
2
|
|
167
|
+
)} + '\\n mediaId:'${options.mediaId}`
|
|
168
|
+
);
|
|
169
|
+
throw err;
|
|
170
|
+
});
|
|
156
171
|
}
|
|
157
172
|
}
|
|
@@ -26,6 +26,8 @@ describe('plugin-meetings', () => {
|
|
|
26
26
|
},
|
|
27
27
|
};
|
|
28
28
|
|
|
29
|
+
webex.boundedStorage.get = sinon.mock().returns(Promise.resolve(JSON.stringify({anycastEntryPoint: "aws-eu-west-1"})))
|
|
30
|
+
|
|
29
31
|
meetingsRequest = new MeetingRequest(
|
|
30
32
|
{},
|
|
31
33
|
{
|
|
@@ -206,6 +208,31 @@ describe('plugin-meetings', () => {
|
|
|
206
208
|
const requestParams = meetingsRequest.request.getCall(0).args[0];
|
|
207
209
|
|
|
208
210
|
assert.deepEqual(requestParams.body.deviceCapabilities, undefined);
|
|
211
|
+
|
|
212
|
+
});
|
|
213
|
+
|
|
214
|
+
it('includes joinCookie correctly', async () => {
|
|
215
|
+
const locusUrl = 'locusURL';
|
|
216
|
+
const deviceUrl = 'deviceUrl';
|
|
217
|
+
const correlationId = 'random-uuid';
|
|
218
|
+
const roapMessage = 'roap-message';
|
|
219
|
+
const permissionToken = 'permission-token';
|
|
220
|
+
|
|
221
|
+
await meetingsRequest.joinMeeting({
|
|
222
|
+
locusUrl,
|
|
223
|
+
deviceUrl,
|
|
224
|
+
correlationId,
|
|
225
|
+
roapMessage,
|
|
226
|
+
permissionToken,
|
|
227
|
+
});
|
|
228
|
+
const requestParams = meetingsRequest.request.getCall(0).args[0];
|
|
229
|
+
|
|
230
|
+
assert.equal(requestParams.method, 'POST');
|
|
231
|
+
assert.equal(requestParams.uri, `${locusUrl}/participant?alternateRedirect=true`);
|
|
232
|
+
assert.deepEqual(requestParams.body.clientMediaPreferences, {
|
|
233
|
+
"joinCookie": {anycastEntryPoint: "aws-eu-west-1"},
|
|
234
|
+
"preferTranscoding": true
|
|
235
|
+
});
|
|
209
236
|
});
|
|
210
237
|
});
|
|
211
238
|
|
|
@@ -22,8 +22,8 @@ describe('isAnyClusterReachable', () => {
|
|
|
22
22
|
|
|
23
23
|
const result = await reachability.isAnyClusterReachable();
|
|
24
24
|
|
|
25
|
-
|
|
26
|
-
|
|
25
|
+
assert.equal(result, expectedValue);
|
|
26
|
+
};
|
|
27
27
|
|
|
28
28
|
it('returns true when udp is reachable', async () => {
|
|
29
29
|
await checkIsClusterReachable({x: {udp: {reachable: 'true'}, tcp: {reachable: 'false'}}}, true);
|
|
@@ -66,19 +66,30 @@ describe('gatherReachability', () => {
|
|
|
66
66
|
it('stores the reachability', async () => {
|
|
67
67
|
const reachability = new Reachability(webex);
|
|
68
68
|
|
|
69
|
-
const
|
|
70
|
-
|
|
69
|
+
const reachabilityResults = {
|
|
70
|
+
clusters: {
|
|
71
|
+
clusterId: {
|
|
72
|
+
udp: 'testUDP',
|
|
73
|
+
},
|
|
74
|
+
},
|
|
75
|
+
}
|
|
76
|
+
const getClustersResult = {
|
|
77
|
+
clusters: {clusterId: 'cluster'},
|
|
78
|
+
joinCookie: {id: 'id'}
|
|
79
|
+
};
|
|
71
80
|
|
|
72
|
-
reachability.reachabilityRequest.getClusters = sinon.stub().returns(
|
|
81
|
+
reachability.reachabilityRequest.getClusters = sinon.stub().returns(getClustersResult);
|
|
73
82
|
(reachability as any).performReachabilityCheck = sinon.stub().returns(reachabilityResults)
|
|
74
83
|
|
|
75
84
|
const result = await reachability.gatherReachability();
|
|
76
85
|
|
|
77
86
|
assert.equal(result, reachabilityResults);
|
|
78
87
|
|
|
79
|
-
const
|
|
88
|
+
const storedResultForReachabilityResult = await webex.boundedStorage.get('Reachability', 'reachability.result');
|
|
89
|
+
const storedResultForJoinCookie = await webex.boundedStorage.get('Reachability', 'reachability.joinCookie');
|
|
80
90
|
|
|
81
|
-
assert.equal(JSON.stringify(result),
|
|
91
|
+
assert.equal(JSON.stringify(result), storedResultForReachabilityResult);
|
|
92
|
+
assert.equal(JSON.stringify(getClustersResult.joinCookie), storedResultForJoinCookie);
|
|
82
93
|
});
|
|
83
94
|
|
|
84
95
|
});
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
import sinon from 'sinon';
|
|
2
|
+
import {assert} from '@webex/test-helper-chai';
|
|
3
|
+
import MockWebex from '@webex/test-helper-mock-webex';
|
|
4
|
+
import Meetings from '@webex/plugin-meetings';
|
|
5
|
+
import ReachabilityRequest from '@webex/plugin-meetings/src/reachability/request';
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
describe('plugin-meetings/reachability', () => {
|
|
9
|
+
let reachabilityRequest;
|
|
10
|
+
let webex;
|
|
11
|
+
|
|
12
|
+
beforeEach(() => {
|
|
13
|
+
webex = new MockWebex({
|
|
14
|
+
children: {
|
|
15
|
+
meetings: Meetings,
|
|
16
|
+
},
|
|
17
|
+
});
|
|
18
|
+
|
|
19
|
+
webex.meetings.clientRegion = {
|
|
20
|
+
countryCode: 'US',
|
|
21
|
+
regionCode: 'WEST-COAST',
|
|
22
|
+
};
|
|
23
|
+
|
|
24
|
+
webex.internal = {
|
|
25
|
+
services: {
|
|
26
|
+
get: sinon.mock().returns('locusUrl'),
|
|
27
|
+
waitForCatalog: sinon.mock().returns(Promise.resolve({})),
|
|
28
|
+
},
|
|
29
|
+
};
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
reachabilityRequest = new ReachabilityRequest(webex);
|
|
33
|
+
|
|
34
|
+
});
|
|
35
|
+
|
|
36
|
+
describe('#getClusters', () => {
|
|
37
|
+
it('sends a GET request with the correct params', async () => {
|
|
38
|
+
webex.request = sinon.mock().returns(Promise.resolve({
|
|
39
|
+
body: {
|
|
40
|
+
clusterClasses: {
|
|
41
|
+
hybridMedia: ["clusterId"]
|
|
42
|
+
},
|
|
43
|
+
clusters: {"clusterId": {
|
|
44
|
+
udp: "testUDP"
|
|
45
|
+
}},
|
|
46
|
+
joinCookie: {anycastEntryPoint: "aws-eu-west-1"}
|
|
47
|
+
}
|
|
48
|
+
}));
|
|
49
|
+
|
|
50
|
+
const res = await reachabilityRequest.getClusters();
|
|
51
|
+
|
|
52
|
+
const requestParams = webex.request.getCall(0).args[0];
|
|
53
|
+
|
|
54
|
+
assert.equal(requestParams.method, 'GET');
|
|
55
|
+
assert.equal(requestParams.resource, `clusters`);
|
|
56
|
+
assert.equal(requestParams.api, 'calliopeDiscovery');
|
|
57
|
+
assert.equal(requestParams.shouldRefreshAccessToken, false);
|
|
58
|
+
|
|
59
|
+
assert.deepEqual(requestParams.qs, {
|
|
60
|
+
JCSupport: 1,
|
|
61
|
+
});
|
|
62
|
+
assert.deepEqual(res.clusters.clusterId, {udp: "testUDP", isVideoMesh: true})
|
|
63
|
+
assert.deepEqual(res.joinCookie, {anycastEntryPoint: "aws-eu-west-1"})
|
|
64
|
+
});
|
|
65
|
+
});
|
|
66
|
+
});
|