Merge pull request #1 from stoically/sync-tests
Add sync tests to mocha suite
This commit is contained in:
commit
e6f5bf76c2
13 changed files with 908 additions and 311 deletions
11
package.json
11
package.json
|
@ -19,14 +19,14 @@
|
||||||
"json": "^9.0.6",
|
"json": "^9.0.6",
|
||||||
"mocha": "^6.2.2",
|
"mocha": "^6.2.2",
|
||||||
"npm-run-all": "^4.0.0",
|
"npm-run-all": "^4.0.0",
|
||||||
"nyc": "^14.1.1",
|
"nyc": "^15.0.0",
|
||||||
"sinon": "^7.5.0",
|
"sinon": "^7.5.0",
|
||||||
"sinon-chai": "^3.3.0",
|
"sinon-chai": "^3.3.0",
|
||||||
"stylelint": "^7.9.0",
|
"stylelint": "^7.9.0",
|
||||||
"stylelint-config-standard": "^16.0.0",
|
"stylelint-config-standard": "^16.0.0",
|
||||||
"stylelint-order": "^0.3.0",
|
"stylelint-order": "^0.3.0",
|
||||||
"web-ext": "^2.9.3",
|
"web-ext": "^2.9.3",
|
||||||
"webextensions-jsdom": "^1.1.0"
|
"webextensions-jsdom": "^1.2.1"
|
||||||
},
|
},
|
||||||
"homepage": "https://github.com/mozilla/multi-account-containers#readme",
|
"homepage": "https://github.com/mozilla/multi-account-containers#readme",
|
||||||
"license": "MPL-2.0",
|
"license": "MPL-2.0",
|
||||||
|
@ -44,9 +44,8 @@
|
||||||
"lint:js": "eslint .",
|
"lint:js": "eslint .",
|
||||||
"package": "rm -rf src/web-ext-artifacts && npm run build && mv src/web-ext-artifacts/firefox_multi-account_containers-*.zip addon.xpi",
|
"package": "rm -rf src/web-ext-artifacts && npm run build && mv src/web-ext-artifacts/firefox_multi-account_containers-*.zip addon.xpi",
|
||||||
"test": "npm run lint && npm run coverage",
|
"test": "npm run lint && npm run coverage",
|
||||||
"mocha": "mocha ./test/setup.js test/**/*.test.js",
|
"test:once": "mocha test/**/*.test.js",
|
||||||
"mochaSingle": "mocha ./test/setup.js",
|
"test:watch": "npm run test:once -- --watch",
|
||||||
"test-watch": "mocha ./test/setup.js test/**/*.test.js --watch",
|
"coverage": "nyc --reporter=html --reporter=text mocha test/**/*.test.js --timeout 60000"
|
||||||
"coverage": "nyc --reporter=html --reporter=text mocha ./test/setup.js test/**/*.test.js --timeout 60000"
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
const assignManager = {
|
window.assignManager = {
|
||||||
MENU_ASSIGN_ID: "open-in-this-container",
|
MENU_ASSIGN_ID: "open-in-this-container",
|
||||||
MENU_REMOVE_ID: "remove-open-in-this-container",
|
MENU_REMOVE_ID: "remove-open-in-this-container",
|
||||||
MENU_SEPARATOR_ID: "separator",
|
MENU_SEPARATOR_ID: "separator",
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
const identityState = {
|
window.identityState = {
|
||||||
storageArea: {
|
storageArea: {
|
||||||
area: browser.storage.local,
|
area: browser.storage.local,
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
const SYNC_DEBUG = true;
|
const SYNC_DEBUG = true;
|
||||||
|
|
||||||
const sync = {
|
window.sync = {
|
||||||
storageArea: {
|
storageArea: {
|
||||||
area: browser.storage.sync,
|
area: browser.storage.sync,
|
||||||
|
|
||||||
|
|
|
@ -6,15 +6,7 @@ module.exports = {
|
||||||
"parserOptions": {
|
"parserOptions": {
|
||||||
"ecmaVersion": 2018
|
"ecmaVersion": 2018
|
||||||
},
|
},
|
||||||
globals: {
|
"rules": {
|
||||||
"sinon": false,
|
"no-restricted-globals": ["error", "browser"]
|
||||||
"expect": false,
|
|
||||||
"nextTick": false,
|
|
||||||
"buildDom": false,
|
|
||||||
"buildBackgroundDom": false,
|
|
||||||
"background": false,
|
|
||||||
"buildPopupDom": false,
|
|
||||||
"popup": false,
|
|
||||||
"helper": false
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,15 +2,16 @@ if (!process.listenerCount("unhandledRejection")) {
|
||||||
// eslint-disable-next-line no-console
|
// eslint-disable-next-line no-console
|
||||||
process.on("unhandledRejection", r => console.log(r));
|
process.on("unhandledRejection", r => console.log(r));
|
||||||
}
|
}
|
||||||
|
|
||||||
const path = require("path");
|
const path = require("path");
|
||||||
const chai = require("chai");
|
const chai = require("chai");
|
||||||
const sinonChai = require("sinon-chai");
|
const sinonChai = require("sinon-chai");
|
||||||
const crypto = require("crypto");
|
const crypto = require("crypto");
|
||||||
global.sinon = require("sinon");
|
const sinon = require("sinon");
|
||||||
global.expect = chai.expect;
|
const expect = chai.expect;
|
||||||
chai.should();
|
chai.should();
|
||||||
chai.use(sinonChai);
|
chai.use(sinonChai);
|
||||||
global.nextTick = () => {
|
const nextTick = () => {
|
||||||
return new Promise(resolve => {
|
return new Promise(resolve => {
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
process.nextTick(resolve);
|
process.nextTick(resolve);
|
||||||
|
@ -18,12 +19,10 @@ global.nextTick = () => {
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
global.helper = require("./helper");
|
|
||||||
|
|
||||||
const webExtensionsJSDOM = require("webextensions-jsdom");
|
const webExtensionsJSDOM = require("webextensions-jsdom");
|
||||||
const manifestPath = path.resolve(path.join(__dirname, "../src/manifest.json"));
|
const manifestPath = path.resolve(path.join(__dirname, "../src/manifest.json"));
|
||||||
|
|
||||||
global.buildDom = async ({background = {}, popup = {}}) => {
|
const buildDom = async ({background = {}, popup = {}}) => {
|
||||||
background = {
|
background = {
|
||||||
...background,
|
...background,
|
||||||
jsdom: {
|
jsdom: {
|
||||||
|
@ -53,33 +52,60 @@ global.buildDom = async ({background = {}, popup = {}}) => {
|
||||||
popup
|
popup
|
||||||
});
|
});
|
||||||
|
|
||||||
// eslint-disable-next-line require-atomic-updates
|
webExtension.browser = webExtension.background.browser;
|
||||||
global.background = webExtension.background;
|
return webExtension;
|
||||||
// eslint-disable-next-line require-atomic-updates
|
|
||||||
global.popup = webExtension.popup;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
global.buildBackgroundDom = async background => {
|
const buildBackgroundDom = background => {
|
||||||
await global.buildDom({
|
return buildDom({
|
||||||
background,
|
background,
|
||||||
popup: false
|
popup: false
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
global.buildPopupDom = async popup => {
|
const buildPopupDom = popup => {
|
||||||
await global.buildDom({
|
return buildDom({
|
||||||
popup,
|
popup,
|
||||||
background: false
|
background: false
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const initializeWithTab = async (details = {
|
||||||
|
cookieStoreId: "firefox-default"
|
||||||
|
}) => {
|
||||||
|
let tab;
|
||||||
|
const webExtension = await buildDom({
|
||||||
|
background: {
|
||||||
|
async afterBuild(background) {
|
||||||
|
tab = await background.browser.tabs._create(details);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
popup: {
|
||||||
|
jsdom: {
|
||||||
|
beforeParse(window) {
|
||||||
|
window.browser.storage.local.set({
|
||||||
|
"browserActionBadgesClicked": [],
|
||||||
|
"onboarding-stage": 6,
|
||||||
|
"achievements": [],
|
||||||
|
"syncEnabled": true
|
||||||
|
});
|
||||||
|
window.browser.storage.local.set.resetHistory();
|
||||||
|
window.browser.storage.sync.clear();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
webExtension.tab = tab;
|
||||||
|
|
||||||
global.afterEach(() => {
|
return webExtension;
|
||||||
if (global.background) {
|
};
|
||||||
global.background.destroy();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (global.popup) {
|
module.exports = {
|
||||||
global.popup.destroy();
|
buildDom,
|
||||||
}
|
buildBackgroundDom,
|
||||||
});
|
buildPopupDom,
|
||||||
|
initializeWithTab,
|
||||||
|
sinon,
|
||||||
|
expect,
|
||||||
|
nextTick,
|
||||||
|
};
|
|
@ -1,25 +1,30 @@
|
||||||
describe("Assignment Feature", () => {
|
const {initializeWithTab} = require("../common");
|
||||||
|
|
||||||
|
describe("Assignment Feature", function () {
|
||||||
const url = "http://example.com";
|
const url = "http://example.com";
|
||||||
|
|
||||||
let activeTab;
|
beforeEach(async function () {
|
||||||
beforeEach(async () => {
|
this.webExt = await initializeWithTab({
|
||||||
activeTab = await helper.browser.initializeWithTab({
|
|
||||||
cookieStoreId: "firefox-container-1",
|
cookieStoreId: "firefox-container-1",
|
||||||
url
|
url
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe("click the 'Always open in' checkbox in the popup", () => {
|
afterEach(function () {
|
||||||
beforeEach(async () => {
|
this.webExt.destroy();
|
||||||
|
});
|
||||||
|
|
||||||
|
describe("click the 'Always open in' checkbox in the popup", function () {
|
||||||
|
beforeEach(async function () {
|
||||||
// popup click to set assignment for activeTab.url
|
// popup click to set assignment for activeTab.url
|
||||||
await helper.popup.clickElementById("container-page-assigned");
|
await this.webExt.popup.helper.clickElementById("container-page-assigned");
|
||||||
});
|
});
|
||||||
|
|
||||||
describe("open new Tab with the assigned URL in the default container", () => {
|
describe("open new Tab with the assigned URL in the default container", function () {
|
||||||
let newTab;
|
let newTab;
|
||||||
beforeEach(async () => {
|
beforeEach(async function () {
|
||||||
// new Tab opening activeTab.url in default container
|
// new Tab opening activeTab.url in default container
|
||||||
newTab = await helper.browser.openNewTab({
|
newTab = await this.webExt.background.browser.tabs._create({
|
||||||
cookieStoreId: "firefox-default",
|
cookieStoreId: "firefox-default",
|
||||||
url
|
url
|
||||||
}, {
|
}, {
|
||||||
|
@ -29,12 +34,12 @@ describe("Assignment Feature", () => {
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
it("should open the confirm page", async () => {
|
it("should open the confirm page", async function () {
|
||||||
// should have created a new tab with the confirm page
|
// should have created a new tab with the confirm page
|
||||||
background.browser.tabs.create.should.have.been.calledWithMatch({
|
this.webExt.background.browser.tabs.create.should.have.been.calledWithMatch({
|
||||||
url: "moz-extension://fake/confirm-page.html?" +
|
url: "moz-extension://fake/confirm-page.html?" +
|
||||||
`url=${encodeURIComponent(url)}` +
|
`url=${encodeURIComponent(url)}` +
|
||||||
`&cookieStoreId=${activeTab.cookieStoreId}`,
|
`&cookieStoreId=${this.webExt.tab.cookieStoreId}`,
|
||||||
cookieStoreId: undefined,
|
cookieStoreId: undefined,
|
||||||
openerTabId: null,
|
openerTabId: null,
|
||||||
index: 2,
|
index: 2,
|
||||||
|
@ -42,29 +47,29 @@ describe("Assignment Feature", () => {
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
it("should remove the new Tab that got opened in the default container", () => {
|
it("should remove the new Tab that got opened in the default container", function () {
|
||||||
background.browser.tabs.remove.should.have.been.calledWith(newTab.id);
|
this.webExt.background.browser.tabs.remove.should.have.been.calledWith(newTab.id);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe("click the 'Always open in' checkbox in the popup again", () => {
|
describe("click the 'Always open in' checkbox in the popup again", function () {
|
||||||
beforeEach(async () => {
|
beforeEach(async function () {
|
||||||
// popup click to remove assignment for activeTab.url
|
// popup click to remove assignment for activeTab.url
|
||||||
await helper.popup.clickElementById("container-page-assigned");
|
await this.webExt.popup.helper.clickElementById("container-page-assigned");
|
||||||
});
|
});
|
||||||
|
|
||||||
describe("open new Tab with the no longer assigned URL in the default container", () => {
|
describe("open new Tab with the no longer assigned URL in the default container", function () {
|
||||||
beforeEach(async () => {
|
beforeEach(async function () {
|
||||||
// new Tab opening activeTab.url in default container
|
// new Tab opening activeTab.url in default container
|
||||||
await helper.browser.openNewTab({
|
await this.webExt.background.browser.tabs._create({
|
||||||
cookieStoreId: "firefox-default",
|
cookieStoreId: "firefox-default",
|
||||||
url
|
url
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
it("should not open the confirm page", async () => {
|
it("should not open the confirm page", async function () {
|
||||||
// should not have created a new tab
|
// should not have created a new tab
|
||||||
background.browser.tabs.create.should.not.have.been.called;
|
this.webExt.background.browser.tabs.create.should.not.have.been.called;
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
|
@ -1,27 +1,33 @@
|
||||||
describe("Containers Management", () => {
|
const {initializeWithTab} = require("../common");
|
||||||
beforeEach(async () => {
|
|
||||||
await helper.browser.initializeWithTab();
|
describe("Containers Management", function () {
|
||||||
|
beforeEach(async function () {
|
||||||
|
this.webExt = await initializeWithTab();
|
||||||
});
|
});
|
||||||
|
|
||||||
describe("creating a new container", () => {
|
afterEach(function () {
|
||||||
beforeEach(async () => {
|
this.webExt.destroy();
|
||||||
await helper.popup.clickElementById("container-add-link");
|
});
|
||||||
await helper.popup.clickElementById("edit-container-ok-link");
|
|
||||||
|
describe("creating a new container", function () {
|
||||||
|
beforeEach(async function () {
|
||||||
|
await this.webExt.popup.helper.clickElementById("container-add-link");
|
||||||
|
await this.webExt.popup.helper.clickElementById("edit-container-ok-link");
|
||||||
});
|
});
|
||||||
|
|
||||||
it("should create it in the browser as well", () => {
|
it("should create it in the browser as well", function () {
|
||||||
background.browser.contextualIdentities.create.should.have.been.calledOnce;
|
this.webExt.background.browser.contextualIdentities.create.should.have.been.calledOnce;
|
||||||
});
|
});
|
||||||
|
|
||||||
describe("removing it afterwards", () => {
|
describe("removing it afterwards", function () {
|
||||||
beforeEach(async () => {
|
beforeEach(async function () {
|
||||||
await helper.popup.clickElementById("edit-containers-link");
|
await this.webExt.popup.helper.clickElementById("edit-containers-link");
|
||||||
await helper.popup.clickLastMatchingElementByQuerySelector(".delete-container-icon");
|
await this.webExt.popup.helper.clickElementByQuerySelectorAll(".delete-container-icon", "last");
|
||||||
await helper.popup.clickElementById("delete-container-ok-link");
|
await this.webExt.popup.helper.clickElementById("delete-container-ok-link");
|
||||||
});
|
});
|
||||||
|
|
||||||
it("should remove it in the browser as well", () => {
|
it("should remove it in the browser as well", function () {
|
||||||
background.browser.contextualIdentities.remove.should.have.been.calledOnce;
|
this.webExt.background.browser.contextualIdentities.remove.should.have.been.calledOnce;
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
|
@ -1,17 +1,24 @@
|
||||||
describe("External Webextensions", () => {
|
const {expect, initializeWithTab} = require("../common");
|
||||||
|
|
||||||
|
describe("External Webextensions", function () {
|
||||||
const url = "http://example.com";
|
const url = "http://example.com";
|
||||||
|
|
||||||
beforeEach(async () => {
|
beforeEach(async function () {
|
||||||
await helper.browser.initializeWithTab({
|
this.webExt = await initializeWithTab({
|
||||||
cookieStoreId: "firefox-container-1",
|
cookieStoreId: "firefox-container-1",
|
||||||
url
|
url
|
||||||
});
|
});
|
||||||
await helper.popup.clickElementById("container-page-assigned");
|
|
||||||
|
await this.webExt.popup.helper.clickElementById("container-page-assigned");
|
||||||
});
|
});
|
||||||
|
|
||||||
describe("with contextualIdentities permissions", () => {
|
afterEach(function () {
|
||||||
it("should be able to get assignments", async () => {
|
this.webExt.destroy();
|
||||||
background.browser.management.get.resolves({
|
});
|
||||||
|
|
||||||
|
describe("with contextualIdentities permissions", function () {
|
||||||
|
it("should be able to get assignments", async function () {
|
||||||
|
this.webExt.background.browser.management.get.resolves({
|
||||||
permissions: ["contextualIdentities"]
|
permissions: ["contextualIdentities"]
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -23,7 +30,7 @@ describe("External Webextensions", () => {
|
||||||
id: "external-webextension"
|
id: "external-webextension"
|
||||||
};
|
};
|
||||||
|
|
||||||
const [promise] = background.browser.runtime.onMessageExternal.addListener.yield(message, sender);
|
const [promise] = this.webExt.background.browser.runtime.onMessageExternal.addListener.yield(message, sender);
|
||||||
const answer = await promise;
|
const answer = await promise;
|
||||||
expect(answer.userContextId === "1").to.be.true;
|
expect(answer.userContextId === "1").to.be.true;
|
||||||
expect(answer.neverAsk === false).to.be.true;
|
expect(answer.neverAsk === false).to.be.true;
|
||||||
|
@ -33,9 +40,9 @@ describe("External Webextensions", () => {
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe("without contextualIdentities permissions", () => {
|
describe("without contextualIdentities permissions", function () {
|
||||||
it("should throw an error", async () => {
|
it("should throw an error", async function () {
|
||||||
background.browser.management.get.resolves({
|
this.webExt.background.browser.management.get.resolves({
|
||||||
permissions: []
|
permissions: []
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -47,7 +54,7 @@ describe("External Webextensions", () => {
|
||||||
id: "external-webextension"
|
id: "external-webextension"
|
||||||
};
|
};
|
||||||
|
|
||||||
const [promise] = background.browser.runtime.onMessageExternal.addListener.yield(message, sender);
|
const [promise] = this.webExt.background.browser.runtime.onMessageExternal.addListener.yield(message, sender);
|
||||||
return promise.catch(error => {
|
return promise.catch(error => {
|
||||||
expect(error.message).to.equal("Missing contextualIdentities permission");
|
expect(error.message).to.equal("Missing contextualIdentities permission");
|
||||||
});
|
});
|
||||||
|
|
|
@ -1,64 +1,695 @@
|
||||||
describe("Sync", () => {
|
const {initializeWithTab} = require("../common");
|
||||||
|
|
||||||
it("should init sync on startup", async () => {
|
describe("Sync", function() {
|
||||||
const tab = await helper.browser.initializeWithTab();
|
beforeEach(async function() {
|
||||||
console.log(await background.browser.storage.local.get());
|
this.webExt = await initializeWithTab();
|
||||||
const mozContainer = await background.browser.contextualIdentities.create({
|
this.syncHelper = new SyncTestHelper(this.webExt);
|
||||||
name: "Mozilla",
|
|
||||||
color: "red",
|
|
||||||
icon: "briefcase",
|
|
||||||
});
|
|
||||||
await background.browser.contextualIdentities.update("firefox-container-2", {color:"purple"});
|
|
||||||
await background.browser.contextualIdentities.update("firefox-container-4", {icon:"pet"});
|
|
||||||
|
|
||||||
await Promise.all([
|
|
||||||
{
|
|
||||||
userContextId: "1",
|
|
||||||
url: "https://twitter.com",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
userContextId: "2",
|
|
||||||
url: "https://www.facebook.com",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
userContextId: "4",
|
|
||||||
url: "https://www.linkedin.com",
|
|
||||||
neverAsk: true,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
userContextId: mozContainer.cookieStoreId.replace("firefox-container-", ""),
|
|
||||||
url: "https://developer.mozilla.org",
|
|
||||||
neverAsk: true,
|
|
||||||
}
|
|
||||||
].map(async (assign) => {
|
|
||||||
await background.browser.tabs.update(tab.id, {
|
|
||||||
cookieStoreId: `firefox-container-${assign.userContextId}`
|
|
||||||
});
|
|
||||||
|
|
||||||
await background.browser.runtime.onMessage.addListener.yield({
|
|
||||||
method: "setOrRemoveAssignment",
|
|
||||||
tabId: tab.id,
|
|
||||||
url: assign.url,
|
|
||||||
userContextId: assign.userContextId,
|
|
||||||
value: !true
|
|
||||||
});
|
|
||||||
|
|
||||||
if (assign.neverAsk) {
|
|
||||||
await nextTick();
|
|
||||||
await background.browser.runtime.onMessage.addListener.yield({
|
|
||||||
method: "neverAsk",
|
|
||||||
neverAsk: true,
|
|
||||||
pageUrl: assign.url,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}));
|
|
||||||
|
|
||||||
// await background.browser.storage.onChanged.addListener.yield();
|
|
||||||
await nextTick();
|
|
||||||
|
|
||||||
const sync = await background.browser.storage.sync.get();
|
|
||||||
console.log("sync", sync);
|
|
||||||
// expect(sync.length).to.equal(4);
|
|
||||||
});
|
});
|
||||||
|
|
||||||
});
|
afterEach(function() {
|
||||||
|
this.webExt.destroy();
|
||||||
|
delete this.syncHelper;
|
||||||
|
});
|
||||||
|
|
||||||
|
it("testIdentityStateCleanup", async function() {
|
||||||
|
await this.syncHelper.stopSyncListeners();
|
||||||
|
console.log("Testing the cleanup of local storage");
|
||||||
|
|
||||||
|
await this.syncHelper.setState({}, LOCAL_DATA, TEST_CONTAINERS, []);
|
||||||
|
|
||||||
|
await this.webExt.browser.storage.local.set({
|
||||||
|
"identitiesState@@_firefox-container-5": {
|
||||||
|
"hiddenTabs": []
|
||||||
|
}
|
||||||
|
});
|
||||||
|
console.log("local storage set: ", await this.webExt.browser.storage.local.get());
|
||||||
|
|
||||||
|
await this.webExt.background.window.identityState.storageArea.upgradeData();
|
||||||
|
|
||||||
|
const macConfigs = await this.webExt.browser.storage.local.get();
|
||||||
|
const identities = [];
|
||||||
|
for(const configKey of Object.keys(macConfigs)) {
|
||||||
|
if (configKey.includes("identitiesState@@_") && !configKey.includes("default")) {
|
||||||
|
identities.push(macConfigs[configKey]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
console.assert(identities.length === 5, "There should be 5 identity entries");
|
||||||
|
for (const identity of identities) {
|
||||||
|
console.assert(!!identity.macAddonUUID, `${identity.name} should have a uuid`);
|
||||||
|
}
|
||||||
|
console.log("!!!Finished!!!");
|
||||||
|
});
|
||||||
|
|
||||||
|
it("testAssignManagerCleanup", async function() {
|
||||||
|
await this.syncHelper.stopSyncListeners();
|
||||||
|
console.log("Testing the cleanup of local storage");
|
||||||
|
|
||||||
|
await this.syncHelper.setState({}, LOCAL_DATA, TEST_CONTAINERS, TEST_ASSIGNMENTS);
|
||||||
|
|
||||||
|
await this.webExt.browser.storage.local.set({
|
||||||
|
"siteContainerMap@@_www.goop.com": {
|
||||||
|
"userContextId": "6",
|
||||||
|
"neverAsk": true,
|
||||||
|
"hostname": "www.goop.com"
|
||||||
|
}
|
||||||
|
});
|
||||||
|
console.log("local storage set: ", await this.webExt.browser.storage.local.get());
|
||||||
|
|
||||||
|
await this.webExt.background.window.identityState.storageArea.upgradeData();
|
||||||
|
await this.webExt.background.window.assignManager.storageArea.upgradeData();
|
||||||
|
|
||||||
|
const macConfigs = await this.webExt.browser.storage.local.get();
|
||||||
|
const assignments = [];
|
||||||
|
for(const configKey of Object.keys(macConfigs)) {
|
||||||
|
if (configKey.includes("siteContainerMap@@_")) {
|
||||||
|
macConfigs[configKey].configKey = configKey;
|
||||||
|
assignments.push(macConfigs[configKey]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
console.assert(assignments.length === 5, "There should be 5 identity entries");
|
||||||
|
for (const assignment of assignments) {
|
||||||
|
console.log(assignment);
|
||||||
|
console.assert(!!assignment.identityMacAddonUUID, `${assignment.configKey} should have a uuid`);
|
||||||
|
}
|
||||||
|
console.log("!!!Finished!!!");
|
||||||
|
});
|
||||||
|
|
||||||
|
it("testReconcileSiteAssignments", async function() {
|
||||||
|
await this.syncHelper.stopSyncListeners();
|
||||||
|
console.log("Testing reconciling Site Assignments");
|
||||||
|
|
||||||
|
await this.syncHelper.setState(
|
||||||
|
DUPE_TEST_SYNC,
|
||||||
|
LOCAL_DATA,
|
||||||
|
TEST_CONTAINERS,
|
||||||
|
SITE_ASSIGNMENT_TEST
|
||||||
|
);
|
||||||
|
|
||||||
|
// add 200ok (bad data).
|
||||||
|
const testSites = {
|
||||||
|
"siteContainerMap@@_developer.mozilla.org": {
|
||||||
|
"userContextId": "588",
|
||||||
|
"neverAsk": true,
|
||||||
|
"identityMacAddonUUID": "d20d7af2-9866-468e-bb43-541efe8c2c2e",
|
||||||
|
"hostname": "developer.mozilla.org"
|
||||||
|
},
|
||||||
|
"siteContainerMap@@_reddit.com": {
|
||||||
|
"userContextId": "592",
|
||||||
|
"neverAsk": true,
|
||||||
|
"identityMacAddonUUID": "3dc916fb-8c0a-4538-9758-73ef819a45f7",
|
||||||
|
"hostname": "reddit.com"
|
||||||
|
},
|
||||||
|
"siteContainerMap@@_twitter.com": {
|
||||||
|
"userContextId": "589",
|
||||||
|
"neverAsk": true,
|
||||||
|
"identityMacAddonUUID": "cdd73c20-c26a-4c06-9b17-735c1f5e9187",
|
||||||
|
"hostname": "twitter.com"
|
||||||
|
},
|
||||||
|
"siteContainerMap@@_www.facebook.com": {
|
||||||
|
"userContextId": "590",
|
||||||
|
"neverAsk": true,
|
||||||
|
"identityMacAddonUUID": "32cc4a9b-05ed-4e54-8e11-732468de62f4",
|
||||||
|
"hostname": "www.facebook.com"
|
||||||
|
},
|
||||||
|
"siteContainerMap@@_www.linkedin.com": {
|
||||||
|
"userContextId": "591",
|
||||||
|
"neverAsk": true,
|
||||||
|
"identityMacAddonUUID": "9ff381e3-4c11-420d-8e12-e352a3318be1",
|
||||||
|
"hostname": "www.linkedin.com"
|
||||||
|
},
|
||||||
|
"siteContainerMap@@_200ok.us": {
|
||||||
|
"userContextId": "1",
|
||||||
|
"neverAsk": true,
|
||||||
|
"identityMacAddonUUID": "b5f5f794-b37e-4cec-9f4e-6490df620336",
|
||||||
|
"hostname": "www.linkedin.com"
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
for (const site of Object.keys(testSites)) {
|
||||||
|
await this.webExt.browser.storage.sync.set({[site]:testSites[site]});
|
||||||
|
}
|
||||||
|
|
||||||
|
await this.webExt.browser.storage.sync.set({
|
||||||
|
deletedSiteList: ["siteContainerMap@@_www.google.com"]
|
||||||
|
});
|
||||||
|
console.log(await this.webExt.browser.storage.sync.get());
|
||||||
|
await this.webExt.background.window.sync.runSync();
|
||||||
|
|
||||||
|
const assignedSites = await this.webExt.background.window.assignManager.storageArea.getAssignedSites();
|
||||||
|
Object.keys(assignedSites).should.have.lengthOf(6);
|
||||||
|
console.log("!!!Finished!!!");
|
||||||
|
});
|
||||||
|
|
||||||
|
it("testInitialSync", async function() {
|
||||||
|
await this.syncHelper.stopSyncListeners();
|
||||||
|
console.log("Testing new install with no sync");
|
||||||
|
|
||||||
|
await this.syncHelper.setState({}, LOCAL_DATA, TEST_CONTAINERS, []);
|
||||||
|
|
||||||
|
await this.webExt.background.window.sync.runSync();
|
||||||
|
|
||||||
|
const getAssignedSites =
|
||||||
|
await this.webExt.background.window.assignManager.storageArea.getAssignedSites();
|
||||||
|
const identities = await this.webExt.browser.contextualIdentities.query({});
|
||||||
|
|
||||||
|
console.assert(
|
||||||
|
identities.length === 5,
|
||||||
|
"There should be 5 identities"
|
||||||
|
);
|
||||||
|
|
||||||
|
console.assert(
|
||||||
|
Object.keys(getAssignedSites).length === 0,
|
||||||
|
"There should be no site assignments"
|
||||||
|
);
|
||||||
|
console.log("!!!Finished!!!");
|
||||||
|
});
|
||||||
|
|
||||||
|
it("test2", async function() {
|
||||||
|
await this.syncHelper.stopSyncListeners();
|
||||||
|
console.log("Testing sync differing from local");
|
||||||
|
|
||||||
|
await this.syncHelper.setState(SYNC_DATA, LOCAL_DATA, TEST_CONTAINERS, TEST_ASSIGNMENTS);
|
||||||
|
|
||||||
|
await this.webExt.background.window.sync.runSync();
|
||||||
|
|
||||||
|
const getAssignedSites =
|
||||||
|
await this.webExt.background.window.assignManager.storageArea.getAssignedSites();
|
||||||
|
|
||||||
|
const identities = await this.webExt.browser.contextualIdentities.query({});
|
||||||
|
|
||||||
|
console.assert(
|
||||||
|
identities.length === 6,
|
||||||
|
"There should be 6 identities"
|
||||||
|
);
|
||||||
|
|
||||||
|
console.assert(
|
||||||
|
Object.keys(getAssignedSites).length === 5,
|
||||||
|
"There should be 5 site assignments"
|
||||||
|
);
|
||||||
|
console.log("!!!Finished!!!");
|
||||||
|
});
|
||||||
|
|
||||||
|
it("dupeTest", async function() {
|
||||||
|
await this.syncHelper.stopSyncListeners();
|
||||||
|
console.log("Test state from sync that duped everything initially");
|
||||||
|
|
||||||
|
await this.syncHelper.setState(
|
||||||
|
DUPE_TEST_SYNC,
|
||||||
|
DUPE_TEST_LOCAL,
|
||||||
|
DUPE_TEST_IDENTS,
|
||||||
|
DUPE_TEST_ASSIGNMENTS
|
||||||
|
);
|
||||||
|
|
||||||
|
await this.webExt.background.window.sync.runSync();
|
||||||
|
|
||||||
|
const getAssignedSites =
|
||||||
|
await this.webExt.background.window.assignManager.storageArea.getAssignedSites();
|
||||||
|
|
||||||
|
const identities = await this.webExt.browser.contextualIdentities.query({});
|
||||||
|
|
||||||
|
console.assert(
|
||||||
|
identities.length === 7,
|
||||||
|
"There should be 7 identities"
|
||||||
|
);
|
||||||
|
|
||||||
|
console.assert(
|
||||||
|
Object.keys(getAssignedSites).length === 5,
|
||||||
|
"There should be 5 site assignments"
|
||||||
|
);
|
||||||
|
|
||||||
|
const personalContainer =
|
||||||
|
this.syncHelper.lookupIdentityBy(identities, {name: "Personal"});
|
||||||
|
console.log(personalContainer);
|
||||||
|
console.assert(
|
||||||
|
personalContainer.color === "red",
|
||||||
|
"Personal Container should be red"
|
||||||
|
);
|
||||||
|
const mozillaContainer =
|
||||||
|
this.syncHelper.lookupIdentityBy(identities, {name: "Mozilla"});
|
||||||
|
console.assert(
|
||||||
|
mozillaContainer.icon === "pet",
|
||||||
|
"Mozilla Container should be pet"
|
||||||
|
);
|
||||||
|
console.log("!!!Finished!!!");
|
||||||
|
});
|
||||||
|
|
||||||
|
it("CIerrorTest", async function() {
|
||||||
|
await this.syncHelper.stopSyncListeners();
|
||||||
|
console.log("Test state from sync that duped everything initially");
|
||||||
|
|
||||||
|
await this.syncHelper.setState(
|
||||||
|
CI_ERROR_TEST_SYNC,
|
||||||
|
CI_ERROR_TEST_LOCAL,
|
||||||
|
CI_ERROR_TEST_IDENTS,
|
||||||
|
CI_ERROR_TEST_SITES
|
||||||
|
);
|
||||||
|
|
||||||
|
await this.webExt.background.window.sync.runSync();
|
||||||
|
|
||||||
|
const getSync = await this.webExt.browser.storage.sync.get();
|
||||||
|
const getAssignedSites =
|
||||||
|
await this.webExt.background.window.assignManager.storageArea.getAssignedSites();
|
||||||
|
|
||||||
|
const identities = await this.webExt.browser.contextualIdentities.query({});
|
||||||
|
|
||||||
|
console.assert(
|
||||||
|
Object.keys(getSync.cookieStoreIDmap).length === 7,
|
||||||
|
"cookieStoreIDmap should have 7 entries"
|
||||||
|
);
|
||||||
|
|
||||||
|
console.assert(
|
||||||
|
identities.length === 7,
|
||||||
|
"There should be 7 identities"
|
||||||
|
);
|
||||||
|
|
||||||
|
console.assert(
|
||||||
|
Object.keys(getAssignedSites).length === 5,
|
||||||
|
"There should be 5 site assignments"
|
||||||
|
);
|
||||||
|
|
||||||
|
const personalContainer =
|
||||||
|
this.syncHelper.lookupIdentityBy(identities, {name: "Personal"});
|
||||||
|
console.log(personalContainer);
|
||||||
|
console.assert(
|
||||||
|
personalContainer.color === "red",
|
||||||
|
"Personal Container should be red"
|
||||||
|
);
|
||||||
|
const mozillaContainer =
|
||||||
|
this.syncHelper.lookupIdentityBy(identities, {name: "Mozilla"});
|
||||||
|
console.assert(
|
||||||
|
mozillaContainer.icon === "pet",
|
||||||
|
"Mozilla Container should be pet"
|
||||||
|
);
|
||||||
|
console.log("!!!Finished!!!");
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
class SyncTestHelper {
|
||||||
|
constructor(webExt) {
|
||||||
|
this.webExt = webExt;
|
||||||
|
}
|
||||||
|
|
||||||
|
async stopSyncListeners() {
|
||||||
|
await this.webExt.browser.storage.onChanged.removeListener(this.webExt.background.window.sync.storageArea.onChangedListener);
|
||||||
|
await this.webExt.background.window.sync.removeContextualIdentityListeners();
|
||||||
|
}
|
||||||
|
|
||||||
|
async setState(syncData, localData, identityData, assignmentData){
|
||||||
|
await this.removeAllContainers();
|
||||||
|
await this.webExt.browser.storage.sync.clear();
|
||||||
|
await this.webExt.browser.storage.sync.set(syncData);
|
||||||
|
await this.webExt.browser.storage.local.clear();
|
||||||
|
await this.webExt.browser.storage.local.set(localData);
|
||||||
|
for (let i=0; i < identityData.length; i++) {
|
||||||
|
//build identities
|
||||||
|
const newIdentity =
|
||||||
|
await this.webExt.browser.contextualIdentities.create(identityData[i]);
|
||||||
|
// fill identies with site assignments
|
||||||
|
if (assignmentData && assignmentData[i]) {
|
||||||
|
const data = {
|
||||||
|
"userContextId":
|
||||||
|
String(
|
||||||
|
newIdentity.cookieStoreId.replace(/^firefox-container-/, "")
|
||||||
|
),
|
||||||
|
"neverAsk": true
|
||||||
|
};
|
||||||
|
|
||||||
|
await this.webExt.browser.storage.local.set({[assignmentData[i]]: data});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
console.log("local storage set: ", await this.webExt.browser.storage.local.get());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
async removeAllContainers() {
|
||||||
|
const identities = await this.webExt.browser.contextualIdentities.query({});
|
||||||
|
console.log(identities);
|
||||||
|
for (const identity of identities) {
|
||||||
|
await this.webExt.browser.contextualIdentities.remove(identity.cookieStoreId);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
lookupIdentityBy(identities, options) {
|
||||||
|
for (const identity of identities) {
|
||||||
|
if (options && options.name) {
|
||||||
|
if (identity.name === options.name) return identity;
|
||||||
|
}
|
||||||
|
if (options && options.color) {
|
||||||
|
if (identity.color === options.color) return identity;
|
||||||
|
}
|
||||||
|
if (options && options.color) {
|
||||||
|
if (identity.color === options.color) return identity;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const TEST_CONTAINERS = [
|
||||||
|
{
|
||||||
|
name: "Personal",
|
||||||
|
color: "blue",
|
||||||
|
icon: "fingerprint"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "Banking",
|
||||||
|
color: "green",
|
||||||
|
icon: "dollar"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "Mozilla",
|
||||||
|
color: "red",
|
||||||
|
icon: "briefcase"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "Groceries, obviously",
|
||||||
|
color: "yellow",
|
||||||
|
icon: "cart"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "Facebook",
|
||||||
|
color: "toolbar",
|
||||||
|
icon: "fence"
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
|
const TEST_ASSIGNMENTS = [
|
||||||
|
"siteContainerMap@@_developer.mozilla.org",
|
||||||
|
"siteContainerMap@@_twitter.com",
|
||||||
|
"siteContainerMap@@_www.facebook.com",
|
||||||
|
"siteContainerMap@@_www.linkedin.com",
|
||||||
|
"siteContainerMap@@_reddit.com"
|
||||||
|
];
|
||||||
|
|
||||||
|
const LOCAL_DATA = {
|
||||||
|
"browserActionBadgesClicked": [ "6.1.1" ],
|
||||||
|
"containerTabsOpened": 7,
|
||||||
|
"identitiesState@@_firefox-default": { "hiddenTabs": [] },
|
||||||
|
"onboarding-stage": 5
|
||||||
|
};
|
||||||
|
|
||||||
|
const SYNC_DATA = {
|
||||||
|
"identity@@_22ded543-5173-44a5-a47a-8813535945ca": {
|
||||||
|
"name": "Personal",
|
||||||
|
"icon": "fingerprint",
|
||||||
|
"color": "red",
|
||||||
|
"cookieStoreId": "firefox-container-146",
|
||||||
|
"macAddonUUID": "22ded543-5173-44a5-a47a-8813535945ca"
|
||||||
|
},
|
||||||
|
"identity@@_63e5212f-0858-418e-b5a3-09c2dea61fcd": {
|
||||||
|
"name": "Oscar",
|
||||||
|
"icon": "dollar",
|
||||||
|
"color": "green",
|
||||||
|
"cookieStoreId": "firefox-container-147",
|
||||||
|
"macAddonUUID": "3e5212f-0858-418e-b5a3-09c2dea61fcd"
|
||||||
|
},
|
||||||
|
"identity@@_71335417-158e-4d74-a55b-e9e9081601ec": {
|
||||||
|
"name": "Mozilla",
|
||||||
|
"icon": "pet",
|
||||||
|
"color": "red",
|
||||||
|
"cookieStoreId": "firefox-container-148",
|
||||||
|
"macAddonUUID": "71335417-158e-4d74-a55b-e9e9081601ec"
|
||||||
|
},
|
||||||
|
"identity@@_59c4e5f7-fe3b-435a-ae60-1340db31a91b": {
|
||||||
|
"name": "Groceries, obviously",
|
||||||
|
"icon": "cart",
|
||||||
|
"color": "pink",
|
||||||
|
"cookieStoreId": "firefox-container-149",
|
||||||
|
"macAddonUUID": "59c4e5f7-fe3b-435a-ae60-1340db31a91b"
|
||||||
|
},
|
||||||
|
"identity@@_3dc916fb-8c0a-4538-9758-73ef819a45f7": {
|
||||||
|
"name": "Facebook",
|
||||||
|
"icon": "fence",
|
||||||
|
"color": "toolbar",
|
||||||
|
"cookieStoreId": "firefox-container-150",
|
||||||
|
"macAddonUUID": "3dc916fb-8c0a-4538-9758-73ef819a45f7"
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const DUPE_TEST_SYNC = {
|
||||||
|
"identity@@_d20d7af2-9866-468e-bb43-541efe8c2c2e": {
|
||||||
|
"name": "Personal",
|
||||||
|
"icon": "fingerprint",
|
||||||
|
"color": "red",
|
||||||
|
"cookieStoreId": "firefox-container-588",
|
||||||
|
"macAddonUUID": "d20d7af2-9866-468e-bb43-541efe8c2c2e"
|
||||||
|
},
|
||||||
|
"identity@@_cdd73c20-c26a-4c06-9b17-735c1f5e9187": {
|
||||||
|
"name": "Big Bird",
|
||||||
|
"icon": "pet",
|
||||||
|
"color": "yellow",
|
||||||
|
"cookieStoreId": "firefox-container-589",
|
||||||
|
"macAddonUUID": "cdd73c20-c26a-4c06-9b17-735c1f5e9187"
|
||||||
|
},
|
||||||
|
"identity@@_32cc4a9b-05ed-4e54-8e11-732468de62f4": {
|
||||||
|
"name": "Mozilla",
|
||||||
|
"icon": "pet",
|
||||||
|
"color": "red",
|
||||||
|
"cookieStoreId": "firefox-container-590",
|
||||||
|
"macAddonUUID": "32cc4a9b-05ed-4e54-8e11-732468de62f4"
|
||||||
|
},
|
||||||
|
"identity@@_9ff381e3-4c11-420d-8e12-e352a3318be1": {
|
||||||
|
"name": "Groceries, obviously",
|
||||||
|
"icon": "cart",
|
||||||
|
"color": "pink",
|
||||||
|
"cookieStoreId": "firefox-container-591",
|
||||||
|
"macAddonUUID": "9ff381e3-4c11-420d-8e12-e352a3318be1"
|
||||||
|
},
|
||||||
|
"identity@@_3dc916fb-8c0a-4538-9758-73ef819a45f7": {
|
||||||
|
"name": "Facebook",
|
||||||
|
"icon": "fence",
|
||||||
|
"color": "toolbar",
|
||||||
|
"cookieStoreId": "firefox-container-592",
|
||||||
|
"macAddonUUID": "3dc916fb-8c0a-4538-9758-73ef819a45f7"
|
||||||
|
},
|
||||||
|
"identity@@_63e5212f-0858-418e-b5a3-09c2dea61fcd": {
|
||||||
|
"name": "Oscar",
|
||||||
|
"icon": "dollar",
|
||||||
|
"color": "green",
|
||||||
|
"cookieStoreId": "firefox-container-593",
|
||||||
|
"macAddonUUID": "63e5212f-0858-418e-b5a3-09c2dea61fcd"
|
||||||
|
},
|
||||||
|
"siteContainerMap@@_developer.mozilla.org": {
|
||||||
|
"userContextId": "588",
|
||||||
|
"neverAsk": true,
|
||||||
|
"identityMacAddonUUID": "d20d7af2-9866-468e-bb43-541efe8c2c2e",
|
||||||
|
"hostname": "developer.mozilla.org"
|
||||||
|
},
|
||||||
|
"siteContainerMap@@_reddit.com": {
|
||||||
|
"userContextId": "592",
|
||||||
|
"neverAsk": true,
|
||||||
|
"identityMacAddonUUID": "3dc916fb-8c0a-4538-9758-73ef819a45f7",
|
||||||
|
"hostname": "reddit.com"
|
||||||
|
},
|
||||||
|
"siteContainerMap@@_twitter.com": {
|
||||||
|
"userContextId": "589",
|
||||||
|
"neverAsk": true,
|
||||||
|
"identityMacAddonUUID": "cdd73c20-c26a-4c06-9b17-735c1f5e9187",
|
||||||
|
"hostname": "twitter.com"
|
||||||
|
},
|
||||||
|
"siteContainerMap@@_www.facebook.com": {
|
||||||
|
"userContextId": "590",
|
||||||
|
"neverAsk": true,
|
||||||
|
"identityMacAddonUUID": "32cc4a9b-05ed-4e54-8e11-732468de62f4",
|
||||||
|
"hostname": "www.facebook.com"
|
||||||
|
},
|
||||||
|
"siteContainerMap@@_www.linkedin.com": {
|
||||||
|
"userContextId": "591",
|
||||||
|
"neverAsk": true,
|
||||||
|
"identityMacAddonUUID": "9ff381e3-4c11-420d-8e12-e352a3318be1",
|
||||||
|
"hostname": "www.linkedin.com"
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const DUPE_TEST_LOCAL = {
|
||||||
|
"beenSynced": true,
|
||||||
|
"browserActionBadgesClicked": [
|
||||||
|
"6.1.1"
|
||||||
|
],
|
||||||
|
"containerTabsOpened": 7,
|
||||||
|
"identitiesState@@_firefox-default": {
|
||||||
|
"hiddenTabs": []
|
||||||
|
},
|
||||||
|
"onboarding-stage": 5,
|
||||||
|
};
|
||||||
|
|
||||||
|
const DUPE_TEST_ASSIGNMENTS = [
|
||||||
|
"siteContainerMap@@_developer.mozilla.org",
|
||||||
|
"siteContainerMap@@_reddit.com",
|
||||||
|
"siteContainerMap@@_twitter.com",
|
||||||
|
"siteContainerMap@@_www.facebook.com",
|
||||||
|
"siteContainerMap@@_www.linkedin.com"
|
||||||
|
];
|
||||||
|
|
||||||
|
const SITE_ASSIGNMENT_TEST = [
|
||||||
|
"siteContainerMap@@_developer.mozilla.org",
|
||||||
|
"siteContainerMap@@_www.facebook.com",
|
||||||
|
"siteContainerMap@@_www.google.com",
|
||||||
|
"siteContainerMap@@_bugzilla.mozilla.org"
|
||||||
|
];
|
||||||
|
|
||||||
|
const DUPE_TEST_IDENTS = [
|
||||||
|
{
|
||||||
|
"name": "Personal",
|
||||||
|
"icon": "fingerprint",
|
||||||
|
"color": "blue",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Banking",
|
||||||
|
"icon": "pet",
|
||||||
|
"color": "green",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Mozilla",
|
||||||
|
"icon": "briefcase",
|
||||||
|
"color": "red",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Groceries, obviously",
|
||||||
|
"icon": "cart",
|
||||||
|
"color": "orange",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Facebook",
|
||||||
|
"icon": "fence",
|
||||||
|
"color": "toolbar",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Big Bird",
|
||||||
|
"icon": "dollar",
|
||||||
|
"color": "yellow",
|
||||||
|
}
|
||||||
|
];
|
||||||
|
|
||||||
|
const CI_ERROR_TEST_SYNC = {
|
||||||
|
"identities": [
|
||||||
|
{
|
||||||
|
"name": "Personal",
|
||||||
|
"icon": "fingerprint",
|
||||||
|
"iconUrl": "resource://usercontext-content/fingerprint.svg",
|
||||||
|
"color": "blue",
|
||||||
|
"colorCode": "#37adff",
|
||||||
|
"cookieStoreId": "firefox-container-6"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Mozilla",
|
||||||
|
"icon": "fruit",
|
||||||
|
"iconUrl": "resource://usercontext-content/fruit.svg",
|
||||||
|
"color": "purple",
|
||||||
|
"colorCode": "#af51f5",
|
||||||
|
"cookieStoreId": "firefox-container-8"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Groceries, obviously",
|
||||||
|
"icon": "cart",
|
||||||
|
"iconUrl": "resource://usercontext-content/cart.svg",
|
||||||
|
"color": "yellow",
|
||||||
|
"colorCode": "#ffcb00",
|
||||||
|
"cookieStoreId": "firefox-container-9"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Facebook",
|
||||||
|
"icon": "circle",
|
||||||
|
"iconUrl": "resource://usercontext-content/circle.svg",
|
||||||
|
"color": "blue",
|
||||||
|
"colorCode": "#37adff",
|
||||||
|
"cookieStoreId": "firefox-container-10"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Work",
|
||||||
|
"icon": "briefcase",
|
||||||
|
"iconUrl": "resource://usercontext-content/briefcase.svg",
|
||||||
|
"color": "orange",
|
||||||
|
"colorCode": "#ff9f00",
|
||||||
|
"cookieStoreId": "firefox-container-11"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Greg's container",
|
||||||
|
"icon": "vacation",
|
||||||
|
"iconUrl": "resource://usercontext-content/vacation.svg",
|
||||||
|
"color": "yellow",
|
||||||
|
"colorCode": "#ffcb00",
|
||||||
|
"cookieStoreId": "firefox-container-14"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"deletedIdentityList": [
|
||||||
|
"8098140e-d406-4321-b4f5-24763b4f9513",
|
||||||
|
"73aebc7a-286f-408a-9a94-a06d29b288e0",
|
||||||
|
"8f153224-bbe8-4664-ba02-0293ddec3e78"
|
||||||
|
],
|
||||||
|
"cookieStoreIDmap": {
|
||||||
|
"firefox-container-10": "58956e95-43fb-44af-95c0-1ec8d83e1e13",
|
||||||
|
"firefox-container-11": "0269558d-6be7-487b-beb1-b720b346d09b",
|
||||||
|
"firefox-container-14": "e48d04cf-6277-4236-8f3d-611287d0caf2",
|
||||||
|
"firefox-container-6": "869a7563-030d-4a63-8a84-209270561d3c",
|
||||||
|
"firefox-container-8": "73aebc7a-286f-408a-9a94-a06d29b288e0",
|
||||||
|
"firefox-container-9": "4831fef4-6f43-47fb-a578-ccdc3ee7f883"
|
||||||
|
},
|
||||||
|
"assignedSites": {
|
||||||
|
"siteContainerMap@@_bugzilla.mozilla.org": {
|
||||||
|
"userContextId": "11",
|
||||||
|
"neverAsk": true,
|
||||||
|
"identityMacAddonUUID": "0269558d-6be7-487b-beb1-b720b346d09b",
|
||||||
|
"hostname": "bugzilla.mozilla.org"
|
||||||
|
},
|
||||||
|
"siteContainerMap@@_www.amazon.com": {
|
||||||
|
"userContextId": "14",
|
||||||
|
"neverAsk": false,
|
||||||
|
"identityMacAddonUUID": "e48d04cf-6277-4236-8f3d-611287d0caf2",
|
||||||
|
"hostname": "www.amazon.com"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"deletedSiteList": [
|
||||||
|
"siteContainerMap@@_www.facebook.com"
|
||||||
|
]
|
||||||
|
};
|
||||||
|
|
||||||
|
const CI_ERROR_TEST_LOCAL = {
|
||||||
|
"browserActionBadgesClicked": [
|
||||||
|
"6.1.1"
|
||||||
|
],
|
||||||
|
"containerTabsOpened": 6,
|
||||||
|
"onboarding-stage": 5,
|
||||||
|
};
|
||||||
|
|
||||||
|
const CI_ERROR_TEST_SITES = [
|
||||||
|
"siteContainerMap@@_bugzilla.mozilla.org",
|
||||||
|
"siteContainerMap@@_www.bankofoklahoma.com",
|
||||||
|
"siteContainerMap@@_www.mozilla.org",
|
||||||
|
"siteContainerMap@@_www.reddit.com"
|
||||||
|
];
|
||||||
|
|
||||||
|
const CI_ERROR_TEST_IDENTS = [
|
||||||
|
{
|
||||||
|
"name": "Personal",
|
||||||
|
"icon": "fingerprint",
|
||||||
|
"color": "blue",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Work",
|
||||||
|
"icon": "briefcase",
|
||||||
|
"color": "orange",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Banking",
|
||||||
|
"icon": "dollar",
|
||||||
|
"color": "green",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Mozilla",
|
||||||
|
"icon": "fruit",
|
||||||
|
"color": "purple",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Groceries, obviously",
|
||||||
|
"icon": "cart",
|
||||||
|
"color": "yellow",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Facebook",
|
||||||
|
"icon": "circle",
|
||||||
|
"color": "blue",
|
||||||
|
}
|
||||||
|
];
|
|
@ -1,81 +0,0 @@
|
||||||
module.exports = {
|
|
||||||
browser: {
|
|
||||||
async initializeWithTab(details = {
|
|
||||||
cookieStoreId: "firefox-default"
|
|
||||||
}) {
|
|
||||||
let tab;
|
|
||||||
await buildDom({
|
|
||||||
background: {
|
|
||||||
async afterBuild(background) {
|
|
||||||
tab = await background.browser.tabs._create(details);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
popup: {
|
|
||||||
jsdom: {
|
|
||||||
beforeParse(window) {
|
|
||||||
window.browser.storage.local.set({
|
|
||||||
"browserActionBadgesClicked": [],
|
|
||||||
"onboarding-stage": 6,
|
|
||||||
"achievements": [],
|
|
||||||
"syncEnabled": true
|
|
||||||
});
|
|
||||||
window.browser.storage.local.set.resetHistory();
|
|
||||||
window.browser.storage.sync.clear();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
return tab;
|
|
||||||
},
|
|
||||||
|
|
||||||
async openNewTab(tab, options = {}) {
|
|
||||||
return background.browser.tabs._create(tab, options);
|
|
||||||
},
|
|
||||||
|
|
||||||
async initSyncTest(details = {}) {
|
|
||||||
if (!details.cookieStoreId) details.cookieStoreId = "firefox-default";
|
|
||||||
if (!details.localStorage) {
|
|
||||||
details.localStorage = {
|
|
||||||
"browserActionBadgesClicked": [],
|
|
||||||
"onboarding-stage": 6,
|
|
||||||
"achievements": [],
|
|
||||||
"syncEnabled": true
|
|
||||||
};
|
|
||||||
}
|
|
||||||
if (!details.syncStorage) details.syncStorage = {};
|
|
||||||
let tab;
|
|
||||||
await buildDom({
|
|
||||||
background: {
|
|
||||||
async afterBuild(background) {
|
|
||||||
tab = await background.browser.tabs._create({ cookieStoreId: details.cookieStoreId });
|
|
||||||
}
|
|
||||||
},
|
|
||||||
popup: {
|
|
||||||
jsdom: {
|
|
||||||
beforeParse(window) {
|
|
||||||
window.browser.storage.clear();
|
|
||||||
window.browser.storage.local.set(details.localStorage);
|
|
||||||
window.browser.storage.local.set.resetHistory();
|
|
||||||
window.browser.storage.sync.clear();
|
|
||||||
window.browser.storage.sync.set(details.syncStorage);
|
|
||||||
window.browser.storage.sync.set.resetHistory();
|
|
||||||
}
|
|
||||||
},
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
return tab;
|
|
||||||
},
|
|
||||||
},
|
|
||||||
|
|
||||||
popup: {
|
|
||||||
async clickElementById(id) {
|
|
||||||
await popup.helper.clickElementById(id);
|
|
||||||
},
|
|
||||||
|
|
||||||
async clickLastMatchingElementByQuerySelector(querySelector) {
|
|
||||||
await popup.helper.clickElementByQuerySelectorAll(querySelector, "last");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
|
@ -1,16 +1,19 @@
|
||||||
describe("#1168", () => {
|
const {expect, sinon, initializeWithTab} = require("../common");
|
||||||
describe("when navigation happens too slow after opening new tab to a page which then redirects", () => {
|
|
||||||
let clock, tab;
|
|
||||||
|
|
||||||
beforeEach(async () => {
|
describe("#1168", function () {
|
||||||
await helper.browser.initializeWithTab({
|
describe("when navigation happens too slow after opening new tab to a page which then redirects", function () {
|
||||||
|
let clock, tab, background;
|
||||||
|
|
||||||
|
beforeEach(async function () {
|
||||||
|
this.webExt = await initializeWithTab({
|
||||||
cookieStoreId: "firefox-container-1",
|
cookieStoreId: "firefox-container-1",
|
||||||
url: "https://bugzilla.mozilla.org"
|
url: "https://bugzilla.mozilla.org"
|
||||||
});
|
});
|
||||||
await helper.popup.clickElementById("container-page-assigned");
|
|
||||||
|
await this.webExt.popup.helper.clickElementById("container-page-assigned");
|
||||||
|
|
||||||
clock = sinon.useFakeTimers();
|
clock = sinon.useFakeTimers();
|
||||||
tab = await helper.browser.openNewTab({});
|
tab = await this.webExt.browser.tabs._create({});
|
||||||
|
|
||||||
clock.tick(2000);
|
clock.tick(2000);
|
||||||
|
|
||||||
|
@ -20,15 +23,16 @@ describe("#1168", () => {
|
||||||
]);
|
]);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
afterEach(function () {
|
||||||
|
this.webExt.destroy();
|
||||||
|
clock.restore();
|
||||||
|
});
|
||||||
|
|
||||||
// Not solved yet
|
// Not solved yet
|
||||||
// See: https://github.com/mozilla/multi-account-containers/issues/1168#issuecomment-378394091
|
// See: https://github.com/mozilla/multi-account-containers/issues/1168#issuecomment-378394091
|
||||||
it.skip("should remove the old tab", async () => {
|
it.skip("should remove the old tab", async function () {
|
||||||
expect(background.browser.tabs.create).to.have.been.calledOnce;
|
expect(background.browser.tabs.create).to.have.been.calledOnce;
|
||||||
expect(background.browser.tabs.remove).to.have.been.calledWith(tab.id);
|
expect(background.browser.tabs.remove).to.have.been.calledWith(tab.id);
|
||||||
});
|
});
|
||||||
|
|
||||||
afterEach(() => {
|
|
||||||
clock.restore();
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
});
|
});
|
|
@ -1,15 +1,18 @@
|
||||||
describe("#940", () => {
|
const {expect, sinon, initializeWithTab} = require("../common");
|
||||||
describe("when other onBeforeRequestHandlers are faster and redirect with the same requestId", () => {
|
|
||||||
it("should not open two confirm pages", async () => {
|
describe("#940", function () {
|
||||||
await helper.browser.initializeWithTab({
|
describe("when other onBeforeRequestHandlers are faster and redirect with the same requestId", function () {
|
||||||
|
it("should not open two confirm pages", async function () {
|
||||||
|
const webExtension = await initializeWithTab({
|
||||||
cookieStoreId: "firefox-container-1",
|
cookieStoreId: "firefox-container-1",
|
||||||
url: "http://example.com"
|
url: "http://example.com"
|
||||||
});
|
});
|
||||||
await helper.popup.clickElementById("container-page-assigned");
|
|
||||||
|
await webExtension.popup.helper.clickElementById("container-page-assigned");
|
||||||
|
|
||||||
const responses = {};
|
const responses = {};
|
||||||
await helper.browser.openNewTab({
|
await webExtension.background.browser.tabs._create({
|
||||||
url: "http://example.com"
|
url: "https://example.com"
|
||||||
}, {
|
}, {
|
||||||
options: {
|
options: {
|
||||||
webRequestRedirects: ["https://example.com"],
|
webRequestRedirects: ["https://example.com"],
|
||||||
|
@ -23,46 +26,55 @@ describe("#940", () => {
|
||||||
expect(result).to.deep.equal({
|
expect(result).to.deep.equal({
|
||||||
cancel: true
|
cancel: true
|
||||||
});
|
});
|
||||||
background.browser.tabs.create.should.have.been.calledOnce;
|
webExtension.browser.tabs.create.should.have.been.calledOnce;
|
||||||
|
|
||||||
|
webExtension.destroy();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe("when redirects change requestId midflight", () => {
|
describe("when redirects change requestId midflight", function () {
|
||||||
let newTab;
|
beforeEach(async function () {
|
||||||
const newTabResponses = {};
|
|
||||||
const redirectedRequest = async (options = {}) => {
|
this.webExt = await initializeWithTab({
|
||||||
global.clock = sinon.useFakeTimers();
|
|
||||||
newTab = await helper.browser.openNewTab({
|
|
||||||
url: "http://youtube.com"
|
|
||||||
}, {
|
|
||||||
options: Object.assign({
|
|
||||||
webRequestRedirects: [
|
|
||||||
"https://youtube.com",
|
|
||||||
"https://www.youtube.com",
|
|
||||||
{
|
|
||||||
url: "https://www.youtube.com",
|
|
||||||
webRequest: {
|
|
||||||
requestId: 2
|
|
||||||
}
|
|
||||||
}
|
|
||||||
],
|
|
||||||
webRequestError: true,
|
|
||||||
instantRedirects: true
|
|
||||||
}, options),
|
|
||||||
responses: newTabResponses
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
beforeEach(async () => {
|
|
||||||
await helper.browser.initializeWithTab({
|
|
||||||
cookieStoreId: "firefox-container-1",
|
cookieStoreId: "firefox-container-1",
|
||||||
url: "https://www.youtube.com"
|
url: "https://www.youtube.com"
|
||||||
});
|
});
|
||||||
await helper.popup.clickElementById("container-page-assigned");
|
await this.webExt.popup.helper.clickElementById("container-page-assigned");
|
||||||
|
|
||||||
|
global.clock = sinon.useFakeTimers();
|
||||||
|
this.redirectedRequest = async (options = {}) => {
|
||||||
|
const newTabResponses = {};
|
||||||
|
const newTab = await this.webExt.browser.tabs._create({
|
||||||
|
url: "http://youtube.com"
|
||||||
|
}, {
|
||||||
|
options: Object.assign({
|
||||||
|
webRequestRedirects: [
|
||||||
|
"https://youtube.com",
|
||||||
|
"https://www.youtube.com",
|
||||||
|
{
|
||||||
|
url: "https://www.youtube.com",
|
||||||
|
webRequest: {
|
||||||
|
requestId: 2
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
webRequestError: true,
|
||||||
|
instantRedirects: true
|
||||||
|
}, options),
|
||||||
|
responses: newTabResponses
|
||||||
|
});
|
||||||
|
|
||||||
|
return [newTabResponses, newTab];
|
||||||
|
};
|
||||||
});
|
});
|
||||||
|
|
||||||
it("should not open two confirm pages", async () => {
|
afterEach(function () {
|
||||||
await redirectedRequest();
|
this.webExt.destroy();
|
||||||
|
global.clock.restore();
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should not open two confirm pages", async function () {
|
||||||
|
const [newTabResponses] = await this.redirectedRequest();
|
||||||
|
|
||||||
// http://youtube.com is not assigned, no cancel, no reopening
|
// http://youtube.com is not assigned, no cancel, no reopening
|
||||||
expect(await newTabResponses.webRequest.onBeforeRequest[0]).to.deep.equal({});
|
expect(await newTabResponses.webRequest.onBeforeRequest[0]).to.deep.equal({});
|
||||||
|
@ -80,17 +92,17 @@ describe("#940", () => {
|
||||||
cancel: true
|
cancel: true
|
||||||
});
|
});
|
||||||
|
|
||||||
background.browser.tabs.create.should.have.been.calledOnce;
|
this.webExt.background.browser.tabs.create.should.have.been.calledOnce;
|
||||||
});
|
});
|
||||||
|
|
||||||
it("should uncancel after webRequest.onCompleted", async () => {
|
it("should uncancel after webRequest.onCompleted", async function () {
|
||||||
await redirectedRequest();
|
const [newTabResponses, newTab] = await this.redirectedRequest();
|
||||||
// remove onCompleted listeners because in the real world this request would never complete
|
// remove onCompleted listeners because in the real world this request would never complete
|
||||||
// and thus might trigger unexpected behavior because the tab gets removed when reopening
|
// and thus might trigger unexpected behavior because the tab gets removed when reopening
|
||||||
background.browser.webRequest.onCompleted.addListener = sinon.stub();
|
this.webExt.background.browser.webRequest.onCompleted.addListener = sinon.stub();
|
||||||
background.browser.tabs.create.resetHistory();
|
this.webExt.background.browser.tabs.create.resetHistory();
|
||||||
// we create a tab with the same id and use the same request id to see if uncanceled
|
// we create a tab with the same id and use the same request id to see if uncanceled
|
||||||
await helper.browser.openNewTab({
|
await this.webExt.browser.tabs._create({
|
||||||
id: newTab.id,
|
id: newTab.id,
|
||||||
url: "https://www.youtube.com"
|
url: "https://www.youtube.com"
|
||||||
}, {
|
}, {
|
||||||
|
@ -101,14 +113,14 @@ describe("#940", () => {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
background.browser.tabs.create.should.have.been.calledOnce;
|
this.webExt.background.browser.tabs.create.should.have.been.calledOnce;
|
||||||
});
|
});
|
||||||
|
|
||||||
it("should uncancel after webRequest.onErrorOccurred", async () => {
|
it("should uncancel after webRequest.onErrorOccurred", async function () {
|
||||||
await redirectedRequest();
|
const [newTabResponses, newTab] = await this.redirectedRequest();
|
||||||
background.browser.tabs.create.resetHistory();
|
this.webExt.background.browser.tabs.create.resetHistory();
|
||||||
// we create a tab with the same id and use the same request id to see if uncanceled
|
// we create a tab with the same id and use the same request id to see if uncanceled
|
||||||
await helper.browser.openNewTab({
|
await this.webExt.browser.tabs._create({
|
||||||
id: newTab.id,
|
id: newTab.id,
|
||||||
url: "https://www.youtube.com"
|
url: "https://www.youtube.com"
|
||||||
}, {
|
}, {
|
||||||
|
@ -120,18 +132,18 @@ describe("#940", () => {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
background.browser.tabs.create.should.have.been.calledOnce;
|
this.webExt.background.browser.tabs.create.should.have.been.calledOnce;
|
||||||
});
|
});
|
||||||
|
|
||||||
it("should uncancel after 2 seconds", async () => {
|
it("should uncancel after 2 seconds", async function () {
|
||||||
await redirectedRequest({
|
const [newTabResponses, newTab] = await this.redirectedRequest({
|
||||||
webRequestDontYield: ["onCompleted", "onErrorOccurred"]
|
webRequestDontYield: ["onCompleted", "onErrorOccurred"]
|
||||||
});
|
});
|
||||||
global.clock.tick(2000);
|
global.clock.tick(2000);
|
||||||
|
|
||||||
background.browser.tabs.create.resetHistory();
|
this.webExt.background.browser.tabs.create.resetHistory();
|
||||||
// we create a tab with the same id and use the same request id to see if uncanceled
|
// we create a tab with the same id and use the same request id to see if uncanceled
|
||||||
await helper.browser.openNewTab({
|
await this.webExt.browser.tabs._create({
|
||||||
id: newTab.id,
|
id: newTab.id,
|
||||||
url: "https://www.youtube.com"
|
url: "https://www.youtube.com"
|
||||||
}, {
|
}, {
|
||||||
|
@ -143,13 +155,13 @@ describe("#940", () => {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
background.browser.tabs.create.should.have.been.calledOnce;
|
this.webExt.background.browser.tabs.create.should.have.been.calledOnce;
|
||||||
});
|
});
|
||||||
|
|
||||||
it("should not influence the canceled url in other tabs", async () => {
|
it("should not influence the canceled url in other tabs", async function () {
|
||||||
await redirectedRequest();
|
await this.redirectedRequest();
|
||||||
background.browser.tabs.create.resetHistory();
|
this.webExt.background.browser.tabs.create.resetHistory();
|
||||||
await helper.browser.openNewTab({
|
await this.webExt.browser.tabs._create({
|
||||||
cookieStoreId: "firefox-default",
|
cookieStoreId: "firefox-default",
|
||||||
url: "https://www.youtube.com"
|
url: "https://www.youtube.com"
|
||||||
}, {
|
}, {
|
||||||
|
@ -158,11 +170,7 @@ describe("#940", () => {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
background.browser.tabs.create.should.have.been.calledOnce;
|
this.webExt.background.browser.tabs.create.should.have.been.calledOnce;
|
||||||
});
|
|
||||||
|
|
||||||
afterEach(() => {
|
|
||||||
global.clock.restore();
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
Loading…
Add table
Reference in a new issue