New Case Study:See how Anthropic automated 95% of dependency reviews with Socket.Learn More
Socket
Sign inDemoInstall
Socket

webrtc-troubleshoot

Package Overview
Dependencies
Maintainers
2
Versions
96
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

webrtc-troubleshoot - npm Package Compare versions

Comparing version 8.1.1 to 9.0.0

webpack.config.js

46

package.json
{
"name": "webrtc-troubleshoot",
"version": "8.1.1",
"version": "9.0.0",
"description": "A way to add webrtc troubleshooting to your app",
"main": "src/index.js",
"license": "MIT",
"config": {

@@ -10,13 +11,6 @@ "report": "report --reporter=lcov --reporter=cobertura"

"scripts": {
"browserify": "browserify -t [ babelify --presets [ es2015 ] ] --s WebRTCTroubleshooter src/index.js -o dist/webrtc-troubleshooter.bundle.js",
"uglify": "uglifyjs dist/webrtc-troubleshooter.bundle.js -o dist/webrtc-troubleshooter.bundle.js",
"build": "npm run browserify && npm run uglify",
"lint": "semistandard",
"lint:fix": "semistandard --fix",
"unit-test": "nyc ava test/unit/*.js",
"postunit-test": "nyc $npm_package_config_report",
"unit-test-file": "ava FILE=process.env.file test/unit/${FILE}",
"coverage": "nyc ava test/unit/*.js",
"coveralls": "cat ./coverage/lcov.info | coveralls",
"test": "npm run lint && npm run unit-test"
"build": "webpack --env=prod --progress --profile --colors",
"unit-test": "nyc --reporter=lcov --reporter=cobertura ava test/unit/*.js",
"test": "semistandard && npm run unit-test && npm run report",
"report": "nyc report"
},

@@ -28,24 +22,22 @@ "repository": "https://github.com/mypurecloud/webrtc-troubleshooter",

"devDependencies": {
"ava": "^0.19.1",
"babel-cli": "^6.22.2",
"babel-preset-es2015": "^6.22.0",
"babelify": "^7.2.0",
"browser-env": "^2.0.31",
"browserify": "^14.0.0",
"coveralls": "^2.13.1",
"ember-cli-github-pages": "^0.1.2",
"nyc": "^10.3.2",
"semistandard": "^10.0.0",
"sinon": "^2.2.0",
"uglify-js": "^2.7.3",
"ava": "^0.25.0",
"babel-core": "^6.25.0",
"babel-loader": "^7.1.1",
"babel-preset-env": "^1.6.1",
"browser-env": "^3.1.0",
"nyc": "^13.0.0",
"semistandard": "^12.0.1",
"sinon": "^2.3.8",
"webpack": "^4.16.2",
"webpack-cli": "^3.1.0",
"webrtc-adapter": "^6.1.5"
},
"dependencies": {
"localmedia": "^4.0.0",
"localmedia": "^5.0.0",
"rtcpeerconnection": "^8.0.1",
"webrtc-stats-gatherer": "^4.2.10"
"webrtc-stats-gatherer": "^6.0.2"
},
"babel": {
"presets": [
"es2015"
"env"
]

@@ -52,0 +44,0 @@ },

@@ -268,4 +268,4 @@ // adapted from https://github.com/webrtc/testrtc

if (!this.resolutionMatchesIndependentOfRotationOrCrop(
report.actualVideoWidth, report.actualVideoHeight, report.mandatoryWidth,
report.mandatoryHeight)) {
report.actualVideoWidth, report.actualVideoHeight, report.mandatoryWidth,
report.mandatoryHeight)) {
this.reportError(`Incorrect captured resolution. Expected ${report.mandatoryWidth} by ${report.mandatoryHeight} but got ${report.actualVideoWidth} by ${report.actualVideoHeight}`);

@@ -272,0 +272,0 @@ } else {

@@ -15,3 +15,3 @@ import TestSuite from './utils/TestSuite';

export default {
module.exports = {
TestSuite,

@@ -18,0 +18,0 @@ AudioTest,

// adapted from https://github.com/webrtc/testrtc
import WebrtcStatsGather from 'webrtc-stats-gatherer';
const WebrtcStatsGather = require('webrtc-stats-gatherer');
const PeerConnection = require('rtcpeerconnection');

@@ -4,0 +4,0 @@

import browserEnv from 'browser-env';
browserEnv();
class Listener {
constructor () {
this._listeners = {};
}
addEventListener (event, listener) {
this._listeners[event] = this._listeners[event] || [];
this._listeners[event].push(listener);
}
trigger (event, args) {
const listeners = this._listeners[event];
if (!listeners || listeners.length === 0) {
return;
}
listeners.forEach(l => l(...args));
}
}
global.RTCTrackEvent = class extends Listener {};
global.RTCDataChannel = class extends Listener {
constructor (label) {
super();
this.label = label;
}
};
global.RTCPeerConnection = class extends Listener {
addTrack () {}
addStream () {}
createOffer () { return Promise.resolve(); }
setLocalDescription () {}
setRemoteDescription () {}
createAnswer () { return Promise.resolve(); }
getStats () { return Promise.resolve(); }
createDataChannel (label) {
return new global.window.RTCDataChannel(label);
}
};
global.MediaTrack = class {
constructor (kind) {
this.kind = kind;
}
stop () {}
};
global.MediaStream = class {
constructor (constraints) {
this._tracks = [];
if (constraints.audio) {
this._tracks.push(new global.MediaTrack('audio'));
}
if (constraints.video) {
this._tracks.push(new global.MediaTrack('video'));
}
}
getTracks () {
return this._tracks;
}
getAudioTracks () {
return this._tracks.filter(t => t.kind === 'audio');
}
getVideoTracks () {
return this._tracks.filter(t => t.kind === 'video');
}
};
global.navigator = {
mediaDevices: {
getUserMedia: constraints => Promise.resolve(new global.MediaStream(constraints))
},
userAgent: 'NODE'
};
global.window = global;
import test from 'ava';
import AdvancedCameraTest from '../../src/diagnostics/AdvancedCameraTest';
import CameraResolutionTest from '../../src/diagnostics/CameraResolutionTest';
let CameraResolutionStub, options, advancedCameraTest;
test.beforeEach(() => {
CameraResolutionStub = {
resolutions: [
[320, 240]
],
start: Promise.resolve([320, 240]),
deferred: {
resolve: () => [320, 240],
reject: () => 'an error'
}
};
options = {
mediaStream: document.createElement('video').mediaStream,
duration: 5,
addTest: () => {},
runNextTest: () => {},
deferred: {
resolve: () => [320, 240],
reject: () => 'received error'
},
stopAllTests: () => {}
};
advancedCameraTest = new AdvancedCameraTest(options);
test('AdvancedCameraTest is a suite of 14 CameraResolutionTest tests', t => {
const options = { duration: 30 };
const advancedCameraTest = new AdvancedCameraTest(options);
t.is(advancedCameraTest.queue.length, 14);
advancedCameraTest.queue.forEach(cameraTest => {
t.is(cameraTest instanceof CameraResolutionTest, true);
t.is(cameraTest.options, options);
});
});
test('start() will return undefined if no more tests', async t => {
const actual = await advancedCameraTest.start.call(CameraResolutionStub);
t.is(actual, undefined);
});

@@ -5,34 +5,8 @@ import test from 'ava';

import AudioBandwidthTest from '../../src/diagnostics/AudioBandwidthTest';
import WebrtcCall from '../../src/utils/WebrtcCall';
let audioBandwidthTest, options;
test.beforeEach(() => {
options = {
mediaOptions: {
audio: {
deviceId: 'someAudioId'
}
},
iceConfig: {
iceServers: []
},
doGetUserMedia: () => Promise.resolve(document.createElement('audio')),
getDeviceName: () => {},
call: {
pc1: {
addTrack: sinon.stub()
},
establishConnection: () => Promise.resolve()
},
gatherStats: () => Promise.resolve('stats')
};
audioBandwidthTest = new AudioBandwidthTest(options);
});
test.after(() => {
delete global.RTCPeerConnection;
delete global.navigator;
delete global.document.documentElement.style.WebkitAppearance;
});
test('start() return error if iceConfig has no iceServers', async t => {
const audioBandwidthTest = new AudioBandwidthTest({
iceConfig: { iceServers: [] },
mediaOptions: { audio: true } });
try {

@@ -46,39 +20,17 @@ await audioBandwidthTest.start();

test('start() should call doGetUserMedia if there is iceServers and return error with results', async t => {
const options = {
options: {
mediaOptions: {
audio: {
deviceId: 'someAudioId'
}
},
iceConfig: {
iceServers: [{ server: '1' }]
}
},
doGetUserMedia: () => Promise.resolve(document.createElement('audio')),
runTest: () => {},
completed: () => {},
getResults: () => ['Some Audio'],
mediaOptions: {
audio: {
deviceId: 'someAudioId'
}
},
iceConfig: {
iceServers: [{ server: '1' }]
},
reject: () => 'return results and err'
};
const audioBandwidthTest = new AudioBandwidthTest(options);
// Mock out RTCPeerConnection for node runtime.
global.RTCPeerConnection = () => {
return {
addEventListener: () => {}
};
};
const actual = await audioBandwidthTest.start.call(options);
t.is(actual, 'return results and err');
const mediaSpy = sinon.spy(global.navigator.mediaDevices, 'getUserMedia');
const audioBandwidthTest = new AudioBandwidthTest({
iceConfig: { iceServers: [{urls: []}] },
mediaOptions: { audio: true }
});
audioBandwidthTest.start();
sinon.assert.calledOnce(mediaSpy);
global.navigator.mediaDevices.getUserMedia.restore();
});
test('getResults() should return object with log, constraints, and stats', t => {
const audioBandwidthTest = new AudioBandwidthTest({
iceConfig: { iceServers: [{urls: []}] },
mediaOptions: { audio: { deviceId: 'someAudioId' } }
});
const actual = audioBandwidthTest.getResults();

@@ -94,2 +46,6 @@ const expected = {

test('addLog() should push message to the log', t => {
const audioBandwidthTest = new AudioBandwidthTest({
iceConfig: { iceServers: [{urls: []}] },
mediaOptions: { audio: true }
});
audioBandwidthTest.addLog('info', { val: 'Test add log' });

@@ -100,42 +56,12 @@ audioBandwidthTest.addLog('error', 'my error');

test('doGetUserMedia() should return stream', async t => {
const options = {
options: {
mediaOptions: {
audio: {
deviceId: 'someAudioId'
}
},
iceConfig: {
iceServers: [{ server: '1' }]
}
},
doGetUserMedia: () => Promise.resolve(document.createElement('audio')),
runTest: () => {},
completed: () => {},
getResults: () => ['Some Audio'],
mediaOptions: {
audio: {
deviceId: 'someAudioId'
}
},
iceConfig: {
iceServers: [{ server: '1' }]
},
reject: () => 'return results and err'
};
const audioBandwidthTest = new AudioBandwidthTest(options);
global.navigator = {
mediaDevices: {
getUserMedia: (constraints) => Promise.resolve(constraints)
}
};
let audioElement = document.createElement('audio');
audioElement.src = `data:audio/x-wav;base64,${new Buffer('wave')}>`;
audioElement.getAudioTracks = () => ['track1', 'track2'];
const actual = await audioBandwidthTest.doGetUserMedia(audioElement);
t.truthy(actual.getAudioTracks(), ['track1', 'track2']);
test('doGetUserMedia() should return add logs with the track label', async t => {
t.plan(0);
// todo
});
test('getDeviceName() should return null if tracks are empty', t => {
const audioBandwidthTest = new AudioBandwidthTest({
iceConfig: { iceServers: [{urls: []}] },
mediaOptions: { audio: true }
});
t.is(audioBandwidthTest.getDeviceName([]), null);

@@ -145,47 +71,41 @@ });

test('getDeviceName() should return label of first track if not empty', t => {
const audioBandwidthTest = new AudioBandwidthTest({
iceConfig: { iceServers: [{urls: []}] },
mediaOptions: { audio: true }
});
const actual = audioBandwidthTest.getDeviceName([
{
label: 'Mommas don\'t let your babies grow up to be cowboys'
label: 'Plantronics'
}
]);
const expected = 'Mommas don\'t let your babies grow up to be cowboys';
const expected = 'Plantronics';
t.is(actual, expected);
});
test('setupCall() should call establishConnection function and addLog function', t => {
const options = {
mediaOptions: {
audio: {
deviceId: 'someAudioId'
}
},
iceConfig: {
iceServers: []
},
doGetUserMedia: () => Promise.resolve(document.createElement('audio')),
getDeviceName: () => {},
call: {
pc1: {
addTrack: sinon.stub()
},
establishConnection: () => Promise.resolve()
},
addLog: sinon.stub()
};
const audioBandwidthTest = new AudioBandwidthTest(options);
t.notThrows(() => audioBandwidthTest.setupCall.apply(options, [
{
getTracks () { return this.getAudioTracks(); },
getAudioTracks: () => {
return [
{
track: 'track1'
}
];
}
}
]));
test('setupCall() should call establishConnection function and addLog function', async t => {
const audioBandwidthTest = new AudioBandwidthTest({
iceConfig: { iceServers: [{urls: []}] },
mediaOptions: { audio: true }
});
audioBandwidthTest.call = new WebrtcCall(audioBandwidthTest.options.iceConfig, audioBandwidthTest.logger);
sinon.stub(audioBandwidthTest.call, 'establishConnection').returns(Promise.resolve());
sinon.stub(audioBandwidthTest.call.pc1.pc, 'addTrack');
const mockTrack = new global.MediaStream({ audio: true });
await audioBandwidthTest.setupCall(mockTrack);
sinon.assert.calledOnce(audioBandwidthTest.call.pc1.pc.addTrack);
sinon.assert.calledOnce(audioBandwidthTest.call.establishConnection);
t.is(audioBandwidthTest.localTrack, mockTrack.getTracks()[0]);
});
test('runTest() should run gatherStats function', async t => {
const audioBandwidthTest = new AudioBandwidthTest({
iceConfig: { iceServers: [{urls: []}] },
mediaOptions: { audio: true }
});
audioBandwidthTest.durationMs = 4;
sinon.stub(audioBandwidthTest, 'gatherStats').callsFake(() => {
audioBandwidthTest.destroy();
});
sinon.stub(audioBandwidthTest, 'gotStats');
audioBandwidthTest.gatherStats = () => Promise.resolve({ prop: 'some Properties' });

@@ -197,133 +117,87 @@ const actual = await audioBandwidthTest.runTest();

test('gatherStats() should resolve if starttime difference is large enough between durationMs', t => {
return audioBandwidthTest.gatherStats.call({
startTime: 100,
durationMs: 900
}).then(() => {
t.truthy(true);
test('gatherStats() should resolve if starttime difference is large enough between durationMs', async t => {
const audioBandwidthTest = new AudioBandwidthTest({
iceConfig: { iceServers: [{urls: []}] },
mediaOptions: { audio: true }
});
audioBandwidthTest.call = { pc1: { getStats: sinon.stub() } };
await audioBandwidthTest.gatherStats();
sinon.assert.notCalled(audioBandwidthTest.call.pc1.getStats);
});
test('gatherStats() should call gotStats', t => {
const context = {
call: {
pc1: {
getStats: () => Promise.resolve('value')
}
},
localTrack: [
{
track: 'track1'
}
],
gotStats: sinon.stub()
};
return audioBandwidthTest.gatherStats.call(context).then(() => {
t.is(context.gotStats.called, true);
test('gatherStats() should call gotStats', async t => {
const audioBandwidthTest = new AudioBandwidthTest({
iceConfig: { iceServers: [{urls: []}] },
mediaOptions: { audio: true }
});
const mockStats = {};
audioBandwidthTest.startTime = new Date();
audioBandwidthTest.call = new WebrtcCall(audioBandwidthTest.options.iceConfig, audioBandwidthTest.logger);
sinon.stub(audioBandwidthTest.call.pc1, 'getStats').returns(Promise.resolve(mockStats));
sinon.stub(audioBandwidthTest, 'gotStats');
await audioBandwidthTest.gatherStats();
sinon.assert.calledOnce(audioBandwidthTest.gotStats);
sinon.assert.calledWith(audioBandwidthTest.gotStats, mockStats);
});
test('gotStats() calls rttStats and bweStats if availableOutgoingBitrate and totalRoundTripTime', t => {
global.document.documentElement.style.WebkitAppearance = '';
global.navigator.userAgent = 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/59.0.3071.36 Safari/537.36';
const context = {
addLog: () => {},
rttStats: {
add: sinon.stub()
},
bweStats: {
add: sinon.stub()
},
runTest: () => Promise.resolve()
};
return audioBandwidthTest.gotStats.call(context, [{
type: 'ssrc',
mediaType: 'audio',
googRtt: 10,
test('gotStats() calls rttStats and bweStats if availableOutgoingBitrate and roundTripTime', async t => {
const audioBandwidthTest = new AudioBandwidthTest({
iceConfig: { iceServers: [{urls: []}] },
mediaOptions: { audio: true }
});
sinon.stub(audioBandwidthTest.rttStats, 'add');
sinon.stub(audioBandwidthTest.bweStats, 'add');
sinon.stub(audioBandwidthTest, 'runTest');
await audioBandwidthTest.gotStats([{
roundTripTime: '30',
timestamp: new Date(),
googJitterReceived: 3,
packetsLost: 0,
packetsSent: 1,
totalRoundTripTime: 55,
availableOutgoingBitrate: 2000
}]).then(() => {
t.is(context.rttStats.add.called, true);
t.is(context.bweStats.add.called, true);
});
availableOutgoingBitrate: '2000'
}]);
sinon.assert.calledOnce(audioBandwidthTest.rttStats.add);
sinon.assert.calledWith(audioBandwidthTest.rttStats.add, sinon.match.date, 30);
sinon.assert.calledOnce(audioBandwidthTest.bweStats.add);
sinon.assert.calledWith(audioBandwidthTest.bweStats.add, sinon.match.date, 2000);
});
test('gotStats() calls rttStats if totalRoundTripTime', t => {
const context = {
addLog: () => {},
rttStats: {
add: sinon.stub()
},
bweStats: {
add: sinon.stub()
},
runTest: () => Promise.resolve()
};
return audioBandwidthTest.gotStats.call(context, [{
id: 'outbound_rtcp_audio_',
jitter: 'too much caffeine, now I have the jitters',
packetsLost: 0,
bytesSent: 25,
timestamp: new Date(),
packetsSent: 3,
totalRoundTripTime: 55
}]).then(() => {
t.is(context.rttStats.add.called, true);
t.is(context.bweStats.add.called, false);
test('gotStats() calls rttStats if totalRoundTripTime', async t => {
const audioBandwidthTest = new AudioBandwidthTest({
iceConfig: { iceServers: [{urls: []}] },
mediaOptions: { audio: true }
});
sinon.stub(audioBandwidthTest.rttStats, 'add');
sinon.stub(audioBandwidthTest, 'runTest');
await audioBandwidthTest.gotStats([{
totalRoundTripTime: '30',
timestamp: new Date()
}]);
sinon.assert.calledOnce(audioBandwidthTest.rttStats.add);
sinon.assert.calledWith(audioBandwidthTest.rttStats.add, sinon.match.date, 30);
});
test('completed() call addLog multiple times and return results', t => {
t.plan(2);
const context = {
addLog: sinon.stub(),
stats: {
mbpsAvg: 5,
mbpsMax: 10
},
bweStats: {
getAverage: () => 25,
getMax: () => 19
},
rttStats: {
getAverage: () => 23,
getMax: () => 50
},
packetsSent: 11,
packetsLost: 2,
jitter: 'some Jitters',
results: {
id: 5,
props: ['one', 'two']
}
};
const actual = audioBandwidthTest.completed.call(context);
t.is(context.addLog.callCount, 6);
t.is(actual.id, 5);
const audioBandwidthTest = new AudioBandwidthTest({
iceConfig: { iceServers: [{urls: []}] },
mediaOptions: { audio: true }
});
sinon.stub(audioBandwidthTest, 'addLog');
const mockResults = {};
audioBandwidthTest.results = mockResults;
const results = audioBandwidthTest.completed();
t.is(results, mockResults);
sinon.assert.callCount(audioBandwidthTest.addLog, 6);
});
test('destroy() calls close and stop functions and then assigns null to call', t => {
const context = {
call: {
pc1: {
getLocalStreams: () => [
{
prop: 'someProp',
getTracks: () => [
{
stop: sinon.stub()
}
]
}
]
},
close: sinon.stub()
}
};
audioBandwidthTest.destroy.call(context);
t.is(context.call, null);
t.plan(2);
const audioBandwidthTest = new AudioBandwidthTest({
iceConfig: { iceServers: [{urls: []}] },
mediaOptions: { audio: true },
logger: { log () {}, error () {}, warn () {}, info () {} }
});
audioBandwidthTest.call = new WebrtcCall(audioBandwidthTest.options.iceConfig, audioBandwidthTest.logger);
sinon.stub(audioBandwidthTest.call, 'close').callsFake(() => t.pass());
audioBandwidthTest.destroy();
t.is(audioBandwidthTest.call, null);
});

@@ -6,25 +6,14 @@ import test from 'ava';

let LocalMediaStub;
test.beforeEach(() => {
LocalMediaStub = {
localMedia: {
start: sinon.stub(),
on: sinon.stub(),
stop: sinon.stub()
}
};
});
test('start() should start localMedia', t => {
const mediaStream = document.createElement('video').mediaStream;
const audioTest = new AudioTest(mediaStream);
audioTest.start.call(LocalMediaStub);
t.is(LocalMediaStub.localMedia.start.called, true);
const audioTest = new AudioTest();
sinon.stub(audioTest.localMedia, 'start');
audioTest.start();
sinon.assert.calledOnce(audioTest.localMedia.start);
});
test('destroy() should stop localMedia', t => {
const mediaStream = document.createElement('video').mediaStream;
const audioTest = new AudioTest(mediaStream);
audioTest.destroy.call(LocalMediaStub);
t.is(LocalMediaStub.localMedia.stop.called, true);
const audioTest = new AudioTest();
sinon.stub(audioTest.localMedia, 'stop');
audioTest.destroy();
sinon.assert.calledOnce(audioTest.localMedia.stop);
});

@@ -8,506 +8,75 @@ import test from 'ava';

test.beforeEach(() => {
const args = [
{
props: [
{
width: 10
},
{
height: 5
}
]
},
{
duration: 'too darn long',
logger: {
log: sinon.stub()
}
}
];
cameraResolutionTest = new CameraResolutionTest(...args);
cameraResolutionTest = new CameraResolutionTest([[320, 640]], {
duration: 30,
logger: { log () {}, warn () {}, info () {} }
});
});
test.after(() => {
delete global.RTCPeerConnection;
delete global.gotOffer;
test.serial('start() should call log function and startGetUserMedia and resolve with results if no error', async t => {
sinon.stub(cameraResolutionTest, 'startGetUserMedia').returns(Promise.resolve());
sinon.stub(cameraResolutionTest, 'getResults');
await cameraResolutionTest.start();
sinon.assert.calledOnce(cameraResolutionTest.startGetUserMedia);
sinon.assert.calledWith(cameraResolutionTest.startGetUserMedia, [320, 640]);
sinon.assert.calledOnce(cameraResolutionTest.getResults);
});
test('start() should call log function and startGetUserMedia and resolve with results if no error', async t => {
t.plan(2);
delete CameraResolutionTest.reject;
CameraResolutionTest.startGetUserMedia = (resolutions) => Promise.resolve(resolutions);
CameraResolutionTest.logger = {
log: sinon.stub()
};
CameraResolutionTest.resolutions = [
{
prop: 'someProp'
}
];
CameraResolutionTest.currentResolution = {
prop: 'someProp'
};
CameraResolutionTest.getResults = () => {
return {
log: 'blob stuff',
stats: [{ val: 'blah' }],
resolutions: [
{
height: 5
},
{
width: 23
}
],
duration: '5ms'
};
};
CameraResolutionTest.resolve = props => props;
CameraResolutionTest.hasError = false;
const actual = await cameraResolutionTest.start.call(CameraResolutionTest);
const expected = {
val: 'blah'
};
t.deepEqual(actual.stats[0], expected);
t.is(CameraResolutionTest.logger.log.called, true);
});
test('getResults() should return object with results', t => {
const context = {
log: 'log it baby',
stats: [
{
prop: 'random stats'
}
],
resolutions: [
{
width: 5
},
{
height: 4
}
],
duration: '10ms'
};
const actual = cameraResolutionTest.getResults.call(context);
const expected = '10ms';
t.is(actual.duration, expected);
const mockLog = ['foo', 'bar'];
const mockStats = { foo: 'bar' };
cameraResolutionTest.log = mockLog;
cameraResolutionTest.stats = mockStats;
const results = cameraResolutionTest.getResults();
t.deepEqual(results, {
log: cameraResolutionTest.log,
stats: cameraResolutionTest.stats,
resolutions: cameraResolutionTest.resolutions,
duration: cameraResolutionTest.duration
});
});
test('reportSuccess(str) should push string onto log and log message', t => {
const context = {
log: [],
logger: {
log: sinon.stub()
}
};
cameraResolutionTest.reportSuccess.call(context);
t.is(context.logger.log.called, true);
test.serial('reportSuccess(str) should push string onto log and log message', t => {
sinon.stub(cameraResolutionTest.logger, 'log');
cameraResolutionTest.log = [];
cameraResolutionTest.reportSuccess('test');
t.deepEqual(cameraResolutionTest.log, ['test']);
sinon.assert.calledOnce(cameraResolutionTest.logger.log);
});
test('reportError(str) should push error to log call logger.warn', t => {
const context = {
log: [],
logger: {
warn: sinon.stub()
}
};
cameraResolutionTest.reportError.call(context);
t.is(context.logger.warn.called, true);
test.serial('reportError(str) should push error to log call logger.warn', t => {
sinon.stub(cameraResolutionTest.logger, 'warn');
cameraResolutionTest.log = [];
cameraResolutionTest.reportError('test');
t.deepEqual(cameraResolutionTest.log, ['test']);
sinon.assert.calledOnce(cameraResolutionTest.logger.warn);
t.is(cameraResolutionTest.hasError, true);
});
test('reportInfo(str) should call logger.info', t => {
const context = {
logger: {
info: sinon.stub()
}
};
cameraResolutionTest.reportInfo.call(context);
t.is(context.logger.info.called, true);
sinon.stub(cameraResolutionTest.logger, 'info');
cameraResolutionTest.log = [];
cameraResolutionTest.reportInfo('test');
t.deepEqual(cameraResolutionTest.log, []);
sinon.assert.calledOnce(cameraResolutionTest.logger.info);
});
test('startGetUserMedia(resolution) should call getUserMedia and maybeContinueGetUserMedia if resolution length is greater than 1', t => {
global.navigator = {
mediaDevices: {
getUserMedia: constraints => {
constraints.getTracks = (track) => {
return [
{
stop: () => {}
}
];
};
return Promise.resolve(constraints);
}
}
};
const context = {
resolutions: [
{
width: 5
},
{
height: 6
}
],
reportSuccess: info => info,
maybeContinueGetUserMedia: sinon.stub()
};
cameraResolutionTest.startGetUserMedia.call(
context,
[
{
width: 5
},
{
height: 6
}
]
).then(() => {
t.is(context.maybeContinueGetUserMedia.called, true);
});
});
test.serial('startGetUserMedia should call getUserMedia and maybeContinueGetUserMedia if resolution length is greater than 1', async t => {
sinon.stub(cameraResolutionTest, 'maybeContinueGetUserMedia');
sinon.stub(cameraResolutionTest, 'collectAndAnalyzeStats');
test('startGetUserMedia(resolution) should call logger.log and collectAndAnalyzeStats if resolution is one', t => {
t.plan(2);
global.navigator = {
mediaDevices: {
getUserMedia: constraints => {
constraints.getTracks = (track) => {
return [
{
stop: () => {}
}
];
};
return Promise.resolve(constraints);
}
}
};
const context = {
resolutions: [],
logger: {
log: sinon.stub()
},
collectAndAnalyzeStats: (stream, resolutions) => resolutions
};
return cameraResolutionTest.startGetUserMedia.call(
context,
[
{
width: 5
},
{
height: 6
}
]
).then(info => {
t.is(context.logger.log.called, true);
t.deepEqual(info, [ { width: 5 }, { height: 6 } ]);
});
cameraResolutionTest.resolutions = [ [320, 640], [1080, 1300] ];
await cameraResolutionTest.startGetUserMedia([320, 640]);
sinon.assert.notCalled(cameraResolutionTest.collectAndAnalyzeStats);
sinon.assert.calledOnce(cameraResolutionTest.maybeContinueGetUserMedia);
});
test('maybeContinueGetUserMedia() should return results if currentResolution is equal to resolution', t => {
const context = {
currentResolution: 3,
resolutions: [
{
prop1: 'one'
},
{
prop2: 'two'
},
{
prop3: 'three'
}
],
getResults: () => {
return {
log: 'log it baby',
stats: [
{
prop: 'random stats'
}
],
resolutions: [
{
width: 5
},
{
height: 4
}
],
duration: '10ms'
};
}
};
const actual = cameraResolutionTest.maybeContinueGetUserMedia.call(context);
const expected = {
log: 'log it baby',
stats: [
{
prop: 'random stats'
}
],
resolutions: [
{
width: 5
},
{
height: 4
}
],
duration: '10ms'
};
t.deepEqual(actual, expected);
});
test.serial('startGetUserMedia should call logger.log and collectAndAnalyzeStats if resolution is one', async t => {
sinon.stub(cameraResolutionTest, 'maybeContinueGetUserMedia');
sinon.stub(cameraResolutionTest, 'collectAndAnalyzeStats');
test('maybeContinueGetUserMedia() should call this.startGetUserMedia if resolution and currentResolution are not equal', t => {
t.plan(0);
const context = {
currentResolution: 3,
resolutions: [
{
prop1: 'one'
},
{
prop2: 'two'
}
],
startGetUserMedia: resolution => Promise.resolve(resolution)
};
return cameraResolutionTest.maybeContinueGetUserMedia.call(context)
.then(resolution => resolution);
await cameraResolutionTest.startGetUserMedia([320, 640]);
sinon.assert.calledOnce(cameraResolutionTest.collectAndAnalyzeStats);
sinon.assert.notCalled(cameraResolutionTest.maybeContinueGetUserMedia);
});
test('collectAndAnalyzeStats(stream, resolution) should reportError and call maybeContinueGetUserMedia is tracks is less than 1', async t => {
const args = [
{
getVideoTracks: () => {
return [];
}
},
{}
];
const context = {
maybeContinueGetUserMedia: () => Promise.resolve([
{
width: 5
},
{
height: 6
}
]),
reportError: () => {}
};
const actual = await cameraResolutionTest.collectAndAnalyzeStats.apply(context, args);
const expected = [
{
width: 5
},
{
height: 6
}
];
t.deepEqual(actual, expected);
});
test('collectAndAnalyzeStats(stream, resolution) should return data with analyzeStats final call', async t => {
// Mock out RTCPeerConnection for node runtime.
global.RTCPeerConnection = () => {
return {
addEventListener: () => {},
addTrack: () => {},
createOffer: () => Promise.resolve(),
setLocalDescription: () => {},
setRemoteDescription: () => {},
createAnswer: () => Promise.resolve(),
gatherStats: () => {},
getStats: () => {
return {
then: () => {}
};
},
gotStats: () => {}
};
};
global.gotOffer = () => {};
const args = [
{
getTracks () { return this.getVideoTracks(); },
getVideoTracks: () => {
return [
{
addEventListener: () => {}
}
];
}
},
{}
];
const context = {
reportError: () => {},
endCall: () => {},
analyzeStats: () => {
return [
{
resolution: [
{
width: 5
},
{
height: 6
}
]
}
];
}
};
const actual = await cameraResolutionTest.collectAndAnalyzeStats.apply(context, args);
const expected = [
{
width: 5
},
{
height: 6
}
];
t.deepEqual(actual[0].resolution, expected);
});
test('analyzeStats should generate statsReport object and call testExpectations', t => {
const context = {
testExpectations: sinon.stub(),
isMuted: false,
extractEncoderSetupTime: () => {},
arrayAverage: () => {}
};
const args = {
resolution: [
{
width: 5
},
{
height: 6
}
],
videoElement: document.createElement('video'),
stream: {
getVideoTracks: () => {
return [
{
label: 'Johnny Walker'
}
];
}
},
frameChecker: {
frameStats: {
numFrames: 5,
numBlackFrames: 0,
numFrozenFrames: 0
}
},
stats: [
{
type: 'ssrc',
googFrameRateInput: 0,
googFrameRateSen: 5
}
]
};
const actual = cameraResolutionTest.analyzeStats.call(context, args);
t.is(actual.cameraName, 'Johnny Walker');
});
test('endCall() should call stop and close', t => {
const context = {
isShuttingDown: false
};
const args = [
{
close: sinon.stub()
},
{
getTracks: () => {
return [
{
stop: () => {}
}
];
}
}
];
cameraResolutionTest.endCall.apply(context, args);
t.is(args[0].close.called, true);
});
test('extractEncodeSetupTime() should annotate and return result', t => {
const stats = [
{
type: 'ssrc',
googFrameRateInput: 50
}
];
const statsCollectTime = [100];
const actual = JSON.parse(cameraResolutionTest.extractEncoderSetupTime(stats, statsCollectTime));
t.is(actual, 0);
});
test('resolutionMatchesIndependentOfRotationOrCrop() should evaulate to boolean from properties passed in', t => {
const args = [10, 15, 10, 15];
const actual = cameraResolutionTest.resolutionMatchesIndependentOfRotationOrCrop(...args);
t.is(actual, true);
t.is(cameraResolutionTest.resolutionMatchesIndependentOfRotationOrCrop([10, 15, 5, 5]), false);
});
test('testExpectations() should call reportSuccess twice if avgSentFbs is positive number and resolutions match', t => {
const context = {
reportInfo: sinon.stub(),
reportError: sinon.stub(),
reportSuccess: sinon.stub(),
resolutionMatchesIndependentOfRotationOrCrop: () => true
};
const report = {
number: 5,
notAvailableStatus: 'not here',
avgSentFps: 5
};
cameraResolutionTest.testExpectations.call(context, report);
t.is(context.reportSuccess.calledTwice, true);
});
test('testExpectations() should call reportError twice if avgSentFbs is less than 5 and resolutions do not match', t => {
const context = {
reportInfo: sinon.stub(),
reportError: sinon.stub(),
reportSuccess: sinon.stub(),
resolutionMatchesIndependentOfRotationOrCrop: () => false
};
const report = {
number: 5,
notAvailableStatus: 'not here',
avgSentFps: 3
};
cameraResolutionTest.testExpectations.call(context, report);
t.is(context.reportError.calledTwice, true);
});
test('testExpectations() should call reportInfo if avgSentFbs is not a number', t => {
const context = {
reportInfo: sinon.stub(),
reportError: sinon.stub(),
reportSuccess: sinon.stub(),
resolutionMatchesIndependentOfRotationOrCrop: () => false
};
const report = {
number: 5,
notAvailableStatus: 'not here',
avgSentFps: 'what'
};
cameraResolutionTest.testExpectations.call(context, report);
t.is(context.reportInfo.called, true);
});
test('arrayAverage() should compute array average', t => {

@@ -514,0 +83,0 @@ const actual = cameraResolutionTest.arrayAverage([1, 2, 3, 4, 5]);

@@ -9,4 +9,2 @@ import test from 'ava';

test.after(() => {
delete global.RTCPeerConnection;
delete global.dataChannel;
connectivityTest = null;

@@ -13,0 +11,0 @@ });

@@ -8,93 +8,34 @@ import test from 'ava';

test.beforeEach(() => {
dataThroughPutTest = new DataThroughPutTest();
dataThroughPutTest = new DataThroughPutTest({
iceServers: [],
logger: {
error: () => {}
}
});
});
test.after(() => {
delete global.RTCPeerConnection;
test.serial('start() should reject if there is now iceServers', t => {
return dataThroughPutTest.start().catch(() => t.pass());
});
test('start() should reject if there is now iceServers', async t => {
const context = {
options: {
iceServers: []
},
logger: {
error: () => {}
},
reject: sinon.stub()
};
await dataThroughPutTest.start.call(context);
t.is(context.reject.called, true);
test.serial('start() should setup webrtc call', async t => {
sinon.stub(dataThroughPutTest, 'sendingStep');
dataThroughPutTest.options.iceServers.push({});
dataThroughPutTest.start();
// todo: assertions about event listners n such
t.plan(0);
});
test('start() should setup webrtc call', async t => {
t.plan(2);
// Mock out RTCPeerConnection for node runtime.
global.RTCPeerConnection = () => {
return {
addEventListener: () => {},
addTrack: () => {},
createOffer: () => Promise.resolve(),
setLocalDescription: () => {},
setRemoteDescription: () => {},
createAnswer: () => Promise.resolve(),
gatherStats: () => {},
getStats: () => {
return {
then: () => {}
};
},
gotStats: () => {},
getRemoteStreams: () => {},
createDataChannel: () => {
return {
onmessage: null,
addEventListener: () => {}
};
},
offer: () => {}
};
test.serial('onReceiverChannel(event) should addEventListener', t => {
sinon.stub(dataThroughPutTest.onMessageReceived, 'bind');
const mockChannel = {
addEventListener: sinon.stub()
};
const context = {
options: {
iceServers: [
{
server1: 'server 1 here'
}
]
},
logger: {
error: () => {}
},
sendingStep: {
bind: sinon.stub()
},
onReceiverChannel: {
bind: sinon.stub()
}
};
await dataThroughPutTest.start.call(context);
t.is(context.sendingStep.bind.called, true);
t.is(context.onReceiverChannel.bind.called, true);
dataThroughPutTest.onReceiverChannel(mockChannel);
sinon.assert.calledOnce(dataThroughPutTest.onMessageReceived.bind);
sinon.assert.calledOnce(mockChannel.addEventListener);
});
test('onReceiverChannel(event) should addEventListener', t => {
test.serial('sendingStep() should send packets', t => {
const context = {
onMessageReceived: {
bind: sinon.stub()
}
};
dataThroughPutTest.onReceiverChannel.call(
context,
{
channel: {
addEventListener: () => {}
}
}
);
t.is(context.onMessageReceived.bind.called, true);
});
test('sendingStep() should send packets', t => {
const context = {
maxNumberOfPacketsToSend: 5,

@@ -114,3 +55,3 @@ senderChannel: {

test('onMessageReceived(event) should compute values but not resolve if now - this.lastBitrateMeasureTime >= 1000', t => {
test.serial('onMessageReceived(event) should compute values but not resolve if now - this.lastBitrateMeasureTime >= 1000', t => {
const context = {

@@ -138,11 +79,4 @@ lastBitrateMeasureTime: 0,

test('destroy() should call close', t => {
test.serial('destroy() should call close', t => {
t.plan(0);
const context = {
call: {
close: () => {}
},
throughputTimeout: 5
};
dataThroughPutTest.destroy.call(context);
});

@@ -9,12 +9,5 @@ import test from 'ava';

audioTest = new SymmetricNatTest();
window.RTCPeerConnection = class {
createOffer () {
return Promise.resolve({});
}
createDataChannel () {}
setLocalDescription () {}
};
});
test('should result in asymmetric if it gets a single srflx candidate', t => {
test.serial('should result in asymmetric if it gets a single srflx candidate', t => {
sinon.stub(window.RTCPeerConnection.prototype, 'setLocalDescription').callsFake(function () {

@@ -46,3 +39,4 @@ window.setTimeout(() => {

test('should result in noSrflx if it gets no candidates', t => {
test.serial('should result in noSrflx if it gets no candidates', t => {
window.RTCPeerConnection.prototype.setLocalDescription.restore();
sinon.stub(window.RTCPeerConnection.prototype, 'setLocalDescription').callsFake(function () {

@@ -60,3 +54,4 @@ window.setTimeout(() => {

test('should result in noSrflx if it gets only host candidates candidates', t => {
test.serial('should result in noSrflx if it gets only host candidates candidates', t => {
window.RTCPeerConnection.prototype.setLocalDescription.restore();
sinon.stub(window.RTCPeerConnection.prototype, 'setLocalDescription').callsFake(function () {

@@ -81,4 +76,5 @@ window.setTimeout(() => {

test('should result in noSrflx if it gets only host candidates candidates', t => {
test.serial('should result in noSrflx if it gets only host candidates candidates', t => {
const audioTest = new SymmetricNatTest();
window.RTCPeerConnection.prototype.setLocalDescription.restore();
sinon.stub(window.RTCPeerConnection.prototype, 'setLocalDescription').callsFake(function () {

@@ -103,4 +99,5 @@ window.setTimeout(() => {

test('should result in symmetric if it gets different ports for the same related port', t => {
test.serial('should result in symmetric if it gets different ports for the same related port', t => {
const audioTest = new SymmetricNatTest();
window.RTCPeerConnection.prototype.setLocalDescription.restore();
sinon.stub(window.RTCPeerConnection.prototype, 'setLocalDescription').callsFake(function () {

@@ -107,0 +104,0 @@ window.setTimeout(() => {

@@ -28,5 +28,5 @@ import test from 'ava';

return testSuite.start.call(context)
.then(results => {
t.deepEqual(results, [1, 2, 3]);
});
.then(results => {
t.deepEqual(results, [1, 2, 3]);
});
});

@@ -41,6 +41,6 @@

return testSuite.start.call(context)
.then(results => t.fail('should not get here'))
.catch(err => {
t.is(err.message, 'A test failure occurred');
});
.then(results => t.fail('should not get here'))
.catch(err => {
t.is(err.message, 'A test failure occurred');
});
});

@@ -47,0 +47,0 @@

@@ -22,3 +22,2 @@ import test from 'ava';

test.after(() => {
delete global.RTCPeerConnection;
delete global.navigator;

@@ -41,8 +40,2 @@ });

test('start() should call gotStream when providedStream and return results', async t => {
// Mock out RTCPeerConnection for node runtime.
global.RTCPeerConnection = function () {
return {
addEventListener: () => {}
};
};
const context = {

@@ -75,8 +68,2 @@ options: {

test('start() should call doGetUserMedia when not providedStream and return results', async t => {
// Mock out RTCPeerConnection for node runtime.
global.RTCPeerConnection = function () {
return {
addEventListener: () => {}
};
};
const context = {

@@ -106,8 +93,2 @@ options: {

test('start() should return error if hasError', async t => {
// Mock out RTCPeerConnection for node runtime.
global.RTCPeerConnection = function () {
return {
addEventListener: () => {}
};
};
const context = {

@@ -181,3 +162,3 @@ options: {

let audioElement = document.createElement('video');
audioElement.src = `data:audio/x-wav;base64,${new Buffer('wave')}>`;
audioElement.src = `data:audio/x-wav;base64,${new Buffer('wave')}>`; // eslint-disable-line
audioElement.getVideoTracks = () => ['track1', 'track2'];

@@ -209,28 +190,3 @@ const context = {

test('gotStream() should call establishConnect', t => {
const context = {
call: {
pc1: {
addTrack: sinon.stub()
},
establishConnection: () => Promise.resolve()
},
addLog: sinon.stub(),
gatherStats: () => Promise.resolve()
};
return videoBandwidthTest.gotStream.call(
context,
{
getTracks () { return this.getVideoTracks(); },
getVideoTracks: () => {
return [
{
prop: 'some prop'
}
];
}
}
).then(() => {
t.is(context.call.pc1.pc.addTrack.called, true);
t.is(context.addLog.called, true);
});
t.plan(0);
});

@@ -253,5 +209,5 @@

return videoBandwidthTest.gatherStats.call(context)
.then(val => {
t.is(val, 'completed');
});
.then(val => {
t.is(val, 'completed');
});
});

@@ -274,5 +230,5 @@

return videoBandwidthTest.gatherStats.call(context)
.then(val => {
t.is(context.gotStats.bind.called, true);
});
.then(val => {
t.is(context.gotStats.bind.called, true);
});
});

@@ -279,0 +235,0 @@

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc