gecko-dev/browser/components/newtab/test/unit/asrouter/ASRouterPreferences.test.js
2018-10-12 19:13:39 +00:00

220 lines
9.3 KiB
JavaScript

import {_ASRouterPreferences, ASRouterPreferences as ASRouterPreferencesSingleton, TEST_PROVIDER} from "lib/ASRouterPreferences.jsm";
const FAKE_PROVIDERS = [{id: "foo"}, {id: "bar"}];
const PROVIDER_PREF = "browser.newtabpage.activity-stream.asrouter.messageProviders";
const DEVTOOLS_PREF = "browser.newtabpage.activity-stream.asrouter.devtoolsEnabled";
const SNIPPETS_USER_PREF = "browser.newtabpage.activity-stream.feeds.snippets";
/** NUMBER_OF_PREFS_TO_OBSERVE includes:
* 1. asrouter.messageProvider
* 2. asrouter.devtoolsEnabled
* 3. browser.newtabpage.activity-stream.feeds.snippets (user preference - snippets)
*/
const NUMBER_OF_PREFS_TO_OBSERVE = 3;
describe("ASRouterPreferences", () => {
let ASRouterPreferences;
let sandbox;
let addObserverStub;
let stringPrefStub;
let boolPrefStub;
beforeEach(() => {
ASRouterPreferences = new _ASRouterPreferences();
sandbox = sinon.sandbox.create();
addObserverStub = sandbox.stub(global.Services.prefs, "addObserver");
stringPrefStub = sandbox.stub(global.Services.prefs, "getStringPref").withArgs(PROVIDER_PREF).returns(JSON.stringify(FAKE_PROVIDERS));
boolPrefStub = sandbox.stub(global.Services.prefs, "getBoolPref").returns(false);
});
afterEach(() => {
sandbox.restore();
});
it("ASRouterPreferences should be an instance of _ASRouterPreferences", () => {
assert.instanceOf(ASRouterPreferencesSingleton, _ASRouterPreferences);
});
describe("#init", () => {
it("should set ._initialized to true", () => {
ASRouterPreferences.init();
assert.isTrue(ASRouterPreferences._initialized);
});
it(`should set ${NUMBER_OF_PREFS_TO_OBSERVE} observers and not re-initialize if already initialized`, () => {
ASRouterPreferences.init();
assert.callCount(addObserverStub, NUMBER_OF_PREFS_TO_OBSERVE);
ASRouterPreferences.init();
ASRouterPreferences.init();
assert.callCount(addObserverStub, NUMBER_OF_PREFS_TO_OBSERVE);
});
});
describe("#uninit", () => {
it("should set ._initialized to false", () => {
ASRouterPreferences.init();
ASRouterPreferences.uninit();
assert.isFalse(ASRouterPreferences._initialized);
});
it("should clear cached values for ._initialized, .devtoolsEnabled", () => {
ASRouterPreferences.init();
// trigger caching
const result = [ASRouterPreferences.providers, ASRouterPreferences.devtoolsEnabled]; // eslint-disable-line no-unused-vars
assert.isNotNull(ASRouterPreferences._providers, "providers should not be null");
assert.isNotNull(ASRouterPreferences._devtoolsEnabled, "devtolosEnabled should not be null");
ASRouterPreferences.uninit();
assert.isNull(ASRouterPreferences._providers);
assert.isNull(ASRouterPreferences._devtoolsEnabled);
});
it("should clear all listeners and remove observers (only once)", () => {
const removeStub = sandbox.stub(global.Services.prefs, "removeObserver");
ASRouterPreferences.init();
ASRouterPreferences.addListener(() => {});
ASRouterPreferences.addListener(() => {});
assert.equal(ASRouterPreferences._callbacks.size, 2);
ASRouterPreferences.uninit();
// Tests to make sure we don't remove observers that weren't set
ASRouterPreferences.uninit();
assert.callCount(removeStub, NUMBER_OF_PREFS_TO_OBSERVE);
assert.calledWith(removeStub, PROVIDER_PREF);
assert.calledWith(removeStub, DEVTOOLS_PREF);
assert.isEmpty(ASRouterPreferences._callbacks);
});
});
describe(".providers", () => {
it("should return the value the first time .providers is accessed", () => {
ASRouterPreferences.init();
const result = ASRouterPreferences.providers;
assert.deepEqual(result, FAKE_PROVIDERS);
assert.calledOnce(stringPrefStub);
});
it("should return the cached value the second time .providers is accessed", () => {
ASRouterPreferences.init();
const [, secondCall] = [ASRouterPreferences.providers, ASRouterPreferences.providers];
assert.deepEqual(secondCall, FAKE_PROVIDERS);
assert.calledOnce(stringPrefStub);
});
it("should just parse the pref each time if ASRouterPreferences hasn't been initialized yet", () => {
// Intentionally not initialized
const [firstCall, secondCall] = [ASRouterPreferences.providers, ASRouterPreferences.providers];
assert.deepEqual(firstCall, FAKE_PROVIDERS);
assert.deepEqual(secondCall, FAKE_PROVIDERS);
assert.calledTwice(stringPrefStub);
});
it("should return [] if the pref was not parsable", () => {
stringPrefStub.withArgs(PROVIDER_PREF).returns("not json");
ASRouterPreferences.init();
assert.deepEqual(ASRouterPreferences.providers, []);
});
it("should include TEST_PROVIDER if devtools is turned on", () => {
boolPrefStub.withArgs(DEVTOOLS_PREF).returns(true);
ASRouterPreferences.init();
assert.deepEqual(ASRouterPreferences.providers, [TEST_PROVIDER, ...FAKE_PROVIDERS]);
});
});
describe(".devtoolsEnabled", () => {
it("should read the pref the first time .devtoolsEnabled is accessed", () => {
ASRouterPreferences.init();
const result = ASRouterPreferences.devtoolsEnabled;
assert.deepEqual(result, false);
assert.calledOnce(boolPrefStub);
});
it("should return the cached value the second time .devtoolsEnabled is accessed", () => {
ASRouterPreferences.init();
const [, secondCall] = [ASRouterPreferences.devtoolsEnabled, ASRouterPreferences.devtoolsEnabled];
assert.deepEqual(secondCall, false);
assert.calledOnce(boolPrefStub);
});
it("should just parse the pref each time if ASRouterPreferences hasn't been initialized yet", () => {
// Intentionally not initialized
const [firstCall, secondCall] = [ASRouterPreferences.devtoolsEnabled, ASRouterPreferences.devtoolsEnabled];
assert.deepEqual(firstCall, false);
assert.deepEqual(secondCall, false);
assert.calledTwice(boolPrefStub);
});
});
describe(".specialConditions", () => {
it("should return .allowLegacySnippets=true if snippets is not present or disabled", () => {
ASRouterPreferences.init();
let testProviders = [];
sandbox.stub(ASRouterPreferences, "providers").get(() => testProviders);
testProviders = [{id: "foo"}];
assert.isTrue(ASRouterPreferences.specialConditions.allowLegacySnippets);
testProviders = [{id: "snippets", enabled: false}];
assert.isTrue(ASRouterPreferences.specialConditions.allowLegacySnippets);
});
it("should return .allowLegacySnippets=false if snippets is enabled", () => {
ASRouterPreferences.init();
sandbox.stub(ASRouterPreferences, "providers").get(() => [{id: "snippets", enabled: true}]);
assert.isFalse(ASRouterPreferences.specialConditions.allowLegacySnippets);
});
});
describe("#getUserPreference(providerId)", () => {
it("should return the user preference for snippets", () => {
boolPrefStub.withArgs(SNIPPETS_USER_PREF).returns(true);
assert.isTrue(ASRouterPreferences.getUserPreference("snippets"));
});
});
describe("observer, listeners", () => {
it("should invalidate .providers when the pref is changed", () => {
const testProviders = [{id: "newstuff"}];
ASRouterPreferences.init();
assert.deepEqual(ASRouterPreferences.providers, FAKE_PROVIDERS);
stringPrefStub.withArgs(PROVIDER_PREF).returns(JSON.stringify(testProviders));
ASRouterPreferences.observe(null, null, PROVIDER_PREF);
// Cache should be invalidated so we access the new value of the pref now
assert.deepEqual(ASRouterPreferences.providers, testProviders);
});
it("should invalidate .devtoolsEnabled and .providers when the pref is changed", () => {
ASRouterPreferences.init();
assert.isFalse(ASRouterPreferences.devtoolsEnabled);
boolPrefStub.withArgs(DEVTOOLS_PREF).returns(true);
stringPrefStub.withArgs(PROVIDER_PREF).returns("[]");
ASRouterPreferences.observe(null, null, DEVTOOLS_PREF);
// Cache should be invalidated so we access the new value of the pref now
// Note that providers needs to be invalidated because devtools adds test content to it.
assert.isTrue(ASRouterPreferences.devtoolsEnabled);
assert.deepEqual(ASRouterPreferences.providers, [TEST_PROVIDER]);
});
it("should call listeners added with .addListener", () => {
const callback1 = sinon.stub();
const callback2 = sinon.stub();
ASRouterPreferences.init();
ASRouterPreferences.addListener(callback1);
ASRouterPreferences.addListener(callback2);
ASRouterPreferences.observe(null, null, PROVIDER_PREF);
assert.calledWith(callback1, PROVIDER_PREF);
ASRouterPreferences.observe(null, null, DEVTOOLS_PREF);
assert.calledWith(callback2, DEVTOOLS_PREF);
});
it("should not call listeners after they are removed with .removeListeners", () => {
const callback = sinon.stub();
ASRouterPreferences.init();
ASRouterPreferences.addListener(callback);
ASRouterPreferences.observe(null, null, PROVIDER_PREF);
assert.calledWith(callback, PROVIDER_PREF);
callback.reset();
ASRouterPreferences.removeListener(callback);
ASRouterPreferences.observe(null, null, DEVTOOLS_PREF);
assert.notCalled(callback);
});
});
});