@webex/plugin-meetings 3.0.0-stream-classes.3 → 3.0.0-stream-classes.5
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 +5 -1
- 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.js +25 -1
- package/dist/locus-info/index.js.map +1 -1
- package/dist/locus-info/parser.js +5 -0
- package/dist/locus-info/parser.js.map +1 -1
- package/dist/meeting/index.js +72 -15
- package/dist/meeting/index.js.map +1 -1
- package/dist/meeting/locusMediaRequest.js +1 -1
- package/dist/meeting/locusMediaRequest.js.map +1 -1
- package/dist/meeting/request.js +24 -14
- package/dist/meeting/request.js.map +1 -1
- package/dist/meeting/util.js +33 -3
- package/dist/meeting/util.js.map +1 -1
- package/dist/meetings/index.js +3 -4
- package/dist/meetings/index.js.map +1 -1
- package/dist/metrics/constants.js +4 -1
- package/dist/metrics/constants.js.map +1 -1
- package/dist/multistream/remoteMediaManager.js +46 -9
- package/dist/multistream/remoteMediaManager.js.map +1 -1
- package/dist/reachability/index.js +2 -11
- package/dist/reachability/index.js.map +1 -1
- package/dist/reachability/request.js.map +1 -1
- package/dist/reconnection-manager/index.js +26 -22
- package/dist/reconnection-manager/index.js.map +1 -1
- package/dist/roap/index.js +5 -7
- package/dist/roap/index.js.map +1 -1
- package/dist/roap/request.js +1 -0
- package/dist/roap/request.js.map +1 -1
- package/dist/roap/turnDiscovery.js +3 -4
- package/dist/roap/turnDiscovery.js.map +1 -1
- package/dist/types/constants.d.ts +1 -0
- package/dist/types/meeting/index.d.ts +16 -2
- package/dist/types/meeting/locusMediaRequest.d.ts +1 -2
- package/dist/types/meeting/request.d.ts +2 -1
- package/dist/types/meeting/util.d.ts +9 -1
- package/dist/types/metrics/constants.d.ts +3 -0
- package/dist/types/multistream/remoteMediaManager.d.ts +9 -1
- package/dist/types/reachability/index.d.ts +0 -6
- package/dist/types/reachability/request.d.ts +1 -1
- package/dist/types/roap/request.d.ts +2 -1
- package/package.json +1 -1
- package/src/constants.ts +3 -2
- package/src/locus-info/index.ts +33 -2
- package/src/locus-info/parser.ts +7 -0
- package/src/meeting/index.ts +59 -16
- package/src/meeting/locusMediaRequest.ts +2 -3
- package/src/meeting/request.ts +16 -6
- package/src/meeting/util.ts +36 -2
- package/src/meetings/index.ts +2 -2
- package/src/metrics/constants.ts +3 -0
- package/src/multistream/remoteMediaManager.ts +41 -4
- package/src/reachability/index.ts +4 -10
- package/src/reachability/request.ts +1 -1
- package/src/reconnection-manager/index.ts +13 -11
- package/src/roap/index.ts +2 -4
- package/src/roap/request.ts +2 -1
- package/src/roap/turnDiscovery.ts +2 -3
- package/test/integration/spec/converged-space-meetings.js +7 -7
- package/test/integration/spec/journey.js +85 -103
- package/test/integration/spec/space-meeting.js +9 -9
- package/test/unit/spec/locus-info/index.js +118 -1
- package/test/unit/spec/meeting/index.js +95 -30
- package/test/unit/spec/meeting/locusMediaRequest.ts +1 -2
- package/test/unit/spec/meeting/request.js +23 -0
- package/test/unit/spec/meeting/utils.js +73 -4
- package/test/unit/spec/meetings/index.js +68 -3
- package/test/unit/spec/multistream/remoteMediaManager.ts +10 -2
- package/test/unit/spec/reachability/index.ts +8 -8
- package/test/unit/spec/reconnection-manager/index.js +21 -0
- package/test/unit/spec/roap/index.ts +5 -1
- package/test/unit/spec/roap/turnDiscovery.ts +11 -4
- package/test/utils/integrationTestUtils.js +4 -4
|
@@ -20,6 +20,7 @@ import MeetingCollection from '@webex/plugin-meetings/src/meetings/collection';
|
|
|
20
20
|
import MeetingsUtil from '@webex/plugin-meetings/src/meetings/util';
|
|
21
21
|
import PersonalMeetingRoom from '@webex/plugin-meetings/src/personal-meeting-room';
|
|
22
22
|
import Reachability from '@webex/plugin-meetings/src/reachability';
|
|
23
|
+
import Metrics from '@webex/plugin-meetings/src/metrics';
|
|
23
24
|
|
|
24
25
|
import testUtils from '../../../utils/testUtils';
|
|
25
26
|
import {
|
|
@@ -46,6 +47,8 @@ describe('plugin-meetings', () => {
|
|
|
46
47
|
debug: () => {},
|
|
47
48
|
};
|
|
48
49
|
|
|
50
|
+
let triggerProxyStub;
|
|
51
|
+
|
|
49
52
|
beforeEach(() => {
|
|
50
53
|
StaticConfig.set({
|
|
51
54
|
bandwidth: {
|
|
@@ -57,7 +60,7 @@ describe('plugin-meetings', () => {
|
|
|
57
60
|
verboseEvents: true,
|
|
58
61
|
enable: false,
|
|
59
62
|
});
|
|
60
|
-
sinon.stub(TriggerProxy, 'trigger').returns(true);
|
|
63
|
+
triggerProxyStub = sinon.stub(TriggerProxy, 'trigger').returns(true);
|
|
61
64
|
});
|
|
62
65
|
|
|
63
66
|
let webex;
|
|
@@ -367,7 +370,7 @@ describe('plugin-meetings', () => {
|
|
|
367
370
|
|
|
368
371
|
assert.exists(result);
|
|
369
372
|
assert.instanceOf(result, VirtualBackgroundEffect);
|
|
370
|
-
assert.containsAllKeys(result, ['loadModel', 'isEnabled', '
|
|
373
|
+
assert.containsAllKeys(result, ['loadModel', 'isEnabled', 'options']);
|
|
371
374
|
assert.deepEqual(result.options, {
|
|
372
375
|
mode: 'BLUR',
|
|
373
376
|
blurStrength: 'STRONG',
|
|
@@ -396,7 +399,7 @@ describe('plugin-meetings', () => {
|
|
|
396
399
|
|
|
397
400
|
assert.exists(result);
|
|
398
401
|
assert.instanceOf(result, VirtualBackgroundEffect);
|
|
399
|
-
assert.containsAllKeys(result, ['loadModel', 'isEnabled', '
|
|
402
|
+
assert.containsAllKeys(result, ['loadModel', 'isEnabled', 'options']);
|
|
400
403
|
assert.deepEqual(result.options, {...effectOptions, authToken: "fake_token"});
|
|
401
404
|
assert.exists(result.enable);
|
|
402
405
|
assert.exists(result.disable);
|
|
@@ -2092,5 +2095,67 @@ describe('plugin-meetings', () => {
|
|
|
2092
2095
|
assert.calledWith(webex.meetings.handleLocusEvent, {locus: breakoutLocus, locusUrl: breakoutLocus.url});
|
|
2093
2096
|
});
|
|
2094
2097
|
});
|
|
2098
|
+
|
|
2099
|
+
describe('uploading of logs', () => {
|
|
2100
|
+
let metricsSpy;
|
|
2101
|
+
let meeting;
|
|
2102
|
+
|
|
2103
|
+
beforeEach(async () => {
|
|
2104
|
+
webex.meetings.config.autoUploadLogs = true;
|
|
2105
|
+
webex.meetings.loggerRequest.uploadLogs = sinon.stub().resolves();
|
|
2106
|
+
|
|
2107
|
+
sinon.stub(webex.meetings.meetingInfo, 'fetchInfoOptions').resolves({});
|
|
2108
|
+
sinon.stub(webex.meetings.meetingInfo, 'fetchMeetingInfo').resolves({});
|
|
2109
|
+
|
|
2110
|
+
triggerProxyStub.restore();
|
|
2111
|
+
|
|
2112
|
+
metricsSpy = sinon.stub(Metrics, 'sendBehavioralMetric');
|
|
2113
|
+
|
|
2114
|
+
meeting = await webex.meetings.create('test');
|
|
2115
|
+
|
|
2116
|
+
meeting.locusId = 'locus id';
|
|
2117
|
+
meeting.correlationId = 'correlation id';
|
|
2118
|
+
meeting.locusInfo = {
|
|
2119
|
+
fullState: { lastActive: 'last active'},
|
|
2120
|
+
info: { webExMeetingId: 'meeting id'}
|
|
2121
|
+
}
|
|
2122
|
+
});
|
|
2123
|
+
|
|
2124
|
+
afterEach(() => {
|
|
2125
|
+
sinon.restore();
|
|
2126
|
+
})
|
|
2127
|
+
|
|
2128
|
+
it('sends metrics on success', async () => {
|
|
2129
|
+
|
|
2130
|
+
await meeting.uploadLogs();
|
|
2131
|
+
|
|
2132
|
+
await testUtils.flushPromises();
|
|
2133
|
+
|
|
2134
|
+
assert.calledOnceWithExactly(metricsSpy, 'js_sdk_upload_logs_success', {
|
|
2135
|
+
callStart: 'last active',
|
|
2136
|
+
correlationId: 'correlation id',
|
|
2137
|
+
feedbackId: 'correlation id',
|
|
2138
|
+
locusId: 'locus id',
|
|
2139
|
+
meetingId: 'meeting id',
|
|
2140
|
+
});
|
|
2141
|
+
});
|
|
2142
|
+
|
|
2143
|
+
it('sends metrics on failure', async () => {
|
|
2144
|
+
webex.meetings.loggerRequest.uploadLogs.rejects(new Error('fake error'));
|
|
2145
|
+
|
|
2146
|
+
await meeting.uploadLogs();
|
|
2147
|
+
|
|
2148
|
+
await testUtils.flushPromises();
|
|
2149
|
+
|
|
2150
|
+
assert.calledOnceWithExactly(metricsSpy, 'js_sdk_upload_logs_failure', sinon.match({
|
|
2151
|
+
callStart: 'last active',
|
|
2152
|
+
correlationId: 'correlation id',
|
|
2153
|
+
feedbackId: 'correlation id',
|
|
2154
|
+
locusId: 'locus id',
|
|
2155
|
+
meetingId: 'meeting id',
|
|
2156
|
+
reason: 'fake error',
|
|
2157
|
+
}));
|
|
2158
|
+
});
|
|
2159
|
+
});
|
|
2095
2160
|
});
|
|
2096
2161
|
});
|
|
@@ -747,7 +747,11 @@ describe('RemoteMediaManager', () => {
|
|
|
747
747
|
|
|
748
748
|
assert.calledWith(
|
|
749
749
|
logger.log,
|
|
750
|
-
'RemoteMediaManager#
|
|
750
|
+
'RemoteMediaManager#setLayout --> new layout selected: Stage'
|
|
751
|
+
);
|
|
752
|
+
assert.calledWith(
|
|
753
|
+
logger.log,
|
|
754
|
+
'RemoteMediaManager#logMainVideoReceiveSlots --> MAIN VIDEO receive slots: unused=0, activeSpeaker=6, receiverSelected=4\ngroup: thumbnails\nfake video slot, fake video slot, fake video slot, fake video slot, fake video slot, fake video slot\nreceiverSelected:\n stage-1: fake video slot\n stage-2: fake video slot\n stage-3: fake video slot\n stage-4: fake video slot\n'
|
|
751
755
|
);
|
|
752
756
|
});
|
|
753
757
|
|
|
@@ -769,7 +773,11 @@ describe('RemoteMediaManager', () => {
|
|
|
769
773
|
|
|
770
774
|
assert.calledWith(
|
|
771
775
|
logger.log,
|
|
772
|
-
'RemoteMediaManager#
|
|
776
|
+
'RemoteMediaManager#setLayout --> new layout selected: AllEqual'
|
|
777
|
+
);
|
|
778
|
+
assert.calledWith(
|
|
779
|
+
logger.log,
|
|
780
|
+
'RemoteMediaManager#logMainVideoReceiveSlots --> MAIN VIDEO receive slots: unused=0, activeSpeaker=9, receiverSelected=0\ngroup: main\nfake video slot, fake video slot, fake video slot, fake video slot, fake video slot, fake video slot, fake video slot, fake video slot, fake video slot\nreceiverSelected:\n'
|
|
773
781
|
);
|
|
774
782
|
});
|
|
775
783
|
|
|
@@ -2,6 +2,8 @@ import {assert} from '@webex/test-helper-chai';
|
|
|
2
2
|
import MockWebex from '@webex/test-helper-mock-webex';
|
|
3
3
|
import sinon from 'sinon';
|
|
4
4
|
import Reachability, {ICECandidateResult} from '@webex/plugin-meetings/src/reachability/';
|
|
5
|
+
import MeetingUtil from '@webex/plugin-meetings/src/meeting/util';
|
|
6
|
+
|
|
5
7
|
import { IP_VERSION } from '@webex/plugin-meetings/src/constants';
|
|
6
8
|
|
|
7
9
|
describe('isAnyClusterReachable', () => {
|
|
@@ -9,6 +11,12 @@ describe('isAnyClusterReachable', () => {
|
|
|
9
11
|
|
|
10
12
|
beforeEach(() => {
|
|
11
13
|
webex = new MockWebex();
|
|
14
|
+
|
|
15
|
+
sinon.stub(MeetingUtil, 'getIpVersion').returns(IP_VERSION.unknown);
|
|
16
|
+
});
|
|
17
|
+
|
|
18
|
+
afterEach(() => {
|
|
19
|
+
sinon.restore();
|
|
12
20
|
});
|
|
13
21
|
|
|
14
22
|
const checkIsClusterReachable = async (mockStorage: any, expectedValue: boolean) => {
|
|
@@ -251,12 +259,4 @@ describe('gatherReachability', () => {
|
|
|
251
259
|
});
|
|
252
260
|
});
|
|
253
261
|
});
|
|
254
|
-
|
|
255
|
-
describe('getIpVersion', () => {
|
|
256
|
-
it('returns unknown', () => {
|
|
257
|
-
const reachability = new Reachability(webex);
|
|
258
|
-
|
|
259
|
-
assert.equal(reachability.getIpVersion(), IP_VERSION.unknown);
|
|
260
|
-
})
|
|
261
|
-
})
|
|
262
262
|
});
|
|
@@ -58,6 +58,9 @@ describe('plugin-meetings', () => {
|
|
|
58
58
|
updateMediaConnection: sinon.stub(),
|
|
59
59
|
},
|
|
60
60
|
webex: {
|
|
61
|
+
credentials: {
|
|
62
|
+
isUnverifiedGuest: false,
|
|
63
|
+
},
|
|
61
64
|
meetings: {
|
|
62
65
|
getMeetingByType: sinon.stub().returns(true),
|
|
63
66
|
syncMeetings: sinon.stub().resolves({}),
|
|
@@ -71,6 +74,24 @@ describe('plugin-meetings', () => {
|
|
|
71
74
|
};
|
|
72
75
|
});
|
|
73
76
|
|
|
77
|
+
it('syncs meetings if it is not an unverified guest', async () => {
|
|
78
|
+
const rm = new ReconnectionManager(fakeMeeting);
|
|
79
|
+
|
|
80
|
+
await rm.reconnect();
|
|
81
|
+
|
|
82
|
+
assert.calledOnce(rm.webex.meetings.syncMeetings);
|
|
83
|
+
});
|
|
84
|
+
|
|
85
|
+
it('does not sync meetings if it is an unverified guest', async () => {
|
|
86
|
+
const rm = new ReconnectionManager(fakeMeeting);
|
|
87
|
+
|
|
88
|
+
rm.webex.credentials.isUnverifiedGuest = true;
|
|
89
|
+
|
|
90
|
+
await rm.reconnect();
|
|
91
|
+
|
|
92
|
+
assert.notCalled(rm.webex.meetings.syncMeetings);
|
|
93
|
+
});
|
|
94
|
+
|
|
74
95
|
it('uses correct TURN TLS information on the reconnection', async () => {
|
|
75
96
|
const rm = new ReconnectionManager(fakeMeeting);
|
|
76
97
|
|
|
@@ -6,6 +6,8 @@ import MockWebex from '@webex/test-helper-mock-webex';
|
|
|
6
6
|
import RoapRequest from '@webex/plugin-meetings/src/roap/request';
|
|
7
7
|
import Roap from '@webex/plugin-meetings/src/roap/';
|
|
8
8
|
import Meeting from '@webex/plugin-meetings/src/meeting';
|
|
9
|
+
import MeetingUtil from '@webex/plugin-meetings/src/meeting/util';
|
|
10
|
+
|
|
9
11
|
import { IP_VERSION } from '../../../../src/constants';
|
|
10
12
|
|
|
11
13
|
describe('Roap', () => {
|
|
@@ -62,9 +64,11 @@ describe('Roap', () => {
|
|
|
62
64
|
setRoapSeq: sinon.stub(),
|
|
63
65
|
config: {experimental: {enableTurnDiscovery: false}},
|
|
64
66
|
locusMediaRequest: {fake: true},
|
|
65
|
-
webex: { meetings: { reachability: { isAnyClusterReachable: () => true
|
|
67
|
+
webex: { meetings: { reachability: { isAnyClusterReachable: () => true}}},
|
|
66
68
|
};
|
|
67
69
|
|
|
70
|
+
sinon.stub(MeetingUtil, 'getIpVersion').returns(IP_VERSION.unknown);
|
|
71
|
+
|
|
68
72
|
sendRoapStub = sinon.stub(RoapRequest.prototype, 'sendRoap').resolves({});
|
|
69
73
|
meeting.setRoapSeq.resetHistory();
|
|
70
74
|
});
|
|
@@ -5,6 +5,7 @@ import TurnDiscovery from '@webex/plugin-meetings/src/roap/turnDiscovery';
|
|
|
5
5
|
import Metrics from '@webex/plugin-meetings/src/metrics';
|
|
6
6
|
import BEHAVIORAL_METRICS from '@webex/plugin-meetings/src/metrics/constants';
|
|
7
7
|
import RoapRequest from '@webex/plugin-meetings/src/roap/request';
|
|
8
|
+
import MeetingUtil from '@webex/plugin-meetings/src/meeting/util';
|
|
8
9
|
|
|
9
10
|
import testUtils from '../../../utils/testUtils';
|
|
10
11
|
import { IP_VERSION } from '../../../../src/constants';
|
|
@@ -24,6 +25,7 @@ describe('TurnDiscovery', () => {
|
|
|
24
25
|
clock = sinon.useFakeTimers();
|
|
25
26
|
|
|
26
27
|
sinon.stub(Metrics, 'sendBehavioralMetric');
|
|
28
|
+
sinon.stub(MeetingUtil, 'getIpVersion').returns(IP_VERSION.unknown);
|
|
27
29
|
|
|
28
30
|
mockRoapRequest = {
|
|
29
31
|
sendRoap: sinon.fake.resolves({mediaConnections: FAKE_MEDIA_CONNECTIONS_FROM_LOCUS}),
|
|
@@ -53,7 +55,6 @@ describe('TurnDiscovery', () => {
|
|
|
53
55
|
updateMediaConnections: sinon.stub(),
|
|
54
56
|
webex: {meetings: {reachability: {
|
|
55
57
|
isAnyClusterReachable: () => Promise.resolve(false),
|
|
56
|
-
getIpVersion: () => IP_VERSION.unknown,
|
|
57
58
|
}}},
|
|
58
59
|
isMultistream: false,
|
|
59
60
|
locusMediaRequest: { fake: true },
|
|
@@ -73,7 +74,8 @@ describe('TurnDiscovery', () => {
|
|
|
73
74
|
await testUtils.flushPromises();
|
|
74
75
|
|
|
75
76
|
assert.calledOnce(mockRoapRequest.sendRoap);
|
|
76
|
-
|
|
77
|
+
|
|
78
|
+
const expectedSendRoapArgs: any = {
|
|
77
79
|
roapMessage: {
|
|
78
80
|
messageType,
|
|
79
81
|
version: '2',
|
|
@@ -83,8 +85,13 @@ describe('TurnDiscovery', () => {
|
|
|
83
85
|
mediaId: expectedMediaId,
|
|
84
86
|
meetingId: testMeeting.id,
|
|
85
87
|
locusMediaRequest: testMeeting.locusMediaRequest,
|
|
86
|
-
|
|
87
|
-
|
|
88
|
+
};
|
|
89
|
+
|
|
90
|
+
if (messageType === 'TURN_DISCOVERY_REQUEST') {
|
|
91
|
+
expectedSendRoapArgs.ipVersion = 0;
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
assert.calledWith(mockRoapRequest.sendRoap, expectedSendRoapArgs);
|
|
88
95
|
|
|
89
96
|
if (messageType === 'TURN_DISCOVERY_REQUEST') {
|
|
90
97
|
// check also that we've applied the media connections from the response
|
|
@@ -6,7 +6,7 @@ const addMedia = async (user, options = {}) => {
|
|
|
6
6
|
const {microphone, camera} = options;
|
|
7
7
|
|
|
8
8
|
if (options.multistream) {
|
|
9
|
-
await user.meeting.addMedia({
|
|
9
|
+
await user.meeting.addMedia({localStreams: {microphone, camera}});
|
|
10
10
|
} else {
|
|
11
11
|
const mediaReadyPromises = Array.isArray(options.expectedMediaReadyTypes)
|
|
12
12
|
? options.expectedMediaReadyTypes.reduce((output, expectedMediaReadyType) => {
|
|
@@ -31,13 +31,13 @@ const addMedia = async (user, options = {}) => {
|
|
|
31
31
|
|
|
32
32
|
user.meeting.on('media:ready', mediaReady);
|
|
33
33
|
|
|
34
|
-
await user.meeting.addMedia({
|
|
34
|
+
await user.meeting.addMedia({localStreams: {microphone, camera}});
|
|
35
35
|
await Promise.all(Object.values(mediaReadyPromises).map((defer) => defer.promise));
|
|
36
36
|
};
|
|
37
37
|
|
|
38
38
|
|
|
39
|
-
assert.exists(user.meeting.mediaProperties.
|
|
40
|
-
assert.exists(user.meeting.mediaProperties.
|
|
39
|
+
assert.exists(user.meeting.mediaProperties.audioStream, 'audioStream not present');
|
|
40
|
+
assert.exists(user.meeting.mediaProperties.videoStream, 'videoStream not present');
|
|
41
41
|
|
|
42
42
|
};
|
|
43
43
|
|