test: add more test cases to reach a full code coverage.

- if the a browser global already exists, it should not be overridden
- use Object.defineProperty on the wrapped browser global
  (and test "has" for cached properties)
- delete a property defined with Object.defineProperty
- methods that are not wrapped are proxied correctly
- the special onMessage wrapper should not wrap a listener that is not
  a function
- test that a returned rejected Promise on the onMessage listener
  is turned in the parameter of the sendResponse callback
This commit is contained in:
Luca Greco 2016-10-11 16:39:13 +02:00
parent 92ccea2e15
commit 6cca044a5c
3 changed files with 129 additions and 7 deletions

View File

@ -11,4 +11,55 @@ describe("browser-polyfill", () => {
assert.equal(typeof window.browser, "object", "Got the window.browser object");
});
});
it("do not override the global browser namespace if it already exists", () => {
const fakeChrome = {
runtime: {lastError: null},
};
const fakeBrowser = {
mycustomns: {mykey: true},
};
return setupTestDOMWindow(fakeChrome, fakeBrowser).then(window => {
assert.deepEqual(window.browser, fakeBrowser,
"The existent browser has not been wrapped");
});
});
describe("browser wrapper", () => {
it("supports custom properties defined using Object.defineProperty", () => {
const fakeChrome = {};
return setupTestDOMWindow(fakeChrome).then(window => {
Object.defineProperty(window.browser, "myns", {
enumerable: true,
configurable: true,
value: {mykey: true},
});
assert.ok("myns" in window.browser, "The custom property exists");
assert.ok("mykey" in window.browser.myns,
"The content of the custom property exists");
assert.deepEqual(window.browser.myns, {mykey: true},
"The custom property has the expected content");
delete window.browser.myns;
assert.ok(!("myns" in window.browser),
"The deleted custom defined property has been removed");
});
});
it("returns undefined for property undefined in the target", () => {
const fakeChrome = {myns: {mykey: true}};
return setupTestDOMWindow(fakeChrome).then(window => {
assert.equal(window.browser.myns.mykey, true,
"Got the expected result from a wrapped property");
assert.equal(window.browser.myns.nonexistent, undefined,
"Got undefined for non existent property");
assert.equal(window.browser.nonexistent, undefined,
"Got undefined for non existent namespaces");
});
});
});
});

View File

@ -1,11 +1,31 @@
"use strict";
const {assert} = require("chai");
const sinon = require("sinon");
const {setupTestDOMWindow} = require("./setup");
describe("browser-polyfill", () => {
describe("proxies non-wrapped functions", () => {
it("should proxy non-wrapped methods", () => {
const fakeChrome = {
runtime: {
nonwrappedmethod: sinon.spy(),
},
};
return setupTestDOMWindow(fakeChrome).then(window => {
assert.ok(window.browser.runtime.nonwrappedmethod);
const fakeCallback = () => {};
window.browser.runtime.nonwrappedmethod(fakeCallback);
const receivedCallback = fakeChrome.runtime.nonwrappedmethod.firstCall.args[0];
assert.equal(fakeCallback, receivedCallback,
"The callback has not been wrapped for the nonwrappedmethod");
});
});
it("should proxy getters and setters", () => {
const fakeChrome = {
runtime: {myprop: "previous-value"},
@ -58,6 +78,10 @@ describe("browser-polyfill", () => {
const fakeChrome = {};
return setupTestDOMWindow(fakeChrome).then(window => {
window.browser.newns = {newkey: "test-value"};
assert.ok("newns" in window.browser, "The custom namespace is in the wrapper");
assert.ok("newns" in window.chrome, "The custom namespace is in the target");
assert.equal(window.browser.newns.newkey, "test-value",
"Got the expected result from setting a wrapped property name");
@ -69,7 +93,6 @@ describe("browser-polyfill", () => {
assert.deepEqual(window.browser.newns, window.chrome.newns,
"chrome.newns and browser.newns are the same");
delete window.browser.newns.newkey2;
assert.equal(window.browser.newns.newkey2, undefined,
"Got the expected result from setting a wrapped property name");

View File

@ -7,6 +7,29 @@ const {setupTestDOMWindow} = require("./setup");
describe("browser-polyfill", () => {
describe("wrapped runtime.onMessage listener", () => {
it("do not wrap the listener if it is not a function", () => {
const fakeChrome = {
runtime: {
lastError: null,
onMessage: {
addListener: sinon.spy(),
hasListener: sinon.stub(),
removeListener: sinon.spy(),
},
},
};
return setupTestDOMWindow(fakeChrome).then(window => {
const fakeNonFunctionListener = {fake: "non function listener"};
window.browser.runtime.onMessage.addListener(fakeNonFunctionListener);
assert.deepEqual(fakeChrome.runtime.onMessage.addListener.firstCall.args[0],
fakeNonFunctionListener,
"The non-function listener has not been wrapped");
});
});
it("keeps track of the listeners added", () => {
const messageListener = sinon.spy();
@ -75,20 +98,29 @@ describe("browser-polyfill", () => {
},
};
// Plain value returned.
const messageListener = sinon.stub();
const firstResponse = "fake reply";
const secondResponse = Promise.resolve("fake reply2");
// Resolved Promise returned.
const secondResponse = Promise.resolve("fake reply 2");
// Rejected Promise returned.
const thirdResponse = Promise.reject("fake error 3");
const sendResponseSpy = sinon.spy();
messageListener.onFirstCall().returns(firstResponse)
.onSecondCall().returns(secondResponse);
messageListener
.onFirstCall().returns(firstResponse)
.onSecondCall().returns(secondResponse)
.onThirdCall().returns(thirdResponse);
let wrappedListener;
return setupTestDOMWindow(fakeChrome).then(window => {
window.browser.runtime.onMessage.addListener(messageListener);
assert.ok(fakeChrome.runtime.onMessage.addListener.calledOnce);
const wrappedListener = fakeChrome.runtime.onMessage.addListener.firstCall.args[0];
wrappedListener = fakeChrome.runtime.onMessage.addListener.firstCall.args[0];
wrappedListener("fake message", {name: "fake sender"}, sendResponseSpy);
@ -110,11 +142,27 @@ describe("browser-polyfill", () => {
"The unwrapped message listener has been called");
assert.deepEqual(messageListener.secondCall.args,
["fake message2", {name: "fake sender2"}],
"The unwrapped message listener has received the expected parameters");
"The unwrapped listener has received the expected parameters");
assert.ok(sendResponseSpy.calledTwice, "The sendResponse function has been called");
assert.equal(sendResponseSpy.secondCall.args[0], "fake reply2",
assert.equal(sendResponseSpy.secondCall.args[0], "fake reply 2",
"sendResponse callback has been called with the expected parameters");
}).then(() => {
wrappedListener("fake message3", {name: "fake sender3"}, sendResponseSpy);
// Wait the third response promise to be rejected.
return thirdResponse.catch(err => {
assert.equal(messageListener.callCount, 3,
"The unwrapped message listener has been called");
assert.deepEqual(messageListener.thirdCall.args,
["fake message3", {name: "fake sender3"}],
"The unwrapped listener has received the expected parameters");
assert.equal(sendResponseSpy.callCount, 3,
"The sendResponse function has been called");
assert.equal(sendResponseSpy.thirdCall.args[0], err,
"sendResponse callback has been called with the expected parameters");
});
});
});
});