gecko-dev/browser/components/loop/test/standalone/multiplexGum_test.js
Dan Mosedale 6a56092839 Bug 1093931 - Update Loop mocha unit test framework to v2.0.1, which supports Promises, r=Standard8
--HG--
rename : browser/components/loop/test/shared/vendor/mocha-1.17.1.css => browser/components/loop/test/shared/vendor/mocha-2.0.1.css
rename : browser/components/loop/test/shared/vendor/mocha-1.17.1.js => browser/components/loop/test/shared/vendor/mocha-2.0.1.js
2014-11-07 13:59:09 -08:00

366 lines
12 KiB
JavaScript

/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/. */
/*global loop, sinon, it, beforeEach, afterEach, describe*/
var expect = chai.expect;
describe("loop.standaloneMedia._MultiplexGum", function() {
"use strict";
var defaultGum =
navigator.getUserMedia ||
navigator.mozGetUserMedia ||
navigator.webkitGetUserMedia ||
(window["TBPlugin"] && TBPlugin.getUserMedia);
var sandbox;
var multiplexGum;
beforeEach(function() {
sandbox = sinon.sandbox.create();
multiplexGum = new loop.standaloneMedia._MultiplexGum();
loop.standaloneMedia.setSingleton(multiplexGum);
});
afterEach(function() {
sandbox.restore();
});
describe("#constructor", function() {
it("pending should default to false", function() {
expect(multiplexGum.userMedia.pending).to.equal(false);
});
});
describe("default getUserMedia", function() {
it("should call getPermsAndCacheMedia", function() {
var fakeOptions = {audio: true, video: true};
var successCB = function() {};
var errorCB = function() {};
sandbox.stub(navigator, "originalGum");
sandbox.stub(loop.standaloneMedia._MultiplexGum.prototype,
"getPermsAndCacheMedia");
multiplexGum = new loop.standaloneMedia._MultiplexGum();
defaultGum(fakeOptions, successCB, errorCB);
sinon.assert.calledOnce(multiplexGum.getPermsAndCacheMedia);
sinon.assert.calledWithExactly(multiplexGum.getPermsAndCacheMedia,
fakeOptions, successCB, errorCB);
});
});
describe("#getPermsAndCacheMedia", function() {
beforeEach(function() {
sandbox.stub(navigator, "originalGum");
});
it("should change pending to true", function() {
multiplexGum.getPermsAndCacheMedia();
expect(multiplexGum.userMedia.pending).to.equal(true);
});
it("should call originalGum", function() {
multiplexGum.getPermsAndCacheMedia();
sinon.assert.calledOnce(navigator.originalGum);
});
it("should reset the pending state when the error callback is called",
function(done) {
var fakeError = new Error();
navigator.originalGum.callsArgWith(2, fakeError);
multiplexGum.getPermsAndCacheMedia(null, null, function onError(error) {
expect(multiplexGum.userMedia.pending).to.equal(false);
done();
});
});
it("should reset the pending state when the success callback is called",
function(done) {
var fakeLocalStream = {};
navigator.originalGum.callsArgWith(1, fakeLocalStream);
multiplexGum.getPermsAndCacheMedia(null,
function onSuccess(localStream) {
expect(multiplexGum.userMedia.pending).to.equal(false);
done();
}, null);
});
it("should call the error callback when originalGum calls back an error",
function(done) {
var fakeError = new Error();
navigator.originalGum.callsArgWith(2, fakeError);
multiplexGum.getPermsAndCacheMedia(null, null, function onError(error) {
expect(error).to.eql(fakeError);
done();
});
});
it("should propagate the success callback when originalGum succeeds",
function(done) {
var fakeLocalStream = {};
navigator.originalGum.callsArgWith(1, fakeLocalStream);
multiplexGum.getPermsAndCacheMedia(null,
function onSuccess(localStream) {
expect(localStream).to.eql(fakeLocalStream);
done();
}, null);
});
it("should call the success callback when the stream is cached",
function(done) {
var fakeLocalStream = {};
multiplexGum.userMedia.localStream = fakeLocalStream;
sinon.assert.notCalled(navigator.originalGum);
multiplexGum.getPermsAndCacheMedia(null,
function onSuccess(localStream) {
expect(localStream).to.eql(fakeLocalStream);
done();
}, null);
});
it("should call the error callback when an error is cached",
function(done) {
var fakeError = new Error();
multiplexGum.userMedia.error = fakeError;
sinon.assert.notCalled(navigator.originalGum);
multiplexGum.getPermsAndCacheMedia(null, null, function onError(error) {
expect(error).to.eql(fakeError);
done();
});
});
it("should clear the error when success is called back", function(done) {
var fakeError = new Error();
var fakeLocalStream = {};
multiplexGum.userMedia.localStream = fakeLocalStream;
multiplexGum.userMedia.error = fakeError;
multiplexGum.getPermsAndCacheMedia(null, function onSuccess(localStream) {
expect(multiplexGum.userMedia.error).to.not.eql(fakeError);
expect(localStream).to.eql(fakeLocalStream);
done();
}, null);
});
it("should call all success callbacks when success is achieved",
function(done) {
var fakeLocalStream = {};
var calls = 0;
// Async is needed so that the callbacks can be queued up.
navigator.originalGum.callsArgWithAsync(1, fakeLocalStream);
multiplexGum.getPermsAndCacheMedia(null, function onSuccess(localStream) {
calls += 1;
expect(localStream).to.eql(fakeLocalStream);
}, null);
expect(multiplexGum.userMedia).to.have.property('pending', true);
multiplexGum.getPermsAndCacheMedia(null, function onSuccess(localStream) {
calls += 10;
expect(localStream).to.eql(fakeLocalStream);
expect(calls).to.equal(11);
done();
}, null);
});
it("should call all error callbacks when error is encountered",
function(done) {
var fakeError = new Error();
var calls = 0;
// Async is needed so that the callbacks can be queued up.
navigator.originalGum.callsArgWithAsync(2, fakeError);
multiplexGum.getPermsAndCacheMedia(null, null, function onError(error) {
calls += 1;
expect(error).to.eql(fakeError);
});
expect(multiplexGum.userMedia).to.have.property('pending', true);
multiplexGum.getPermsAndCacheMedia(null, null, function onError(error) {
calls += 10;
expect(error).to.eql(fakeError);
expect(calls).to.eql(11);
done();
});
});
it("should not call a getPermsAndCacheMedia success callback at the time" +
" of gUM success callback fires",
function() {
var fakeLocalStream = {};
multiplexGum.userMedia.localStream = fakeLocalStream;
navigator.originalGum.callsArgWith(1, fakeLocalStream);
var calledOnce = false;
var promiseCalledOnce = new Promise(function(resolve, reject) {
multiplexGum.getPermsAndCacheMedia(null,
function gPACMSuccess(localStream) {
expect(localStream).to.eql(fakeLocalStream);
expect(multiplexGum.userMedia).to.have.property('pending', false);
expect(multiplexGum.userMedia.successCallbacks.length).to.equal(0);
if (calledOnce) {
sinon.assert.fail("original callback was called twice");
}
calledOnce = true;
resolve();
}, function() {
sinon.assert.fail("error callback should not have fired");
reject();
});
});
return promiseCalledOnce.then(function() {
defaultGum(null, function gUMSuccess(localStream2) {
expect(localStream2).to.eql(fakeLocalStream);
expect(multiplexGum.userMedia).to.have.property('pending', false);
expect(multiplexGum.userMedia.successCallbacks.length).to.equal(0);
});
});
});
it("should not call a getPermsAndCacheMedia error callback when the " +
" gUM error callback fires",
function() {
var fakeError = "monkeys ate the stream";
multiplexGum.userMedia.error = fakeError;
navigator.originalGum.callsArgWith(2, fakeError);
var calledOnce = false;
var promiseCalledOnce = new Promise(function(resolve, reject) {
multiplexGum.getPermsAndCacheMedia(null, function() {
sinon.assert.fail("success callback should not have fired");
reject();
}, function gPACMError(errString) {
expect(errString).to.eql(fakeError);
expect(multiplexGum.userMedia).to.have.property('pending', false);
if (calledOnce) {
sinon.assert.fail("original error callback was called twice");
}
calledOnce = true;
resolve();
});
});
return promiseCalledOnce.then(function() {
defaultGum(null, function() {},
function gUMError(errString) {
expect(errString).to.eql(fakeError);
expect(multiplexGum.userMedia).to.have.property('pending', false);
});
});
});
it("should call the success callback with a new stream, " +
" when a new stream is available",
function(done) {
var endedStream = {ended: true};
var newStream = {};
multiplexGum.userMedia.localStream = endedStream;
navigator.originalGum.callsArgWith(1, newStream);
multiplexGum.getPermsAndCacheMedia(null, function onSuccess(localStream) {
expect(localStream).to.eql(newStream);
done();
}, null);
});
});
describe("#reset", function () {
it("should reset all userMedia state to default", function() {
// If userMedia is defined, then it needs to have all of
// the properties that multipleGum will depend on. It is
// easier to simply delete the object than to setup a fake
// state of the object.
delete multiplexGum.userMedia;
multiplexGum.reset();
expect(multiplexGum.userMedia).to.deep.equal({
error: null,
localStream: null,
pending: false,
errorCallbacks: [],
successCallbacks: [],
});
});
it("should call all queued error callbacks with 'PERMISSION_DENIED'",
function(done) {
sandbox.stub(navigator, "originalGum");
multiplexGum.getPermsAndCacheMedia(null, function(localStream) {
sinon.assert.fail(
"The success callback shouldn't be called due to reset");
}, function(error) {
expect(error).to.equal("PERMISSION_DENIED");
done();
});
multiplexGum.reset();
});
it("should call MST.stop() on the stream tracks", function() {
var stopStub = sandbox.stub();
multiplexGum.userMedia.localStream = {stop: stopStub};
multiplexGum.reset();
sinon.assert.calledOnce(stopStub);
});
it("should not call MST.stop() on the stream tracks if .stop() doesn't exist",
function() {
multiplexGum.userMedia.localStream = {};
try {
multiplexGum.reset();
} catch (ex) {
sinon.assert.fail(
"reset shouldn't throw when a stream doesn't implement stop(): "
+ ex);
}
});
it("should not get stuck in recursion if the error callback calls 'reset'",
function() {
sandbox.stub(navigator, "originalGum");
navigator.originalGum.callsArgWith(2, "PERMISSION_DENIED");
var calledOnce = false;
multiplexGum.getPermsAndCacheMedia(null, null, function() {
if (calledOnce) {
sinon.assert.fail("reset should only be called once");
}
calledOnce = true;
multiplexGum.reset.bind(multiplexGum)();
});
});
it("should not get stuck in recursion if the success callback calls 'reset'",
function() {
sandbox.stub(navigator, "originalGum");
navigator.originalGum.callsArgWith(1, {});
var calledOnce = false;
multiplexGum.getPermsAndCacheMedia(null, function() {
calledOnce = true;
multiplexGum.reset.bind(multiplexGum)();
}, function() {
if (calledOnce) {
sinon.assert.fail("reset should only be called once");
}
calledOnce = true;
});
});
});
});