@webex/plugin-meetings 3.0.0-stream-classes.4 → 3.0.0-test.1
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/common/errors/no-meeting-info.js +51 -0
- package/dist/common/errors/no-meeting-info.js.map +1 -0
- package/dist/common/errors/reclaim-host-role-errors.js +158 -0
- package/dist/common/errors/reclaim-host-role-errors.js.map +1 -0
- package/dist/common/errors/webex-errors.js +23 -3
- package/dist/common/errors/webex-errors.js.map +1 -1
- package/dist/common/logs/request.js +5 -1
- package/dist/common/logs/request.js.map +1 -1
- package/dist/config.js +1 -1
- package/dist/config.js.map +1 -1
- package/dist/constants.js +69 -9
- package/dist/constants.js.map +1 -1
- package/dist/index.js +11 -1
- package/dist/index.js.map +1 -1
- package/dist/interceptors/index.js +15 -0
- package/dist/interceptors/index.js.map +1 -0
- package/dist/interceptors/locusRetry.js +93 -0
- package/dist/interceptors/locusRetry.js.map +1 -0
- package/dist/interpretation/index.js +16 -2
- package/dist/interpretation/index.js.map +1 -1
- package/dist/interpretation/siLanguage.js +1 -1
- package/dist/locus-info/index.js +40 -11
- package/dist/locus-info/index.js.map +1 -1
- package/dist/locus-info/mediaSharesUtils.js +15 -1
- package/dist/locus-info/mediaSharesUtils.js.map +1 -1
- package/dist/locus-info/parser.js +42 -21
- package/dist/locus-info/parser.js.map +1 -1
- package/dist/media/index.js +10 -6
- package/dist/media/index.js.map +1 -1
- package/dist/media/properties.js +13 -3
- package/dist/media/properties.js.map +1 -1
- package/dist/mediaQualityMetrics/config.js +135 -330
- package/dist/mediaQualityMetrics/config.js.map +1 -1
- package/dist/meeting/in-meeting-actions.js +4 -0
- package/dist/meeting/in-meeting-actions.js.map +1 -1
- package/dist/meeting/index.js +2187 -1074
- package/dist/meeting/index.js.map +1 -1
- package/dist/meeting/muteState.js +37 -25
- package/dist/meeting/muteState.js.map +1 -1
- package/dist/meeting/request.js +34 -19
- package/dist/meeting/request.js.map +1 -1
- package/dist/meeting/util.js +71 -0
- package/dist/meeting/util.js.map +1 -1
- package/dist/meeting-info/index.js +48 -23
- package/dist/meeting-info/index.js.map +1 -1
- package/dist/meeting-info/meeting-info-v2.js +25 -4
- package/dist/meeting-info/meeting-info-v2.js.map +1 -1
- package/dist/meeting-info/utilv2.js +1 -1
- package/dist/meeting-info/utilv2.js.map +1 -1
- package/dist/meetings/collection.js +17 -0
- package/dist/meetings/collection.js.map +1 -1
- package/dist/meetings/index.js +142 -57
- package/dist/meetings/index.js.map +1 -1
- package/dist/meetings/util.js +2 -6
- package/dist/meetings/util.js.map +1 -1
- package/dist/member/index.js +9 -0
- package/dist/member/index.js.map +1 -1
- package/dist/member/util.js +11 -0
- package/dist/member/util.js.map +1 -1
- package/dist/members/index.js +17 -1
- package/dist/members/index.js.map +1 -1
- package/dist/members/types.js.map +1 -1
- package/dist/members/util.js +15 -4
- package/dist/members/util.js.map +1 -1
- package/dist/metrics/constants.js +15 -1
- package/dist/metrics/constants.js.map +1 -1
- package/dist/multistream/mediaRequestManager.js +1 -1
- package/dist/multistream/mediaRequestManager.js.map +1 -1
- package/dist/multistream/remoteMediaGroup.js +16 -2
- package/dist/multistream/remoteMediaGroup.js.map +1 -1
- package/dist/multistream/remoteMediaManager.js +222 -73
- package/dist/multistream/remoteMediaManager.js.map +1 -1
- package/dist/multistream/sendSlotManager.js +22 -0
- package/dist/multistream/sendSlotManager.js.map +1 -1
- package/dist/reachability/clusterReachability.js +356 -0
- package/dist/reachability/clusterReachability.js.map +1 -0
- package/dist/reachability/index.js +262 -432
- package/dist/reachability/index.js.map +1 -1
- package/dist/reachability/request.js +1 -1
- package/dist/reachability/request.js.map +1 -1
- package/dist/reachability/util.js +29 -0
- package/dist/reachability/util.js.map +1 -0
- package/dist/reconnection-manager/index.js +113 -96
- package/dist/reconnection-manager/index.js.map +1 -1
- package/dist/roap/index.js +57 -25
- package/dist/roap/index.js.map +1 -1
- package/dist/roap/request.js +5 -13
- package/dist/roap/request.js.map +1 -1
- package/dist/roap/turnDiscovery.js +173 -81
- package/dist/roap/turnDiscovery.js.map +1 -1
- package/dist/rtcMetrics/index.js +68 -6
- package/dist/rtcMetrics/index.js.map +1 -1
- package/dist/statsAnalyzer/index.js +338 -289
- package/dist/statsAnalyzer/index.js.map +1 -1
- package/dist/statsAnalyzer/mqaUtil.js +296 -156
- package/dist/statsAnalyzer/mqaUtil.js.map +1 -1
- package/dist/types/common/errors/no-meeting-info.d.ts +14 -0
- package/dist/types/common/errors/reclaim-host-role-errors.d.ts +60 -0
- package/dist/types/common/errors/webex-errors.d.ts +13 -1
- package/dist/types/common/logs/request.d.ts +2 -0
- package/dist/types/config.d.ts +1 -1
- package/dist/types/constants.d.ts +66 -13
- package/dist/types/index.d.ts +1 -1
- package/dist/types/interceptors/index.d.ts +2 -0
- package/dist/types/interceptors/locusRetry.d.ts +27 -0
- package/dist/types/locus-info/index.d.ts +1 -1
- package/dist/types/locus-info/parser.d.ts +3 -2
- package/dist/types/mediaQualityMetrics/config.d.ts +99 -223
- package/dist/types/meeting/in-meeting-actions.d.ts +4 -0
- package/dist/types/meeting/index.d.ts +285 -34
- package/dist/types/meeting/locusMediaRequest.d.ts +1 -2
- package/dist/types/meeting/muteState.d.ts +2 -8
- package/dist/types/meeting/request.d.ts +4 -1
- package/dist/types/meeting/util.d.ts +25 -1
- package/dist/types/meeting-info/index.d.ts +7 -0
- package/dist/types/meeting-info/meeting-info-v2.d.ts +1 -0
- package/dist/types/meetings/collection.d.ts +9 -0
- package/dist/types/meetings/index.d.ts +42 -14
- package/dist/types/member/index.d.ts +1 -0
- package/dist/types/members/types.d.ts +1 -0
- package/dist/types/members/util.d.ts +5 -0
- package/dist/types/metrics/constants.d.ts +15 -0
- package/dist/types/multistream/mediaRequestManager.d.ts +2 -0
- package/dist/types/multistream/remoteMediaGroup.d.ts +2 -0
- package/dist/types/multistream/remoteMediaManager.d.ts +25 -1
- package/dist/types/multistream/sendSlotManager.d.ts +9 -0
- package/dist/types/reachability/clusterReachability.d.ts +109 -0
- package/dist/types/reachability/index.d.ts +59 -112
- package/dist/types/reachability/request.d.ts +1 -1
- package/dist/types/reachability/util.d.ts +8 -0
- package/dist/types/reconnection-manager/index.d.ts +10 -0
- package/dist/types/roap/index.d.ts +2 -1
- package/dist/types/roap/request.d.ts +2 -1
- package/dist/types/roap/turnDiscovery.d.ts +21 -4
- package/dist/types/rtcMetrics/index.d.ts +15 -1
- package/dist/types/statsAnalyzer/index.d.ts +28 -11
- package/dist/types/statsAnalyzer/mqaUtil.d.ts +28 -4
- package/dist/types/webinar/collection.d.ts +16 -0
- package/dist/types/webinar/index.d.ts +5 -0
- package/dist/webinar/collection.js +44 -0
- package/dist/webinar/collection.js.map +1 -0
- package/dist/webinar/index.js +69 -0
- package/dist/webinar/index.js.map +1 -0
- package/package.json +3 -2
- package/src/common/errors/no-meeting-info.ts +24 -0
- package/src/common/errors/reclaim-host-role-errors.ts +134 -0
- package/src/common/errors/webex-errors.ts +19 -2
- package/src/common/logs/request.ts +5 -1
- package/src/config.ts +1 -1
- package/src/constants.ts +71 -6
- package/src/index.ts +5 -0
- package/src/interceptors/index.ts +3 -0
- package/src/interceptors/locusRetry.ts +67 -0
- package/src/interpretation/index.ts +18 -1
- package/src/locus-info/index.ts +52 -16
- package/src/locus-info/mediaSharesUtils.ts +16 -0
- package/src/locus-info/parser.ts +47 -21
- package/src/media/index.ts +8 -6
- package/src/media/properties.ts +17 -2
- package/src/mediaQualityMetrics/config.ts +103 -238
- package/src/meeting/in-meeting-actions.ts +8 -0
- package/src/meeting/index.ts +1510 -529
- package/src/meeting/muteState.ts +34 -20
- package/src/meeting/request.ts +19 -1
- package/src/meeting/util.ts +97 -0
- package/src/meeting-info/index.ts +47 -20
- package/src/meeting-info/meeting-info-v2.ts +27 -5
- package/src/meeting-info/utilv2.ts +1 -1
- package/src/meetings/collection.ts +13 -0
- package/src/meetings/index.ts +112 -31
- package/src/meetings/util.ts +2 -8
- package/src/member/index.ts +9 -0
- package/src/member/util.ts +14 -0
- package/src/members/index.ts +29 -2
- package/src/members/types.ts +1 -0
- package/src/members/util.ts +15 -1
- package/src/metrics/constants.ts +14 -0
- package/src/multistream/mediaRequestManager.ts +4 -1
- package/src/multistream/remoteMediaGroup.ts +19 -0
- package/src/multistream/remoteMediaManager.ts +141 -18
- package/src/multistream/sendSlotManager.ts +29 -0
- package/src/reachability/clusterReachability.ts +320 -0
- package/src/reachability/index.ts +221 -382
- package/src/reachability/request.ts +1 -1
- package/src/reachability/util.ts +24 -0
- package/src/reconnection-manager/index.ts +87 -83
- package/src/roap/index.ts +60 -24
- package/src/roap/request.ts +3 -16
- package/src/roap/turnDiscovery.ts +112 -39
- package/src/rtcMetrics/index.ts +71 -5
- package/src/statsAnalyzer/index.ts +430 -427
- package/src/statsAnalyzer/mqaUtil.ts +317 -168
- package/src/webinar/collection.ts +31 -0
- package/src/webinar/index.ts +62 -0
- package/test/integration/spec/converged-space-meetings.js +7 -7
- package/test/integration/spec/journey.js +86 -104
- package/test/integration/spec/space-meeting.js +9 -9
- package/test/unit/spec/interceptors/locusRetry.ts +131 -0
- package/test/unit/spec/interpretation/index.ts +36 -3
- package/test/unit/spec/locus-info/index.js +205 -12
- package/test/unit/spec/locus-info/lib/SeqCmp.json +16 -0
- package/test/unit/spec/locus-info/mediaSharesUtils.ts +10 -0
- package/test/unit/spec/locus-info/parser.js +54 -13
- package/test/unit/spec/media/index.ts +20 -4
- package/test/unit/spec/media/properties.ts +2 -2
- package/test/unit/spec/meeting/in-meeting-actions.ts +4 -0
- package/test/unit/spec/meeting/index.js +4027 -1075
- package/test/unit/spec/meeting/muteState.js +219 -67
- package/test/unit/spec/meeting/request.js +63 -12
- package/test/unit/spec/meeting/utils.js +93 -0
- package/test/unit/spec/meeting-info/index.js +180 -61
- package/test/unit/spec/meeting-info/meetinginfov2.js +196 -53
- package/test/unit/spec/meetings/collection.js +12 -0
- package/test/unit/spec/meetings/index.js +619 -206
- package/test/unit/spec/meetings/utils.js +35 -12
- package/test/unit/spec/member/index.js +8 -7
- package/test/unit/spec/member/util.js +32 -0
- package/test/unit/spec/members/index.js +130 -17
- package/test/unit/spec/members/utils.js +26 -0
- package/test/unit/spec/multistream/mediaRequestManager.ts +20 -2
- package/test/unit/spec/multistream/remoteMediaGroup.ts +80 -1
- package/test/unit/spec/multistream/remoteMediaManager.ts +210 -3
- package/test/unit/spec/multistream/sendSlotManager.ts +50 -18
- package/test/unit/spec/reachability/clusterReachability.ts +279 -0
- package/test/unit/spec/reachability/index.ts +505 -135
- package/test/unit/spec/reachability/util.ts +40 -0
- package/test/unit/spec/reconnection-manager/index.js +74 -17
- package/test/unit/spec/roap/index.ts +181 -61
- package/test/unit/spec/roap/request.ts +27 -3
- package/test/unit/spec/roap/turnDiscovery.ts +362 -101
- package/test/unit/spec/rtcMetrics/index.ts +57 -3
- package/test/unit/spec/stats-analyzer/index.js +1225 -12
- package/test/unit/spec/webinar/collection.ts +13 -0
- package/test/unit/spec/webinar/index.ts +60 -0
- package/test/utils/integrationTestUtils.js +4 -4
- package/test/utils/webex-test-users.js +12 -4
|
@@ -162,9 +162,24 @@ describe('plugin-meetings', () => {
|
|
|
162
162
|
});
|
|
163
163
|
|
|
164
164
|
describe("#handleRoapMercury", () => {
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
165
|
+
let envelope;
|
|
166
|
+
let meetingCollection;
|
|
167
|
+
let roapMessageReceived;
|
|
168
|
+
let handleTurnDiscoveryResponse;
|
|
169
|
+
let meeting;
|
|
170
|
+
|
|
171
|
+
beforeEach(() => {
|
|
172
|
+
roapMessageReceived = sinon.stub();
|
|
173
|
+
handleTurnDiscoveryResponse = sinon.stub();
|
|
174
|
+
|
|
175
|
+
meeting = {
|
|
176
|
+
id: 'meeting-id',
|
|
177
|
+
roapMessageReceived,
|
|
178
|
+
roap: {
|
|
179
|
+
turnDiscovery: {handleTurnDiscoveryResponse}
|
|
180
|
+
}
|
|
181
|
+
};
|
|
182
|
+
envelope = {
|
|
168
183
|
data: {
|
|
169
184
|
message:{
|
|
170
185
|
seq: "seq",
|
|
@@ -178,17 +193,12 @@ describe('plugin-meetings', () => {
|
|
|
178
193
|
eventType: 'locus.message.roap',
|
|
179
194
|
}
|
|
180
195
|
};
|
|
181
|
-
|
|
182
|
-
getByKey: () =>
|
|
183
|
-
id: 'meeting-id',
|
|
184
|
-
mediaProperties: {
|
|
185
|
-
webrtcMediaConnection: {
|
|
186
|
-
roapMessageReceived
|
|
187
|
-
}
|
|
188
|
-
}
|
|
189
|
-
})
|
|
196
|
+
meetingCollection = {
|
|
197
|
+
getByKey: () => meeting
|
|
190
198
|
};
|
|
199
|
+
});
|
|
191
200
|
|
|
201
|
+
it('it sends the correct behaviour metric', () => {
|
|
192
202
|
MeetingsUtil.handleRoapMercury(envelope, meetingCollection);
|
|
193
203
|
assert.calledWith(Metrics.sendBehavioralMetric, BEHAVIORAL_METRICS.ROAP_MERCURY_EVENT_RECEIVED, {
|
|
194
204
|
correlation_id: 'correlationId',
|
|
@@ -207,6 +217,19 @@ describe('plugin-meetings', () => {
|
|
|
207
217
|
})
|
|
208
218
|
|
|
209
219
|
});
|
|
220
|
+
|
|
221
|
+
it('calls handleTurnDiscoveryResponse for TURN_DISCOVERY_RESPONSE', () => {
|
|
222
|
+
envelope.data.message.messageType = 'TURN_DISCOVERY_RESPONSE';
|
|
223
|
+
delete envelope.data.message.sdps;
|
|
224
|
+
MeetingsUtil.handleRoapMercury(envelope, meetingCollection);
|
|
225
|
+
assert.calledWith(meeting.roap.turnDiscovery.handleTurnDiscoveryResponse, {
|
|
226
|
+
seq: "seq",
|
|
227
|
+
messageType: 'TURN_DISCOVERY_RESPONSE',
|
|
228
|
+
errorType: 'errorType',
|
|
229
|
+
tieBreaker: 'tieBreaker',
|
|
230
|
+
errorCause: 'errorCause',
|
|
231
|
+
}, 'from mercury')
|
|
232
|
+
});
|
|
210
233
|
})
|
|
211
234
|
});
|
|
212
235
|
|
|
@@ -17,13 +17,7 @@ describe('member', () => {
|
|
|
17
17
|
assert.exists(member.supportsInterpretation);
|
|
18
18
|
assert.exists(member.supportsBreakouts);
|
|
19
19
|
assert.exists(member.supportLiveAnnotation);
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
it('checks that processParticipant calls isHandRaised', () => {
|
|
23
|
-
sinon.spy(MemberUtil, 'isHandRaised');
|
|
24
|
-
member.processParticipant(participant);
|
|
25
|
-
|
|
26
|
-
assert.calledOnceWithExactly(MemberUtil.isHandRaised, participant);
|
|
20
|
+
assert.exists(member.canReclaimHost);
|
|
27
21
|
});
|
|
28
22
|
|
|
29
23
|
describe('roles', () => {
|
|
@@ -49,6 +43,13 @@ describe('member', () => {
|
|
|
49
43
|
|
|
50
44
|
assert.calledOnceWithExactly(MemberUtil.isHandRaised, participant);
|
|
51
45
|
});
|
|
46
|
+
|
|
47
|
+
it('checks that processParticipant calls canReclaimHost', () => {
|
|
48
|
+
sinon.spy(MemberUtil, 'canReclaimHost');
|
|
49
|
+
member.processParticipant(participant);
|
|
50
|
+
|
|
51
|
+
assert.calledOnceWithExactly(MemberUtil.canReclaimHost, participant);
|
|
52
|
+
});
|
|
52
53
|
})
|
|
53
54
|
|
|
54
55
|
describe('#processMember', () => {
|
|
@@ -50,6 +50,38 @@ describe('plugin-meetings', () => {
|
|
|
50
50
|
});
|
|
51
51
|
});
|
|
52
52
|
|
|
53
|
+
describe('MemberUtil.canReclaimHost', () => {
|
|
54
|
+
it('throws error when there is no participant', () => {
|
|
55
|
+
assert.throws(() => {
|
|
56
|
+
MemberUtil.canReclaimHost();
|
|
57
|
+
}, 'canReclaimHostRole could not be processed, participant is undefined.');
|
|
58
|
+
});
|
|
59
|
+
|
|
60
|
+
it('returns true when canReclaimHostRole is true', () => {
|
|
61
|
+
const participant = {
|
|
62
|
+
canReclaimHostRole: true,
|
|
63
|
+
};
|
|
64
|
+
|
|
65
|
+
assert.isTrue(MemberUtil.canReclaimHost(participant));
|
|
66
|
+
});
|
|
67
|
+
|
|
68
|
+
it('returns false when canReclaimHostRole is false', () => {
|
|
69
|
+
const participant = {
|
|
70
|
+
canReclaimHostRole: false,
|
|
71
|
+
};
|
|
72
|
+
|
|
73
|
+
assert.isFalse(MemberUtil.canReclaimHost(participant));
|
|
74
|
+
});
|
|
75
|
+
|
|
76
|
+
it('returns false when canReclaimHostRole is falsy', () => {
|
|
77
|
+
const participant = {
|
|
78
|
+
canReclaimHostRole: undefined,
|
|
79
|
+
};
|
|
80
|
+
|
|
81
|
+
assert.isFalse(MemberUtil.canReclaimHost(participant));
|
|
82
|
+
});
|
|
83
|
+
});
|
|
84
|
+
|
|
53
85
|
describe('MemberUtil.extractControlRoles', () => {
|
|
54
86
|
it('happy path extract control roles', () => {
|
|
55
87
|
const participant = {
|
|
@@ -17,6 +17,12 @@ import MembersUtil from '@webex/plugin-meetings/src/members/util';
|
|
|
17
17
|
import * as MembersRequestImport from '@webex/plugin-meetings/src/members/request';
|
|
18
18
|
import Trigger from '@webex/plugin-meetings/src/common/events/trigger-proxy';
|
|
19
19
|
import {EVENT_TRIGGERS} from '@webex/plugin-meetings/src/constants';
|
|
20
|
+
import {
|
|
21
|
+
ReclaimHostEmptyWrongKeyError,
|
|
22
|
+
ReclaimHostIsHostAlreadyError,
|
|
23
|
+
ReclaimHostNotAllowedError,
|
|
24
|
+
ReclaimHostNotSupportedError,
|
|
25
|
+
} from '../../../../src/common/errors/reclaim-host-role-errors';
|
|
20
26
|
|
|
21
27
|
const {assert} = chai;
|
|
22
28
|
|
|
@@ -337,7 +343,17 @@ describe('plugin-meetings', () => {
|
|
|
337
343
|
});
|
|
338
344
|
|
|
339
345
|
describe('#assignRoles', () => {
|
|
340
|
-
const
|
|
346
|
+
const fakeRoles = [
|
|
347
|
+
{type: 'PRESENTER', hasRole: true},
|
|
348
|
+
{type: 'MODERATOR', hasRole: false},
|
|
349
|
+
{type: 'COHOST', hasRole: true},
|
|
350
|
+
];
|
|
351
|
+
|
|
352
|
+
const resolvedValue = "it worked";
|
|
353
|
+
|
|
354
|
+
const genericMessage = 'Generic error from the API';
|
|
355
|
+
|
|
356
|
+
const setup = (locusUrl, errorCode) => {
|
|
341
357
|
const members = createMembers({url: locusUrl});
|
|
342
358
|
|
|
343
359
|
const spies = {
|
|
@@ -345,9 +361,14 @@ describe('plugin-meetings', () => {
|
|
|
345
361
|
MembersUtil,
|
|
346
362
|
'generateRoleAssignmentMemberOptions'
|
|
347
363
|
),
|
|
348
|
-
assignRolesMember: sandbox.spy(members.membersRequest, 'assignRolesMember'),
|
|
349
364
|
};
|
|
350
365
|
|
|
366
|
+
if (errorCode) {
|
|
367
|
+
spies.assignRolesMember = sandbox.stub(members.membersRequest, 'assignRolesMember').rejects({body: {errorCode}, message: genericMessage});
|
|
368
|
+
} else {
|
|
369
|
+
spies.assignRolesMember = sandbox.stub(members.membersRequest, 'assignRolesMember').resolves(resolvedValue);
|
|
370
|
+
}
|
|
371
|
+
|
|
351
372
|
return {members, spies};
|
|
352
373
|
};
|
|
353
374
|
|
|
@@ -357,6 +378,21 @@ describe('plugin-meetings', () => {
|
|
|
357
378
|
assert.notCalled(spies.assignRolesMember);
|
|
358
379
|
};
|
|
359
380
|
|
|
381
|
+
const checkError = async (error, expectedMemberId, expectedRoles, expectedLocusUrl, resultPromise, expectedMessage, spies) => {
|
|
382
|
+
await assert.isRejected(resultPromise, error, expectedMessage);
|
|
383
|
+
assert.calledOnceWithExactly(
|
|
384
|
+
spies.generateRoleAssignmentMemberOptions,
|
|
385
|
+
expectedMemberId,
|
|
386
|
+
expectedRoles,
|
|
387
|
+
expectedLocusUrl
|
|
388
|
+
);
|
|
389
|
+
assert.calledOnceWithExactly(spies.assignRolesMember, {
|
|
390
|
+
memberId: expectedMemberId,
|
|
391
|
+
roles: expectedRoles,
|
|
392
|
+
locusUrl: expectedLocusUrl,
|
|
393
|
+
});
|
|
394
|
+
};
|
|
395
|
+
|
|
360
396
|
const checkValid = async (
|
|
361
397
|
resultPromise,
|
|
362
398
|
spies,
|
|
@@ -364,7 +400,7 @@ describe('plugin-meetings', () => {
|
|
|
364
400
|
expectedRoles,
|
|
365
401
|
expectedLocusUrl
|
|
366
402
|
) => {
|
|
367
|
-
await assert.isFulfilled(resultPromise);
|
|
403
|
+
const resolvedValue = await assert.isFulfilled(resultPromise);
|
|
368
404
|
assert.calledOnceWithExactly(
|
|
369
405
|
spies.generateRoleAssignmentMemberOptions,
|
|
370
406
|
expectedMemberId,
|
|
@@ -376,7 +412,7 @@ describe('plugin-meetings', () => {
|
|
|
376
412
|
roles: expectedRoles,
|
|
377
413
|
locusUrl: expectedLocusUrl,
|
|
378
414
|
});
|
|
379
|
-
assert.strictEqual(
|
|
415
|
+
assert.strictEqual(resolvedValue, resolvedValue);
|
|
380
416
|
};
|
|
381
417
|
|
|
382
418
|
it('should not make a request if there is no member id', async () => {
|
|
@@ -387,7 +423,7 @@ describe('plugin-meetings', () => {
|
|
|
387
423
|
await checkInvalid(
|
|
388
424
|
resultPromise,
|
|
389
425
|
'The member id must be defined to assign the roles to a member.',
|
|
390
|
-
spies
|
|
426
|
+
spies,
|
|
391
427
|
);
|
|
392
428
|
});
|
|
393
429
|
|
|
@@ -399,7 +435,92 @@ describe('plugin-meetings', () => {
|
|
|
399
435
|
await checkInvalid(
|
|
400
436
|
resultPromise,
|
|
401
437
|
'The associated locus url for this meetings members object must be defined.',
|
|
402
|
-
spies
|
|
438
|
+
spies,
|
|
439
|
+
);
|
|
440
|
+
});
|
|
441
|
+
|
|
442
|
+
it('should not make a request if locus throws ReclaimHostNotSupportedError', async () => {
|
|
443
|
+
const memberId = uuid.v4();
|
|
444
|
+
const {members, spies} = setup(url1, 2400127);
|
|
445
|
+
|
|
446
|
+
const resultPromise = members.assignRoles(memberId, fakeRoles);
|
|
447
|
+
|
|
448
|
+
await checkError(
|
|
449
|
+
ReclaimHostNotSupportedError,
|
|
450
|
+
memberId,
|
|
451
|
+
fakeRoles,
|
|
452
|
+
url1,
|
|
453
|
+
resultPromise,
|
|
454
|
+
'Non converged meetings, PSTN or SIP users in converged meetings are not supported currently.',
|
|
455
|
+
spies,
|
|
456
|
+
);
|
|
457
|
+
});
|
|
458
|
+
|
|
459
|
+
it('should not make a request if locus throws ReclaimHostNotAllowedError', async () => {
|
|
460
|
+
const memberId = uuid.v4();
|
|
461
|
+
const {members, spies} = setup(url1, 2403135);
|
|
462
|
+
|
|
463
|
+
const resultPromise = members.assignRoles(memberId, fakeRoles);
|
|
464
|
+
|
|
465
|
+
await checkError(
|
|
466
|
+
ReclaimHostNotAllowedError,
|
|
467
|
+
memberId,
|
|
468
|
+
fakeRoles,
|
|
469
|
+
url1,
|
|
470
|
+
resultPromise,
|
|
471
|
+
'Reclaim Host Role Not Allowed For Other Participants. Participants cannot claim host role in PMR meeting, space instant meeting or escalated instant meeting. However, the original host still can reclaim host role when it manually makes another participant to be the host.',
|
|
472
|
+
spies,
|
|
473
|
+
);
|
|
474
|
+
});
|
|
475
|
+
|
|
476
|
+
it('should not make a request if locus throws ReclaimHostEmptyWrongKeyError', async () => {
|
|
477
|
+
const memberId = uuid.v4();
|
|
478
|
+
const {members, spies} = setup(url1, 2403136);
|
|
479
|
+
|
|
480
|
+
const resultPromise = members.assignRoles(memberId, fakeRoles);
|
|
481
|
+
|
|
482
|
+
await checkError(
|
|
483
|
+
ReclaimHostEmptyWrongKeyError,
|
|
484
|
+
memberId,
|
|
485
|
+
fakeRoles,
|
|
486
|
+
url1,
|
|
487
|
+
resultPromise,
|
|
488
|
+
'Host Key Not Specified Or Matched. The original host can reclaim the host role without entering the host key. However, any other person who claims the host role must enter the host key to get it.',
|
|
489
|
+
spies,
|
|
490
|
+
);
|
|
491
|
+
});
|
|
492
|
+
|
|
493
|
+
it('should not make a request if locus throws ReclaimHostIsHostAlreadyError', async () => {
|
|
494
|
+
const memberId = uuid.v4();
|
|
495
|
+
const {members, spies} = setup(url1, 2409150);
|
|
496
|
+
|
|
497
|
+
const resultPromise = members.assignRoles(memberId, fakeRoles);
|
|
498
|
+
|
|
499
|
+
await checkError(
|
|
500
|
+
ReclaimHostIsHostAlreadyError,
|
|
501
|
+
memberId,
|
|
502
|
+
fakeRoles,
|
|
503
|
+
url1,
|
|
504
|
+
resultPromise,
|
|
505
|
+
'Participant Having Host Role Already. Participant who sends request to reclaim host role has already a host role.',
|
|
506
|
+
spies,
|
|
507
|
+
);
|
|
508
|
+
});
|
|
509
|
+
|
|
510
|
+
it('should not make a request if locus throws a different error', async () => {
|
|
511
|
+
const memberId = uuid.v4();
|
|
512
|
+
const {members, spies} = setup(url1, 1234);
|
|
513
|
+
|
|
514
|
+
const resultPromise = members.assignRoles(memberId, fakeRoles);
|
|
515
|
+
|
|
516
|
+
await checkError(
|
|
517
|
+
{body: {errorCode: 1234}, message: genericMessage},
|
|
518
|
+
memberId,
|
|
519
|
+
fakeRoles,
|
|
520
|
+
url1,
|
|
521
|
+
resultPromise,
|
|
522
|
+
genericMessage,
|
|
523
|
+
spies,
|
|
403
524
|
);
|
|
404
525
|
});
|
|
405
526
|
|
|
@@ -407,22 +528,14 @@ describe('plugin-meetings', () => {
|
|
|
407
528
|
const memberId = uuid.v4();
|
|
408
529
|
const {members, spies} = setup(url1);
|
|
409
530
|
|
|
410
|
-
const resultPromise = members.assignRoles(memberId,
|
|
411
|
-
{type: 'PRESENTER', hasRole: true},
|
|
412
|
-
{type: 'MODERATOR', hasRole: false},
|
|
413
|
-
{type: 'COHOST', hasRole: true},
|
|
414
|
-
]);
|
|
531
|
+
const resultPromise = members.assignRoles(memberId, fakeRoles);
|
|
415
532
|
|
|
416
533
|
await checkValid(
|
|
417
534
|
resultPromise,
|
|
418
535
|
spies,
|
|
419
536
|
memberId,
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
{type: 'MODERATOR', hasRole: false},
|
|
423
|
-
{type: 'COHOST', hasRole: true},
|
|
424
|
-
],
|
|
425
|
-
url1
|
|
537
|
+
fakeRoles,
|
|
538
|
+
url1,
|
|
426
539
|
);
|
|
427
540
|
});
|
|
428
541
|
});
|
|
@@ -59,6 +59,32 @@ describe('plugin-meetings', () => {
|
|
|
59
59
|
},
|
|
60
60
|
});
|
|
61
61
|
});
|
|
62
|
+
|
|
63
|
+
it('returns the correct request params with a hostKey', () => {
|
|
64
|
+
const format = {
|
|
65
|
+
locusUrl: 'locusUrl',
|
|
66
|
+
memberId: 'test',
|
|
67
|
+
roles: [
|
|
68
|
+
{type: 'PRESENTER', hasRole: true, hostKey: '123456'},
|
|
69
|
+
{type: 'MODERATOR', hasRole: false, hostKey: '123456'},
|
|
70
|
+
{type: 'COHOST', hasRole: true, hostKey: '123456'},
|
|
71
|
+
],
|
|
72
|
+
};
|
|
73
|
+
|
|
74
|
+
assert.deepEqual(MembersUtil.getRoleAssignmentMemberRequestParams(format), {
|
|
75
|
+
method: 'PATCH',
|
|
76
|
+
uri: `locusUrl/${PARTICIPANT}/test/${CONTROLS}`,
|
|
77
|
+
body: {
|
|
78
|
+
role: {
|
|
79
|
+
roles: [
|
|
80
|
+
{type: 'PRESENTER', hasRole: true, hostKey: '123456'},
|
|
81
|
+
{type: 'MODERATOR', hasRole: false, hostKey: '123456'},
|
|
82
|
+
{type: 'COHOST', hasRole: true, hostKey: '123456'},
|
|
83
|
+
],
|
|
84
|
+
},
|
|
85
|
+
},
|
|
86
|
+
});
|
|
87
|
+
});
|
|
62
88
|
});
|
|
63
89
|
|
|
64
90
|
describe('#generateRaiseHandMemberOptions', () => {
|
|
@@ -14,6 +14,7 @@ type ExpectedActiveSpeaker = {
|
|
|
14
14
|
receiveSlots: Array<ReceiveSlot>;
|
|
15
15
|
maxFs?: number;
|
|
16
16
|
maxMbps?: number;
|
|
17
|
+
namedMediaGroups?:[{type: number, value: number}];
|
|
17
18
|
};
|
|
18
19
|
type ExpectedReceiverSelected = {
|
|
19
20
|
policy: 'receiver-selected';
|
|
@@ -80,7 +81,7 @@ describe('MediaRequestManager', () => {
|
|
|
80
81
|
});
|
|
81
82
|
|
|
82
83
|
// helper function for adding an active speaker request
|
|
83
|
-
const addActiveSpeakerRequest = (priority, receiveSlots, maxFs, commit = false, preferLiveVideo = true) =>
|
|
84
|
+
const addActiveSpeakerRequest = (priority, receiveSlots, maxFs, commit = false, preferLiveVideo = true, namedMediaGroups = undefined) =>
|
|
84
85
|
mediaRequestManager.addRequest(
|
|
85
86
|
{
|
|
86
87
|
policyInfo: {
|
|
@@ -89,6 +90,7 @@ describe('MediaRequestManager', () => {
|
|
|
89
90
|
crossPriorityDuplication: CROSS_PRIORITY_DUPLICATION,
|
|
90
91
|
crossPolicyDuplication: CROSS_POLICY_DUPLICATION,
|
|
91
92
|
preferLiveVideo,
|
|
93
|
+
namedMediaGroups,
|
|
92
94
|
},
|
|
93
95
|
receiveSlots,
|
|
94
96
|
codecInfo: {
|
|
@@ -590,7 +592,14 @@ describe('MediaRequestManager', () => {
|
|
|
590
592
|
MAX_FS_720p,
|
|
591
593
|
false
|
|
592
594
|
);
|
|
593
|
-
|
|
595
|
+
addActiveSpeakerRequest(
|
|
596
|
+
254,
|
|
597
|
+
[fakeReceiveSlots[8], fakeReceiveSlots[9], fakeReceiveSlots[10]],
|
|
598
|
+
MAX_FS_720p,
|
|
599
|
+
false,
|
|
600
|
+
true,
|
|
601
|
+
[{type: 1, value: 20}],
|
|
602
|
+
);
|
|
594
603
|
// nothing should be sent out as we didn't commit the requests
|
|
595
604
|
assert.notCalled(sendMediaRequestsCallback);
|
|
596
605
|
|
|
@@ -631,6 +640,15 @@ describe('MediaRequestManager', () => {
|
|
|
631
640
|
maxFs: MAX_FS_720p,
|
|
632
641
|
maxMbps: MAX_MBPS_720p,
|
|
633
642
|
},
|
|
643
|
+
{
|
|
644
|
+
policy: 'active-speaker',
|
|
645
|
+
priority: 254,
|
|
646
|
+
receiveSlots: [fakeWcmeSlots[8], fakeWcmeSlots[9], fakeWcmeSlots[10]],
|
|
647
|
+
maxPayloadBitsPerSecond: MAX_PAYLOADBITSPS_720p,
|
|
648
|
+
maxFs: MAX_FS_720p,
|
|
649
|
+
maxMbps: MAX_MBPS_720p,
|
|
650
|
+
namedMediaGroups: [{type: 1, value: 20}],
|
|
651
|
+
},
|
|
634
652
|
]);
|
|
635
653
|
});
|
|
636
654
|
|
|
@@ -6,6 +6,7 @@ import {RemoteMedia} from '@webex/plugin-meetings/src/multistream/remoteMedia';
|
|
|
6
6
|
import {ReceiveSlot} from '@webex/plugin-meetings/src/multistream/receiveSlot';
|
|
7
7
|
import sinon from 'sinon';
|
|
8
8
|
import {assert} from '@webex/test-helper-chai';
|
|
9
|
+
import { NamedMediaGroup } from "@webex/json-multistream";
|
|
9
10
|
|
|
10
11
|
class FakeSlot extends EventEmitter {
|
|
11
12
|
public mediaType: MediaType;
|
|
@@ -24,6 +25,7 @@ describe('RemoteMediaGroup', () => {
|
|
|
24
25
|
|
|
25
26
|
let fakeMediaRequestManager;
|
|
26
27
|
let fakeReceiveSlots;
|
|
28
|
+
let fakeNamedMediaSlots;
|
|
27
29
|
|
|
28
30
|
let activeSpeakerRequestCounter;
|
|
29
31
|
let receiverSelectedRequestCounter;
|
|
@@ -50,6 +52,10 @@ describe('RemoteMediaGroup', () => {
|
|
|
50
52
|
fakeReceiveSlots = Array(NUM_SLOTS)
|
|
51
53
|
.fill(null)
|
|
52
54
|
.map((_, index) => new FakeSlot(MediaType.VideoMain, `fake receive slot ${index}`));
|
|
55
|
+
|
|
56
|
+
fakeNamedMediaSlots = Array(1)
|
|
57
|
+
.fill(null)
|
|
58
|
+
.map((_, index) => new FakeSlot(MediaType.AudioMain, `fake named media receive slot ${index}`));
|
|
53
59
|
});
|
|
54
60
|
|
|
55
61
|
const getLastActiveSpeakerRequestId = () =>
|
|
@@ -144,6 +150,79 @@ describe('RemoteMediaGroup', () => {
|
|
|
144
150
|
|
|
145
151
|
});
|
|
146
152
|
|
|
153
|
+
describe('setNamedMediaGroup', () => {
|
|
154
|
+
it('updates named media group', () => {
|
|
155
|
+
|
|
156
|
+
const nameGroup1 = { type: 1, value: 20 };
|
|
157
|
+
const nameGroup2 = { type: 1, value: 24 };
|
|
158
|
+
const group = new RemoteMediaGroup(fakeMediaRequestManager, fakeNamedMediaSlots, 255, true, {
|
|
159
|
+
namedMediaGroup: nameGroup1,
|
|
160
|
+
});
|
|
161
|
+
fakeMediaRequestManager.addRequest.resetHistory();
|
|
162
|
+
group.setNamedMediaGroup(nameGroup2, false);
|
|
163
|
+
|
|
164
|
+
assert.calledOnce(fakeMediaRequestManager.cancelRequest);
|
|
165
|
+
|
|
166
|
+
assert.calledOnce(fakeMediaRequestManager.addRequest);
|
|
167
|
+
|
|
168
|
+
assert.calledWith(
|
|
169
|
+
fakeMediaRequestManager.addRequest,
|
|
170
|
+
sinon.match({
|
|
171
|
+
policyInfo: sinon.match({
|
|
172
|
+
policy: 'active-speaker',
|
|
173
|
+
priority: 255,
|
|
174
|
+
namedMediaGroups: sinon.match([{type: 1, value: 24}]),
|
|
175
|
+
}),
|
|
176
|
+
receiveSlots: fakeNamedMediaSlots,
|
|
177
|
+
codecInfo: undefined,
|
|
178
|
+
}),
|
|
179
|
+
false,
|
|
180
|
+
);
|
|
181
|
+
});
|
|
182
|
+
|
|
183
|
+
it('does not call add request when named media group has not changed', () => {
|
|
184
|
+
const group = new RemoteMediaGroup(fakeMediaRequestManager, fakeNamedMediaSlots, 255, true, {
|
|
185
|
+
namedMediaGroup: { type: 1, value: 20 },
|
|
186
|
+
});
|
|
187
|
+
fakeMediaRequestManager.addRequest.resetHistory();
|
|
188
|
+
group.setNamedMediaGroup({ type: 1, value: 20 }, false);
|
|
189
|
+
|
|
190
|
+
assert.notCalled(fakeMediaRequestManager.cancelRequest);
|
|
191
|
+
|
|
192
|
+
assert.notCalled(fakeMediaRequestManager.addRequest);
|
|
193
|
+
});
|
|
194
|
+
|
|
195
|
+
it('remove named media group', () => {
|
|
196
|
+
|
|
197
|
+
const nameGroup1 = { type: 1, value: 20 };
|
|
198
|
+
const nameGroup2 = { type: 1, value: 0 };
|
|
199
|
+
const group = new RemoteMediaGroup(fakeMediaRequestManager, fakeNamedMediaSlots, 255, true, {
|
|
200
|
+
namedMediaGroup: nameGroup1,
|
|
201
|
+
});
|
|
202
|
+
fakeMediaRequestManager.addRequest.resetHistory();
|
|
203
|
+
group.setNamedMediaGroup(nameGroup2, true);
|
|
204
|
+
|
|
205
|
+
assert.calledOnce(fakeMediaRequestManager.cancelRequest);
|
|
206
|
+
|
|
207
|
+
assert.calledOnce(fakeMediaRequestManager.addRequest);
|
|
208
|
+
|
|
209
|
+
assert.calledWith(
|
|
210
|
+
fakeMediaRequestManager.addRequest,
|
|
211
|
+
sinon.match({
|
|
212
|
+
policyInfo: sinon.match({
|
|
213
|
+
policy: 'active-speaker',
|
|
214
|
+
priority: 255,
|
|
215
|
+
nameMediaGroups: undefined,
|
|
216
|
+
}),
|
|
217
|
+
receiveSlots: fakeNamedMediaSlots,
|
|
218
|
+
codecInfo: undefined,
|
|
219
|
+
}),
|
|
220
|
+
true,
|
|
221
|
+
);
|
|
222
|
+
});
|
|
223
|
+
|
|
224
|
+
});
|
|
225
|
+
|
|
147
226
|
describe('setActiveSpeakerCsis', () => {
|
|
148
227
|
it('checks when there is a csi and remote media is not in pinned array', () => {
|
|
149
228
|
const PINNED_INDEX = 2;
|
|
@@ -251,7 +330,7 @@ describe('RemoteMediaGroup', () => {
|
|
|
251
330
|
assert.strictEqual(group.getRemoteMedia('pinned').length, 1);
|
|
252
331
|
|
|
253
332
|
assert.strictEqual(group.isPinned(remoteMedia), true);
|
|
254
|
-
|
|
333
|
+
|
|
255
334
|
assert.calledTwice(fakeMediaRequestManager.cancelRequest);
|
|
256
335
|
assert.calledWith(fakeMediaRequestManager.cancelRequest, 'fake receiver selected request 1');
|
|
257
336
|
|