@webex/plugin-meetings 2.13.0 → 2.14.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/meeting/effectsState.js +328 -0
- package/dist/meeting/effectsState.js.map +1 -0
- package/dist/meeting/index.js +68 -177
- package/dist/meeting/index.js.map +1 -1
- package/package.json +6 -6
- package/src/meeting/effectsState.js +206 -0
- package/src/meeting/index.js +64 -97
- package/test/unit/spec/meeting/effectsState.js +292 -0
- package/test/unit/spec/meeting/index.js +30 -176
|
@@ -0,0 +1,292 @@
|
|
|
1
|
+
/* eslint-disable camelcase */
|
|
2
|
+
import {assert} from '@webex/test-helper-chai';
|
|
3
|
+
import sinon from 'sinon';
|
|
4
|
+
import MockWebex from '@webex/test-helper-mock-webex';
|
|
5
|
+
|
|
6
|
+
import BEHAVIORAL_METRICS from '@webex/plugin-meetings/src/metrics/constants';
|
|
7
|
+
import {BNR_STATUS} from '@webex/plugin-meetings/src/constants';
|
|
8
|
+
import Meeting from '@webex/plugin-meetings/src/meeting';
|
|
9
|
+
import Meetings from '@webex/plugin-meetings';
|
|
10
|
+
import Metrics from '@webex/plugin-meetings/src/metrics';
|
|
11
|
+
import MediaUtil from '@webex/plugin-meetings/src/media/util';
|
|
12
|
+
import MeetingUtil from '@webex/plugin-meetings/src/meeting/util';
|
|
13
|
+
import createEffectsState from '@webex/plugin-meetings/src/meeting/effectsState';
|
|
14
|
+
import LoggerProxy from '@webex/plugin-meetings/src/common/logs/logger-proxy';
|
|
15
|
+
import LoggerConfig from '@webex/plugin-meetings/src/common/logs/logger-config';
|
|
16
|
+
|
|
17
|
+
describe('plugin-meetings', () => {
|
|
18
|
+
const logger = {
|
|
19
|
+
info: () => {},
|
|
20
|
+
log: () => {},
|
|
21
|
+
error: () => {},
|
|
22
|
+
warn: () => {},
|
|
23
|
+
trace: () => {},
|
|
24
|
+
debug: () => {}
|
|
25
|
+
};
|
|
26
|
+
|
|
27
|
+
beforeEach(() => {
|
|
28
|
+
sinon.stub(Metrics, 'sendBehavioralMetric');
|
|
29
|
+
});
|
|
30
|
+
afterEach(() => {
|
|
31
|
+
sinon.restore();
|
|
32
|
+
});
|
|
33
|
+
|
|
34
|
+
Object.defineProperty(global.window.navigator, 'mediaDevices', {
|
|
35
|
+
writable: true,
|
|
36
|
+
value: {
|
|
37
|
+
getSupportedConstraints: sinon.stub().returns({
|
|
38
|
+
sampleRate: true
|
|
39
|
+
})
|
|
40
|
+
},
|
|
41
|
+
});
|
|
42
|
+
LoggerConfig.set({verboseEvents: true, enable: false});
|
|
43
|
+
LoggerProxy.set(logger);
|
|
44
|
+
|
|
45
|
+
let webex;
|
|
46
|
+
let meeting;
|
|
47
|
+
let uuid1;
|
|
48
|
+
|
|
49
|
+
const fakeMediaTrack = () => ({
|
|
50
|
+
id: Date.now().toString(),
|
|
51
|
+
stop: () => {},
|
|
52
|
+
readyState: 'live',
|
|
53
|
+
enabled: true,
|
|
54
|
+
getSettings: () => ({
|
|
55
|
+
sampleRate: 48000
|
|
56
|
+
})
|
|
57
|
+
});
|
|
58
|
+
|
|
59
|
+
class FakeMediaStream {
|
|
60
|
+
constructor(tracks) {
|
|
61
|
+
this.active = false;
|
|
62
|
+
this.id = '5146425f-c240-48cc-b86b-27d422988fb7';
|
|
63
|
+
this.tracks = tracks;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
addTrack = () => undefined;
|
|
67
|
+
|
|
68
|
+
getAudioTracks = () => this.tracks;
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
class FakeAudioContext {
|
|
72
|
+
constructor() {
|
|
73
|
+
this.state = 'running';
|
|
74
|
+
this.baseLatency = 0.005333333333333333;
|
|
75
|
+
this.currentTime = 2.7946666666666666;
|
|
76
|
+
this.sampleRate = 48000;
|
|
77
|
+
this.audioWorklet = {
|
|
78
|
+
addModule: async () => undefined,
|
|
79
|
+
};
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
onstatechange = null;
|
|
83
|
+
|
|
84
|
+
createMediaStreamSource() {
|
|
85
|
+
return {
|
|
86
|
+
connect: () => undefined,
|
|
87
|
+
mediaStream: {
|
|
88
|
+
getAudioTracks() {
|
|
89
|
+
// eslint-disable-next-line no-undef
|
|
90
|
+
return [new MediaStreamTrack()];
|
|
91
|
+
},
|
|
92
|
+
},
|
|
93
|
+
};
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
createMediaStreamDestination() {
|
|
97
|
+
return {
|
|
98
|
+
stream: {
|
|
99
|
+
getAudioTracks() {
|
|
100
|
+
// eslint-disable-next-line no-undef
|
|
101
|
+
return [new MediaStreamTrack()];
|
|
102
|
+
},
|
|
103
|
+
},
|
|
104
|
+
};
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
class FakeAudioWorkletNode {
|
|
109
|
+
constructor() {
|
|
110
|
+
this.port = {
|
|
111
|
+
postMessage: () => undefined,
|
|
112
|
+
};
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
connect() {
|
|
116
|
+
/* placeholder method */
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
class FakeMediaStreamTrack {
|
|
121
|
+
constructor() {
|
|
122
|
+
this.kind = 'audio';
|
|
123
|
+
this.enabled = true;
|
|
124
|
+
this.label = 'Default - MacBook Pro Microphone (Built-in)';
|
|
125
|
+
this.muted = false;
|
|
126
|
+
this.readyState = 'live';
|
|
127
|
+
this.contentHint = '';
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
getSettings() {
|
|
131
|
+
return {
|
|
132
|
+
sampleRate: 48000
|
|
133
|
+
};
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
Object.defineProperty(global, 'MediaStream', {
|
|
137
|
+
writable: true,
|
|
138
|
+
value: FakeMediaStream,
|
|
139
|
+
});
|
|
140
|
+
|
|
141
|
+
Object.defineProperty(global, 'AudioContext', {
|
|
142
|
+
writable: true,
|
|
143
|
+
value: FakeAudioContext,
|
|
144
|
+
});
|
|
145
|
+
|
|
146
|
+
Object.defineProperty(global, 'AudioWorkletNode', {
|
|
147
|
+
writable: true,
|
|
148
|
+
value: FakeAudioWorkletNode,
|
|
149
|
+
});
|
|
150
|
+
|
|
151
|
+
Object.defineProperty(global, 'MediaStreamTrack', {
|
|
152
|
+
writable: true,
|
|
153
|
+
value: FakeMediaStreamTrack,
|
|
154
|
+
});
|
|
155
|
+
|
|
156
|
+
let effects;
|
|
157
|
+
|
|
158
|
+
beforeEach(() => {
|
|
159
|
+
webex = new MockWebex({
|
|
160
|
+
children: {
|
|
161
|
+
meetings: Meetings
|
|
162
|
+
}
|
|
163
|
+
});
|
|
164
|
+
MediaUtil.createPeerConnection = sinon.stub().returns({});
|
|
165
|
+
meeting = new Meeting(
|
|
166
|
+
{
|
|
167
|
+
userId: uuid1
|
|
168
|
+
},
|
|
169
|
+
{
|
|
170
|
+
parent: webex
|
|
171
|
+
}
|
|
172
|
+
);
|
|
173
|
+
|
|
174
|
+
effects = createEffectsState('BNR');
|
|
175
|
+
meeting.canUpdateMedia = sinon.stub().returns(true);
|
|
176
|
+
MeetingUtil.validateOptions = sinon.stub().returns(Promise.resolve());
|
|
177
|
+
MeetingUtil.updateTransceiver = sinon.stub();
|
|
178
|
+
|
|
179
|
+
meeting.addMedia = sinon.stub().returns(Promise.resolve());
|
|
180
|
+
meeting.getMediaStreams = sinon.stub().returns(Promise.resolve());
|
|
181
|
+
sinon.replace(meeting, 'addMedia', () => {
|
|
182
|
+
sinon.stub(meeting.mediaProperties, 'audioTrack').value(fakeMediaTrack());
|
|
183
|
+
sinon.stub(meeting.mediaProperties, 'mediaDirection').value({
|
|
184
|
+
receiveAudio: true
|
|
185
|
+
});
|
|
186
|
+
});
|
|
187
|
+
});
|
|
188
|
+
|
|
189
|
+
describe('bnr effect library', () => {
|
|
190
|
+
beforeEach(async () => {
|
|
191
|
+
await meeting.getMediaStreams();
|
|
192
|
+
await meeting.addMedia();
|
|
193
|
+
});
|
|
194
|
+
describe('#enableBNR', () => {
|
|
195
|
+
it('should have #enableBnr', () => {
|
|
196
|
+
assert.exists(effects.enableBNR);
|
|
197
|
+
});
|
|
198
|
+
|
|
199
|
+
it('does bnr effect enable on audio track', async () => {
|
|
200
|
+
assert.isTrue(await effects.handleClientRequest(true, meeting));
|
|
201
|
+
assert.equal(effects.state.bnr.enabled, BNR_STATUS.ENABLED);
|
|
202
|
+
|
|
203
|
+
assert(Metrics.sendBehavioralMetric.calledOnce);
|
|
204
|
+
assert.calledWith(
|
|
205
|
+
Metrics.sendBehavioralMetric,
|
|
206
|
+
BEHAVIORAL_METRICS.ENABLE_BNR_SUCCESS,
|
|
207
|
+
);
|
|
208
|
+
});
|
|
209
|
+
|
|
210
|
+
it('does resolve request if bnr is already enabled', async () => {
|
|
211
|
+
effects.state.bnr.enabled = BNR_STATUS.ENABLED;
|
|
212
|
+
assert.isTrue(await effects.handleClientRequest(true, meeting));
|
|
213
|
+
assert.equal(effects.state.bnr.enabled, BNR_STATUS.ENABLED);
|
|
214
|
+
});
|
|
215
|
+
|
|
216
|
+
it('if called twice, does bnr effect enable on audio track for the first request and resolves second', async () => {
|
|
217
|
+
Promise.all([effects.handleClientRequest(true, meeting), effects.handleClientRequest(true, meeting)])
|
|
218
|
+
.then((resolveFirst, resolveSecond) => {
|
|
219
|
+
assert.isTrue(resolveFirst);
|
|
220
|
+
assert.isTrue(resolveSecond);
|
|
221
|
+
assert.calledOnce(MediaUtil.createMediaStream);
|
|
222
|
+
});
|
|
223
|
+
});
|
|
224
|
+
|
|
225
|
+
it('should throw error for inappropriate sample rate and send error metrics', async () => {
|
|
226
|
+
const fakeMediaTrack1 = () => ({
|
|
227
|
+
id: Date.now().toString(),
|
|
228
|
+
stop: () => {},
|
|
229
|
+
readyState: 'live',
|
|
230
|
+
getSettings: () => ({
|
|
231
|
+
sampleRate: 49000
|
|
232
|
+
})
|
|
233
|
+
});
|
|
234
|
+
|
|
235
|
+
sinon.stub(meeting.mediaProperties, 'audioTrack').value(fakeMediaTrack1());
|
|
236
|
+
|
|
237
|
+
// eslint-disable-next-line no-undef
|
|
238
|
+
MediaUtil.createMediaStream = sinon.stub().returns(new MediaStream([fakeMediaTrack1()]));
|
|
239
|
+
try {
|
|
240
|
+
await effects.handleClientRequest(true, meeting);
|
|
241
|
+
}
|
|
242
|
+
catch (err) {
|
|
243
|
+
assert(Metrics.sendBehavioralMetric.calledOnce);
|
|
244
|
+
assert.calledWith(
|
|
245
|
+
Metrics.sendBehavioralMetric,
|
|
246
|
+
BEHAVIORAL_METRICS.ENABLE_BNR_FAILURE, {
|
|
247
|
+
reason: err.message,
|
|
248
|
+
stack: err.stack
|
|
249
|
+
}
|
|
250
|
+
);
|
|
251
|
+
assert.equal(err.message, 'Sample rate of 49000 is not supported.');
|
|
252
|
+
}
|
|
253
|
+
});
|
|
254
|
+
});
|
|
255
|
+
|
|
256
|
+
describe('#disableBNR', () => {
|
|
257
|
+
beforeEach(() => {
|
|
258
|
+
effects.state.bnr.enabled = BNR_STATUS.ENABLED;
|
|
259
|
+
});
|
|
260
|
+
it('should have #disableBnr', () => {
|
|
261
|
+
assert.exists(effects.disableBNR);
|
|
262
|
+
});
|
|
263
|
+
|
|
264
|
+
it('does bnr disable on audio track', async () => {
|
|
265
|
+
assert.isTrue(await effects.handleClientRequest(false, meeting));
|
|
266
|
+
assert.equal(effects.state.bnr.enabled, BNR_STATUS.NOT_ENABLED);
|
|
267
|
+
|
|
268
|
+
assert(Metrics.sendBehavioralMetric.calledOnce);
|
|
269
|
+
assert.calledWith(
|
|
270
|
+
Metrics.sendBehavioralMetric,
|
|
271
|
+
BEHAVIORAL_METRICS.DISABLE_BNR_SUCCESS,
|
|
272
|
+
);
|
|
273
|
+
});
|
|
274
|
+
|
|
275
|
+
it('reject request for disable bnr if not enabled', async () => {
|
|
276
|
+
try {
|
|
277
|
+
await effects.handleClientRequest(false, meeting);
|
|
278
|
+
}
|
|
279
|
+
catch (e) {
|
|
280
|
+
assert.equal(e.message, 'Can not disable as BNR is not enabled');
|
|
281
|
+
assert.equal(effects.state.bnr.enabled, BNR_STATUS.ENABLED);
|
|
282
|
+
|
|
283
|
+
assert(Metrics.sendBehavioralMetric.calledOnce);
|
|
284
|
+
assert.calledWith(
|
|
285
|
+
Metrics.sendBehavioralMetric,
|
|
286
|
+
BEHAVIORAL_METRICS.DISABLE_BNR_FAILURE,
|
|
287
|
+
);
|
|
288
|
+
}
|
|
289
|
+
});
|
|
290
|
+
});
|
|
291
|
+
});
|
|
292
|
+
});
|
|
@@ -466,108 +466,7 @@ describe('plugin-meetings', () => {
|
|
|
466
466
|
})
|
|
467
467
|
});
|
|
468
468
|
|
|
469
|
-
class FakeMediaStream {
|
|
470
|
-
constructor(tracks) {
|
|
471
|
-
this.active = false;
|
|
472
|
-
this.id = '5146425f-c240-48cc-b86b-27d422988fb7';
|
|
473
|
-
this.tracks = tracks;
|
|
474
|
-
}
|
|
475
|
-
|
|
476
|
-
addTrack = () => undefined;
|
|
477
|
-
|
|
478
|
-
getAudioTracks = () => this.tracks;
|
|
479
|
-
}
|
|
480
|
-
|
|
481
|
-
class FakeAudioContext {
|
|
482
|
-
constructor() {
|
|
483
|
-
this.state = 'running';
|
|
484
|
-
this.baseLatency = 0.005333333333333333;
|
|
485
|
-
this.currentTime = 2.7946666666666666;
|
|
486
|
-
this.sampleRate = 48000;
|
|
487
|
-
this.audioWorklet = {
|
|
488
|
-
addModule: async () => undefined,
|
|
489
|
-
};
|
|
490
|
-
}
|
|
491
|
-
|
|
492
|
-
onstatechange = null;
|
|
493
|
-
|
|
494
|
-
createMediaStreamSource() {
|
|
495
|
-
return {
|
|
496
|
-
connect: () => undefined,
|
|
497
|
-
mediaStream: {
|
|
498
|
-
getAudioTracks() {
|
|
499
|
-
// eslint-disable-next-line no-undef
|
|
500
|
-
return [new MediaStreamTrack()];
|
|
501
|
-
},
|
|
502
|
-
},
|
|
503
|
-
};
|
|
504
|
-
}
|
|
505
|
-
|
|
506
|
-
createMediaStreamDestination() {
|
|
507
|
-
return {
|
|
508
|
-
stream: {
|
|
509
|
-
getAudioTracks() {
|
|
510
|
-
// eslint-disable-next-line no-undef
|
|
511
|
-
return [new MediaStreamTrack()];
|
|
512
|
-
},
|
|
513
|
-
},
|
|
514
|
-
};
|
|
515
|
-
}
|
|
516
|
-
}
|
|
517
|
-
|
|
518
|
-
class FakeAudioWorkletNode {
|
|
519
|
-
constructor() {
|
|
520
|
-
this.port = {
|
|
521
|
-
postMessage: () => undefined,
|
|
522
|
-
};
|
|
523
|
-
}
|
|
524
|
-
|
|
525
|
-
connect() {
|
|
526
|
-
/* placeholder method */
|
|
527
|
-
}
|
|
528
|
-
}
|
|
529
|
-
|
|
530
|
-
class FakeMediaStreamTrack {
|
|
531
|
-
constructor() {
|
|
532
|
-
this.kind = 'audio';
|
|
533
|
-
this.enabled = true;
|
|
534
|
-
this.label = 'Default - MacBook Pro Microphone (Built-in)';
|
|
535
|
-
this.muted = false;
|
|
536
|
-
this.readyState = 'live';
|
|
537
|
-
this.contentHint = '';
|
|
538
|
-
}
|
|
539
|
-
|
|
540
|
-
getSettings() {
|
|
541
|
-
return {
|
|
542
|
-
sampleRate: 48000
|
|
543
|
-
};
|
|
544
|
-
}
|
|
545
|
-
}
|
|
546
|
-
Object.defineProperty(global, 'MediaStream', {
|
|
547
|
-
writable: true,
|
|
548
|
-
value: FakeMediaStream,
|
|
549
|
-
});
|
|
550
|
-
|
|
551
|
-
Object.defineProperty(global, 'AudioContext', {
|
|
552
|
-
writable: true,
|
|
553
|
-
value: FakeAudioContext,
|
|
554
|
-
});
|
|
555
|
-
|
|
556
|
-
Object.defineProperty(global, 'AudioWorkletNode', {
|
|
557
|
-
writable: true,
|
|
558
|
-
value: FakeAudioWorkletNode,
|
|
559
|
-
});
|
|
560
|
-
|
|
561
|
-
Object.defineProperty(global, 'MediaStreamTrack', {
|
|
562
|
-
writable: true,
|
|
563
|
-
value: FakeMediaStreamTrack,
|
|
564
|
-
});
|
|
565
|
-
|
|
566
469
|
beforeEach(() => {
|
|
567
|
-
meeting.canUpdateMedia = sinon.stub().returns(true);
|
|
568
|
-
MeetingUtil.validateOptions = sinon.stub().returns(Promise.resolve());
|
|
569
|
-
MeetingUtil.updateTransceiver = sinon.stub();
|
|
570
|
-
|
|
571
470
|
meeting.getMediaStreams = sinon.stub().returns(Promise.resolve());
|
|
572
471
|
sinon.replace(meeting, 'addMedia', () => {
|
|
573
472
|
sinon.stub(meeting.mediaProperties, 'audioTrack').value(fakeMediaTrack());
|
|
@@ -575,11 +474,7 @@ describe('plugin-meetings', () => {
|
|
|
575
474
|
receiveAudio: true
|
|
576
475
|
});
|
|
577
476
|
});
|
|
578
|
-
|
|
579
|
-
// eslint-disable-next-line no-undef
|
|
580
|
-
MediaUtil.createMediaStream = sinon.stub().returns(new MediaStream([fakeMediaTrack()]));
|
|
581
477
|
});
|
|
582
|
-
|
|
583
478
|
describe('#enableBNR', () => {
|
|
584
479
|
it('should have #enableBnr', () => {
|
|
585
480
|
assert.exists(meeting.enableBNR);
|
|
@@ -594,26 +489,14 @@ describe('plugin-meetings', () => {
|
|
|
594
489
|
});
|
|
595
490
|
|
|
596
491
|
describe('after audio attached to meeting', () => {
|
|
492
|
+
let handleClientRequest;
|
|
493
|
+
|
|
597
494
|
beforeEach(async () => {
|
|
598
495
|
await meeting.getMediaStreams();
|
|
599
496
|
await meeting.addMedia();
|
|
600
497
|
});
|
|
601
498
|
|
|
602
|
-
it('should return true for appropriate sample rate', async () => {
|
|
603
|
-
const response = await meeting.enableBNR();
|
|
604
|
-
|
|
605
|
-
assert(Metrics.sendBehavioralMetric.calledOnce);
|
|
606
|
-
assert.calledWith(
|
|
607
|
-
Metrics.sendBehavioralMetric,
|
|
608
|
-
BEHAVIORAL_METRICS.ENABLE_BNR_SUCCESS,
|
|
609
|
-
);
|
|
610
|
-
|
|
611
|
-
assert.equal(response, true);
|
|
612
|
-
});
|
|
613
|
-
|
|
614
499
|
it('should throw error if meeting audio is muted', async () => {
|
|
615
|
-
await meeting.getMediaStreams();
|
|
616
|
-
await meeting.addMedia();
|
|
617
500
|
const handleClientRequest = (meeting, mute) => {
|
|
618
501
|
meeting.mediaProperties.audioTrack.enabled = !mute;
|
|
619
502
|
|
|
@@ -621,82 +504,53 @@ describe('plugin-meetings', () => {
|
|
|
621
504
|
};
|
|
622
505
|
const isMuted = () => !meeting.mediaProperties.audioTrack.enabled;
|
|
623
506
|
|
|
507
|
+
meeting.locusInfo.parsedLocus = {self: {state: 'JOINED'}};
|
|
624
508
|
meeting.mediaId = 'mediaId';
|
|
625
509
|
meeting.audio = {handleClientRequest, isMuted};
|
|
626
|
-
meeting.locusInfo.parsedLocus = {self: {state: 'JOINED'}};
|
|
627
510
|
await meeting.muteAudio();
|
|
628
511
|
await meeting.enableBNR().catch((err) => {
|
|
629
|
-
assert(Metrics.sendBehavioralMetric.calledOnce);
|
|
630
|
-
assert.calledWith(
|
|
631
|
-
Metrics.sendBehavioralMetric,
|
|
632
|
-
BEHAVIORAL_METRICS.ENABLE_BNR_FAILURE, {
|
|
633
|
-
reason: err.message,
|
|
634
|
-
stack: err.stack
|
|
635
|
-
}
|
|
636
|
-
);
|
|
637
512
|
assert.equal(err.message, 'Cannot enable BNR while meeting is muted');
|
|
638
513
|
});
|
|
639
514
|
});
|
|
640
515
|
|
|
641
|
-
it('should
|
|
642
|
-
|
|
643
|
-
|
|
644
|
-
|
|
645
|
-
readyState: 'live',
|
|
646
|
-
getSettings: () => ({
|
|
647
|
-
sampleRate: 49000
|
|
648
|
-
})
|
|
649
|
-
});
|
|
516
|
+
it('should return true on enable bnr success', async () => {
|
|
517
|
+
handleClientRequest = sinon.stub().returns(Promise.resolve(true));
|
|
518
|
+
meeting.effects = {handleClientRequest};
|
|
519
|
+
const response = await meeting.enableBNR();
|
|
650
520
|
|
|
651
|
-
|
|
652
|
-
|
|
653
|
-
// eslint-disable-next-line no-undef
|
|
654
|
-
MediaUtil.createMediaStream = sinon.stub().returns(new MediaStream([fakeMediaTrack()]));
|
|
655
|
-
|
|
656
|
-
await meeting.enableBNR()
|
|
657
|
-
.then(() => {
|
|
658
|
-
assert.fail('The expected Error was not thrown.');
|
|
659
|
-
})
|
|
660
|
-
.catch((err) => {
|
|
661
|
-
assert(Metrics.sendBehavioralMetric.calledOnce);
|
|
662
|
-
assert.calledWith(
|
|
663
|
-
Metrics.sendBehavioralMetric,
|
|
664
|
-
BEHAVIORAL_METRICS.ENABLE_BNR_FAILURE, {
|
|
665
|
-
reason: err.message,
|
|
666
|
-
stack: err.stack
|
|
667
|
-
}
|
|
668
|
-
);
|
|
669
|
-
assert.equal(err.message, 'Sample rate of 49000 is not supported.');
|
|
670
|
-
});
|
|
521
|
+
assert.equal(response, true);
|
|
671
522
|
});
|
|
672
523
|
});
|
|
673
524
|
});
|
|
674
525
|
|
|
675
526
|
describe('#disableBNR', () => {
|
|
676
|
-
|
|
677
|
-
|
|
678
|
-
|
|
679
|
-
|
|
527
|
+
describe('before audio attached to meeting', () => {
|
|
528
|
+
it('should have #disableBnr', () => {
|
|
529
|
+
assert.exists(meeting.disableBNR);
|
|
530
|
+
});
|
|
680
531
|
|
|
681
|
-
|
|
682
|
-
|
|
532
|
+
it('should throw no audio error', async () => {
|
|
533
|
+
await meeting.disableBNR().catch((err) => {
|
|
534
|
+
assert.equal(err.toString(), 'Error: Meeting doesn\'t have an audioTrack attached');
|
|
535
|
+
});
|
|
536
|
+
});
|
|
683
537
|
});
|
|
538
|
+
describe('after audio attached to meeting', () => {
|
|
539
|
+
beforeEach(async () => {
|
|
540
|
+
await meeting.getMediaStreams();
|
|
541
|
+
await meeting.addMedia();
|
|
542
|
+
});
|
|
684
543
|
|
|
685
|
-
|
|
686
|
-
|
|
687
|
-
const response = await meeting.disableBNR();
|
|
544
|
+
let handleClientRequest;
|
|
545
|
+
let isBnrEnabled;
|
|
688
546
|
|
|
689
|
-
|
|
690
|
-
|
|
547
|
+
it('should return true on disable bnr success', async () => {
|
|
548
|
+
handleClientRequest = sinon.stub().returns(Promise.resolve(true));
|
|
549
|
+
isBnrEnabled = sinon.stub().returns(Promise.resolve(true));
|
|
550
|
+
meeting.effects = {handleClientRequest, isBnrEnabled};
|
|
551
|
+
const response = await meeting.disableBNR();
|
|
691
552
|
|
|
692
|
-
|
|
693
|
-
await meeting.disableBNR().catch((err) => {
|
|
694
|
-
assert(Metrics.sendBehavioralMetric.calledOnce);
|
|
695
|
-
assert.calledWith(
|
|
696
|
-
Metrics.sendBehavioralMetric,
|
|
697
|
-
BEHAVIORAL_METRICS.DISABLE_BNR_FAILURE,
|
|
698
|
-
);
|
|
699
|
-
assert.equal(err.message, 'Can not disable as BNR is not enabled');
|
|
553
|
+
assert.equal(response, true);
|
|
700
554
|
});
|
|
701
555
|
});
|
|
702
556
|
});
|