@webex/plugin-meetings 3.4.0-next.9 → 3.5.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/breakouts/breakout.js +1 -1
- package/dist/breakouts/index.js +1 -1
- package/dist/interpretation/index.js +1 -1
- package/dist/interpretation/siLanguage.js +1 -1
- package/dist/meeting/index.js +77 -11
- package/dist/meeting/index.js.map +1 -1
- package/dist/meeting/util.js +1 -0
- package/dist/meeting/util.js.map +1 -1
- package/dist/networkQualityMonitor/index.js +227 -0
- package/dist/networkQualityMonitor/index.js.map +1 -0
- package/dist/types/meeting/index.d.ts +9 -0
- package/dist/types/networkQualityMonitor/index.d.ts +70 -0
- package/dist/webinar/index.js +1 -1
- package/package.json +22 -22
- package/src/meeting/index.ts +39 -4
- package/src/meeting/util.ts +2 -0
- package/test/integration/spec/converged-space-meetings.js +1 -1
- package/test/unit/spec/breakouts/index.ts +1 -0
- package/test/unit/spec/interceptors/locusRetry.ts +11 -10
- package/test/unit/spec/media/MediaConnectionAwaiter.ts +1 -0
- package/test/unit/spec/media/index.ts +1 -0
- package/test/unit/spec/media/properties.ts +1 -1
- package/test/unit/spec/meeting/connectionStateHandler.ts +1 -0
- package/test/unit/spec/meeting/index.js +28 -0
- package/test/unit/spec/meeting/locusMediaRequest.ts +3 -2
- package/test/unit/spec/meeting/request.js +1 -0
- package/test/unit/spec/meeting/utils.js +4 -0
- package/test/unit/spec/meeting-info/meetinginfov2.js +10 -11
- package/test/unit/spec/meeting-info/request.js +1 -1
- package/test/unit/spec/members/request.js +2 -1
- package/test/unit/spec/multistream/mediaRequestManager.ts +1 -0
- package/test/unit/spec/multistream/receiveSlot.ts +1 -0
- package/test/unit/spec/multistream/receiveSlotManager.ts +1 -0
- package/test/unit/spec/multistream/remoteMedia.ts +1 -0
- package/test/unit/spec/multistream/remoteMediaGroup.ts +1 -0
- package/test/unit/spec/multistream/remoteMediaManager.ts +1 -0
- package/test/unit/spec/multistream/sendSlotManager.ts +1 -0
- package/test/unit/spec/personal-meeting-room/personal-meeting-room.js +0 -1
- package/test/unit/spec/reachability/request.js +1 -0
- package/test/unit/spec/roap/request.ts +1 -0
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
import EventsScope from '../common/events/events-scope';
|
|
2
|
+
/**
|
|
3
|
+
* Meeting - network quality event
|
|
4
|
+
* Emitted on each interval of retrieving stats Analyzer data
|
|
5
|
+
* @event network:quality
|
|
6
|
+
* @type {Object}
|
|
7
|
+
* @property {string} mediaType {video|audio}
|
|
8
|
+
* @property {number} networkQualityScore - value determined in determineUplinkNetworkQuality
|
|
9
|
+
* @memberof NetworkQualityMonitor
|
|
10
|
+
*/
|
|
11
|
+
/**
|
|
12
|
+
* NetworkQualityMonitor class that will emit events based on detected quality
|
|
13
|
+
*
|
|
14
|
+
* @class NetworkQualityMonitor
|
|
15
|
+
* @extends {EventsScope}
|
|
16
|
+
*/
|
|
17
|
+
export default class NetworkQualityMonitor extends EventsScope {
|
|
18
|
+
config: any;
|
|
19
|
+
frequencyTypes: any;
|
|
20
|
+
indicatorTypes: any;
|
|
21
|
+
mediaType: any;
|
|
22
|
+
networkQualityScore: any;
|
|
23
|
+
networkQualityStatus: any;
|
|
24
|
+
/**
|
|
25
|
+
* Creates a new instance of NetworkQualityMonitor
|
|
26
|
+
* @constructor
|
|
27
|
+
* @public
|
|
28
|
+
* @param {Object} config
|
|
29
|
+
* @property {Object} indicatorTypes - network properties used to evaluate network quality used as constants
|
|
30
|
+
* @property {Object} frequencyTypes - frequency properties used as constants {uplink|send} {downlink|receive}
|
|
31
|
+
* @property {number} networkQualityScore - 0|1 1 is acceptable 0 is bad/unknown
|
|
32
|
+
* @property {Object} networkQualityStatus - hash object based on indicatorTypes and frequencyTypes
|
|
33
|
+
* @property {string} mediaType - audio|video
|
|
34
|
+
*/
|
|
35
|
+
constructor(config: any);
|
|
36
|
+
/**
|
|
37
|
+
* emits NETWORK_QUALITY event on meeting with payload of media type and uplinkNetworkQuality score
|
|
38
|
+
*
|
|
39
|
+
* @memberof NetworkQualityMonitor
|
|
40
|
+
* @returns {void}
|
|
41
|
+
*/
|
|
42
|
+
emitNetworkQuality(): void;
|
|
43
|
+
/**
|
|
44
|
+
* invokes emitNetworkQuality method resets values back to default
|
|
45
|
+
* @returns {void}
|
|
46
|
+
* @memberof NetworkQualityMonitor
|
|
47
|
+
*/
|
|
48
|
+
updateNetworkQualityStatus(): void;
|
|
49
|
+
/**
|
|
50
|
+
* filter data to determine uplink network quality, invoked on same interval as stats analyzer remote-inbout-rtp
|
|
51
|
+
* @param {Object} configObj
|
|
52
|
+
* @param {string} configObj.mediaType {audio|video}
|
|
53
|
+
* @param {RTCStats} configObj.remoteRtpResults RTC stats remote obj
|
|
54
|
+
* @param {Object} configObj.statsAnalyzerCurrentStats statsResults
|
|
55
|
+
* @returns {void}
|
|
56
|
+
* @public
|
|
57
|
+
* @memberof NetworkQualityMonitor
|
|
58
|
+
*/
|
|
59
|
+
determineUplinkNetworkQuality({ mediaType, remoteRtpResults, statsAnalyzerCurrentStats, }: {
|
|
60
|
+
mediaType: string;
|
|
61
|
+
remoteRtpResults: any;
|
|
62
|
+
statsAnalyzerCurrentStats: object;
|
|
63
|
+
}): void;
|
|
64
|
+
/**
|
|
65
|
+
* Get the current status of network quaility object - networkQualityStatus
|
|
66
|
+
* @returns {Object}
|
|
67
|
+
* @public
|
|
68
|
+
*/
|
|
69
|
+
get networkQualityStats(): any;
|
|
70
|
+
}
|
package/dist/webinar/index.js
CHANGED
|
@@ -62,7 +62,7 @@ var Webinar = _webexCore.WebexPlugin.extend({
|
|
|
62
62
|
updateCanManageWebcast: function updateCanManageWebcast(canManageWebcast) {
|
|
63
63
|
this.set('canManageWebcast', canManageWebcast);
|
|
64
64
|
},
|
|
65
|
-
version: "3.
|
|
65
|
+
version: "3.5.0"
|
|
66
66
|
});
|
|
67
67
|
var _default = exports.default = Webinar;
|
|
68
68
|
//# sourceMappingURL=index.js.map
|
package/package.json
CHANGED
|
@@ -43,13 +43,13 @@
|
|
|
43
43
|
"@webex/eslint-config-legacy": "0.0.0",
|
|
44
44
|
"@webex/jest-config-legacy": "0.0.0",
|
|
45
45
|
"@webex/legacy-tools": "0.0.0",
|
|
46
|
-
"@webex/plugin-meetings": "3.
|
|
47
|
-
"@webex/plugin-rooms": "3.
|
|
48
|
-
"@webex/test-helper-chai": "3.
|
|
49
|
-
"@webex/test-helper-mocha": "3.
|
|
50
|
-
"@webex/test-helper-mock-webex": "3.
|
|
51
|
-
"@webex/test-helper-retry": "3.
|
|
52
|
-
"@webex/test-helper-test-users": "3.
|
|
46
|
+
"@webex/plugin-meetings": "3.5.0",
|
|
47
|
+
"@webex/plugin-rooms": "3.5.0",
|
|
48
|
+
"@webex/test-helper-chai": "3.5.0",
|
|
49
|
+
"@webex/test-helper-mocha": "3.5.0",
|
|
50
|
+
"@webex/test-helper-mock-webex": "3.5.0",
|
|
51
|
+
"@webex/test-helper-retry": "3.5.0",
|
|
52
|
+
"@webex/test-helper-test-users": "3.5.0",
|
|
53
53
|
"chai": "^4.3.4",
|
|
54
54
|
"chai-as-promised": "^7.1.1",
|
|
55
55
|
"eslint": "^8.24.0",
|
|
@@ -61,21 +61,21 @@
|
|
|
61
61
|
"typescript": "^4.7.4"
|
|
62
62
|
},
|
|
63
63
|
"dependencies": {
|
|
64
|
-
"@webex/common": "3.
|
|
65
|
-
"@webex/internal-media-core": "2.
|
|
66
|
-
"@webex/internal-plugin-conversation": "3.
|
|
67
|
-
"@webex/internal-plugin-device": "3.
|
|
68
|
-
"@webex/internal-plugin-llm": "3.
|
|
69
|
-
"@webex/internal-plugin-mercury": "3.
|
|
70
|
-
"@webex/internal-plugin-metrics": "3.
|
|
71
|
-
"@webex/internal-plugin-support": "3.
|
|
72
|
-
"@webex/internal-plugin-user": "3.
|
|
73
|
-
"@webex/internal-plugin-voicea": "3.
|
|
74
|
-
"@webex/media-helpers": "3.
|
|
75
|
-
"@webex/plugin-people": "3.
|
|
76
|
-
"@webex/plugin-rooms": "3.
|
|
64
|
+
"@webex/common": "3.5.0",
|
|
65
|
+
"@webex/internal-media-core": "2.11.1",
|
|
66
|
+
"@webex/internal-plugin-conversation": "3.5.0",
|
|
67
|
+
"@webex/internal-plugin-device": "3.5.0",
|
|
68
|
+
"@webex/internal-plugin-llm": "3.5.0",
|
|
69
|
+
"@webex/internal-plugin-mercury": "3.5.0",
|
|
70
|
+
"@webex/internal-plugin-metrics": "3.5.0",
|
|
71
|
+
"@webex/internal-plugin-support": "3.5.0",
|
|
72
|
+
"@webex/internal-plugin-user": "3.5.0",
|
|
73
|
+
"@webex/internal-plugin-voicea": "3.5.0",
|
|
74
|
+
"@webex/media-helpers": "3.5.0",
|
|
75
|
+
"@webex/plugin-people": "3.5.0",
|
|
76
|
+
"@webex/plugin-rooms": "3.5.0",
|
|
77
77
|
"@webex/web-capabilities": "^1.4.0",
|
|
78
|
-
"@webex/webex-core": "3.
|
|
78
|
+
"@webex/webex-core": "3.5.0",
|
|
79
79
|
"ampersand-collection": "^2.0.2",
|
|
80
80
|
"bowser": "^2.11.0",
|
|
81
81
|
"btoa": "^1.2.1",
|
|
@@ -91,5 +91,5 @@
|
|
|
91
91
|
"//": [
|
|
92
92
|
"TODO: upgrade jwt-decode when moving to node 18"
|
|
93
93
|
],
|
|
94
|
-
"version": "3.
|
|
94
|
+
"version": "3.5.0"
|
|
95
95
|
}
|
package/src/meeting/index.ts
CHANGED
|
@@ -538,6 +538,7 @@ export default class Meeting extends StatelessWebexPlugin {
|
|
|
538
538
|
id: string;
|
|
539
539
|
isMultistream: boolean;
|
|
540
540
|
locusUrl: string;
|
|
541
|
+
#isoLocalClientMeetingJoinTime?: string;
|
|
541
542
|
mediaConnections: any[];
|
|
542
543
|
mediaId?: string;
|
|
543
544
|
meetingFiniteStateMachine: any;
|
|
@@ -1521,6 +1522,17 @@ export default class Meeting extends StatelessWebexPlugin {
|
|
|
1521
1522
|
* @memberof Meeting
|
|
1522
1523
|
*/
|
|
1523
1524
|
this.iceCandidatesCount = 0;
|
|
1525
|
+
|
|
1526
|
+
/**
|
|
1527
|
+
* Start time of meeting as an ISO string
|
|
1528
|
+
* based on browser time, so can only be used to compute durations client side
|
|
1529
|
+
* undefined if meeting has not been joined, set once on meeting join, and not updated again
|
|
1530
|
+
* @instance
|
|
1531
|
+
* @type {string}
|
|
1532
|
+
* @private
|
|
1533
|
+
* @memberof Meeting
|
|
1534
|
+
*/
|
|
1535
|
+
this.#isoLocalClientMeetingJoinTime = undefined;
|
|
1524
1536
|
}
|
|
1525
1537
|
|
|
1526
1538
|
/**
|
|
@@ -1569,6 +1581,15 @@ export default class Meeting extends StatelessWebexPlugin {
|
|
|
1569
1581
|
this.callStateForMetrics.correlationId = correlationId;
|
|
1570
1582
|
}
|
|
1571
1583
|
|
|
1584
|
+
/**
|
|
1585
|
+
* Getter - Returns isoLocalClientMeetingJoinTime
|
|
1586
|
+
* This will be set once on meeting join, and not updated again
|
|
1587
|
+
* @returns {string | undefined}
|
|
1588
|
+
*/
|
|
1589
|
+
get isoLocalClientMeetingJoinTime(): string | undefined {
|
|
1590
|
+
return this.#isoLocalClientMeetingJoinTime;
|
|
1591
|
+
}
|
|
1592
|
+
|
|
1572
1593
|
/**
|
|
1573
1594
|
* Set meeting info and trigger `MEETING_INFO_AVAILABLE` event
|
|
1574
1595
|
* @param {any} info
|
|
@@ -5232,6 +5253,11 @@ export default class Meeting extends StatelessWebexPlugin {
|
|
|
5232
5253
|
this.meetingFiniteStateMachine.join();
|
|
5233
5254
|
this.setupLocusMediaRequest();
|
|
5234
5255
|
|
|
5256
|
+
// @ts-ignore
|
|
5257
|
+
this.webex.internal.device.meetingStarted();
|
|
5258
|
+
|
|
5259
|
+
this.#isoLocalClientMeetingJoinTime = new Date().toISOString();
|
|
5260
|
+
|
|
5235
5261
|
LoggerProxy.logger.log('Meeting:index#join --> Success');
|
|
5236
5262
|
|
|
5237
5263
|
Metrics.sendBehavioralMetric(BEHAVIORAL_METRICS.JOIN_SUCCESS, {
|
|
@@ -6518,12 +6544,21 @@ export default class Meeting extends StatelessWebexPlugin {
|
|
|
6518
6544
|
*
|
|
6519
6545
|
* @private
|
|
6520
6546
|
* @static
|
|
6547
|
+
* @param {boolean} isAudioEnabled
|
|
6548
|
+
* @param {boolean} isVideoEnabled
|
|
6521
6549
|
* @returns {Promise<void>}
|
|
6522
6550
|
*/
|
|
6523
|
-
private static async handleDeviceLogging(): Promise<void> {
|
|
6524
|
-
try {
|
|
6525
|
-
const devices = await getDevices();
|
|
6526
6551
|
|
|
6552
|
+
private static async handleDeviceLogging(isAudioEnabled, isVideoEnabled): Promise<void> {
|
|
6553
|
+
try {
|
|
6554
|
+
let devices = [];
|
|
6555
|
+
if (isVideoEnabled && isAudioEnabled) {
|
|
6556
|
+
devices = await getDevices();
|
|
6557
|
+
} else if (isVideoEnabled) {
|
|
6558
|
+
devices = await getDevices(Media.DeviceKind.VIDEO_INPUT);
|
|
6559
|
+
} else if (isAudioEnabled) {
|
|
6560
|
+
devices = await getDevices(Media.DeviceKind.AUDIO_INPUT);
|
|
6561
|
+
}
|
|
6527
6562
|
MeetingUtil.handleDeviceLogging(devices);
|
|
6528
6563
|
} catch {
|
|
6529
6564
|
// getDevices may fail if we don't have browser permissions, that's ok, we still can have a media connection
|
|
@@ -7016,7 +7051,7 @@ export default class Meeting extends StatelessWebexPlugin {
|
|
|
7016
7051
|
);
|
|
7017
7052
|
|
|
7018
7053
|
if (audioEnabled || videoEnabled) {
|
|
7019
|
-
await Meeting.handleDeviceLogging();
|
|
7054
|
+
await Meeting.handleDeviceLogging(audioEnabled, videoEnabled);
|
|
7020
7055
|
} else {
|
|
7021
7056
|
LoggerProxy.logger.info(`${LOG_HEADER} device logging not required`);
|
|
7022
7057
|
}
|
package/src/meeting/util.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { config } from 'dotenv';
|
|
2
1
|
import 'jsdom-global/register';
|
|
2
|
+
import {config} from 'dotenv';
|
|
3
3
|
import {assert} from '@webex/test-helper-chai';
|
|
4
4
|
import {skipInNode} from '@webex/test-helper-mocha';
|
|
5
5
|
import BrowserDetection from '@webex/plugin-meetings/dist/common/browser-detection';
|
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
*/
|
|
4
4
|
|
|
5
5
|
/* eslint-disable camelcase */
|
|
6
|
+
import 'jsdom-global/register';
|
|
6
7
|
import {assert} from '@webex/test-helper-chai';
|
|
7
8
|
import { expect } from "@webex/test-helper-chai";
|
|
8
9
|
import MockWebex from '@webex/test-helper-mock-webex';
|
|
@@ -13,7 +14,7 @@ import sinon from 'sinon';
|
|
|
13
14
|
|
|
14
15
|
describe('plugin-meetings', () => {
|
|
15
16
|
describe('Interceptors', () => {
|
|
16
|
-
describe('LocusRetryStatusInterceptor', () => {
|
|
17
|
+
describe('LocusRetryStatusInterceptor', () => {
|
|
17
18
|
let interceptor, webex;
|
|
18
19
|
beforeEach(() => {
|
|
19
20
|
webex = new MockWebex({
|
|
@@ -24,7 +25,7 @@ describe('plugin-meetings', () => {
|
|
|
24
25
|
interceptor = Reflect.apply(LocusRetryStatusInterceptor.create, {
|
|
25
26
|
sessionId: 'mock-webex_uuid',
|
|
26
27
|
}, []);
|
|
27
|
-
});
|
|
28
|
+
});
|
|
28
29
|
describe('#onResponseError', () => {
|
|
29
30
|
const options = {
|
|
30
31
|
method: 'POST',
|
|
@@ -41,7 +42,7 @@ describe('plugin-meetings', () => {
|
|
|
41
42
|
headers: {
|
|
42
43
|
trackingid: 'test',
|
|
43
44
|
'retry-after': 1000,
|
|
44
|
-
},
|
|
45
|
+
},
|
|
45
46
|
uri: `https://locus-test.webex.com/locus/api/v1/loci/call`,
|
|
46
47
|
},
|
|
47
48
|
body: {
|
|
@@ -54,7 +55,7 @@ describe('plugin-meetings', () => {
|
|
|
54
55
|
headers: {
|
|
55
56
|
trackingid: 'test',
|
|
56
57
|
'retry-after': 1000,
|
|
57
|
-
},
|
|
58
|
+
},
|
|
58
59
|
uri: `https://locus-test.webex.com/locus/api/v1/loci/call`,
|
|
59
60
|
},
|
|
60
61
|
body: {
|
|
@@ -73,7 +74,7 @@ describe('plugin-meetings', () => {
|
|
|
73
74
|
|
|
74
75
|
return interceptor.onResponseError(options, reason2).then(() => {
|
|
75
76
|
expect(handleRetryStub.calledWith(options, 1000)).to.be.true;
|
|
76
|
-
|
|
77
|
+
|
|
77
78
|
});
|
|
78
79
|
});
|
|
79
80
|
});
|
|
@@ -92,7 +93,7 @@ describe('plugin-meetings', () => {
|
|
|
92
93
|
it('returns the correct resolved value when the request is successful', () => {
|
|
93
94
|
const mockResponse = 'mock response'
|
|
94
95
|
interceptor.webex.request = sinon.stub().returns(Promise.resolve(mockResponse));
|
|
95
|
-
|
|
96
|
+
|
|
96
97
|
return interceptor.handleRetryRequestLocusServiceError(options, retryAfterTime)
|
|
97
98
|
.then((response) => {
|
|
98
99
|
expect(response).to.equal(mockResponse);
|
|
@@ -101,9 +102,9 @@ describe('plugin-meetings', () => {
|
|
|
101
102
|
|
|
102
103
|
it('rejects the promise when the request is unsuccessful', () => {
|
|
103
104
|
const rejectionReason = 'Service Unavaialble after retry';
|
|
104
|
-
|
|
105
|
+
|
|
105
106
|
interceptor.webex.request = sinon.stub().returns(Promise.reject(rejectionReason));
|
|
106
|
-
|
|
107
|
+
|
|
107
108
|
return interceptor.handleRetryRequestLocusServiceError(options, retryAfterTime)
|
|
108
109
|
.catch((error) => {
|
|
109
110
|
expect(error).to.equal(rejectionReason);
|
|
@@ -114,10 +115,10 @@ describe('plugin-meetings', () => {
|
|
|
114
115
|
let clock;
|
|
115
116
|
clock = sinon.useFakeTimers();
|
|
116
117
|
const mockResponse = 'mock response'
|
|
117
|
-
|
|
118
|
+
|
|
118
119
|
interceptor.webex.request = sinon.stub().returns(Promise.resolve(mockResponse));
|
|
119
120
|
const promise = interceptor.handleRetryRequestLocusServiceError(options, retryAfterTime);
|
|
120
|
-
|
|
121
|
+
|
|
121
122
|
clock.tick(retryAfterTime);
|
|
122
123
|
|
|
123
124
|
return promise.then(() => {
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
+
import 'jsdom-global/register';
|
|
1
2
|
import {assert} from '@webex/test-helper-chai';
|
|
2
3
|
import sinon from 'sinon';
|
|
3
4
|
import {ConnectionState} from '@webex/internal-media-core';
|
|
4
5
|
import MediaProperties from '@webex/plugin-meetings/src/media/properties';
|
|
5
|
-
import testUtils from '../../../utils/testUtils';
|
|
6
6
|
import {Defer} from '@webex/common';
|
|
7
7
|
import MediaConnectionAwaiter from '../../../../src/media/MediaConnectionAwaiter';
|
|
8
8
|
|
|
@@ -331,6 +331,7 @@ describe('plugin-meetings', () => {
|
|
|
331
331
|
assert.isNull(meeting.partner);
|
|
332
332
|
assert.isNull(meeting.type);
|
|
333
333
|
assert.isNull(meeting.owner);
|
|
334
|
+
assert.isUndefined(meeting.isoLocalClientMeetingJoinTime);
|
|
334
335
|
assert.isNull(meeting.hostId);
|
|
335
336
|
assert.isNull(meeting.policy);
|
|
336
337
|
assert.instanceOf(meeting.meetingRequest, MeetingRequest);
|
|
@@ -1587,6 +1588,10 @@ describe('plugin-meetings', () => {
|
|
|
1587
1588
|
sandbox.stub(MeetingUtil, 'joinMeeting').returns(Promise.resolve(joinMeetingResult));
|
|
1588
1589
|
});
|
|
1589
1590
|
|
|
1591
|
+
afterEach(() => {
|
|
1592
|
+
assert.exists(meeting.isoLocalClientMeetingJoinTime);
|
|
1593
|
+
});
|
|
1594
|
+
|
|
1590
1595
|
it('should join the meeting and return promise', async () => {
|
|
1591
1596
|
const join = meeting.join({pstnAudioType: 'dial-in'});
|
|
1592
1597
|
meeting.config.enableAutomaticLLM = true;
|
|
@@ -1605,6 +1610,7 @@ describe('plugin-meetings', () => {
|
|
|
1605
1610
|
const result = await join;
|
|
1606
1611
|
|
|
1607
1612
|
assert.calledOnce(MeetingUtil.joinMeeting);
|
|
1613
|
+
assert.calledOnce(webex.internal.device.meetingStarted);
|
|
1608
1614
|
assert.calledOnce(meeting.setLocus);
|
|
1609
1615
|
assert.equal(result, joinMeetingResult);
|
|
1610
1616
|
assert.calledWith(webex.internal.llm.on, 'online', meeting.handleLLMOnline);
|
|
@@ -4278,6 +4284,20 @@ describe('plugin-meetings', () => {
|
|
|
4278
4284
|
assert.calledTwice(locusMediaRequestStub);
|
|
4279
4285
|
});
|
|
4280
4286
|
|
|
4287
|
+
it('addMedia() works correctly when media is disabled with no streams to publish', async () => {
|
|
4288
|
+
const handleDeviceLoggingSpy = sinon.spy(Meeting, 'handleDeviceLogging');
|
|
4289
|
+
await meeting.addMedia({audioEnabled: false});
|
|
4290
|
+
//calling handleDeviceLogging with audioEnaled as true adn videoEnabled as false
|
|
4291
|
+
assert.calledWith(handleDeviceLoggingSpy,false,true);
|
|
4292
|
+
});
|
|
4293
|
+
|
|
4294
|
+
it('addMedia() works correctly when video is disabled with no streams to publish', async () => {
|
|
4295
|
+
const handleDeviceLoggingSpy = sinon.spy(Meeting, 'handleDeviceLogging');
|
|
4296
|
+
await meeting.addMedia({videoEnabled: false});
|
|
4297
|
+
//calling handleDeviceLogging audioEnabled as true videoEnabled as false
|
|
4298
|
+
assert.calledWith(handleDeviceLoggingSpy,true,false);
|
|
4299
|
+
});
|
|
4300
|
+
|
|
4281
4301
|
it('addMedia() works correctly when video is disabled with no streams to publish', async () => {
|
|
4282
4302
|
await meeting.addMedia({videoEnabled: false});
|
|
4283
4303
|
await simulateRoapOffer();
|
|
@@ -4344,6 +4364,14 @@ describe('plugin-meetings', () => {
|
|
|
4344
4364
|
assert.calledTwice(locusMediaRequestStub);
|
|
4345
4365
|
});
|
|
4346
4366
|
|
|
4367
|
+
|
|
4368
|
+
it('addMedia() works correctly when both shareAudio and shareVideo is disabled with no streams publish', async () => {
|
|
4369
|
+
const handleDeviceLoggingSpy = sinon.spy(Meeting, 'handleDeviceLogging');
|
|
4370
|
+
await meeting.addMedia({shareAudioEnabled: false, shareVideoEnabled: false});
|
|
4371
|
+
//calling handleDeviceLogging with audioEnabled true and videoEnabled as true
|
|
4372
|
+
assert.calledWith(handleDeviceLoggingSpy,true,true);
|
|
4373
|
+
});
|
|
4374
|
+
|
|
4347
4375
|
describe('publishStreams()/unpublishStreams() calls', () => {
|
|
4348
4376
|
[
|
|
4349
4377
|
{mediaEnabled: true, expected: {direction: 'sendrecv', localMuteSentValue: false}},
|
|
@@ -1,6 +1,7 @@
|
|
|
1
|
+
import 'jsdom-global/register';
|
|
1
2
|
import sinon from 'sinon';
|
|
2
3
|
import {assert} from '@webex/test-helper-chai';
|
|
3
|
-
import { cloneDeep
|
|
4
|
+
import { cloneDeep } from 'lodash';
|
|
4
5
|
|
|
5
6
|
import MockWebex from '@webex/test-helper-mock-webex';
|
|
6
7
|
import Meetings from '@webex/plugin-meetings';
|
|
@@ -495,4 +496,4 @@ describe('LocusMediaRequest.send()', () => {
|
|
|
495
496
|
});
|
|
496
497
|
|
|
497
498
|
});
|
|
498
|
-
})
|
|
499
|
+
})
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import 'jsdom-global/register';
|
|
1
2
|
import sinon from 'sinon';
|
|
2
3
|
import {assert} from '@webex/test-helper-chai';
|
|
3
4
|
import Meetings from '@webex/plugin-meetings';
|
|
@@ -71,6 +72,7 @@ describe('plugin-meetings', () => {
|
|
|
71
72
|
assert.calledOnce(meeting.updateLLMConnection);
|
|
72
73
|
assert.calledOnce(meeting.breakouts.cleanUp);
|
|
73
74
|
assert.calledOnce(meeting.simultaneousInterpretation.cleanUp);
|
|
75
|
+
assert.calledOnce(webex.internal.device.meetingEnded);
|
|
74
76
|
});
|
|
75
77
|
|
|
76
78
|
it('do clean up on meeting object with LLM disabled', async () => {
|
|
@@ -87,6 +89,7 @@ describe('plugin-meetings', () => {
|
|
|
87
89
|
assert.notCalled(meeting.updateLLMConnection);
|
|
88
90
|
assert.calledOnce(meeting.breakouts.cleanUp);
|
|
89
91
|
assert.calledOnce(meeting.simultaneousInterpretation.cleanUp);
|
|
92
|
+
assert.calledOnce(webex.internal.device.meetingEnded);
|
|
90
93
|
});
|
|
91
94
|
|
|
92
95
|
it('do clean up on meeting object with no config', async () => {
|
|
@@ -102,6 +105,7 @@ describe('plugin-meetings', () => {
|
|
|
102
105
|
assert.notCalled(meeting.updateLLMConnection);
|
|
103
106
|
assert.calledOnce(meeting.breakouts.cleanUp);
|
|
104
107
|
assert.calledOnce(meeting.simultaneousInterpretation.cleanUp);
|
|
108
|
+
assert.calledOnce(webex.internal.device.meetingEnded);
|
|
105
109
|
});
|
|
106
110
|
});
|
|
107
111
|
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/*!
|
|
2
2
|
* Copyright (c) 2015-2020 Cisco Systems, Inc. See LICENSE file.
|
|
3
3
|
*/
|
|
4
|
-
|
|
4
|
+
import 'jsdom-global/register';
|
|
5
5
|
import {assert} from '@webex/test-helper-chai';
|
|
6
6
|
import sinon from 'sinon';
|
|
7
7
|
import MockWebex from '@webex/test-helper-mock-webex';
|
|
@@ -23,7 +23,6 @@ import MeetingInfoUtil from '@webex/plugin-meetings/src/meeting-info/utilv2';
|
|
|
23
23
|
import Metrics from '@webex/plugin-meetings/src/metrics';
|
|
24
24
|
import BEHAVIORAL_METRICS from '@webex/plugin-meetings/src/metrics/constants';
|
|
25
25
|
import {forEach} from 'lodash';
|
|
26
|
-
import { request } from 'express';
|
|
27
26
|
|
|
28
27
|
describe('plugin-meetings', () => {
|
|
29
28
|
const conversation = {
|
|
@@ -433,7 +432,7 @@ describe('plugin-meetings', () => {
|
|
|
433
432
|
assert.deepEqual(submitInternalEventCalls[1].args[0], {
|
|
434
433
|
name: 'internal.client.meetinginfo.response',
|
|
435
434
|
});
|
|
436
|
-
|
|
435
|
+
|
|
437
436
|
assert.deepEqual(submitClientEventCalls[1].args[0], {
|
|
438
437
|
name: 'client.meetinginfo.response',
|
|
439
438
|
payload: {
|
|
@@ -484,9 +483,9 @@ describe('plugin-meetings', () => {
|
|
|
484
483
|
requestResponse.body.confIdStr = confIdStr;
|
|
485
484
|
}
|
|
486
485
|
const extraParams = {mtid: 'm9fe0afd8c435e892afcce9ea25b97046', joinTXId: 'TSmrX61wNF'}
|
|
487
|
-
|
|
486
|
+
|
|
488
487
|
webex.request.resolves(requestResponse);
|
|
489
|
-
|
|
488
|
+
|
|
490
489
|
const result = await meetingInfo.fetchMeetingInfo(
|
|
491
490
|
'1234323',
|
|
492
491
|
DESTINATION_TYPE.MEETING_ID,
|
|
@@ -497,7 +496,7 @@ describe('plugin-meetings', () => {
|
|
|
497
496
|
extraParams,
|
|
498
497
|
{meetingId, sendCAevents}
|
|
499
498
|
);
|
|
500
|
-
|
|
499
|
+
|
|
501
500
|
assert.calledWith(webex.request, {
|
|
502
501
|
method: 'POST',
|
|
503
502
|
service: WBXAPPAPI_SERVICE,
|
|
@@ -515,7 +514,7 @@ describe('plugin-meetings', () => {
|
|
|
515
514
|
Metrics.sendBehavioralMetric,
|
|
516
515
|
BEHAVIORAL_METRICS.FETCH_MEETING_INFO_V1_SUCCESS
|
|
517
516
|
);
|
|
518
|
-
|
|
517
|
+
|
|
519
518
|
const submitInternalEventCalls = webex.internal.newMetrics.submitInternalEvent.getCalls();
|
|
520
519
|
const submitClientEventCalls = webex.internal.newMetrics.submitClientEvent.getCalls();
|
|
521
520
|
|
|
@@ -529,7 +528,7 @@ describe('plugin-meetings', () => {
|
|
|
529
528
|
meetingId,
|
|
530
529
|
}
|
|
531
530
|
});
|
|
532
|
-
|
|
531
|
+
|
|
533
532
|
assert.deepEqual(submitInternalEventCalls[1].args[0], {
|
|
534
533
|
name: 'internal.client.meetinginfo.response',
|
|
535
534
|
});
|
|
@@ -591,7 +590,7 @@ describe('plugin-meetings', () => {
|
|
|
591
590
|
|
|
592
591
|
const submitInternalEventCalls = webex.internal.newMetrics.submitInternalEvent.getCalls();
|
|
593
592
|
const submitClientEventCalls = webex.internal.newMetrics.submitClientEvent.getCalls();
|
|
594
|
-
|
|
593
|
+
|
|
595
594
|
assert.deepEqual(submitInternalEventCalls[0].args[0], {
|
|
596
595
|
name: 'internal.client.meetinginfo.request',
|
|
597
596
|
});
|
|
@@ -601,7 +600,7 @@ describe('plugin-meetings', () => {
|
|
|
601
600
|
meetingId: 'meetingId',
|
|
602
601
|
}
|
|
603
602
|
});
|
|
604
|
-
|
|
603
|
+
|
|
605
604
|
assert.deepEqual(submitInternalEventCalls[1].args[0], {
|
|
606
605
|
name: 'internal.client.meetinginfo.response',
|
|
607
606
|
});
|
|
@@ -629,7 +628,7 @@ describe('plugin-meetings', () => {
|
|
|
629
628
|
it(`should not send CA metric if meetingId is not provided disregarding if sendCAevents is ${sendCAevents}`, async () => {
|
|
630
629
|
const message = 'a message';
|
|
631
630
|
const meetingInfoData = 'meeting info';
|
|
632
|
-
|
|
631
|
+
|
|
633
632
|
webex.request = sinon.stub().rejects({
|
|
634
633
|
statusCode: 403,
|
|
635
634
|
body: {message, code: 403102, data: {meetingInfo: meetingInfoData}},
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import 'jsdom-global/register';
|
|
1
2
|
import sinon from 'sinon';
|
|
2
3
|
import chai from 'chai';
|
|
3
4
|
import uuid from 'uuid';
|
|
@@ -131,7 +132,7 @@ describe('plugin-meetings', () => {
|
|
|
131
132
|
locusUrl: url1,
|
|
132
133
|
memberIds: ['1', '2'],
|
|
133
134
|
};
|
|
134
|
-
|
|
135
|
+
|
|
135
136
|
await membersRequest.admitMember(options)
|
|
136
137
|
|
|
137
138
|
checkRequest({
|