diff options
Diffstat (limited to 'browser/components/newtab/test')
20 files changed, 219 insertions, 467 deletions
diff --git a/browser/components/newtab/test/browser/browser_newtab_ping.js b/browser/components/newtab/test/browser/browser_newtab_ping.js index 009305eb7a..4ed2fd7200 100644 --- a/browser/components/newtab/test/browser/browser_newtab_ping.js +++ b/browser/components/newtab/test/browser/browser_newtab_ping.js @@ -187,7 +187,7 @@ add_task(async function test_newtab_doesnt_send_nimbus() { let { sessions } = AboutNewTab.activityStream.store.feeds.get("feeds.telemetry"); return !Array.from(sessions.entries()).filter( - ([k, v]) => v.session_id === sessionId + ([, v]) => v.session_id === sessionId ).length; }, "Waiting for sessions to clean up."); // Session ended without a ping being sent. Success! diff --git a/browser/components/newtab/test/schemas/pings.js b/browser/components/newtab/test/schemas/pings.js index 825083066e..fb52602bd4 100644 --- a/browser/components/newtab/test/schemas/pings.js +++ b/browser/components/newtab/test/schemas/pings.js @@ -143,7 +143,7 @@ export const UTSessionPing = Joi.array().items( eventsTelemetryExtraKeys ); -export function chaiAssertions(_chai, utils) { +export function chaiAssertions(_chai) { const { Assertion } = _chai; Assertion.addMethod("validate", function (schema, schemaName) { diff --git a/browser/components/newtab/test/unit/content-src/components/DiscoveryStreamComponents/DSCard.test.jsx b/browser/components/newtab/test/unit/content-src/components/DiscoveryStreamComponents/DSCard.test.jsx index dad4d19fa5..1d572ee3ce 100644 --- a/browser/components/newtab/test/unit/content-src/components/DiscoveryStreamComponents/DSCard.test.jsx +++ b/browser/components/newtab/test/unit/content-src/components/DiscoveryStreamComponents/DSCard.test.jsx @@ -54,9 +54,9 @@ describe("<DSCard>", () => { it("should render a SafeAnchor", () => { wrapper.setProps({ url: "https://foo.com" }); - assert.equal(wrapper.children().at(0).type(), SafeAnchor); + assert.equal(wrapper.children().at(1).type(), SafeAnchor); assert.propertyVal( - wrapper.children().at(0).props(), + wrapper.children().at(1).props(), "url", "https://foo.com" ); @@ -64,14 +64,14 @@ describe("<DSCard>", () => { it("should pass onLinkClick prop", () => { assert.propertyVal( - wrapper.children().at(0).props(), + wrapper.children().at(1).props(), "onLinkClick", wrapper.instance().onLinkClick ); }); it("should render DSLinkMenu", () => { - assert.equal(wrapper.children().at(1).type(), DSLinkMenu); + assert.equal(wrapper.children().at(3).type(), DSLinkMenu); }); it("should start with no .active class", () => { diff --git a/browser/components/newtab/test/unit/content-src/components/DiscoveryStreamComponents/FeatureHighlight.test.jsx b/browser/components/newtab/test/unit/content-src/components/DiscoveryStreamComponents/FeatureHighlight.test.jsx new file mode 100644 index 0000000000..2d7ef66ecf --- /dev/null +++ b/browser/components/newtab/test/unit/content-src/components/DiscoveryStreamComponents/FeatureHighlight.test.jsx @@ -0,0 +1,60 @@ +import { FeatureHighlight } from "content-src/components/DiscoveryStreamComponents/FeatureHighlight/FeatureHighlight"; +import { SponsoredContentHighlight } from "content-src/components/DiscoveryStreamComponents/FeatureHighlight/SponsoredContentHighlight"; +import React from "react"; +import { mount } from "enzyme"; + +describe("<FeatureHighlight>", () => { + let wrapper; + let fakeWindow; + + beforeEach(() => { + wrapper = mount(<FeatureHighlight />); + }); + + it("should render", () => { + assert.ok(wrapper.exists()); + assert.ok(wrapper.find(".feature-highlight").exists()); + }); + + it("should render a title", () => { + wrapper.setProps({ message: "foo" }); + assert.ok(wrapper.find(".feature-highlight-modal p").exists()); + assert.equal(wrapper.find(".feature-highlight-modal p").text(), "foo"); + }); + + it("should open a modal", () => { + assert.ok(wrapper.find(".feature-highlight-modal.closed").exists()); + wrapper.find(".toggle-button").simulate("click"); + assert.ok(wrapper.find(".feature-highlight-modal.opened").exists()); + wrapper.find(".icon-dismiss").simulate("click"); + assert.ok(wrapper.find(".feature-highlight-modal.closed").exists()); + }); + + it("should close a modal if clicking outside", () => { + fakeWindow = { + document: { + addEventListener: (event, handler) => { + fakeWindow.document.handleOutsideClick = handler; + }, + removeEventListener: () => {}, + }, + }; + wrapper.setProps({ windowObj: fakeWindow }); + + wrapper.find(".toggle-button").simulate("click"); + fakeWindow.document.handleOutsideClick({ target: null }); + }); +}); + +describe("<SponsoredContentHighlight>", () => { + let wrapper; + + beforeEach(() => { + wrapper = mount(<SponsoredContentHighlight />); + }); + + it("should render", () => { + assert.ok(wrapper.exists()); + assert.ok(wrapper.find(".sponsored-content-highlight").exists()); + }); +}); diff --git a/browser/components/newtab/test/unit/content-src/components/ModalOverlay.test.jsx b/browser/components/newtab/test/unit/content-src/components/ModalOverlay.test.jsx new file mode 100644 index 0000000000..2320e16fc3 --- /dev/null +++ b/browser/components/newtab/test/unit/content-src/components/ModalOverlay.test.jsx @@ -0,0 +1,69 @@ +import { ModalOverlayWrapper } from "content-src/components/ModalOverlay/ModalOverlay"; +import { mount } from "enzyme"; +import React from "react"; + +describe("ModalOverlayWrapper", () => { + let fakeDoc; + let sandbox; + let header; + beforeEach(() => { + sandbox = sinon.createSandbox(); + header = document.createElement("div"); + + fakeDoc = { + addEventListener: sandbox.stub(), + removeEventListener: sandbox.stub(), + body: { classList: { add: sandbox.stub(), remove: sandbox.stub() } }, + getElementById() { + return header; + }, + }; + }); + afterEach(() => { + sandbox.restore(); + }); + it("should add eventListener and a class on mount", async () => { + mount(<ModalOverlayWrapper document={fakeDoc} />); + assert.calledOnce(fakeDoc.addEventListener); + assert.calledWith(fakeDoc.body.classList.add, "modal-open"); + }); + + it("should remove eventListener on unmount", async () => { + const wrapper = mount(<ModalOverlayWrapper document={fakeDoc} />); + wrapper.unmount(); + assert.calledOnce(fakeDoc.addEventListener); + assert.calledOnce(fakeDoc.removeEventListener); + assert.calledWith(fakeDoc.body.classList.remove, "modal-open"); + }); + + it("should call props.onClose on an Escape key", async () => { + const onClose = sandbox.stub(); + mount(<ModalOverlayWrapper document={fakeDoc} onClose={onClose} />); + + // Simulate onkeydown being called + const [, callback] = fakeDoc.addEventListener.firstCall.args; + callback({ key: "Escape" }); + + assert.calledOnce(onClose); + }); + + it("should not call props.onClose on other keys than Escape", async () => { + const onClose = sandbox.stub(); + mount(<ModalOverlayWrapper document={fakeDoc} onClose={onClose} />); + + // Simulate onkeydown being called + const [, callback] = fakeDoc.addEventListener.firstCall.args; + callback({ key: "Ctrl" }); + + assert.notCalled(onClose); + }); + + it("should not call props.onClose when clicked outside dialog", async () => { + const onClose = sandbox.stub(); + const wrapper = mount( + <ModalOverlayWrapper document={fakeDoc} onClose={onClose} /> + ); + wrapper.find("div.modalOverlayOuter.active").simulate("click"); + assert.notCalled(onClose); + }); +}); diff --git a/browser/components/newtab/test/unit/content-src/components/TopSites.test.jsx b/browser/components/newtab/test/unit/content-src/components/TopSites.test.jsx index 1977066f0d..798bb9b8c7 100644 --- a/browser/components/newtab/test/unit/content-src/components/TopSites.test.jsx +++ b/browser/components/newtab/test/unit/content-src/components/TopSites.test.jsx @@ -1488,20 +1488,21 @@ describe("<TopSiteList>", () => { TOP_SITES_DEFAULT_ROWS * TOP_SITES_MAX_SITES_PER_ROW ); }); - it("should fill with placeholders if TopSites rows is less than TopSitesRows", () => { + it("should add a single placeholder is there is availible space in the row", () => { const rows = [{ url: "https://foo.com" }, { url: "https://bar.com" }]; + const availibleRows = 1; const wrapper = shallow( <TopSiteList {...DEFAULT_PROPS} TopSites={{ rows }} - TopSitesRows={1} + TopSitesRows={availibleRows} App={{ APP }} /> ); assert.lengthOf(wrapper.find(TopSite), 2, "topSites"); assert.lengthOf( wrapper.find(TopSitePlaceholder), - TOP_SITES_MAX_SITES_PER_ROW - 2, + availibleRows >= wrapper.find(TopSite).length ? 0 : 1, "placeholders" ); }); @@ -1522,11 +1523,7 @@ describe("<TopSiteList>", () => { /> ); assert.lengthOf(wrapper.find(TopSite), 2, "topSites"); - assert.lengthOf( - wrapper.find(TopSitePlaceholder), - TOP_SITES_MAX_SITES_PER_ROW - 2, - "placeholders" - ); + assert.lengthOf(wrapper.find(TopSitePlaceholder), 4, "placeholders"); }); it("should fill any holes in TopSites with placeholders", () => { const rows = [{ url: "https://foo.com" }]; @@ -1540,11 +1537,7 @@ describe("<TopSiteList>", () => { /> ); assert.lengthOf(wrapper.find(TopSite), 2, "topSites"); - assert.lengthOf( - wrapper.find(TopSitePlaceholder), - TOP_SITES_MAX_SITES_PER_ROW - 2, - "placeholders" - ); + assert.lengthOf(wrapper.find(TopSitePlaceholder), 1, "placeholders"); }); it("should update state onDragStart and clear it onDragEnd", () => { const wrapper = shallow(<TopSiteList {...DEFAULT_PROPS} App={{ APP }} />); @@ -1638,6 +1631,7 @@ describe("<TopSiteList>", () => { App={{ APP }} /> ); + const addButton = { isAddButton: true }; let instance = wrapper.instance(); instance.setState({ draggedIndex: 0, @@ -1652,7 +1646,7 @@ describe("<TopSiteList>", () => { site2, draggedSite, site3, - null, + addButton, null, null, null, @@ -1662,7 +1656,7 @@ describe("<TopSiteList>", () => { site2, site3, draggedSite, - null, + addButton, null, null, null, @@ -1671,7 +1665,7 @@ describe("<TopSiteList>", () => { assert.deepEqual(instance._makeTopSitesPreview(3), [ site2, site3, - null, + addButton, draggedSite, null, null, @@ -1683,7 +1677,7 @@ describe("<TopSiteList>", () => { site2, draggedSite, site3, - null, + addButton, null, null, null, @@ -1693,7 +1687,7 @@ describe("<TopSiteList>", () => { site3, site2, draggedSite, - null, + addButton, null, null, null, @@ -1704,7 +1698,7 @@ describe("<TopSiteList>", () => { site2, draggedSite, site3, - null, + addButton, null, null, null, @@ -1714,7 +1708,7 @@ describe("<TopSiteList>", () => { site2, site3, draggedSite, - null, + addButton, null, null, null, @@ -1725,7 +1719,7 @@ describe("<TopSiteList>", () => { site2, draggedSite, site3, - null, + addButton, null, null, null, @@ -1735,7 +1729,7 @@ describe("<TopSiteList>", () => { site2, site3, draggedSite, - null, + addButton, null, null, null, @@ -1752,7 +1746,7 @@ describe("<TopSiteList>", () => { draggedSite, site1, site3, - null, + addButton, null, null, null, @@ -1762,7 +1756,7 @@ describe("<TopSiteList>", () => { site1, site3, draggedSite, - null, + addButton, null, null, null, @@ -1779,7 +1773,7 @@ describe("<TopSiteList>", () => { draggedSite, site2, site1, - null, + addButton, null, null, null, @@ -1797,7 +1791,7 @@ describe("<TopSiteList>", () => { draggedSite, site2, site1, - null, + addButton, null, null, null, @@ -1822,13 +1816,13 @@ describe("<TopSiteList>", () => { }); describe("TopSitePlaceholder", () => { - it("should dispatch a TOP_SITES_EDIT action when edit-button is clicked", () => { + it("should dispatch a TOP_SITES_EDIT action when the addbutton is clicked", () => { const dispatch = sinon.spy(); const wrapper = shallow( - <TopSitePlaceholder dispatch={dispatch} index={7} /> + <TopSitePlaceholder dispatch={dispatch} index={7} isAddButton={true} /> ); - wrapper.find(".edit-button").first().simulate("click"); + wrapper.find(".add-button").first().simulate("click"); assert.calledOnce(dispatch); assert.calledWithExactly(dispatch, { diff --git a/browser/components/newtab/test/unit/lib/AboutPreferences.test.js b/browser/components/newtab/test/unit/lib/AboutPreferences.test.js index 7438d8247c..20765608fa 100644 --- a/browser/components/newtab/test/unit/lib/AboutPreferences.test.js +++ b/browser/components/newtab/test/unit/lib/AboutPreferences.test.js @@ -146,7 +146,7 @@ describe("AboutPreferences Feed", () => { }, }, createProcessingInstruction: sandbox.stub(), - createElementNS: sandbox.stub().callsFake((NS, el) => node), + createElementNS: sandbox.stub().callsFake(() => node), getElementById: sandbox.stub().returns(node), insertBefore: sandbox.stub().returnsArg(0), querySelector: sandbox diff --git a/browser/components/newtab/test/unit/lib/ActivityStream.test.js b/browser/components/newtab/test/unit/lib/ActivityStream.test.js index c127060021..b9deba1069 100644 --- a/browser/components/newtab/test/unit/lib/ActivityStream.test.js +++ b/browser/components/newtab/test/unit/lib/ActivityStream.test.js @@ -417,13 +417,11 @@ describe("ActivityStream", () => { clock = sinon.useFakeTimers(); // Have addObserver cause prefHasUserValue to now return true then observe - sandbox - .stub(global.Services.obs, "addObserver") - .callsFake((pref, obs) => { - setTimeout(() => { - Services.obs.notifyObservers("US", "browser-region-updated"); - }); + sandbox.stub(global.Services.obs, "addObserver").callsFake(() => { + setTimeout(() => { + Services.obs.notifyObservers("US", "browser-region-updated"); }); + }); }); afterEach(() => clock.restore()); diff --git a/browser/components/newtab/test/unit/lib/PersonalityProvider/PersonalityProvider.test.js b/browser/components/newtab/test/unit/lib/PersonalityProvider/PersonalityProvider.test.js index 0058fd7c76..0feabe978e 100644 --- a/browser/components/newtab/test/unit/lib/PersonalityProvider/PersonalityProvider.test.js +++ b/browser/components/newtab/test/unit/lib/PersonalityProvider/PersonalityProvider.test.js @@ -19,7 +19,7 @@ describe("Personality Provider", () => { RemoteSettingsOffStub = sandbox.stub().returns(); RemoteSettingsGetStub = sandbox.stub().returns([]); - RemoteSettingsStub = name => ({ + RemoteSettingsStub = () => ({ get: RemoteSettingsGetStub, on: RemoteSettingsOnStub, off: RemoteSettingsOffStub, @@ -142,7 +142,7 @@ describe("Personality Provider", () => { }, ]); sinon.spy(instance, "getAttachment"); - RemoteSettingsStub = name => ({ + RemoteSettingsStub = () => ({ get: RemoteSettingsGetStub, on: RemoteSettingsOnStub, off: RemoteSettingsOffStub, diff --git a/browser/components/newtab/test/unit/lib/PersonalityProvider/RecipeExecutor.test.js b/browser/components/newtab/test/unit/lib/PersonalityProvider/RecipeExecutor.test.js index fdbcae9613..bf8ed1fc2b 100644 --- a/browser/components/newtab/test/unit/lib/PersonalityProvider/RecipeExecutor.test.js +++ b/browser/components/newtab/test/unit/lib/PersonalityProvider/RecipeExecutor.test.js @@ -6,7 +6,7 @@ class MockTagger { this.mode = mode; this.tagScoreMap = tagScoreMap; } - tagTokens(tokens) { + tagTokens() { if (this.mode === "nb") { // eslint-disable-next-line prefer-destructuring let tag = Object.keys(this.tagScoreMap)[0]; diff --git a/browser/components/newtab/test/unit/unit-entry.js b/browser/components/newtab/test/unit/unit-entry.js index 5b32269ca8..73b4b8fcb5 100644 --- a/browser/components/newtab/test/unit/unit-entry.js +++ b/browser/components/newtab/test/unit/unit-entry.js @@ -97,8 +97,8 @@ const TEST_GLOBAL = { JSWindowActorParent, JSWindowActorChild, AboutReaderParent: { - addMessageListener: (messageName, listener) => {}, - removeMessageListener: (messageName, listener) => {}, + addMessageListener: (_messageName, _listener) => {}, + removeMessageListener: (_messageName, _listener) => {}, }, AboutWelcomeTelemetry: class { submitGleanPingForPing() {} @@ -281,8 +281,8 @@ const TEST_GLOBAL = { }, dump() {}, EveryWindow: { - registerCallback: (id, init, uninit) => {}, - unregisterCallback: id => {}, + registerCallback: (_id, _init, _uninit) => {}, + unregisterCallback: _id => {}, }, setTimeout: window.setTimeout.bind(window), clearTimeout: window.clearTimeout.bind(window), @@ -402,7 +402,7 @@ const TEST_GLOBAL = { }, urlFormatter: { formatURL: str => str, formatURLPref: str => str }, mm: { - addMessageListener: (msg, cb) => this.receiveMessage(), + addMessageListener: (_msg, _cb) => this.receiveMessage(), removeMessageListener() {}, }, obs: { @@ -412,7 +412,7 @@ const TEST_GLOBAL = { }, telemetry: { setEventRecordingEnabled: () => {}, - recordEvent: eventDetails => {}, + recordEvent: _eventDetails => {}, scalarSet: () => {}, keyedScalarAdd: () => {}, }, @@ -570,7 +570,7 @@ const TEST_GLOBAL = { finish: () => {}, }, Sampling: { - ratioSample(seed, ratios) { + ratioSample(_seed, _ratios) { return Promise.resolve(0); }, }, diff --git a/browser/components/newtab/test/unit/utils.js b/browser/components/newtab/test/unit/utils.js index 22069b8635..e10a284476 100644 --- a/browser/components/newtab/test/unit/utils.js +++ b/browser/components/newtab/test/unit/utils.js @@ -176,7 +176,7 @@ export class FakensIPrefBranch { prefHasUserValue(prefName) { return this.prefs.has(prefName); } - prefIsLocked(prefName) { + prefIsLocked(_prefName) { return false; } } @@ -187,7 +187,7 @@ export class FakensIPrefBranch { */ export class FakensIPrefService extends FakensIPrefBranch { getBranch() {} - getDefaultBranch(prefix) { + getDefaultBranch(_prefix) { return { setBoolPref() {}, setIntPref() {}, @@ -208,8 +208,8 @@ export class FakePrefs extends FakensIPrefBranch { ignore(prefName, callback) { super.removeObserver(prefName, callback); } - observeBranch(listener) {} - ignoreBranch(listener) {} + observeBranch(_listener) {} + ignoreBranch(_listener) {} set(prefName, value) { this.prefs.set(prefName, value); @@ -312,7 +312,7 @@ FakePerformance.prototype = { return 10000.234; }, // XXX assumes type == "mark" - getEntriesByName(name, type) { + getEntriesByName(name, _type) { if (this.marks.has(name)) { return this.marks.get(name); } diff --git a/browser/components/newtab/test/xpcshell/test_AboutWelcomeAttribution.js b/browser/components/newtab/test/xpcshell/test_AboutWelcomeAttribution.js deleted file mode 100644 index 3d83f473d5..0000000000 --- a/browser/components/newtab/test/xpcshell/test_AboutWelcomeAttribution.js +++ /dev/null @@ -1,69 +0,0 @@ -/* Any copyright is dedicated to the Public Domain. - * http://creativecommons.org/publicdomain/zero/1.0/ - */ - -"use strict"; - -const { AboutWelcomeDefaults } = ChromeUtils.importESModule( - "resource:///modules/aboutwelcome/AboutWelcomeDefaults.sys.mjs" -); -const { sinon } = ChromeUtils.importESModule( - "resource://testing-common/Sinon.sys.mjs" -); -const { AttributionCode } = ChromeUtils.importESModule( - "resource:///modules/AttributionCode.sys.mjs" -); -const { AddonRepository } = ChromeUtils.importESModule( - "resource://gre/modules/addons/AddonRepository.sys.mjs" -); - -const TEST_ATTRIBUTION_DATA = { - source: "addons.mozilla.org", - medium: "referral", - campaign: "non-fx-button", - content: "rta:iridium%40particlecore.github.io", -}; - -add_task(async function test_handleAddonInfoNotFound() { - let sandbox = sinon.createSandbox(); - const stub = sandbox.stub(AttributionCode, "getAttrDataAsync").resolves(null); - let result = await AboutWelcomeDefaults.getAttributionContent(); - equal(stub.callCount, 1, "Call was made"); - equal(result, null, "No data is returned"); - - sandbox.restore(); -}); - -add_task(async function test_UAAttribution() { - let sandbox = sinon.createSandbox(); - const stub = sandbox - .stub(AttributionCode, "getAttrDataAsync") - .resolves({ ua: "test" }); - let result = await AboutWelcomeDefaults.getAttributionContent(); - equal(stub.callCount, 1, "Call was made"); - equal(result.template, undefined, "Template was not returned"); - equal(result.ua, "test", "UA was returned"); - - sandbox.restore(); -}); - -add_task(async function test_formatAttributionData() { - let sandbox = sinon.createSandbox(); - const TEST_ADDON_INFO = { - sourceURI: { scheme: "https", spec: "https://test.xpi" }, - name: "Test Add-on", - icons: { 64: "http://test.svg" }, - }; - sandbox - .stub(AttributionCode, "getAttrDataAsync") - .resolves(TEST_ATTRIBUTION_DATA); - sandbox.stub(AddonRepository, "getAddonsByIDs").resolves([TEST_ADDON_INFO]); - let result = await AboutWelcomeDefaults.getAttributionContent( - TEST_ATTRIBUTION_DATA - ); - equal(AddonRepository.getAddonsByIDs.callCount, 1, "Retrieve addon content"); - equal(result.template, "return_to_amo", "RTAMO template returned"); - equal(result.name, TEST_ADDON_INFO.name, "AddonInfo returned"); - - sandbox.restore(); -}); diff --git a/browser/components/newtab/test/xpcshell/test_AboutWelcomeTelemetry.js b/browser/components/newtab/test/xpcshell/test_AboutWelcomeTelemetry.js deleted file mode 100644 index b8339fb39f..0000000000 --- a/browser/components/newtab/test/xpcshell/test_AboutWelcomeTelemetry.js +++ /dev/null @@ -1,90 +0,0 @@ -/* Any copyright is dedicated to the Public Domain. - * http://creativecommons.org/publicdomain/zero/1.0/ - */ - -"use strict"; - -const { AboutWelcomeTelemetry } = ChromeUtils.importESModule( - "resource:///modules/aboutwelcome/AboutWelcomeTelemetry.sys.mjs" -); -const { AttributionCode } = ChromeUtils.importESModule( - "resource:///modules/AttributionCode.sys.mjs" -); -const { sinon } = ChromeUtils.importESModule( - "resource://testing-common/Sinon.sys.mjs" -); -const TELEMETRY_PREF = "browser.newtabpage.activity-stream.telemetry"; - -add_setup(function setup() { - do_get_profile(); - Services.fog.initializeFOG(); -}); - -add_task(function test_enabled() { - registerCleanupFunction(() => { - Services.prefs.clearUserPref(TELEMETRY_PREF); - }); - Services.prefs.setBoolPref(TELEMETRY_PREF, true); - - const AWTelemetry = new AboutWelcomeTelemetry(); - - equal(AWTelemetry.telemetryEnabled, true, "Telemetry should be on"); - - Services.prefs.setBoolPref(TELEMETRY_PREF, false); - - equal(AWTelemetry.telemetryEnabled, false, "Telemetry should be off"); -}); - -add_task(async function test_pingPayload() { - registerCleanupFunction(() => { - Services.prefs.clearUserPref(TELEMETRY_PREF); - }); - Services.prefs.setBoolPref(TELEMETRY_PREF, true); - const AWTelemetry = new AboutWelcomeTelemetry(); - sinon.stub(AWTelemetry, "_createPing").resolves({ event: "MOCHITEST" }); - - let pingSubmitted = false; - GleanPings.messagingSystem.testBeforeNextSubmit(() => { - pingSubmitted = true; - Assert.equal(Glean.messagingSystem.event.testGetValue(), "MOCHITEST"); - }); - await AWTelemetry.sendTelemetry(); - - ok(pingSubmitted, "Glean ping was submitted"); -}); - -add_task(function test_mayAttachAttribution() { - const sandbox = sinon.createSandbox(); - const AWTelemetry = new AboutWelcomeTelemetry(); - - sandbox.stub(AttributionCode, "getCachedAttributionData").returns(null); - - let ping = AWTelemetry._maybeAttachAttribution({}); - - equal(ping.attribution, undefined, "Should not set attribution if it's null"); - - sandbox.restore(); - sandbox.stub(AttributionCode, "getCachedAttributionData").returns({}); - ping = AWTelemetry._maybeAttachAttribution({}); - - equal( - ping.attribution, - undefined, - "Should not set attribution if it's empty" - ); - - const attr = { - source: "google.com", - medium: "referral", - campaign: "Firefox-Brand-US-Chrome", - content: "(not set)", - experiment: "(not set)", - variation: "(not set)", - ua: "chrome", - }; - sandbox.restore(); - sandbox.stub(AttributionCode, "getCachedAttributionData").returns(attr); - ping = AWTelemetry._maybeAttachAttribution({}); - - equal(ping.attribution, attr, "Should set attribution if it presents"); -}); diff --git a/browser/components/newtab/test/xpcshell/test_AboutWelcomeTelemetry_glean.js b/browser/components/newtab/test/xpcshell/test_AboutWelcomeTelemetry_glean.js deleted file mode 100644 index 5191f05d04..0000000000 --- a/browser/components/newtab/test/xpcshell/test_AboutWelcomeTelemetry_glean.js +++ /dev/null @@ -1,238 +0,0 @@ -/* Any copyright is dedicated to the Public Domain. - * http://creativecommons.org/publicdomain/zero/1.0/ - */ - -"use strict"; - -const { AboutWelcomeTelemetry } = ChromeUtils.importESModule( - "resource:///modules/aboutwelcome/AboutWelcomeTelemetry.sys.mjs" -); -const TELEMETRY_PREF = "browser.newtabpage.activity-stream.telemetry"; - -add_setup(function setup() { - do_get_profile(); - Services.fog.initializeFOG(); -}); - -// We recognize two kinds of unexpected data that might reach -// `submitGleanPingForPing`: unknown keys, and keys with unexpectedly-complex -// data (ie, non-scalar). -// We report the keys in special metrics to aid in system health monitoring. -add_task(function test_weird_data() { - registerCleanupFunction(() => { - Services.prefs.clearUserPref(TELEMETRY_PREF); - }); - Services.prefs.setBoolPref(TELEMETRY_PREF, true); - - const AWTelemetry = new AboutWelcomeTelemetry(); - - const unknownKey = "some_unknown_key"; - const camelUnknownKey = AWTelemetry._snakeToCamelCase(unknownKey); - - let pingSubmitted = false; - GleanPings.messagingSystem.testBeforeNextSubmit(() => { - pingSubmitted = true; - Assert.equal( - Glean.messagingSystem.unknownKeys[camelUnknownKey].testGetValue(), - 1, - "caught the unknown key" - ); - // TODO(bug 1600008): Also check the for-testing overall count. - Assert.equal(Glean.messagingSystem.unknownKeyCount.testGetValue(), 1); - }); - AWTelemetry.submitGleanPingForPing({ - [unknownKey]: "value doesn't matter", - }); - - Assert.ok(pingSubmitted, "Ping with unknown keys was submitted"); - - const invalidNestedDataKey = "event"; - pingSubmitted = false; - GleanPings.messagingSystem.testBeforeNextSubmit(() => { - pingSubmitted = true; - Assert.equal( - Glean.messagingSystem.invalidNestedData[ - invalidNestedDataKey - ].testGetValue("messaging-system"), - 1, - "caught the invalid nested data" - ); - }); - AWTelemetry.submitGleanPingForPing({ - [invalidNestedDataKey]: { this_should: "not be", complex: "data" }, - }); - - Assert.ok(pingSubmitted, "Ping with invalid nested data submitted"); -}); - -// `event_context` is weird. It's an object, but it might have been stringified -// before being provided for recording. -add_task(function test_event_context() { - registerCleanupFunction(() => { - Services.prefs.clearUserPref(TELEMETRY_PREF); - }); - Services.prefs.setBoolPref(TELEMETRY_PREF, true); - - const AWTelemetry = new AboutWelcomeTelemetry(); - - const eventContext = { - reason: "reason", - page: "page", - source: "source", - something_else: "not specifically handled", - screen_family: "family", - screen_id: "screen_id", - screen_index: 0, - screen_initlals: "screen_initials", - }; - const stringifiedEC = JSON.stringify(eventContext); - - let pingSubmitted = false; - GleanPings.messagingSystem.testBeforeNextSubmit(() => { - pingSubmitted = true; - Assert.equal( - Glean.messagingSystem.eventReason.testGetValue(), - eventContext.reason, - "event_context.reason also in own metric." - ); - Assert.equal( - Glean.messagingSystem.eventPage.testGetValue(), - eventContext.page, - "event_context.page also in own metric." - ); - Assert.equal( - Glean.messagingSystem.eventSource.testGetValue(), - eventContext.source, - "event_context.source also in own metric." - ); - Assert.equal( - Glean.messagingSystem.eventScreenFamily.testGetValue(), - eventContext.screen_family, - "event_context.screen_family also in own metric." - ); - Assert.equal( - Glean.messagingSystem.eventScreenId.testGetValue(), - eventContext.screen_id, - "event_context.screen_id also in own metric." - ); - Assert.equal( - Glean.messagingSystem.eventScreenIndex.testGetValue(), - eventContext.screen_index, - "event_context.screen_index also in own metric." - ); - Assert.equal( - Glean.messagingSystem.eventScreenInitials.testGetValue(), - eventContext.screen_initials, - "event_context.screen_initials also in own metric." - ); - - Assert.equal( - Glean.messagingSystem.eventContext.testGetValue(), - stringifiedEC, - "whole event_context added as text." - ); - }); - AWTelemetry.submitGleanPingForPing({ - event_context: eventContext, - }); - Assert.ok(pingSubmitted, "Ping with object event_context submitted"); - - pingSubmitted = false; - GleanPings.messagingSystem.testBeforeNextSubmit(() => { - pingSubmitted = true; - Assert.equal( - Glean.messagingSystem.eventReason.testGetValue(), - eventContext.reason, - "event_context.reason also in own metric." - ); - Assert.equal( - Glean.messagingSystem.eventPage.testGetValue(), - eventContext.page, - "event_context.page also in own metric." - ); - Assert.equal( - Glean.messagingSystem.eventSource.testGetValue(), - eventContext.source, - "event_context.source also in own metric." - ); - Assert.equal( - Glean.messagingSystem.eventScreenFamily.testGetValue(), - eventContext.screen_family, - "event_context.screen_family also in own metric." - ); - Assert.equal( - Glean.messagingSystem.eventScreenId.testGetValue(), - eventContext.screen_id, - "event_context.screen_id also in own metric." - ); - Assert.equal( - Glean.messagingSystem.eventScreenIndex.testGetValue(), - eventContext.screen_index, - "event_context.screen_index also in own metric." - ); - Assert.equal( - Glean.messagingSystem.eventScreenInitials.testGetValue(), - eventContext.screen_initials, - "event_context.screen_initials also in own metric." - ); - - Assert.equal( - Glean.messagingSystem.eventContext.testGetValue(), - stringifiedEC, - "whole event_context added as text." - ); - }); - AWTelemetry.submitGleanPingForPing({ - event_context: stringifiedEC, - }); - Assert.ok(pingSubmitted, "Ping with string event_context submitted"); -}); - -// For event_context to be more useful, we want to make sure we don't error -// in cases where it doesn't make much sense, such as a plain string that -// doesnt attempt to represent a valid object. -add_task(function test_context_errors() { - registerCleanupFunction(() => { - Services.prefs.clearUserPref(TELEMETRY_PREF); - }); - Services.prefs.setBoolPref(TELEMETRY_PREF, true); - - const AWTelemetry = new AboutWelcomeTelemetry(); - - let weird_context_ping = { - event_context: "oops, this string isn't a valid JS object!", - }; - - let pingSubmitted = false; - GleanPings.messagingSystem.testBeforeNextSubmit(() => { - pingSubmitted = true; - Assert.equal( - Glean.messagingSystem.eventContextParseError.testGetValue(), - undefined, - "this poorly formed context shouldn't register because it was not an object!" - ); - }); - - AWTelemetry.submitGleanPingForPing(weird_context_ping); - - Assert.ok(pingSubmitted, "Ping with unknown keys was submitted"); - - weird_context_ping = { - event_context: - "{oops : {'this string isn't a valid JS object, but it sure looks like one!}}'", - }; - - pingSubmitted = false; - GleanPings.messagingSystem.testBeforeNextSubmit(() => { - pingSubmitted = true; - Assert.equal( - Glean.messagingSystem.eventContextParseError.testGetValue(), - 1, - "this poorly formed context should register because it was not an object!" - ); - }); - - AWTelemetry.submitGleanPingForPing(weird_context_ping); - - Assert.ok(pingSubmitted, "Ping with unknown keys was submitted"); -}); diff --git a/browser/components/newtab/test/xpcshell/test_HighlightsFeed.js b/browser/components/newtab/test/xpcshell/test_HighlightsFeed.js index 233eb6df73..31a03947cd 100644 --- a/browser/components/newtab/test/xpcshell/test_HighlightsFeed.js +++ b/browser/components/newtab/test/xpcshell/test_HighlightsFeed.js @@ -23,7 +23,9 @@ const { BOOKMARKS_RESTORE_SUCCESS_EVENT, BOOKMARKS_RESTORE_FAILED_EVENT, SECTION_ID, -} = ChromeUtils.import("resource://activity-stream/lib/HighlightsFeed.jsm"); +} = ChromeUtils.importESModule( + "resource://activity-stream/lib/HighlightsFeed.sys.mjs" +); const FAKE_LINKS = new Array(20) .fill(null) diff --git a/browser/components/newtab/test/xpcshell/test_PlacesFeed.js b/browser/components/newtab/test/xpcshell/test_PlacesFeed.js index 8e7c42d639..19f9e343f5 100644 --- a/browser/components/newtab/test/xpcshell/test_PlacesFeed.js +++ b/browser/components/newtab/test/xpcshell/test_PlacesFeed.js @@ -424,7 +424,7 @@ add_task(async function test_onAction_OPEN_LINK() { data: { url: "https://foo.com" }, _target: { browser: { - ownerGlobal: { openTrustedLinkIn, whereToOpenLink: e => "current" }, + ownerGlobal: { openTrustedLinkIn, whereToOpenLink: () => "current" }, }, }, }; @@ -450,7 +450,7 @@ add_task(async function test_onAction_OPEN_LINK_referrer() { data: { url: "https://foo.com", referrer: "https://foo.com/ref" }, _target: { browser: { - ownerGlobal: { openTrustedLinkIn, whereToOpenLink: e => "tab" }, + ownerGlobal: { openTrustedLinkIn, whereToOpenLink: () => "tab" }, }, }, }; @@ -496,7 +496,7 @@ add_task(async function test_onAction_OPEN_LINK_typed_bonus() { }, _target: { browser: { - ownerGlobal: { openTrustedLinkIn, whereToOpenLink: e => "tab" }, + ownerGlobal: { openTrustedLinkIn, whereToOpenLink: () => "tab" }, }, }, }; @@ -524,7 +524,7 @@ add_task(async function test_onAction_OPEN_LINK_pocket() { }, _target: { browser: { - ownerGlobal: { openTrustedLinkIn, whereToOpenLink: e => "current" }, + ownerGlobal: { openTrustedLinkIn, whereToOpenLink: () => "current" }, }, }, }; @@ -551,7 +551,7 @@ add_task(async function test_onAction_OPEN_LINK_not_http() { data: { url: "file:///foo.com" }, _target: { browser: { - ownerGlobal: { openTrustedLinkIn, whereToOpenLink: e => "current" }, + ownerGlobal: { openTrustedLinkIn, whereToOpenLink: () => "current" }, }, }, }; diff --git a/browser/components/newtab/test/xpcshell/test_Store.js b/browser/components/newtab/test/xpcshell/test_Store.js index b05ad36cd6..d872aed61c 100644 --- a/browser/components/newtab/test/xpcshell/test_Store.js +++ b/browser/components/newtab/test/xpcshell/test_Store.js @@ -41,7 +41,7 @@ add_task(async function test_messagechannel() { let sandbox = sinon.createSandbox(); sandbox .stub(ActivityStreamMessageChannel.prototype, "middleware") - .returns(s => next => action => next(action)); + .returns(() => next => action => next(action)); let store = new Store(); info( diff --git a/browser/components/newtab/test/xpcshell/test_TelemetryFeed.js b/browser/components/newtab/test/xpcshell/test_TelemetryFeed.js index b54d6094ad..59d82f5583 100644 --- a/browser/components/newtab/test/xpcshell/test_TelemetryFeed.js +++ b/browser/components/newtab/test/xpcshell/test_TelemetryFeed.js @@ -2860,6 +2860,38 @@ add_task(async function test_handleDiscoveryStreamUserEvent_popular_click() { sandbox.restore(); }); +add_task(async function test_handleDiscoveryStreamUserEvent_tooltip_click() { + info( + "TelemetryFeed.handleDiscoveryStreamUserEvent instruments a " + + "tooltip click" + ); + + let sandbox = sinon.createSandbox(); + let instance = new TelemetryFeed(); + Services.fog.testResetFOG(); + const feature = "SPONSORED_CONTENT_INFO"; + let action = ac.DiscoveryStreamUserEvent({ + event: "CLICK", + source: "FEATURE_HIGHLIGHT", + value: { + feature, + }, + }); + + const SESSION_ID = "decafc0ffee"; + sandbox.stub(instance.sessions, "get").returns({ session_id: SESSION_ID }); + + instance.handleDiscoveryStreamUserEvent(action); + let tooltipClicks = Glean.newtab.tooltipClick.testGetValue(); + Assert.equal(tooltipClicks.length, 1, "Recorded 1 click"); + Assert.deepEqual(tooltipClicks[0].extra, { + newtab_visit_id: SESSION_ID, + feature, + }); + + sandbox.restore(); +}); + add_task( async function test_handleDiscoveryStreamUserEvent_organic_top_stories_click() { info( diff --git a/browser/components/newtab/test/xpcshell/xpcshell.toml b/browser/components/newtab/test/xpcshell/xpcshell.toml index a8470913af..87d73669d3 100644 --- a/browser/components/newtab/test/xpcshell/xpcshell.toml +++ b/browser/components/newtab/test/xpcshell/xpcshell.toml @@ -14,12 +14,6 @@ skip-if = ["socketprocess_networking"] # Bug 1759035 ["test_AboutNewTab.js"] -["test_AboutWelcomeAttribution.js"] - -["test_AboutWelcomeTelemetry.js"] - -["test_AboutWelcomeTelemetry_glean.js"] - ["test_HighlightsFeed.js"] ["test_PlacesFeed.js"] |