diff options
Diffstat (limited to '')
-rw-r--r-- | browser/components/newtab/test/unit/lib/AboutPreferences.test.js | 429 |
1 files changed, 429 insertions, 0 deletions
diff --git a/browser/components/newtab/test/unit/lib/AboutPreferences.test.js b/browser/components/newtab/test/unit/lib/AboutPreferences.test.js new file mode 100644 index 0000000000..7438d8247c --- /dev/null +++ b/browser/components/newtab/test/unit/lib/AboutPreferences.test.js @@ -0,0 +1,429 @@ +/* global Services */ +import { + AboutPreferences, + PREFERENCES_LOADED_EVENT, +} from "lib/AboutPreferences.sys.mjs"; +import { + actionTypes as at, + actionCreators as ac, +} from "common/Actions.sys.mjs"; +import { GlobalOverrider } from "test/unit/utils"; + +describe("AboutPreferences Feed", () => { + let globals; + let sandbox; + let Sections; + let DiscoveryStream; + let instance; + + beforeEach(() => { + globals = new GlobalOverrider(); + sandbox = globals.sandbox; + Sections = []; + DiscoveryStream = { config: { enabled: false } }; + instance = new AboutPreferences(); + instance.store = { + dispatch: sandbox.stub(), + getState: () => ({ Sections, DiscoveryStream }), + }; + globals.set("NimbusFeatures", { + newtab: { getAllVariables: sandbox.stub() }, + }); + }); + afterEach(() => { + globals.restore(); + }); + + describe("#onAction", () => { + it("should call .init() on an INIT action", () => { + const stub = sandbox.stub(instance, "init"); + + instance.onAction({ type: at.INIT }); + + assert.calledOnce(stub); + }); + it("should call .uninit() on an UNINIT action", () => { + const stub = sandbox.stub(instance, "uninit"); + + instance.onAction({ type: at.UNINIT }); + + assert.calledOnce(stub); + }); + it("should call .openPreferences on SETTINGS_OPEN", () => { + const action = { + type: at.SETTINGS_OPEN, + _target: { browser: { ownerGlobal: { openPreferences: sinon.spy() } } }, + }; + instance.onAction(action); + assert.calledOnce(action._target.browser.ownerGlobal.openPreferences); + }); + it("should call .BrowserOpenAddonsMgr with the extension id on OPEN_WEBEXT_SETTINGS", () => { + const action = { + type: at.OPEN_WEBEXT_SETTINGS, + data: "foo", + _target: { + browser: { ownerGlobal: { BrowserOpenAddonsMgr: sinon.spy() } }, + }, + }; + instance.onAction(action); + assert.calledWith( + action._target.browser.ownerGlobal.BrowserOpenAddonsMgr, + "addons://detail/foo" + ); + }); + }); + describe("#observe", () => { + it("should watch for about:preferences loading", () => { + sandbox.stub(Services.obs, "addObserver"); + + instance.init(); + + assert.calledOnce(Services.obs.addObserver); + assert.calledWith( + Services.obs.addObserver, + instance, + PREFERENCES_LOADED_EVENT + ); + }); + it("should stop watching on uninit", () => { + sandbox.stub(Services.obs, "removeObserver"); + + instance.uninit(); + + assert.calledOnce(Services.obs.removeObserver); + assert.calledWith( + Services.obs.removeObserver, + instance, + PREFERENCES_LOADED_EVENT + ); + }); + it("should try to render on event", async () => { + const stub = sandbox.stub(instance, "renderPreferences"); + Sections.push({}); + + await instance.observe(window, PREFERENCES_LOADED_EVENT); + + assert.calledOnce(stub); + assert.equal(stub.firstCall.args[0], window); + assert.include(stub.firstCall.args[1], Sections[0]); + }); + it("Hide topstories rows select in sections if discovery stream is enabled", async () => { + const stub = sandbox.stub(instance, "renderPreferences"); + + Sections.push({ + rowsPref: "row_pref", + maxRows: 3, + pref: { descString: "foo" }, + learnMore: { link: "https://foo.com" }, + id: "topstories", + }); + DiscoveryStream = { config: { enabled: true } }; + + await instance.observe(window, PREFERENCES_LOADED_EVENT); + + assert.calledOnce(stub); + const [, structure] = stub.firstCall.args; + assert.equal(structure[0].id, "search"); + assert.equal(structure[1].id, "topsites"); + assert.equal(structure[2].id, "topstories"); + assert.isEmpty(structure[2].rowsPref); + }); + }); + describe("#renderPreferences", () => { + let node; + let prefStructure; + let Preferences; + let gHomePane; + const testRender = () => + instance.renderPreferences( + { + document: { + createXULElement: sandbox.stub().returns(node), + l10n: { + setAttributes(el, id, args) { + el.setAttribute("data-l10n-id", id); + el.setAttribute("data-l10n-args", JSON.stringify(args)); + }, + }, + createProcessingInstruction: sandbox.stub(), + createElementNS: sandbox.stub().callsFake((NS, el) => node), + getElementById: sandbox.stub().returns(node), + insertBefore: sandbox.stub().returnsArg(0), + querySelector: sandbox + .stub() + .returns({ appendChild: sandbox.stub() }), + }, + Preferences, + gHomePane, + }, + prefStructure, + DiscoveryStream.config + ); + beforeEach(() => { + node = { + appendChild: sandbox.stub().returnsArg(0), + addEventListener: sandbox.stub(), + classList: { add: sandbox.stub(), remove: sandbox.stub() }, + cloneNode: sandbox.stub().returnsThis(), + insertAdjacentElement: sandbox.stub().returnsArg(1), + setAttribute: sandbox.stub(), + remove: sandbox.stub(), + style: {}, + }; + prefStructure = []; + Preferences = { + add: sandbox.stub(), + get: sandbox.stub().returns({ + on: sandbox.stub(), + }), + }; + gHomePane = { toggleRestoreDefaultsBtn: sandbox.stub() }; + }); + describe("#getString", () => { + it("should not fail if titleString is not provided", () => { + prefStructure = [{ pref: {} }]; + + testRender(); + assert.calledWith( + node.setAttribute, + "data-l10n-id", + sinon.match.typeOf("undefined") + ); + }); + it("should return the string id if titleString is just a string", () => { + const titleString = "foo"; + prefStructure = [{ pref: { titleString } }]; + + testRender(); + assert.calledWith(node.setAttribute, "data-l10n-id", titleString); + }); + it("should set id and args if titleString is an object with id and values", () => { + const titleString = { id: "foo", values: { provider: "bar" } }; + prefStructure = [{ pref: { titleString } }]; + + testRender(); + assert.calledWith(node.setAttribute, "data-l10n-id", titleString.id); + assert.calledWith( + node.setAttribute, + "data-l10n-args", + JSON.stringify(titleString.values) + ); + }); + }); + describe("#linkPref", () => { + it("should add a pref to the global", () => { + prefStructure = [{ pref: { feed: "feed" } }]; + + testRender(); + + assert.calledOnce(Preferences.add); + }); + it("should skip adding if not shown", () => { + prefStructure = [{ shouldHidePref: true }]; + + testRender(); + + assert.notCalled(Preferences.add); + }); + }); + describe("pref icon", () => { + it("should default to webextension icon", () => { + prefStructure = [{ pref: { feed: "feed" } }]; + + testRender(); + + assert.calledWith( + node.setAttribute, + "src", + "chrome://activity-stream/content/data/content/assets/glyph-webextension-16.svg" + ); + }); + it("should use desired glyph icon", () => { + prefStructure = [{ icon: "mail", pref: { feed: "feed" } }]; + + testRender(); + + assert.calledWith( + node.setAttribute, + "src", + "chrome://activity-stream/content/data/content/assets/glyph-mail-16.svg" + ); + }); + it("should use specified chrome icon", () => { + const icon = "chrome://the/icon.svg"; + prefStructure = [{ icon, pref: { feed: "feed" } }]; + + testRender(); + + assert.calledWith(node.setAttribute, "src", icon); + }); + }); + describe("title line", () => { + it("should render a title", () => { + const titleString = "the_title"; + prefStructure = [{ pref: { titleString } }]; + + testRender(); + + assert.calledWith(node.setAttribute, "data-l10n-id", titleString); + }); + }); + describe("top stories", () => { + const href = "https://disclaimer/"; + const eventSource = "https://disclaimer/"; + beforeEach(() => { + prefStructure = [ + { + id: "topstories", + pref: { feed: "feed", learnMore: { link: { href } } }, + eventSource, + }, + ]; + }); + it("should add a link for top stories", () => { + testRender(); + assert.calledWith(node.setAttribute, "href", href); + }); + it("should setup a user event for top stories eventSource", () => { + sinon.spy(instance, "setupUserEvent"); + testRender(); + assert.calledWith(node.addEventListener, "command"); + assert.calledWith(instance.setupUserEvent, node, eventSource); + }); + it("should setup a user event for top stories nested pref eventSource", () => { + sinon.spy(instance, "setupUserEvent"); + prefStructure = [ + { + id: "topstories", + pref: { + feed: "feed", + learnMore: { link: { href } }, + nestedPrefs: [ + { + name: "showSponsored", + titleString: + "home-prefs-recommended-by-option-sponsored-stories", + icon: "icon-info", + eventSource: "POCKET_SPOCS", + }, + ], + }, + }, + ]; + testRender(); + assert.calledWith(node.addEventListener, "command"); + assert.calledWith(instance.setupUserEvent, node, "POCKET_SPOCS"); + }); + it("should fire store dispatch with onCommand", () => { + const element = { + addEventListener: (command, action) => { + // Trigger the action right away because we only care about testing the action here. + action({ target: { checked: true } }); + }, + }; + instance.setupUserEvent(element, eventSource); + assert.calledWith( + instance.store.dispatch, + ac.UserEvent({ + event: "PREF_CHANGED", + source: eventSource, + value: { menu_source: "ABOUT_PREFERENCES", status: true }, + }) + ); + }); + }); + describe("description line", () => { + it("should render a description", () => { + const descString = "the_desc"; + prefStructure = [{ pref: { descString } }]; + + testRender(); + + assert.calledWith(node.setAttribute, "data-l10n-id", descString); + }); + it("should render rows dropdown with appropriate number", () => { + prefStructure = [ + { rowsPref: "row_pref", maxRows: 3, pref: { descString: "foo" } }, + ]; + + testRender(); + + assert.calledWith(node.setAttribute, "value", 1); + assert.calledWith(node.setAttribute, "value", 2); + assert.calledWith(node.setAttribute, "value", 3); + }); + }); + describe("nested prefs", () => { + const titleString = "im_nested"; + beforeEach(() => { + prefStructure = [{ pref: { nestedPrefs: [{ titleString }] } }]; + }); + it("should render a nested pref", () => { + testRender(); + + assert.calledWith(node.setAttribute, "data-l10n-id", titleString); + }); + it("should set node hidden to true", () => { + prefStructure[0].pref.nestedPrefs[0].hidden = true; + + testRender(); + + assert.isTrue(node.hidden); + }); + it("should add a change event", () => { + testRender(); + + assert.calledOnce(Preferences.get().on); + assert.calledWith(Preferences.get().on, "change"); + }); + it("should default node disabled to false", async () => { + Preferences.get = sandbox.stub().returns({ + on: sandbox.stub(), + _value: true, + }); + + testRender(); + + assert.isFalse(node.disabled); + }); + it("should default node disabled to true", async () => { + testRender(); + + assert.isTrue(node.disabled); + }); + it("should set node disabled to true", async () => { + const pref = { + on: sandbox.stub(), + _value: true, + }; + Preferences.get = sandbox.stub().returns(pref); + + testRender(); + pref._value = !pref._value; + await Preferences.get().on.firstCall.args[1](); + + assert.isTrue(node.disabled); + }); + it("should set node disabled to false", async () => { + const pref = { + on: sandbox.stub(), + _value: false, + }; + Preferences.get = sandbox.stub().returns(pref); + + testRender(); + pref._value = !pref._value; + await Preferences.get().on.firstCall.args[1](); + + assert.isFalse(node.disabled); + }); + }); + describe("restore defaults btn", () => { + it("should call toggleRestoreDefaultsBtn", () => { + testRender(); + + assert.calledOnce(gHomePane.toggleRestoreDefaultsBtn); + }); + }); + }); +}); |