@webex/plugin-meetings 1.147.1 → 1.148.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.
- package/dist/constants.js +17 -1
- package/dist/constants.js.map +1 -1
- package/dist/meeting/index.js +278 -181
- package/dist/meeting/index.js.map +1 -1
- package/dist/meeting/request.js +72 -29
- package/dist/meeting/request.js.map +1 -1
- package/dist/meeting/util.js +4 -4
- package/dist/meeting/util.js.map +1 -1
- package/package.json +5 -5
- package/src/constants.js +10 -0
- package/src/meeting/index.js +110 -15
- package/src/meeting/request.js +53 -9
- package/src/meeting/util.js +4 -4
- package/test/unit/spec/meeting/index.js +65 -1
- package/test/unit/spec/meeting/request.js +30 -5
package/src/constants.js
CHANGED
|
@@ -1220,6 +1220,7 @@ export const METRICS_OPERATIONAL_MEASURES = {
|
|
|
1220
1220
|
SET_MEETING_QUALITY_FAILURE: 'js_sdk_set_meeting_quality_failures',
|
|
1221
1221
|
STOP_FLOOR_REQUEST_FAILURE: 'js_sdk_stop_floor_request_failures',
|
|
1222
1222
|
ADD_DIAL_IN_FAILURE: 'js_sdk_add_dial_in_failure',
|
|
1223
|
+
ADD_DIAL_OUT_FAILURE: 'js_sdk_add_dial_out_failure',
|
|
1223
1224
|
UPDATE_MEDIA_FAILURE: 'js_sdk_update_media_failures',
|
|
1224
1225
|
UNMUTE_AUDIO_FAILURE: 'js_sdk_unmute_audio_failures',
|
|
1225
1226
|
UNMUTE_VIDEO_FAILURE: 'js_sdk_unmute_video_failures',
|
|
@@ -1232,3 +1233,12 @@ export const METRICS_OPERATIONAL_MEASURES = {
|
|
|
1232
1233
|
UPLOAD_LOGS_FAILURE: 'js_sdk_upload_logs_failure',
|
|
1233
1234
|
RECEIVE_TRANSCRIPTION_FAILURE: 'js_sdk_receive_transcription_failure'
|
|
1234
1235
|
};
|
|
1236
|
+
|
|
1237
|
+
export const PSTN_STATUS = {
|
|
1238
|
+
JOINED: 'JOINED', // we have provisioned a pstn device, which can be used to connect
|
|
1239
|
+
CONNECTED: 'CONNECTED', // user is connected to audio with pstn device
|
|
1240
|
+
LEFT: 'LEFT', // user has disconnected from the pstn device
|
|
1241
|
+
TRANSFERRING: 'TRANSFERRING', // usually happens in dial-out after the CONNECTED state
|
|
1242
|
+
SUCCESS: 'SUCCESS', // happens after the transfer (TRANSFERRING) is successful
|
|
1243
|
+
UNKNOWN: '' // placeholder if we haven't been told what the status is
|
|
1244
|
+
};
|
package/src/meeting/index.js
CHANGED
|
@@ -57,6 +57,7 @@ import {
|
|
|
57
57
|
ONLINE,
|
|
58
58
|
OFFLINE,
|
|
59
59
|
PC_BAIL_TIMEOUT,
|
|
60
|
+
PSTN_STATUS,
|
|
60
61
|
QUALITY_LEVELS,
|
|
61
62
|
RECORDING_STATE,
|
|
62
63
|
ROAP_SEQ_PRE,
|
|
@@ -710,13 +711,14 @@ export default class Meeting extends StatelessWebexPlugin {
|
|
|
710
711
|
*/
|
|
711
712
|
this.floorGrantPending = false;
|
|
712
713
|
/**
|
|
713
|
-
* The latest status of the dial in device (can be "JOINED", "CONNECTED", "LEFT"
|
|
714
|
+
* The latest status of the dial in device (can be "JOINED", "CONNECTED", "LEFT",
|
|
715
|
+
* "TRANSFERRING", "SUCCESS" or "")
|
|
714
716
|
* @instance
|
|
715
717
|
* @type {String}
|
|
716
718
|
* @private
|
|
717
719
|
* @memberof Meeting
|
|
718
720
|
*/
|
|
719
|
-
this.dialInDeviceStatus =
|
|
721
|
+
this.dialInDeviceStatus = PSTN_STATUS.UNKNOWN;
|
|
720
722
|
/**
|
|
721
723
|
* the url for provisioned device used to dial in
|
|
722
724
|
* @instance
|
|
@@ -725,6 +727,23 @@ export default class Meeting extends StatelessWebexPlugin {
|
|
|
725
727
|
* @memberof Meeting
|
|
726
728
|
*/
|
|
727
729
|
this.dialInUrl = '';
|
|
730
|
+
/**
|
|
731
|
+
* The latest status of the dial out device (can be "JOINED", "CONNECTED", "LEFT",
|
|
732
|
+
* "TRANSFERRING", "SUCCESS" or "")
|
|
733
|
+
* @instance
|
|
734
|
+
* @type {String}
|
|
735
|
+
* @private
|
|
736
|
+
* @memberof Meeting
|
|
737
|
+
*/
|
|
738
|
+
this.dialOutDeviceStatus = PSTN_STATUS.UNKNOWN;
|
|
739
|
+
/**
|
|
740
|
+
* the url for provisioned device used to dial out
|
|
741
|
+
* @instance
|
|
742
|
+
* @type {String}
|
|
743
|
+
* @private
|
|
744
|
+
* @memberof Meeting
|
|
745
|
+
*/
|
|
746
|
+
this.dialOutUrl = '';
|
|
728
747
|
/**
|
|
729
748
|
* @instance
|
|
730
749
|
* @type {MediaMetrics}
|
|
@@ -1144,9 +1163,28 @@ export default class Meeting extends StatelessWebexPlugin {
|
|
|
1144
1163
|
pstnUpdate(payload) {
|
|
1145
1164
|
if (this.locusInfo.self) {
|
|
1146
1165
|
const dialInPstnDevice = payload.newSelf?.pstnDevices.find((device) => device.url === this.dialInUrl);
|
|
1166
|
+
const dialOutPstnDevice = payload.newSelf?.pstnDevices.find((device) => device.url === this.dialOutUrl);
|
|
1167
|
+
let changed = false;
|
|
1147
1168
|
|
|
1148
1169
|
if (dialInPstnDevice) {
|
|
1149
|
-
|
|
1170
|
+
const newStatus = dialInPstnDevice.dialingStatus ?? dialInPstnDevice.state;
|
|
1171
|
+
|
|
1172
|
+
if (newStatus !== this.dialInDeviceStatus) {
|
|
1173
|
+
this.dialInDeviceStatus = newStatus;
|
|
1174
|
+
changed = true;
|
|
1175
|
+
}
|
|
1176
|
+
}
|
|
1177
|
+
|
|
1178
|
+
if (dialOutPstnDevice) {
|
|
1179
|
+
const newStatus = dialOutPstnDevice.dialingStatus ?? dialOutPstnDevice.state;
|
|
1180
|
+
|
|
1181
|
+
if (newStatus !== this.dialOutDeviceStatus) {
|
|
1182
|
+
this.dialOutDeviceStatus = newStatus;
|
|
1183
|
+
changed = true;
|
|
1184
|
+
}
|
|
1185
|
+
}
|
|
1186
|
+
|
|
1187
|
+
if (changed) {
|
|
1150
1188
|
Trigger.trigger(
|
|
1151
1189
|
this,
|
|
1152
1190
|
{
|
|
@@ -1157,7 +1195,11 @@ export default class Meeting extends StatelessWebexPlugin {
|
|
|
1157
1195
|
{
|
|
1158
1196
|
dialIn: {
|
|
1159
1197
|
status: this.dialInDeviceStatus,
|
|
1160
|
-
attendeeId: dialInPstnDevice
|
|
1198
|
+
attendeeId: dialInPstnDevice?.attendeeId
|
|
1199
|
+
},
|
|
1200
|
+
dialOut: {
|
|
1201
|
+
status: this.dialOutDeviceStatus,
|
|
1202
|
+
attendeeId: dialOutPstnDevice?.attendeeId
|
|
1161
1203
|
}
|
|
1162
1204
|
}
|
|
1163
1205
|
);
|
|
@@ -3313,7 +3355,7 @@ export default class Meeting extends StatelessWebexPlugin {
|
|
|
3313
3355
|
/**
|
|
3314
3356
|
* Use phone for meeting audio
|
|
3315
3357
|
* @param {String} phoneNumber If provided, it will dial-out using this number. If not provided, dial-in will be used
|
|
3316
|
-
* @returns {Promise} Resolves once the dial-in or dial-out request has completed
|
|
3358
|
+
* @returns {Promise} Resolves once the dial-in or dial-out request has completed, or rejects if it failed
|
|
3317
3359
|
* @public
|
|
3318
3360
|
* @memberof Meeting
|
|
3319
3361
|
*/
|
|
@@ -3322,17 +3364,28 @@ export default class Meeting extends StatelessWebexPlugin {
|
|
|
3322
3364
|
return this.dialInPstn();
|
|
3323
3365
|
}
|
|
3324
3366
|
|
|
3325
|
-
return
|
|
3367
|
+
return this.dialOutPstn(phoneNumber);
|
|
3368
|
+
}
|
|
3369
|
+
|
|
3370
|
+
/**
|
|
3371
|
+
* Determines if the given pstnStatus is in a state which implies the phone is provisioned
|
|
3372
|
+
* @param {String} pstnStatus
|
|
3373
|
+
* @returns {Boolean}
|
|
3374
|
+
* @private
|
|
3375
|
+
* @memberof Meeting
|
|
3376
|
+
*/
|
|
3377
|
+
isPhoneProvisioned(pstnStatus) {
|
|
3378
|
+
return [PSTN_STATUS.JOINED, PSTN_STATUS.CONNECTED, PSTN_STATUS.SUCCESS].includes(pstnStatus);
|
|
3326
3379
|
}
|
|
3327
3380
|
|
|
3328
3381
|
/**
|
|
3329
3382
|
* Enable dial-in for audio
|
|
3330
|
-
* @returns {Promise} Resolves once the dial-in request has completed
|
|
3383
|
+
* @returns {Promise} Resolves once the dial-in request has completed, or rejects if it failed
|
|
3331
3384
|
* @private
|
|
3332
3385
|
* @memberof Meeting
|
|
3333
3386
|
*/
|
|
3334
3387
|
dialInPstn() {
|
|
3335
|
-
if (this.
|
|
3388
|
+
if (this.isPhoneProvisioned(this.dialInDeviceStatus)) return Promise.resolve(); // prevent multiple dial in devices from being provisioned
|
|
3336
3389
|
|
|
3337
3390
|
const {correlationId, locusUrl} = this;
|
|
3338
3391
|
|
|
@@ -3357,6 +3410,47 @@ export default class Meeting extends StatelessWebexPlugin {
|
|
|
3357
3410
|
stack: error.stack
|
|
3358
3411
|
}
|
|
3359
3412
|
);
|
|
3413
|
+
|
|
3414
|
+
return Promise.reject(error);
|
|
3415
|
+
});
|
|
3416
|
+
}
|
|
3417
|
+
|
|
3418
|
+
/**
|
|
3419
|
+
* Enable dial-out for audio
|
|
3420
|
+
* @param {String} phoneNumber Phone number to dial out to
|
|
3421
|
+
* @returns {Promise} Resolves once the dial-out request has completed (it doesn't wait for the user to answer the phone), or rejects if it failed
|
|
3422
|
+
* @private
|
|
3423
|
+
* @memberof Meeting
|
|
3424
|
+
*/
|
|
3425
|
+
dialOutPstn(phoneNumber) {
|
|
3426
|
+
if (this.isPhoneProvisioned(this.dialOutDeviceStatus)) return Promise.resolve(); // prevent multiple dial out devices from being provisioned
|
|
3427
|
+
|
|
3428
|
+
const {correlationId, locusUrl} = this;
|
|
3429
|
+
|
|
3430
|
+
if (!this.dialOutUrl) this.dialOutUrl = `dialout:///${uuid.v4()}`;
|
|
3431
|
+
|
|
3432
|
+
return this.meetingRequest.dialOut({
|
|
3433
|
+
correlationId,
|
|
3434
|
+
dialOutUrl: this.dialOutUrl,
|
|
3435
|
+
phoneNumber,
|
|
3436
|
+
locusUrl,
|
|
3437
|
+
clientUrl: this.deviceUrl
|
|
3438
|
+
}).then((res) => {
|
|
3439
|
+
this.locusInfo.onFullLocus(res.body.locus);
|
|
3440
|
+
}).catch((error) => {
|
|
3441
|
+
Metrics.sendOperationalMetric(
|
|
3442
|
+
METRICS_OPERATIONAL_MEASURES.ADD_DIAL_OUT_FAILURE,
|
|
3443
|
+
{
|
|
3444
|
+
correlation_id: this.correlationId,
|
|
3445
|
+
dial_out_url: this.dialOutUrl,
|
|
3446
|
+
locus_id: locusUrl.split('/').pop(),
|
|
3447
|
+
client_url: this.deviceUrl,
|
|
3448
|
+
reason: error.error?.message,
|
|
3449
|
+
stack: error.stack
|
|
3450
|
+
}
|
|
3451
|
+
);
|
|
3452
|
+
|
|
3453
|
+
return Promise.reject(error);
|
|
3360
3454
|
});
|
|
3361
3455
|
}
|
|
3362
3456
|
|
|
@@ -3368,13 +3462,14 @@ export default class Meeting extends StatelessWebexPlugin {
|
|
|
3368
3462
|
* @returns {Promise}
|
|
3369
3463
|
*/
|
|
3370
3464
|
disconnectPhoneAudio() {
|
|
3371
|
-
|
|
3372
|
-
|
|
3373
|
-
|
|
3374
|
-
|
|
3375
|
-
|
|
3376
|
-
|
|
3377
|
-
|
|
3465
|
+
return Promise.all([
|
|
3466
|
+
this.isPhoneProvisioned(this.dialInDeviceStatus) ?
|
|
3467
|
+
MeetingUtil.disconnectPhoneAudio(this, this.dialInUrl) :
|
|
3468
|
+
Promise.resolve(),
|
|
3469
|
+
this.isPhoneProvisioned(this.dialOutDeviceStatus) ?
|
|
3470
|
+
MeetingUtil.disconnectPhoneAudio(this, this.dialOutUrl) :
|
|
3471
|
+
Promise.resolve()
|
|
3472
|
+
]);
|
|
3378
3473
|
}
|
|
3379
3474
|
|
|
3380
3475
|
/**
|
package/src/meeting/request.js
CHANGED
|
@@ -20,6 +20,7 @@ import {
|
|
|
20
20
|
MEDIA,
|
|
21
21
|
PARTICIPANT,
|
|
22
22
|
PROVISIONAL_TYPE_DIAL_IN,
|
|
23
|
+
PROVISIONAL_TYPE_DIAL_OUT,
|
|
23
24
|
SEND_DTMF_ENDPOINT,
|
|
24
25
|
_SLIDES_
|
|
25
26
|
} from '../constants';
|
|
@@ -182,6 +183,48 @@ export default class MeetingRequest extends StatelessWebexPlugin {
|
|
|
182
183
|
});
|
|
183
184
|
}
|
|
184
185
|
|
|
186
|
+
/**
|
|
187
|
+
* Make a network request to add a dial out device
|
|
188
|
+
* @param {Object} options
|
|
189
|
+
* @param {String} options.correlationId
|
|
190
|
+
* @param {String} options.localUrl url for the meeting
|
|
191
|
+
* @param {String} options.dialOutUrl identifier for the to-be provisioned device
|
|
192
|
+
* @param {String} options.phoneNumber phone number to dial out to
|
|
193
|
+
* @param {String} options.clientUrl identifier for the web device
|
|
194
|
+
* @returns {Promise}
|
|
195
|
+
* @private
|
|
196
|
+
*/
|
|
197
|
+
dialOut({
|
|
198
|
+
locusUrl, dialOutUrl, phoneNumber, clientUrl, correlationId
|
|
199
|
+
}) {
|
|
200
|
+
LoggerProxy.logger.info(
|
|
201
|
+
'Meeting:request#dialOut --> Provisioning a dial out device',
|
|
202
|
+
correlationId
|
|
203
|
+
);
|
|
204
|
+
const uri = `${locusUrl}/${PARTICIPANT}`;
|
|
205
|
+
|
|
206
|
+
const body = {
|
|
207
|
+
device: {
|
|
208
|
+
deviceType: deviceType.PROVISIONAL,
|
|
209
|
+
provisionalType: PROVISIONAL_TYPE_DIAL_OUT,
|
|
210
|
+
url: dialOutUrl,
|
|
211
|
+
dialoutAddress: phoneNumber,
|
|
212
|
+
clientUrl
|
|
213
|
+
},
|
|
214
|
+
correlationId
|
|
215
|
+
};
|
|
216
|
+
|
|
217
|
+
return this.request({
|
|
218
|
+
method: HTTP_VERBS.POST,
|
|
219
|
+
uri,
|
|
220
|
+
body
|
|
221
|
+
}).catch((err) => {
|
|
222
|
+
LoggerProxy.logger.error(`Meeting:request#dialOut --> Error provisioning a dial out device, error ${err}`);
|
|
223
|
+
|
|
224
|
+
throw err;
|
|
225
|
+
});
|
|
226
|
+
}
|
|
227
|
+
|
|
185
228
|
/**
|
|
186
229
|
* Syns the missed delta event
|
|
187
230
|
* @param {Object} options
|
|
@@ -241,21 +284,20 @@ export default class MeetingRequest extends StatelessWebexPlugin {
|
|
|
241
284
|
}
|
|
242
285
|
|
|
243
286
|
/**
|
|
244
|
-
* Make a network request to make a provisioned
|
|
287
|
+
* Make a network request to make a provisioned phone leave the meeting
|
|
245
288
|
* @param {Object} options
|
|
246
289
|
* @param {String} options.locusUrl
|
|
247
|
-
* @param {String} options.
|
|
248
|
-
* @param {String} options.deviceUrl
|
|
249
|
-
* @param {String} options.resourceId,
|
|
290
|
+
* @param {String} options.phoneUrl
|
|
250
291
|
* @param {String} options.correlationId
|
|
292
|
+
* @param {String} options.selfId
|
|
251
293
|
* @returns {Promise}
|
|
252
294
|
* @private
|
|
253
295
|
*/
|
|
254
|
-
|
|
255
|
-
locusUrl,
|
|
296
|
+
disconnectPhoneAudio({
|
|
297
|
+
locusUrl, phoneUrl, correlationId, selfId
|
|
256
298
|
}) {
|
|
257
299
|
LoggerProxy.logger.info(
|
|
258
|
-
`Meeting:request#
|
|
300
|
+
`Meeting:request#disconnectPhoneAudio --> request phone ${phoneUrl} to leave`,
|
|
259
301
|
correlationId
|
|
260
302
|
);
|
|
261
303
|
const uri = `${locusUrl}/${PARTICIPANT}/${selfId}/${LEAVE}`;
|
|
@@ -263,7 +305,7 @@ export default class MeetingRequest extends StatelessWebexPlugin {
|
|
|
263
305
|
const body = {
|
|
264
306
|
device: {
|
|
265
307
|
deviceType: deviceType.PROVISIONAL,
|
|
266
|
-
url:
|
|
308
|
+
url: phoneUrl
|
|
267
309
|
},
|
|
268
310
|
correlationId
|
|
269
311
|
};
|
|
@@ -273,7 +315,9 @@ export default class MeetingRequest extends StatelessWebexPlugin {
|
|
|
273
315
|
uri,
|
|
274
316
|
body
|
|
275
317
|
}).catch((err) => {
|
|
276
|
-
LoggerProxy.logger.error(
|
|
318
|
+
LoggerProxy.logger.error(
|
|
319
|
+
`Meeting:request#disconnectPhoneAudio --> Error when requesting phone ${phoneUrl} to leave, error ${err}`
|
|
320
|
+
);
|
|
277
321
|
|
|
278
322
|
throw err;
|
|
279
323
|
});
|
package/src/meeting/util.js
CHANGED
|
@@ -134,7 +134,7 @@ MeetingUtil.cleanUp = (meeting) => {
|
|
|
134
134
|
.then(() => meeting.roap.stop(meeting.correlationId, meeting.roapSeq));
|
|
135
135
|
};
|
|
136
136
|
|
|
137
|
-
MeetingUtil.
|
|
137
|
+
MeetingUtil.disconnectPhoneAudio = (meeting, phoneUrl) => {
|
|
138
138
|
if (meeting.meetingState === FULL_STATE.INACTIVE) {
|
|
139
139
|
return Promise.reject(new MeetingNotActiveError());
|
|
140
140
|
}
|
|
@@ -143,11 +143,11 @@ MeetingUtil.leavePstn = (meeting, dialInUrl) => {
|
|
|
143
143
|
locusUrl: meeting.locusUrl,
|
|
144
144
|
selfId: meeting.selfId,
|
|
145
145
|
correlationId: meeting.correlationId,
|
|
146
|
-
|
|
146
|
+
phoneUrl
|
|
147
147
|
};
|
|
148
148
|
|
|
149
149
|
return meeting.meetingRequest
|
|
150
|
-
.
|
|
150
|
+
.disconnectPhoneAudio(options)
|
|
151
151
|
.then((response) => {
|
|
152
152
|
if (response?.body?.locus) {
|
|
153
153
|
meeting.locusInfo.onFullLocus(response.body.locus);
|
|
@@ -155,7 +155,7 @@ MeetingUtil.leavePstn = (meeting, dialInUrl) => {
|
|
|
155
155
|
})
|
|
156
156
|
.catch((err) => {
|
|
157
157
|
LoggerProxy.logger.error(
|
|
158
|
-
`Meeting:util#
|
|
158
|
+
`Meeting:util#disconnectPhoneAudio --> An error occured while disconnecting phone audio in meeting ${
|
|
159
159
|
meeting.id
|
|
160
160
|
}, error: ${err}`
|
|
161
161
|
);
|
|
@@ -1902,7 +1902,9 @@ describe('plugin-meetings', () => {
|
|
|
1902
1902
|
|
|
1903
1903
|
describe('#usePhoneAudio', () => {
|
|
1904
1904
|
beforeEach(() => {
|
|
1905
|
-
meeting.meetingRequest.dialIn = sinon.stub().returns(Promise.resolve());
|
|
1905
|
+
meeting.meetingRequest.dialIn = sinon.stub().returns(Promise.resolve({body: {locus: 'testData'}}));
|
|
1906
|
+
meeting.meetingRequest.dialOut = sinon.stub().returns(Promise.resolve({body: {locus: 'testData'}}));
|
|
1907
|
+
meeting.locusInfo.onFullLocus = sinon.stub().returns(Promise.resolve());
|
|
1906
1908
|
});
|
|
1907
1909
|
|
|
1908
1910
|
it('with no parameters triggers dial-in, delegating request to meetingRequest correctly', async () => {
|
|
@@ -1915,8 +1917,11 @@ describe('plugin-meetings', () => {
|
|
|
1915
1917
|
locusUrl: meeting.locusUrl,
|
|
1916
1918
|
clientUrl: meeting.deviceUrl
|
|
1917
1919
|
});
|
|
1920
|
+
assert.calledWith(meeting.locusInfo.onFullLocus, 'testData');
|
|
1921
|
+
assert.notCalled(meeting.meetingRequest.dialOut);
|
|
1918
1922
|
|
|
1919
1923
|
meeting.meetingRequest.dialIn.resetHistory();
|
|
1924
|
+
meeting.locusInfo.onFullLocus.resetHistory();
|
|
1920
1925
|
|
|
1921
1926
|
// try again. the dial in urls should match
|
|
1922
1927
|
await meeting.usePhoneAudio();
|
|
@@ -1927,6 +1932,65 @@ describe('plugin-meetings', () => {
|
|
|
1927
1932
|
locusUrl: meeting.locusUrl,
|
|
1928
1933
|
clientUrl: meeting.deviceUrl
|
|
1929
1934
|
});
|
|
1935
|
+
assert.calledWith(meeting.locusInfo.onFullLocus, 'testData');
|
|
1936
|
+
assert.notCalled(meeting.meetingRequest.dialOut);
|
|
1937
|
+
});
|
|
1938
|
+
|
|
1939
|
+
it('given a phone number, triggers dial-out, delegating request to meetingRequest correctly', async () => {
|
|
1940
|
+
const phoneNumber = '+442088241000';
|
|
1941
|
+
|
|
1942
|
+
await meeting.usePhoneAudio(phoneNumber);
|
|
1943
|
+
const DIAL_OUT_URL = meeting.dialOutUrl;
|
|
1944
|
+
|
|
1945
|
+
assert.calledWith(meeting.meetingRequest.dialOut, {
|
|
1946
|
+
correlationId: meeting.correlationId,
|
|
1947
|
+
dialOutUrl: DIAL_OUT_URL,
|
|
1948
|
+
locusUrl: meeting.locusUrl,
|
|
1949
|
+
clientUrl: meeting.deviceUrl,
|
|
1950
|
+
phoneNumber
|
|
1951
|
+
});
|
|
1952
|
+
assert.calledWith(meeting.locusInfo.onFullLocus, 'testData');
|
|
1953
|
+
assert.notCalled(meeting.meetingRequest.dialIn);
|
|
1954
|
+
|
|
1955
|
+
meeting.meetingRequest.dialOut.resetHistory();
|
|
1956
|
+
meeting.locusInfo.onFullLocus.resetHistory();
|
|
1957
|
+
|
|
1958
|
+
// try again. the dial out urls should match
|
|
1959
|
+
await meeting.usePhoneAudio(phoneNumber);
|
|
1960
|
+
|
|
1961
|
+
assert.calledWith(meeting.meetingRequest.dialOut, {
|
|
1962
|
+
correlationId: meeting.correlationId,
|
|
1963
|
+
dialOutUrl: DIAL_OUT_URL,
|
|
1964
|
+
locusUrl: meeting.locusUrl,
|
|
1965
|
+
clientUrl: meeting.deviceUrl,
|
|
1966
|
+
phoneNumber
|
|
1967
|
+
});
|
|
1968
|
+
assert.calledWith(meeting.locusInfo.onFullLocus, 'testData');
|
|
1969
|
+
assert.notCalled(meeting.meetingRequest.dialIn);
|
|
1970
|
+
});
|
|
1971
|
+
|
|
1972
|
+
it('rejects if the request failed (dial in)', () => {
|
|
1973
|
+
const error = 'something bad happened';
|
|
1974
|
+
|
|
1975
|
+
meeting.meetingRequest.dialIn = sinon.stub().returns(Promise.reject(error));
|
|
1976
|
+
|
|
1977
|
+
return meeting.usePhoneAudio().then(() => Promise.reject(new Error('Promise resolved when it should have rejected'))).catch((e) => {
|
|
1978
|
+
assert.equal(e, error);
|
|
1979
|
+
|
|
1980
|
+
return Promise.resolve();
|
|
1981
|
+
});
|
|
1982
|
+
});
|
|
1983
|
+
|
|
1984
|
+
it('rejects if the request failed (dial out)', async () => {
|
|
1985
|
+
const error = 'something bad happened';
|
|
1986
|
+
|
|
1987
|
+
meeting.meetingRequest.dialOut = sinon.stub().returns(Promise.reject(error));
|
|
1988
|
+
|
|
1989
|
+
return meeting.usePhoneAudio('+441234567890').then(() => Promise.reject(new Error('Promise resolved when it should have rejected'))).catch((e) => {
|
|
1990
|
+
assert.equal(e, error);
|
|
1991
|
+
|
|
1992
|
+
return Promise.resolve();
|
|
1993
|
+
});
|
|
1930
1994
|
});
|
|
1931
1995
|
});
|
|
1932
1996
|
|
|
@@ -152,23 +152,48 @@ describe('plugin-meetings', () => {
|
|
|
152
152
|
assert.equal(requestParams.body.device.clientUrl, 'clientUrl');
|
|
153
153
|
});
|
|
154
154
|
|
|
155
|
-
it('sends
|
|
155
|
+
it('sends dial out pstn request', async () => {
|
|
156
|
+
const locusUrl = 'locusUrl';
|
|
157
|
+
const clientUrl = 'clientUrl';
|
|
158
|
+
const correlationId = 'random-uuid';
|
|
159
|
+
const dialOutUrl = 'url';
|
|
160
|
+
const phoneNumber = '+442088241000';
|
|
161
|
+
|
|
162
|
+
await meetingsRequest.dialOut({
|
|
163
|
+
locusUrl,
|
|
164
|
+
clientUrl,
|
|
165
|
+
correlationId,
|
|
166
|
+
dialOutUrl,
|
|
167
|
+
phoneNumber
|
|
168
|
+
});
|
|
169
|
+
const requestParams = meetingsRequest.request.getCall(0).args[0];
|
|
170
|
+
|
|
171
|
+
assert.equal(requestParams.method, 'POST');
|
|
172
|
+
assert.equal(requestParams.uri, `${locusUrl}/participant`);
|
|
173
|
+
assert.equal(requestParams.body.device.url, dialOutUrl);
|
|
174
|
+
assert.equal(requestParams.body.device.deviceType, 'PROVISIONAL');
|
|
175
|
+
assert.equal(requestParams.body.device.provisionalType, 'DIAL_OUT');
|
|
176
|
+
assert.equal(requestParams.body.device.clientUrl, 'clientUrl');
|
|
177
|
+
assert.equal(requestParams.body.device.dialoutAddress, phoneNumber);
|
|
178
|
+
});
|
|
179
|
+
|
|
180
|
+
it('sends disconnect phone audio request', async () => {
|
|
156
181
|
const locusUrl = 'locusUrl';
|
|
157
182
|
const selfId = 'selfId';
|
|
158
183
|
const correlationId = 'random-uuid';
|
|
159
|
-
const
|
|
184
|
+
const phoneUrl = 'url';
|
|
160
185
|
|
|
161
|
-
await meetingsRequest.
|
|
186
|
+
await meetingsRequest.disconnectPhoneAudio({
|
|
162
187
|
locusUrl,
|
|
163
188
|
selfId,
|
|
164
189
|
correlationId,
|
|
165
|
-
|
|
190
|
+
phoneUrl
|
|
166
191
|
});
|
|
167
192
|
const requestParams = meetingsRequest.request.getCall(0).args[0];
|
|
168
193
|
|
|
169
194
|
assert.equal(requestParams.method, 'PUT');
|
|
170
195
|
assert.equal(requestParams.uri, `${locusUrl}/participant/${selfId}/leave`);
|
|
171
|
-
assert.equal(requestParams.body.device.url,
|
|
196
|
+
assert.equal(requestParams.body.device.url, phoneUrl);
|
|
172
197
|
assert.equal(requestParams.body.device.deviceType, 'PROVISIONAL');
|
|
173
198
|
});
|
|
174
199
|
});
|