1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378 |
- /* global Services */
- import {actionCreators as ac, actionTypes as at, actionUtils as au} from "common/Actions.jsm";
- import {
- ASRouterEventPing,
- BasePing,
- ImpressionStatsPing,
- PerfPing,
- SessionPing,
- SpocsFillPing,
- UndesiredPing,
- UserEventPing,
- } from "test/schemas/pings";
- import {FakePrefs, GlobalOverrider} from "test/unit/utils";
- import {ASRouterPreferences} from "lib/ASRouterPreferences.jsm";
- import injector from "inject!lib/TelemetryFeed.jsm";
- const FAKE_UUID = "{foo-123-foo}";
- const FAKE_ROUTER_MESSAGE_PROVIDER = [{id: "cfr", enabled: true}];
- const FAKE_ROUTER_MESSAGE_PROVIDER_COHORT = [{id: "cfr", enabled: true, cohort: "cohort_group"}];
- describe("TelemetryFeed", () => {
- let globals;
- let sandbox;
- let expectedUserPrefs;
- let browser = {getAttribute() { return "true"; }};
- let instance;
- let clock;
- let fakeHomePageUrl;
- let fakeHomePage;
- let fakeExtensionSettingsStore;
- class PingCentre {sendPing() {} uninit() {} sendStructuredIngestionPing() {}}
- class UTEventReporting {
- sendUserEvent() {}
- sendSessionEndEvent() {}
- sendTrailheadEnrollEvent() {}
- uninit() {}
- }
- class PerfService {
- getMostRecentAbsMarkStartByName() { return 1234; }
- mark() {}
- absNow() { return 123; }
- get timeOrigin() { return 123456; }
- }
- const perfService = new PerfService();
- const {
- TelemetryFeed,
- USER_PREFS_ENCODING,
- PREF_IMPRESSION_ID,
- TELEMETRY_PREF,
- EVENTS_TELEMETRY_PREF,
- STRUCTURED_INGESTION_TELEMETRY_PREF,
- STRUCTURED_INGESTION_ENDPOINT_PREF,
- } = injector({
- "common/PerfService.jsm": {perfService},
- "lib/UTEventReporting.jsm": {UTEventReporting},
- });
- beforeEach(() => {
- globals = new GlobalOverrider();
- sandbox = globals.sandbox;
- clock = sinon.useFakeTimers();
- fakeHomePageUrl = "about:home";
- fakeHomePage = {
- get() {
- return fakeHomePageUrl;
- },
- };
- fakeExtensionSettingsStore = {
- initialize() {
- return Promise.resolve();
- },
- getSetting() {},
- };
- sandbox.spy(global.Cu, "reportError");
- globals.set("gUUIDGenerator", {generateUUID: () => FAKE_UUID});
- globals.set("aboutNewTabService", {
- overridden: false,
- newTabURL: "",
- });
- globals.set("HomePage", fakeHomePage);
- globals.set("ExtensionSettingsStore", fakeExtensionSettingsStore);
- globals.set("PingCentre", PingCentre);
- globals.set("UTEventReporting", UTEventReporting);
- sandbox.stub(ASRouterPreferences, "providers").get(() => FAKE_ROUTER_MESSAGE_PROVIDER);
- instance = new TelemetryFeed();
- });
- afterEach(() => {
- clock.restore();
- globals.restore();
- FakePrefs.prototype.prefs = {};
- ASRouterPreferences.uninit();
- });
- describe("#init", () => {
- it("should add .pingCentre, a PingCentre instance", () => {
- assert.instanceOf(instance.pingCentre, PingCentre);
- });
- it("should add .pingCentreForASRouter, a PingCentre instance", () => {
- assert.instanceOf(instance.pingCentreForASRouter, PingCentre);
- });
- it("should add .utEvents, a UTEventReporting instance", () => {
- assert.instanceOf(instance.utEvents, UTEventReporting);
- });
- it("should make this.browserOpenNewtabStart() observe browser-open-newtab-start", () => {
- sandbox.spy(Services.obs, "addObserver");
- instance.init();
- assert.calledTwice(Services.obs.addObserver);
- assert.calledWithExactly(Services.obs.addObserver,
- instance.browserOpenNewtabStart, "browser-open-newtab-start");
- });
- it("should add window open listener", () => {
- sandbox.spy(Services.obs, "addObserver");
- instance.init();
- assert.calledTwice(Services.obs.addObserver);
- assert.calledWithExactly(Services.obs.addObserver,
- instance._addWindowListeners, "domwindowopened");
- });
- it("should add TabPinned event listener on new windows", () => {
- const stub = {addEventListener: sandbox.stub()};
- sandbox.spy(Services.obs, "addObserver");
- instance.init();
- assert.calledTwice(Services.obs.addObserver);
- const [cb] = Services.obs.addObserver.secondCall.args;
- cb(stub);
- assert.calledTwice(stub.addEventListener);
- assert.calledWithExactly(stub.addEventListener, "unload", instance.handleEvent);
- assert.calledWithExactly(stub.addEventListener, "TabPinned", instance.handleEvent);
- });
- it("should create impression id if none exists", () => {
- assert.equal(instance._impressionId, FAKE_UUID);
- });
- it("should set impression id if it exists", () => {
- FakePrefs.prototype.prefs = {};
- FakePrefs.prototype.prefs[PREF_IMPRESSION_ID] = "fakeImpressionId";
- assert.equal(new TelemetryFeed()._impressionId, "fakeImpressionId");
- });
- it("should register listeners on existing windows", () => {
- const stub = sandbox.stub();
- globals.set({
- Services: {
- ...Services,
- wm: {getEnumerator: () => [{addEventListener: stub}]},
- },
- });
- instance.init();
- assert.calledTwice(stub);
- assert.calledWithExactly(stub, "unload", instance.handleEvent);
- assert.calledWithExactly(stub, "TabPinned", instance.handleEvent);
- });
- describe("telemetry pref changes from false to true", () => {
- beforeEach(() => {
- FakePrefs.prototype.prefs = {};
- FakePrefs.prototype.prefs[TELEMETRY_PREF] = false;
- instance = new TelemetryFeed();
- assert.propertyVal(instance, "telemetryEnabled", false);
- });
- it("should set the enabled property to true", () => {
- instance._prefs.set(TELEMETRY_PREF, true);
- assert.propertyVal(instance, "telemetryEnabled", true);
- });
- });
- describe("events telemetry pref changes from false to true", () => {
- beforeEach(() => {
- FakePrefs.prototype.prefs = {};
- FakePrefs.prototype.prefs[EVENTS_TELEMETRY_PREF] = false;
- instance = new TelemetryFeed();
- assert.propertyVal(instance, "eventTelemetryEnabled", false);
- });
- it("should set the enabled property to true", () => {
- instance._prefs.set(EVENTS_TELEMETRY_PREF, true);
- assert.propertyVal(instance, "eventTelemetryEnabled", true);
- });
- });
- describe("Structured Ingestion telemetry pref changes from false to true", () => {
- beforeEach(() => {
- FakePrefs.prototype.prefs = {};
- FakePrefs.prototype.prefs[STRUCTURED_INGESTION_TELEMETRY_PREF] = false;
- instance = new TelemetryFeed();
- assert.propertyVal(instance, "structuredIngestionTelemetryEnabled", false);
- });
- it("should set the enabled property to true", () => {
- instance._prefs.set(STRUCTURED_INGESTION_TELEMETRY_PREF, true);
- assert.propertyVal(instance, "structuredIngestionTelemetryEnabled", true);
- });
- });
- });
- describe("#handleEvent", () => {
- it("should dispatch a TAB_PINNED_EVENT", () => {
- sandbox.stub(instance, "sendEvent");
- globals.set({
- Services: {
- ...Services,
- wm: {getEnumerator: () => [{gBrowser: {tabs: [{pinned: true}]}}]},
- },
- });
- instance.handleEvent({type: "TabPinned", target: {}});
- assert.calledOnce(instance.sendEvent);
- const [ping] = instance.sendEvent.firstCall.args;
- assert.propertyVal(ping, "event", "TABPINNED");
- assert.propertyVal(ping, "source", "TAB_CONTEXT_MENU");
- assert.propertyVal(ping, "session_id", "n/a");
- assert.propertyVal(ping.value, "total_pinned_tabs", 1);
- });
- it("should skip private windows", () => {
- sandbox.stub(instance, "sendEvent");
- globals.set({PrivateBrowsingUtils: {isWindowPrivate: () => true}});
- instance.handleEvent({type: "TabPinned", target: {}});
- assert.notCalled(instance.sendEvent);
- });
- it("should return the correct value for total_pinned_tabs", () => {
- sandbox.stub(instance, "sendEvent");
- globals.set({
- Services: {
- ...Services,
- wm: {
- getEnumerator: () => [{
- gBrowser: {tabs: [{pinned: true}, {pinned: false}]},
- }],
- },
- },
- });
- instance.handleEvent({type: "TabPinned", target: {}});
- assert.calledOnce(instance.sendEvent);
- const [ping] = instance.sendEvent.firstCall.args;
- assert.propertyVal(ping, "event", "TABPINNED");
- assert.propertyVal(ping, "source", "TAB_CONTEXT_MENU");
- assert.propertyVal(ping, "session_id", "n/a");
- assert.propertyVal(ping.value, "total_pinned_tabs", 1);
- });
- it("should return the correct value for total_pinned_tabs (when private windows are open)", () => {
- sandbox.stub(instance, "sendEvent");
- const privateWinStub = sandbox.stub().onCall(0).returns(false)
- .onCall(1)
- .returns(true);
- globals.set({PrivateBrowsingUtils: {isWindowPrivate: privateWinStub}});
- globals.set({
- Services: {
- ...Services,
- wm: {
- getEnumerator: () => [{
- gBrowser: {tabs: [{pinned: true}, {pinned: true}]},
- }],
- },
- },
- });
- instance.handleEvent({type: "TabPinned", target: {}});
- assert.calledOnce(instance.sendEvent);
- const [ping] = instance.sendEvent.firstCall.args;
- assert.propertyVal(ping.value, "total_pinned_tabs", 0);
- });
- it("should unregister the event listeners", () => {
- const stub = {removeEventListener: sandbox.stub()};
- instance.handleEvent({type: "unload", target: stub});
- assert.calledTwice(stub.removeEventListener);
- assert.calledWithExactly(stub.removeEventListener, "unload", instance.handleEvent);
- assert.calledWithExactly(stub.removeEventListener, "TabPinned", instance.handleEvent);
- });
- });
- describe("#addSession", () => {
- it("should add a session and return it", () => {
- const session = instance.addSession("foo");
- assert.equal(instance.sessions.get("foo"), session);
- });
- it("should set the session_id", () => {
- sandbox.spy(global.gUUIDGenerator, "generateUUID");
- const session = instance.addSession("foo");
- assert.calledOnce(global.gUUIDGenerator.generateUUID);
- assert.equal(session.session_id, global.gUUIDGenerator.generateUUID.firstCall.returnValue);
- });
- it("should set the page if a url parameter is given", () => {
- const session = instance.addSession("foo", "about:monkeys");
- assert.propertyVal(session, "page", "about:monkeys");
- });
- it("should set the page prop to 'unknown' if no URL parameter given", () => {
- const session = instance.addSession("foo");
- assert.propertyVal(session, "page", "unknown");
- });
- it("should set the perf type when lacking timestamp", () => {
- const session = instance.addSession("foo");
- assert.propertyVal(session.perf, "load_trigger_type", "unexpected");
- });
- it("should set load_trigger_type to first_window_opened on the first about:home seen", () => {
- const session = instance.addSession("foo", "about:home");
- assert.propertyVal(session.perf, "load_trigger_type",
- "first_window_opened");
- });
- it("should not set load_trigger_type to first_window_opened on the second about:home seen", () => {
- instance.addSession("foo", "about:home");
- const session2 = instance.addSession("foo", "about:home");
- assert.notPropertyVal(session2.perf, "load_trigger_type",
- "first_window_opened");
- });
- it("should set load_trigger_ts to the value of perfService.timeOrigin", () => {
- const session = instance.addSession("foo", "about:home");
- assert.propertyVal(session.perf, "load_trigger_ts",
- 123456);
- });
- it("should create a valid session ping on the first about:home seen", () => {
- // Add a session
- const portID = "foo";
- const session = instance.addSession(portID, "about:home");
- // Create a ping referencing the session
- const ping = instance.createSessionEndEvent(session);
- assert.validate(ping, SessionPing);
- });
- it("should be a valid ping with the data_late_by_ms perf", () => {
- // Add a session
- const portID = "foo";
- const session = instance.addSession(portID, "about:home");
- instance.saveSessionPerfData("foo", {topsites_data_late_by_ms: 10});
- instance.saveSessionPerfData("foo", {highlights_data_late_by_ms: 20});
- // Create a ping referencing the session
- const ping = instance.createSessionEndEvent(session);
- assert.validate(ping, SessionPing);
- assert.propertyVal(instance.sessions.get("foo").perf,
- "highlights_data_late_by_ms", 20);
- assert.propertyVal(instance.sessions.get("foo").perf,
- "topsites_data_late_by_ms", 10);
- });
- it("should be a valid ping with the topsites stats perf", () => {
- // Add a session
- const portID = "foo";
- const session = instance.addSession(portID, "about:home");
- instance.saveSessionPerfData("foo", {
- topsites_icon_stats: {
- "custom_screenshot": 0,
- "screenshot_with_icon": 2,
- "screenshot": 1,
- "tippytop": 2,
- "rich_icon": 1,
- "no_image": 0,
- },
- topsites_pinned: 3,
- topsites_search_shortcuts: 2,
- });
- // Create a ping referencing the session
- const ping = instance.createSessionEndEvent(session);
- assert.validate(ping, SessionPing);
- assert.propertyVal(instance.sessions.get("foo").perf.topsites_icon_stats,
- "screenshot_with_icon", 2);
- assert.equal(instance.sessions.get("foo").perf.topsites_pinned, 3);
- assert.equal(instance.sessions.get("foo").perf.topsites_search_shortcuts, 2);
- });
- });
- describe("#browserOpenNewtabStart", () => {
- it("should call perfService.mark with browser-open-newtab-start", () => {
- sandbox.stub(perfService, "mark");
- instance.browserOpenNewtabStart();
- assert.calledOnce(perfService.mark);
- assert.calledWithExactly(perfService.mark, "browser-open-newtab-start");
- });
- });
- describe("#endSession", () => {
- it("should not throw if there is no session for the given port ID", () => {
- assert.doesNotThrow(() => instance.endSession("doesn't exist"));
- });
- it("should add a session_duration integer if there is a visibility_event_rcvd_ts", () => {
- sandbox.stub(instance, "sendEvent");
- const session = instance.addSession("foo");
- session.perf.visibility_event_rcvd_ts = 444.4732;
- instance.endSession("foo");
- assert.isNumber(session.session_duration);
- assert.ok(Number.isInteger(session.session_duration),
- "session_duration should be an integer");
- });
- it("shouldn't send session ping if there's no visibility_event_rcvd_ts", () => {
- sandbox.stub(instance, "sendEvent");
- instance.addSession("foo");
- instance.endSession("foo");
- assert.notCalled(instance.sendEvent);
- assert.isFalse(instance.sessions.has("foo"));
- });
- it("should remove the session from .sessions", () => {
- sandbox.stub(instance, "sendEvent");
- instance.addSession("foo");
- instance.endSession("foo");
- assert.isFalse(instance.sessions.has("foo"));
- });
- it("should call createSessionSendEvent and sendEvent with the sesssion", () => {
- FakePrefs.prototype.prefs[TELEMETRY_PREF] = true;
- FakePrefs.prototype.prefs[EVENTS_TELEMETRY_PREF] = true;
- instance = new TelemetryFeed();
- sandbox.stub(instance, "sendEvent");
- sandbox.stub(instance, "createSessionEndEvent");
- sandbox.stub(instance.utEvents, "sendSessionEndEvent");
- const session = instance.addSession("foo");
- session.perf.visibility_event_rcvd_ts = 444.4732;
- instance.endSession("foo");
- // Did we call sendEvent with the result of createSessionEndEvent?
- assert.calledWith(instance.createSessionEndEvent, session);
- let sessionEndEvent = instance.createSessionEndEvent.firstCall.returnValue;
- assert.calledWith(instance.sendEvent, sessionEndEvent);
- assert.calledWith(instance.utEvents.sendSessionEndEvent, sessionEndEvent);
- });
- });
- describe("ping creators", () => {
- beforeEach(() => {
- FakePrefs.prototype.prefs = {};
- for (const pref of Object.keys(USER_PREFS_ENCODING)) {
- FakePrefs.prototype.prefs[pref] = true;
- expectedUserPrefs |= USER_PREFS_ENCODING[pref];
- }
- instance.init();
- });
- describe("#createPing", () => {
- it("should create a valid base ping without a session if no portID is supplied", async () => {
- const ping = await instance.createPing();
- assert.validate(ping, BasePing);
- assert.notProperty(ping, "session_id");
- assert.notProperty(ping, "page");
- });
- it("should create a valid base ping with session info if a portID is supplied", async () => {
- // Add a session
- const portID = "foo";
- instance.addSession(portID, "about:home");
- const sessionID = instance.sessions.get(portID).session_id;
- // Create a ping referencing the session
- const ping = await instance.createPing(portID);
- assert.validate(ping, BasePing);
- // Make sure we added the right session-related stuff to the ping
- assert.propertyVal(ping, "session_id", sessionID);
- assert.propertyVal(ping, "page", "about:home");
- });
- it("should create an unexpected base ping if no session yet portID is supplied", async () => {
- const ping = await instance.createPing("foo");
- assert.validate(ping, BasePing);
- assert.propertyVal(ping, "page", "unknown");
- assert.propertyVal(instance.sessions.get("foo").perf, "load_trigger_type", "unexpected");
- });
- it("should create a base ping with user_prefs", async () => {
- const ping = await instance.createPing("foo");
- assert.validate(ping, BasePing);
- assert.propertyVal(ping, "user_prefs", expectedUserPrefs);
- });
- });
- describe("#createUserEvent", () => {
- it("should create a valid event", async () => {
- const portID = "foo";
- const data = {source: "TOP_SITES", event: "CLICK"};
- const action = ac.AlsoToMain(ac.UserEvent(data), portID);
- const session = instance.addSession(portID);
- const ping = await instance.createUserEvent(action);
- // Is it valid?
- assert.validate(ping, UserEventPing);
- // Does it have the right session_id?
- assert.propertyVal(ping, "session_id", session.session_id);
- });
- });
- describe("#createUndesiredEvent", () => {
- it("should create a valid event without a session", async () => {
- const action = ac.UndesiredEvent({source: "TOP_SITES", event: "MISSING_IMAGE", value: 10});
- const ping = await instance.createUndesiredEvent(action);
- // Is it valid?
- assert.validate(ping, UndesiredPing);
- // Does it have the right value?
- assert.propertyVal(ping, "value", 10);
- });
- it("should create a valid event with a session", async () => {
- const portID = "foo";
- const data = {source: "TOP_SITES", event: "MISSING_IMAGE", value: 10};
- const action = ac.AlsoToMain(ac.UndesiredEvent(data), portID);
- const session = instance.addSession(portID);
- const ping = await instance.createUndesiredEvent(action);
- // Is it valid?
- assert.validate(ping, UndesiredPing);
- // Does it have the right session_id?
- assert.propertyVal(ping, "session_id", session.session_id);
- // Does it have the right value?
- assert.propertyVal(ping, "value", 10);
- });
- describe("#validate *_data_late_by_ms", () => {
- it("should create a valid highlights_data_late_by_ms ping", () => {
- const data = {
- type: at.TELEMETRY_UNDESIRED_EVENT,
- data: {
- source: "HIGHLIGHTS",
- event: `highlights_data_late_by_ms`,
- value: 2,
- },
- };
- const ping = instance.createUndesiredEvent(data);
- assert.validate(ping, UndesiredPing);
- assert.propertyVal(ping, "value", data.data.value);
- assert.propertyVal(ping, "event", data.data.event);
- });
- });
- });
- describe("#createPerformanceEvent", () => {
- it("should create a valid event without a session", async () => {
- const action = ac.PerfEvent({event: "SCREENSHOT_FINISHED", value: 100});
- const ping = await instance.createPerformanceEvent(action);
- // Is it valid?
- assert.validate(ping, PerfPing);
- // Does it have the right value?
- assert.propertyVal(ping, "value", 100);
- });
- });
- describe("#createSessionEndEvent", () => {
- it("should create a valid event", async () => {
- const ping = await instance.createSessionEndEvent({
- session_id: FAKE_UUID,
- page: "about:newtab",
- session_duration: 12345,
- perf: {
- load_trigger_ts: 10,
- load_trigger_type: "menu_plus_or_keyboard",
- visibility_event_rcvd_ts: 20,
- is_preloaded: true,
- },
- });
- // Is it valid?
- assert.validate(ping, SessionPing);
- assert.propertyVal(ping, "session_id", FAKE_UUID);
- assert.propertyVal(ping, "page", "about:newtab");
- assert.propertyVal(ping, "session_duration", 12345);
- });
- it("should create a valid unexpected session event", async () => {
- const ping = await instance.createSessionEndEvent({
- session_id: FAKE_UUID,
- page: "about:newtab",
- session_duration: 12345,
- perf: {
- load_trigger_type: "unexpected",
- is_preloaded: true,
- },
- });
- // Is it valid?
- assert.validate(ping, SessionPing);
- assert.propertyVal(ping, "session_id", FAKE_UUID);
- assert.propertyVal(ping, "page", "about:newtab");
- assert.propertyVal(ping, "session_duration", 12345);
- assert.propertyVal(ping.perf, "load_trigger_type", "unexpected");
- });
- });
- });
- describe("#createImpressionStats", () => {
- it("should create a valid impression stats ping", async () => {
- const tiles = [{id: 10001}, {id: 10002}, {id: 10003}];
- const action = ac.ImpressionStats({source: "POCKET", tiles});
- const ping = await instance.createImpressionStats(au.getPortIdOfSender(action), action.data);
- assert.validate(ping, ImpressionStatsPing);
- assert.propertyVal(ping, "source", "POCKET");
- assert.propertyVal(ping, "tiles", tiles);
- });
- it("should create a valid click ping", async () => {
- const tiles = [{id: 10001, pos: 2}];
- const action = ac.ImpressionStats({source: "POCKET", tiles, click: 0});
- const ping = await instance.createImpressionStats(au.getPortIdOfSender(action), action.data);
- assert.validate(ping, ImpressionStatsPing);
- assert.propertyVal(ping, "click", 0);
- assert.propertyVal(ping, "tiles", tiles);
- });
- it("should create a valid block ping", async () => {
- const tiles = [{id: 10001, pos: 2}];
- const action = ac.ImpressionStats({source: "POCKET", tiles, block: 0});
- const ping = await instance.createImpressionStats(au.getPortIdOfSender(action), action.data);
- assert.validate(ping, ImpressionStatsPing);
- assert.propertyVal(ping, "block", 0);
- assert.propertyVal(ping, "tiles", tiles);
- });
- it("should create a valid pocket ping", async () => {
- const tiles = [{id: 10001, pos: 2}];
- const action = ac.ImpressionStats({source: "POCKET", tiles, pocket: 0});
- const ping = await instance.createImpressionStats(au.getPortIdOfSender(action), action.data);
- assert.validate(ping, ImpressionStatsPing);
- assert.propertyVal(ping, "pocket", 0);
- assert.propertyVal(ping, "tiles", tiles);
- });
- });
- describe("#createSpocsFillPing", () => {
- it("should create a valid SPOCS Fill ping", async () => {
- const spocFills = [
- {id: 10001, displayed: 0, reason: "frequency_cap", full_recalc: 1},
- {id: 10002, displayed: 0, reason: "blocked_by_user", full_recalc: 1},
- {id: 10003, displayed: 1, reason: "n/a", full_recalc: 1},
- ];
- const action = ac.DiscoveryStreamSpocsFill({spoc_fills: spocFills});
- const ping = await instance.createSpocsFillPing(action.data);
- assert.validate(ping, SpocsFillPing);
- assert.propertyVal(ping, "spoc_fills", spocFills);
- });
- });
- describe("#applyCFRPolicy", () => {
- it("should use client_id and message_id in prerelease", () => {
- globals.set("UpdateUtils", {getUpdateChannel() { return "nightly"; }});
- const data = {
- action: "cfr_user_event",
- source: "CFR",
- event: "IMPRESSION",
- client_id: "some_client_id",
- impression_id: "some_impression_id",
- message_id: "cfr_message_01",
- bucket_id: "cfr_bucket_01",
- };
- const ping = instance.applyCFRPolicy(data);
- assert.isUndefined(ping.client_id);
- assert.propertyVal(ping, "impression_id", "n/a");
- assert.propertyVal(ping, "message_id", "cfr_message_01");
- assert.isUndefined(ping.bucket_id);
- });
- it("should use impression_id and bucket_id in release", () => {
- globals.set("UpdateUtils", {getUpdateChannel() { return "release"; }});
- const data = {
- action: "cfr_user_event",
- source: "CFR",
- event: "IMPRESSION",
- client_id: "some_client_id",
- impression_id: "some_impression_id",
- message_id: "cfr_message_01",
- bucket_id: "cfr_bucket_01",
- };
- const ping = instance.applyCFRPolicy(data);
- assert.propertyVal(ping, "impression_id", FAKE_UUID);
- assert.propertyVal(ping, "client_id", "n/a");
- assert.propertyVal(ping, "message_id", "cfr_bucket_01");
- assert.isUndefined(ping.bucket_id);
- });
- it("should use client_id and message_id in the experiment cohort in release", () => {
- globals.set("UpdateUtils", {getUpdateChannel() { return "release"; }});
- sandbox.stub(ASRouterPreferences, "providers").get(() => FAKE_ROUTER_MESSAGE_PROVIDER_COHORT);
- const data = {
- action: "cfr_user_event",
- source: "CFR",
- event: "IMPRESSION",
- client_id: "some_client_id",
- impression_id: "some_impression_id",
- message_id: "cfr_message_01",
- bucket_id: "cfr_bucket_01",
- };
- const ping = instance.applyCFRPolicy(data);
- assert.isUndefined(ping.client_id);
- assert.propertyVal(ping, "impression_id", "n/a");
- assert.propertyVal(ping, "message_id", "cfr_message_01");
- assert.isUndefined(ping.bucket_id);
- });
- });
- describe("#applySnippetsPolicy", () => {
- it("should drop client_id and unset impression_id", () => {
- const data = {
- action: "snippets_user_event",
- source: "SNIPPETS",
- event: "IMPRESSION",
- client_id: "n/a",
- impression_id: "some_impression_id",
- message_id: "snippets_message_01",
- };
- const ping = instance.applySnippetsPolicy(data);
- assert.isUndefined(ping.client_id);
- assert.propertyVal(ping, "impression_id", "n/a");
- assert.propertyVal(ping, "message_id", "snippets_message_01");
- });
- });
- describe("#applyOnboardingPolicy", () => {
- it("should drop client_id and unset impression_id", () => {
- const data = {
- action: "onboarding_user_event",
- source: "ONBOARDING",
- event: "CLICK_BUTTION",
- client_id: "n/a",
- impression_id: "some_impression_id",
- message_id: "onboarding_message_01",
- };
- const ping = instance.applyOnboardingPolicy(data);
- assert.isUndefined(ping.client_id);
- assert.propertyVal(ping, "impression_id", "n/a");
- assert.propertyVal(ping, "message_id", "onboarding_message_01");
- });
- });
- describe("#createASRouterEvent", () => {
- it("should create a valid AS Router event", async () => {
- const data = {
- action: "snippet_user_event",
- source: "SNIPPETS",
- event: "CLICK",
- message_id: "snippets_message_01",
- };
- const action = ac.ASRouterUserEvent(data);
- const ping = await instance.createASRouterEvent(action);
- assert.validate(ping, ASRouterEventPing);
- assert.propertyVal(ping, "client_id", "n/a");
- assert.propertyVal(ping, "source", "SNIPPETS");
- assert.propertyVal(ping, "event", "CLICK");
- });
- it("should call applyCFRPolicy if action equals to cfr_user_event", async () => {
- const data = {
- action: "cfr_user_event",
- source: "CFR",
- event: "IMPRESSION",
- message_id: "cfr_message_01",
- };
- sandbox.stub(instance, "applyCFRPolicy");
- const action = ac.ASRouterUserEvent(data);
- await instance.createASRouterEvent(action);
- assert.calledOnce(instance.applyCFRPolicy);
- });
- it("should call applySnippetsPolicy if action equals to snippets_user_event", async () => {
- const data = {
- action: "snippets_user_event",
- source: "SNIPPETS",
- event: "IMPRESSION",
- message_id: "snippets_message_01",
- };
- sandbox.stub(instance, "applySnippetsPolicy");
- const action = ac.ASRouterUserEvent(data);
- await instance.createASRouterEvent(action);
- assert.calledOnce(instance.applySnippetsPolicy);
- });
- it("should call applyOnboardingPolicy if action equals to onboarding_user_event", async () => {
- const data = {
- action: "onboarding_user_event",
- source: "ONBOARDING",
- event: "CLICK_BUTTON",
- message_id: "onboarding_message_01",
- };
- sandbox.stub(instance, "applyOnboardingPolicy");
- const action = ac.ASRouterUserEvent(data);
- await instance.createASRouterEvent(action);
- assert.calledOnce(instance.applyOnboardingPolicy);
- });
- });
- describe("#sendEvent", () => {
- it("should call PingCentre", async () => {
- FakePrefs.prototype.prefs.telemetry = true;
- const event = {};
- instance = new TelemetryFeed();
- sandbox.stub(instance.pingCentre, "sendPing");
- await instance.sendEvent(event);
- assert.calledWith(instance.pingCentre.sendPing, event);
- });
- });
- describe("#sendUTEvent", () => {
- it("should call the UT event function passed in", async () => {
- FakePrefs.prototype.prefs[TELEMETRY_PREF] = true;
- FakePrefs.prototype.prefs[EVENTS_TELEMETRY_PREF] = true;
- const event = {};
- instance = new TelemetryFeed();
- sandbox.stub(instance.utEvents, "sendUserEvent");
- await instance.sendUTEvent(event, instance.utEvents.sendUserEvent);
- assert.calledWith(instance.utEvents.sendUserEvent, event);
- });
- });
- describe("#sendStructuredIngestionEvent", () => {
- it("should call PingCentre sendStructuredIngestionPing", async () => {
- FakePrefs.prototype.prefs[TELEMETRY_PREF] = true;
- FakePrefs.prototype.prefs[STRUCTURED_INGESTION_TELEMETRY_PREF] = true;
- const event = {};
- instance = new TelemetryFeed();
- sandbox.stub(instance.pingCentre, "sendStructuredIngestionPing");
- await instance.sendStructuredIngestionEvent(event, "http://foo.com/base/");
- assert.calledWith(instance.pingCentre.sendStructuredIngestionPing, event);
- });
- });
- describe("#sendASRouterEvent", () => {
- it("should call PingCentre for AS Router", async () => {
- FakePrefs.prototype.prefs.telemetry = true;
- const event = {};
- instance = new TelemetryFeed();
- sandbox.stub(instance.pingCentreForASRouter, "sendPing");
- instance.sendASRouterEvent(event);
- assert.calledWith(instance.pingCentreForASRouter.sendPing, event);
- });
- });
- describe("#setLoadTriggerInfo", () => {
- it("should call saveSessionPerfData w/load_trigger_{ts,type} data", () => {
- const stub = sandbox.stub(instance, "saveSessionPerfData");
- sandbox.stub(perfService, "getMostRecentAbsMarkStartByName").returns(777);
- instance.addSession("port123");
- instance.setLoadTriggerInfo("port123");
- assert.calledWith(stub, "port123", {
- load_trigger_ts: 777,
- load_trigger_type: "menu_plus_or_keyboard",
- });
- });
- it("should not call saveSessionPerfData when getting mark throws", () => {
- const stub = sandbox.stub(instance, "saveSessionPerfData");
- sandbox.stub(perfService, "getMostRecentAbsMarkStartByName").throws();
- instance.addSession("port123");
- instance.setLoadTriggerInfo("port123");
- assert.notCalled(stub);
- });
- });
- describe("#saveSessionPerfData", () => {
- it("should update the given session with the given data", () => {
- instance.addSession("port123");
- assert.notProperty(instance.sessions.get("port123"), "fake_ts");
- const data = {fake_ts: 456, other_fake_ts: 789};
- instance.saveSessionPerfData("port123", data);
- assert.include(instance.sessions.get("port123").perf, data);
- });
- it("should call setLoadTriggerInfo if data has visibility_event_rcvd_ts", () => {
- sandbox.stub(instance, "setLoadTriggerInfo");
- instance.addSession("port123");
- const data = {visibility_event_rcvd_ts: 444455};
- instance.saveSessionPerfData("port123", data);
- assert.calledOnce(instance.setLoadTriggerInfo);
- assert.calledWithExactly(instance.setLoadTriggerInfo, "port123");
- assert.include(instance.sessions.get("port123").perf, data);
- });
- it("shouldn't call setLoadTriggerInfo if data has no visibility_event_rcvd_ts", () => {
- sandbox.stub(instance, "setLoadTriggerInfo");
- instance.addSession("port123");
- instance.saveSessionPerfData("port123", {monkeys_ts: 444455});
- assert.notCalled(instance.setLoadTriggerInfo);
- });
- it("should not call setLoadTriggerInfo when url is about:home", () => {
- sandbox.stub(instance, "setLoadTriggerInfo");
- instance.addSession("port123", "about:home");
- const data = {visibility_event_rcvd_ts: 444455};
- instance.saveSessionPerfData("port123", data);
- assert.notCalled(instance.setLoadTriggerInfo);
- });
- it("should call maybeRecordTopsitesPainted when url is about:home and topsites_first_painted_ts is given", () => {
- const topsites_first_painted_ts = 44455;
- const data = {topsites_first_painted_ts};
- const spy = sandbox.spy();
- sandbox.stub(Services.prefs, "getIntPref").returns(1);
- globals.set("aboutNewTabService", {
- overridden: false,
- newTabURL: "",
- maybeRecordTopsitesPainted: spy,
- });
- instance.addSession("port123", "about:home");
- instance.saveSessionPerfData("port123", data);
- assert.calledOnce(spy);
- assert.calledWith(spy, topsites_first_painted_ts);
- });
- });
- describe("#uninit", () => {
- it("should call .pingCentre.uninit", () => {
- const stub = sandbox.stub(instance.pingCentre, "uninit");
- instance.uninit();
- assert.calledOnce(stub);
- });
- it("should call .utEvents.uninit", () => {
- const stub = sandbox.stub(instance.utEvents, "uninit");
- instance.uninit();
- assert.calledOnce(stub);
- });
- it("should call .pingCentreForASRouter.uninit", () => {
- const stub = sandbox.stub(instance.pingCentreForASRouter, "uninit");
- instance.uninit();
- assert.calledOnce(stub);
- });
- it("should make this.browserOpenNewtabStart() stop observing browser-open-newtab-start and domwindowopened", async () => {
- await instance.init();
- sandbox.spy(Services.obs, "removeObserver");
- sandbox.stub(instance.pingCentre, "uninit");
- await instance.uninit();
- assert.calledTwice(Services.obs.removeObserver);
- assert.calledWithExactly(Services.obs.removeObserver,
- instance.browserOpenNewtabStart, "browser-open-newtab-start");
- assert.calledWithExactly(Services.obs.removeObserver,
- instance._addWindowListeners, "domwindowopened");
- });
- });
- describe("#onAction", () => {
- beforeEach(() => {
- FakePrefs.prototype.prefs = {};
- });
- it("should call .init() on an INIT action", () => {
- const init = sandbox.stub(instance, "init");
- const sendPageTakeoverData = sandbox.stub(instance, "sendPageTakeoverData");
- instance.onAction({type: at.INIT});
- assert.calledOnce(init);
- assert.calledOnce(sendPageTakeoverData);
- });
- 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 .handleNewTabInit on a NEW_TAB_INIT action", () => {
- sandbox.spy(instance, "handleNewTabInit");
- instance.onAction(ac.AlsoToMain({
- type: at.NEW_TAB_INIT,
- data: {url: "about:newtab", browser},
- }));
- assert.calledOnce(instance.handleNewTabInit);
- });
- it("should call .addSession() on a NEW_TAB_INIT action", () => {
- const stub = sandbox.stub(instance, "addSession").returns({perf: {}});
- sandbox.stub(instance, "setLoadTriggerInfo");
- instance.onAction(ac.AlsoToMain({
- type: at.NEW_TAB_INIT,
- data: {url: "about:monkeys", browser},
- }, "port123"));
- assert.calledOnce(stub);
- assert.calledWith(stub, "port123", "about:monkeys");
- });
- it("should call .endSession() on a NEW_TAB_UNLOAD action", () => {
- const stub = sandbox.stub(instance, "endSession");
- instance.onAction(ac.AlsoToMain({type: at.NEW_TAB_UNLOAD}, "port123"));
- assert.calledWith(stub, "port123");
- });
- it("should call .saveSessionPerfData on SAVE_SESSION_PERF_DATA", () => {
- const stub = sandbox.stub(instance, "saveSessionPerfData");
- const data = {some_ts: 10};
- const action = {type: at.SAVE_SESSION_PERF_DATA, data};
- instance.onAction(ac.AlsoToMain(action, "port123"));
- assert.calledWith(stub, "port123", data);
- });
- it("should send an event on a TELEMETRY_UNDESIRED_EVENT action", () => {
- const sendEvent = sandbox.stub(instance, "sendEvent");
- const eventCreator = sandbox.stub(instance, "createUndesiredEvent");
- const action = {type: at.TELEMETRY_UNDESIRED_EVENT};
- instance.onAction(action);
- assert.calledWith(eventCreator, action);
- assert.calledWith(sendEvent, eventCreator.returnValue);
- });
- it("should send an event on a TELEMETRY_USER_EVENT action", () => {
- FakePrefs.prototype.prefs[TELEMETRY_PREF] = true;
- FakePrefs.prototype.prefs[EVENTS_TELEMETRY_PREF] = true;
- instance = new TelemetryFeed();
- const sendEvent = sandbox.stub(instance, "sendEvent");
- const utSendUserEvent = sandbox.stub(instance.utEvents, "sendUserEvent");
- const eventCreator = sandbox.stub(instance, "createUserEvent");
- const action = {type: at.TELEMETRY_USER_EVENT};
- instance.onAction(action);
- assert.calledWith(eventCreator, action);
- assert.calledWith(sendEvent, eventCreator.returnValue);
- assert.calledWith(utSendUserEvent, eventCreator.returnValue);
- });
- it("should call handleASRouterUserEvent on TELEMETRY_USER_EVENT action", () => {
- FakePrefs.prototype.prefs[TELEMETRY_PREF] = true;
- FakePrefs.prototype.prefs[EVENTS_TELEMETRY_PREF] = true;
- instance = new TelemetryFeed();
- const eventHandler = sandbox.spy(instance, "handleASRouterUserEvent");
- const action = {type: at.AS_ROUTER_TELEMETRY_USER_EVENT, data: {event: "CLICK"}};
- instance.onAction(action);
- assert.calledWith(eventHandler, action);
- });
- it("should send an event on a TELEMETRY_PERFORMANCE_EVENT action", () => {
- const sendEvent = sandbox.stub(instance, "sendEvent");
- const eventCreator = sandbox.stub(instance, "createPerformanceEvent");
- const action = {type: at.TELEMETRY_PERFORMANCE_EVENT};
- instance.onAction(action);
- assert.calledWith(eventCreator, action);
- assert.calledWith(sendEvent, eventCreator.returnValue);
- });
- it("should send an event on a TELEMETRY_IMPRESSION_STATS action", () => {
- const sendEvent = sandbox.stub(instance, "sendEvent");
- const eventCreator = sandbox.stub(instance, "createImpressionStats");
- const tiles = [{id: 10001}, {id: 10002}, {id: 10003}];
- const action = ac.ImpressionStats({source: "POCKET", tiles});
- instance.onAction(action);
- assert.calledWith(eventCreator, au.getPortIdOfSender(action), action.data);
- assert.calledWith(sendEvent, eventCreator.returnValue);
- });
- it("should call .handleDiscoveryStreamImpressionStats on a DISCOVERY_STREAM_IMPRESSION_STATS action", () => {
- const session = {};
- sandbox.stub(instance.sessions, "get").returns(session);
- const data = {source: "foo", tiles: [{id: 1}]};
- const action = {type: at.DISCOVERY_STREAM_IMPRESSION_STATS, data};
- sandbox.spy(instance, "handleDiscoveryStreamImpressionStats");
- instance.onAction(ac.AlsoToMain(action, "port123"));
- assert.calledWith(instance.handleDiscoveryStreamImpressionStats, "port123", data);
- });
- it("should call .handleDiscoveryStreamLoadedContent on a DISCOVERY_STREAM_LOADED_CONTENT action", () => {
- const session = {};
- sandbox.stub(instance.sessions, "get").returns(session);
- const data = {source: "foo", tiles: [{id: 1}]};
- const action = {type: at.DISCOVERY_STREAM_LOADED_CONTENT, data};
- sandbox.spy(instance, "handleDiscoveryStreamLoadedContent");
- instance.onAction(ac.AlsoToMain(action, "port123"));
- assert.calledWith(instance.handleDiscoveryStreamLoadedContent, "port123", data);
- });
- it("should send an event on a DISCOVERY_STREAM_SPOCS_FILL action", () => {
- const sendEvent = sandbox.stub(instance, "sendStructuredIngestionEvent");
- const eventCreator = sandbox.stub(instance, "createSpocsFillPing");
- const spocFills = [
- {id: 10001, displayed: 0, reason: "frequency_cap", full_recalc: 1},
- {id: 10002, displayed: 0, reason: "blocked_by_user", full_recalc: 1},
- {id: 10003, displayed: 1, reason: "n/a", full_recalc: 1},
- ];
- const action = ac.DiscoveryStreamSpocsFill({spoc_fills: spocFills});
- instance.onAction(action);
- assert.calledWith(eventCreator, action.data);
- assert.calledWith(sendEvent, eventCreator.returnValue);
- });
- it("should call .handleTrailheadEnrollEvent on a TRAILHEAD_ENROLL_EVENT action", () => {
- const data = {experiment: "foo", type: "bar", branch: "baz"};
- const action = {type: at.TRAILHEAD_ENROLL_EVENT, data};
- sandbox.spy(instance, "handleTrailheadEnrollEvent");
- instance.onAction(action);
- assert.calledWith(instance.handleTrailheadEnrollEvent, action);
- });
- });
- describe("#handleNewTabInit", () => {
- it("should set the session as preloaded if the browser is preloaded", () => {
- const session = {perf: {}};
- let preloadedBrowser = {getAttribute() { return "preloaded"; }};
- sandbox.stub(instance, "addSession").returns(session);
- instance.onAction(ac.AlsoToMain({
- type: at.NEW_TAB_INIT,
- data: {url: "about:newtab", browser: preloadedBrowser},
- }));
- assert.ok(session.perf.is_preloaded);
- });
- it("should set the session as non-preloaded if the browser is non-preloaded", () => {
- const session = {perf: {}};
- let nonPreloadedBrowser = {getAttribute() { return ""; }};
- sandbox.stub(instance, "addSession").returns(session);
- instance.onAction(ac.AlsoToMain({
- type: at.NEW_TAB_INIT,
- data: {url: "about:newtab", browser: nonPreloadedBrowser},
- }));
- assert.ok(!session.perf.is_preloaded);
- });
- });
- describe("#sendPageTakeoverData", () => {
- let fakePrefs = {"browser.newtabpage.enabled": true};
- beforeEach(() => {
- globals.set("Services", Object.assign({}, Services, {prefs: {getBoolPref: key => fakePrefs[key]}}));
- // Services.prefs = {getBoolPref: key => fakePrefs[key]};
- });
- it("should send correct event data for about:home set to custom URL", async () => {
- fakeHomePageUrl = "https://searchprovider.com";
- instance._prefs.set(TELEMETRY_PREF, true);
- instance._classifySite = () => Promise.resolve("other");
- const sendEvent = sandbox.stub(instance, "sendEvent");
- await instance.sendPageTakeoverData();
- assert.calledOnce(sendEvent);
- assert.equal(sendEvent.firstCall.args[0].event, "PAGE_TAKEOVER_DATA");
- assert.deepEqual(sendEvent.firstCall.args[0].value, {
- home_url_category: "other",
- });
- assert.validate(sendEvent.firstCall.args[0], UserEventPing);
- });
- it("should send correct event data for about:newtab set to custom URL", async () => {
- globals.set("aboutNewTabService", {
- overridden: true,
- newTabURL: "https://searchprovider.com",
- });
- instance._prefs.set(TELEMETRY_PREF, true);
- instance._classifySite = () => Promise.resolve("other");
- const sendEvent = sandbox.stub(instance, "sendEvent");
- await instance.sendPageTakeoverData();
- assert.calledOnce(sendEvent);
- assert.equal(sendEvent.firstCall.args[0].event, "PAGE_TAKEOVER_DATA");
- assert.deepEqual(sendEvent.firstCall.args[0].value, {
- newtab_url_category: "other",
- });
- assert.validate(sendEvent.firstCall.args[0], UserEventPing);
- });
- it("should not send an event if neither about:{home,newtab} are set to custom URL", async () => {
- instance._prefs.set(TELEMETRY_PREF, true);
- const sendEvent = sandbox.stub(instance, "sendEvent");
- await instance.sendPageTakeoverData();
- assert.notCalled(sendEvent);
- });
- it("should send home_extension_id and newtab_extension_id when appropriate", async () => {
- const ID = "{abc-foo-bar}";
- fakeExtensionSettingsStore.getSetting = () => ({id: ID});
- instance._prefs.set(TELEMETRY_PREF, true);
- instance._classifySite = () => Promise.resolve("other");
- const sendEvent = sandbox.stub(instance, "sendEvent");
- await instance.sendPageTakeoverData();
- assert.calledOnce(sendEvent);
- assert.equal(sendEvent.firstCall.args[0].event, "PAGE_TAKEOVER_DATA");
- assert.deepEqual(sendEvent.firstCall.args[0].value, {
- home_extension_id: ID,
- newtab_extension_id: ID,
- });
- assert.validate(sendEvent.firstCall.args[0], UserEventPing);
- });
- });
- describe("#sendDiscoveryStreamImpressions", () => {
- it("should not send impression pings if there is no impression data", () => {
- const spy = sandbox.spy(instance, "sendEvent");
- const session = {};
- instance.sendDiscoveryStreamImpressions("foo", session);
- assert.notCalled(spy);
- });
- it("should send impression pings if there is impression data", () => {
- const spy = sandbox.spy(instance, "sendEvent");
- const session = {
- impressionSets: {
- source_foo: [{id: 1, pos: 0}, {id: 2, pos: 1}],
- source_bar: [{id: 3, pos: 0}, {id: 4, pos: 1}],
- },
- };
- instance.sendDiscoveryStreamImpressions("foo", session);
- assert.calledTwice(spy);
- });
- });
- describe("#sendDiscoveryStreamLoadedContent", () => {
- it("should not send loaded content pings if there is no loaded content data", () => {
- const spy = sandbox.spy(instance, "sendEvent");
- const session = {};
- instance.sendDiscoveryStreamLoadedContent("foo", session);
- assert.notCalled(spy);
- });
- it("should send loaded content pings if there is loaded content data", () => {
- const spy = sandbox.spy(instance, "sendEvent");
- const session = {
- loadedContentSets: {
- source_foo: [{id: 1, pos: 0}, {id: 2, pos: 1}],
- source_bar: [{id: 3, pos: 0}, {id: 4, pos: 1}],
- },
- };
- instance.sendDiscoveryStreamLoadedContent("foo", session);
- assert.calledTwice(spy);
- let [payload] = spy.firstCall.args;
- let sources = new Set([]);
- sources.add(payload.source);
- assert.equal(payload.loaded, 2);
- assert.deepEqual(payload.tiles, session.loadedContentSets[payload.source]);
- [payload] = spy.secondCall.args;
- sources.add(payload.source);
- assert.equal(payload.loaded, 2);
- assert.deepEqual(payload.tiles, session.loadedContentSets[payload.source]);
- assert.deepEqual(sources, new Set(["source_foo", "source_bar"]));
- });
- });
- describe("#handleDiscoveryStreamImpressionStats", () => {
- it("should throw for a missing session", () => {
- assert.throws(() => {
- instance.handleDiscoveryStreamImpressionStats("a_missing_port", {});
- }, "Session does not exist.");
- });
- it("should store impression to impressionSets", () => {
- const session = instance.addSession("new_session", "about:newtab");
- instance.handleDiscoveryStreamImpressionStats("new_session",
- {source: "foo", tiles: [{id: 1, pos: 0}]});
- assert.equal(Object.keys(session.impressionSets).length, 1);
- assert.deepEqual(session.impressionSets.foo, [{id: 1, pos: 0}]);
- // Add another ping with the same source
- instance.handleDiscoveryStreamImpressionStats("new_session",
- {source: "foo", tiles: [{id: 2, pos: 1}]});
- assert.deepEqual(session.impressionSets.foo,
- [{id: 1, pos: 0}, {id: 2, pos: 1}]);
- // Add another ping with a different source
- instance.handleDiscoveryStreamImpressionStats("new_session",
- {source: "bar", tiles: [{id: 3, pos: 2}]});
- assert.equal(Object.keys(session.impressionSets).length, 2);
- assert.deepEqual(session.impressionSets.foo, [{id: 1, pos: 0}, {id: 2, pos: 1}]);
- assert.deepEqual(session.impressionSets.bar, [{id: 3, pos: 2}]);
- });
- });
- describe("#handleDiscoveryStreamLoadedContent", () => {
- it("should throw for a missing session", () => {
- assert.throws(() => {
- instance.handleDiscoveryStreamLoadedContent("a_missing_port", {});
- }, "Session does not exist.");
- });
- it("should store loaded content to loadedContentSets", () => {
- const session = instance.addSession("new_session", "about:newtab");
- instance.handleDiscoveryStreamLoadedContent("new_session",
- {source: "foo", tiles: [{id: 1, pos: 0}]});
- assert.equal(Object.keys(session.loadedContentSets).length, 1);
- assert.deepEqual(session.loadedContentSets.foo, [{id: 1, pos: 0}]);
- // Add another ping with the same source
- instance.handleDiscoveryStreamLoadedContent("new_session",
- {source: "foo", tiles: [{id: 2, pos: 1}]});
- assert.deepEqual(session.loadedContentSets.foo,
- [{id: 1, pos: 0}, {id: 2, pos: 1}]);
- // Add another ping with a different source
- instance.handleDiscoveryStreamLoadedContent("new_session",
- {source: "bar", tiles: [{id: 3, pos: 2}]});
- assert.equal(Object.keys(session.loadedContentSets).length, 2);
- assert.deepEqual(session.loadedContentSets.foo, [{id: 1, pos: 0}, {id: 2, pos: 1}]);
- assert.deepEqual(session.loadedContentSets.bar, [{id: 3, pos: 2}]);
- });
- });
- describe("#_generateStructuredIngestionEndpoint", () => {
- it("should generate a valid endpoint", () => {
- const fakeEndpoint = "http://fakeendpoint.com/base/";
- const fakeUUID = "{34f24486-f01a-9749-9c5b-21476af1fa77}";
- const fakeUUIDWithoutBraces = fakeUUID.substring(1, fakeUUID.length - 1);
- FakePrefs.prototype.prefs = {};
- FakePrefs.prototype.prefs[STRUCTURED_INGESTION_ENDPOINT_PREF] = fakeEndpoint;
- sandbox.stub(global.gUUIDGenerator, "generateUUID").returns(fakeUUID);
- const feed = new TelemetryFeed();
- const url = feed._generateStructuredIngestionEndpoint("testPingType", "1");
- assert.equal(url, `${fakeEndpoint}/testPingType/1/${fakeUUIDWithoutBraces}`);
- });
- });
- describe("#handleTrailheadEnrollEvent", () => {
- it("should send a TRAILHEAD_ENROLL_EVENT if the telemetry is enabled", () => {
- FakePrefs.prototype.prefs[TELEMETRY_PREF] = true;
- const data = {experiment: "foo", type: "bar", branch: "baz"};
- instance = new TelemetryFeed();
- sandbox.stub(instance.utEvents, "sendTrailheadEnrollEvent");
- instance.handleTrailheadEnrollEvent({data});
- assert.calledWith(instance.utEvents.sendTrailheadEnrollEvent, data);
- });
- it("should not send TRAILHEAD_ENROLL_EVENT if the telemetry is disabled", () => {
- FakePrefs.prototype.prefs[TELEMETRY_PREF] = false;
- const data = {experiment: "foo", type: "bar", branch: "baz"};
- instance = new TelemetryFeed();
- sandbox.stub(instance.utEvents, "sendTrailheadEnrollEvent");
- instance.handleTrailheadEnrollEvent({data});
- assert.notCalled(instance.utEvents.sendTrailheadEnrollEvent);
- });
- });
- });
|