fune/browser/components/newtab/test/unit/lib/ActivityStream.test.js
2020-02-12 17:42:52 +00:00

454 lines
16 KiB
JavaScript

import { CONTENT_MESSAGE_TYPE } from "common/Actions.jsm";
import injector from "inject!lib/ActivityStream.jsm";
describe("ActivityStream", () => {
let sandbox;
let as;
let ActivityStream;
let PREFS_CONFIG;
function Fake() {}
function FakeStore() {
return { init: () => {}, uninit: () => {}, feeds: { get: () => {} } };
}
beforeEach(() => {
sandbox = sinon.createSandbox();
({ ActivityStream, PREFS_CONFIG } = injector({
"lib/Store.jsm": { Store: FakeStore },
"lib/AboutPreferences.jsm": { AboutPreferences: Fake },
"lib/NewTabInit.jsm": { NewTabInit: Fake },
"lib/PlacesFeed.jsm": { PlacesFeed: Fake },
"lib/PrefsFeed.jsm": { PrefsFeed: Fake },
"lib/SectionsManager.jsm": { SectionsFeed: Fake },
"lib/SystemTickFeed.jsm": { SystemTickFeed: Fake },
"lib/TelemetryFeed.jsm": { TelemetryFeed: Fake },
"lib/FaviconFeed.jsm": { FaviconFeed: Fake },
"lib/TopSitesFeed.jsm": { TopSitesFeed: Fake },
"lib/TopStoriesFeed.jsm": { TopStoriesFeed: Fake },
"lib/HighlightsFeed.jsm": { HighlightsFeed: Fake },
"lib/ASRouterFeed.jsm": { ASRouterFeed: Fake },
"lib/RecommendationProviderSwitcher.jsm": {
RecommendationProviderSwitcher: Fake,
},
"lib/DiscoveryStreamFeed.jsm": { DiscoveryStreamFeed: Fake },
}));
as = new ActivityStream();
sandbox.stub(as.store, "init");
sandbox.stub(as.store, "uninit");
sandbox.stub(as._defaultPrefs, "init");
});
afterEach(() => sandbox.restore());
it("should exist", () => {
assert.ok(ActivityStream);
});
it("should initialize with .initialized=false", () => {
assert.isFalse(as.initialized, ".initialized");
});
describe("#init", () => {
beforeEach(() => {
as.init();
});
it("should initialize default prefs", () => {
assert.calledOnce(as._defaultPrefs.init);
});
it("should set .initialized to true", () => {
assert.isTrue(as.initialized, ".initialized");
});
it("should call .store.init", () => {
assert.calledOnce(as.store.init);
});
it("should pass to Store an INIT event for content", () => {
as.init();
const [, action] = as.store.init.firstCall.args;
assert.equal(action.meta.to, CONTENT_MESSAGE_TYPE);
});
it("should pass to Store an UNINIT event", () => {
as.init();
const [, , action] = as.store.init.firstCall.args;
assert.equal(action.type, "UNINIT");
});
it("should clear old default discoverystream config pref", () => {
sandbox.stub(global.Services.prefs, "prefHasUserValue").returns(true);
sandbox
.stub(global.Services.prefs, "getStringPref")
.returns(
`{"api_key_pref":"extensions.pocket.oAuthConsumerKey","enabled":false,"show_spocs":true,"layout_endpoint":"https://getpocket.cdn.mozilla.net/v3/newtab/layout?version=1&consumer_key=$apiKey&layout_variant=basic"}`
);
sandbox.stub(global.Services.prefs, "clearUserPref");
as.init();
assert.calledWith(
global.Services.prefs.clearUserPref,
"browser.newtabpage.activity-stream.discoverystream.config"
);
});
});
describe("#uninit", () => {
beforeEach(() => {
as.init();
as.uninit();
});
it("should set .initialized to false", () => {
assert.isFalse(as.initialized, ".initialized");
});
it("should call .store.uninit", () => {
assert.calledOnce(as.store.uninit);
});
});
describe("feeds", () => {
it("should create a NewTabInit feed", () => {
const feed = as.feeds.get("feeds.newtabinit")();
assert.instanceOf(feed, Fake);
});
it("should create a Places feed", () => {
const feed = as.feeds.get("feeds.places")();
assert.instanceOf(feed, Fake);
});
it("should create a TopSites feed", () => {
const feed = as.feeds.get("feeds.topsites")();
assert.instanceOf(feed, Fake);
});
it("should create a Telemetry feed", () => {
const feed = as.feeds.get("feeds.telemetry")();
assert.instanceOf(feed, Fake);
});
it("should create a Prefs feed", () => {
const feed = as.feeds.get("feeds.prefs")();
assert.instanceOf(feed, Fake);
});
it("should create a section feed for each section in PREFS_CONFIG", () => {
// If new sections are added, their feeds will have to be added to the
// list of injected feeds above for this test to pass
let feedCount = 0;
for (const pref of PREFS_CONFIG.keys()) {
if (pref.search(/^feeds\.section\.[^.]+$/) === 0) {
const feed = as.feeds.get(pref)();
assert.instanceOf(feed, Fake);
feedCount++;
}
}
assert.isAbove(feedCount, 0);
});
it("should create a AboutPreferences feed", () => {
const feed = as.feeds.get("feeds.aboutpreferences")();
assert.instanceOf(feed, Fake);
});
it("should create a SectionsFeed", () => {
const feed = as.feeds.get("feeds.sections")();
assert.instanceOf(feed, Fake);
});
it("should create a SystemTick feed", () => {
const feed = as.feeds.get("feeds.systemtick")();
assert.instanceOf(feed, Fake);
});
it("should create a Favicon feed", () => {
const feed = as.feeds.get("feeds.favicon")();
assert.instanceOf(feed, Fake);
});
it("should create a ASRouter feed", () => {
const feed = as.feeds.get("feeds.asrouterfeed")();
assert.instanceOf(feed, Fake);
});
it("should create a RecommendationProviderSwitcher feed", () => {
const feed = as.feeds.get("feeds.recommendationproviderswitcher")();
assert.instanceOf(feed, Fake);
});
it("should create a DiscoveryStreamFeed feed", () => {
const feed = as.feeds.get("feeds.discoverystreamfeed")();
assert.instanceOf(feed, Fake);
});
});
describe("_migratePref", () => {
it("should migrate a pref if the user has set a custom value", () => {
sandbox.stub(global.Services.prefs, "prefHasUserValue").returns(true);
sandbox.stub(global.Services.prefs, "getPrefType").returns("integer");
sandbox.stub(global.Services.prefs, "getIntPref").returns(10);
as._migratePref("oldPrefName", result => assert.equal(10, result));
});
it("should not migrate a pref if the user has not set a custom value", () => {
// we bailed out early so we don't check the pref type later
sandbox.stub(global.Services.prefs, "prefHasUserValue").returns(false);
sandbox.stub(global.Services.prefs, "getPrefType");
as._migratePref("oldPrefName");
assert.notCalled(global.Services.prefs.getPrefType);
});
it("should use the proper pref getter for each type", () => {
sandbox.stub(global.Services.prefs, "prefHasUserValue").returns(true);
// Integer
sandbox.stub(global.Services.prefs, "getIntPref");
sandbox.stub(global.Services.prefs, "getPrefType").returns("integer");
as._migratePref("oldPrefName", () => {});
assert.calledWith(global.Services.prefs.getIntPref, "oldPrefName");
// Boolean
sandbox.stub(global.Services.prefs, "getBoolPref");
global.Services.prefs.getPrefType.returns("boolean");
as._migratePref("oldPrefName", () => {});
assert.calledWith(global.Services.prefs.getBoolPref, "oldPrefName");
// String
sandbox.stub(global.Services.prefs, "getStringPref");
global.Services.prefs.getPrefType.returns("string");
as._migratePref("oldPrefName", () => {});
assert.calledWith(global.Services.prefs.getStringPref, "oldPrefName");
});
it("should clear the old pref after setting the new one", () => {
sandbox.stub(global.Services.prefs, "prefHasUserValue").returns(true);
sandbox.stub(global.Services.prefs, "clearUserPref");
sandbox.stub(global.Services.prefs, "getPrefType").returns("integer");
as._migratePref("oldPrefName", () => {});
assert.calledWith(global.Services.prefs.clearUserPref, "oldPrefName");
});
});
describe("_updateDynamicPrefs Discovery Stream", () => {
it("should be true with expected en-US geo and locale", () => {
sandbox.stub(global.Services.prefs, "prefHasUserValue").returns(true);
sandbox.stub(global.Services.prefs, "getStringPref").returns("US");
sandbox
.stub(global.Services.locale, "appLocaleAsBCP47")
.get(() => "en-US");
as._updateDynamicPrefs();
assert.isTrue(
JSON.parse(PREFS_CONFIG.get("discoverystream.config").value).enabled
);
});
it("should be true with expected en-CA geo and locale", () => {
sandbox.stub(global.Services.prefs, "prefHasUserValue").returns(true);
sandbox.stub(global.Services.prefs, "getStringPref").returns("CA");
sandbox
.stub(global.Services.locale, "appLocaleAsBCP47")
.get(() => "en-CA");
as._updateDynamicPrefs();
assert.isTrue(
JSON.parse(PREFS_CONFIG.get("discoverystream.config").value).enabled
);
});
it("should be true with expected de geo and locale", () => {
sandbox.stub(global.Services.prefs, "prefHasUserValue").returns(true);
sandbox.stub(global.Services.prefs, "getStringPref").returns("DE");
sandbox
.stub(global.Services.locale, "appLocaleAsBCP47")
.get(() => "de-DE");
as._updateDynamicPrefs();
assert.isTrue(
JSON.parse(PREFS_CONFIG.get("discoverystream.config").value).enabled
);
});
});
describe("_updateDynamicPrefs topstories default value", () => {
let getStringPrefStub;
let appLocaleAsBCP47Stub;
let prefHasUserValueStub;
beforeEach(() => {
prefHasUserValueStub = sandbox.stub(
global.Services.prefs,
"prefHasUserValue"
);
getStringPrefStub = sandbox.stub(global.Services.prefs, "getStringPref");
appLocaleAsBCP47Stub = sandbox.stub(
global.Services.locale,
"appLocaleAsBCP47"
);
prefHasUserValueStub.returns(true);
appLocaleAsBCP47Stub.get(() => "en-US");
getStringPrefStub.withArgs("browser.search.region").returns("US");
getStringPrefStub
.withArgs(
"browser.newtabpage.activity-stream.discoverystream.region-stories-config"
)
.returns("US,CA");
});
it("should be false with no geo/locale", () => {
prefHasUserValueStub.returns(false);
appLocaleAsBCP47Stub.get(() => "");
getStringPrefStub.withArgs("browser.search.region").returns("");
as._updateDynamicPrefs();
assert.isFalse(PREFS_CONFIG.get("feeds.section.topstories").value);
});
it("should be false with unexpected geo", () => {
getStringPrefStub.withArgs("browser.search.region").returns("NOGEO");
as._updateDynamicPrefs();
assert.isFalse(PREFS_CONFIG.get("feeds.section.topstories").value);
});
it("should be false with expected geo and unexpected locale", () => {
appLocaleAsBCP47Stub.get(() => "no-LOCALE");
as._updateDynamicPrefs();
assert.isFalse(PREFS_CONFIG.get("feeds.section.topstories").value);
});
it("should be true with expected geo and locale", () => {
as._updateDynamicPrefs();
assert.isTrue(PREFS_CONFIG.get("feeds.section.topstories").value);
});
it("should be false after expected geo and locale then unexpected", () => {
getStringPrefStub
.withArgs("browser.search.region")
.onFirstCall()
.returns("US")
.onSecondCall()
.returns("NOGEO");
as._updateDynamicPrefs();
as._updateDynamicPrefs();
assert.isFalse(PREFS_CONFIG.get("feeds.section.topstories").value);
});
it("should be true with updated pref change", () => {
appLocaleAsBCP47Stub.get(() => "en-GB");
getStringPrefStub.withArgs("browser.search.region").returns("GB");
getStringPrefStub
.withArgs(
"browser.newtabpage.activity-stream.discoverystream.region-stories-config"
)
.returns("US,CA,GB");
as._updateDynamicPrefs();
assert.isTrue(PREFS_CONFIG.get("feeds.section.topstories").value);
});
});
describe("_updateDynamicPrefs topstories delayed default value", () => {
let clock;
beforeEach(() => {
clock = sinon.useFakeTimers();
// Have addObserver cause prefHasUserValue to now return true then observe
sandbox
.stub(global.Services.prefs, "addObserver")
.callsFake((pref, obs) => {
sandbox.stub(global.Services.prefs, "prefHasUserValue").returns(true);
setTimeout(() => obs.observe(null, "nsPref:changed", pref)); // eslint-disable-line max-nested-callbacks
});
});
afterEach(() => clock.restore());
it("should set false with unexpected geo", () => {
sandbox.stub(global.Services.prefs, "getStringPref").returns("NOGEO");
as._updateDynamicPrefs();
clock.tick(1);
assert.isFalse(PREFS_CONFIG.get("feeds.section.topstories").value);
});
it("should set true with expected geo and locale", () => {
sandbox.stub(global.Services.prefs, "getStringPref").returns("US");
sandbox
.stub(global.Services.locale, "appLocaleAsBCP47")
.get(() => "en-US");
as._updateDynamicPrefs();
clock.tick(1);
assert.isTrue(PREFS_CONFIG.get("feeds.section.topstories").value);
});
it("should not change default even with expected geo and locale", () => {
as._defaultPrefs.set("feeds.section.topstories", false);
sandbox.stub(global.Services.prefs, "getStringPref").returns("US");
sandbox
.stub(global.Services.locale, "appLocaleAsBCP47")
.get(() => "en-US");
as._updateDynamicPrefs();
clock.tick(1);
assert.isFalse(PREFS_CONFIG.get("feeds.section.topstories").value);
});
});
describe("telemetry reporting on init failure", () => {
it("should send a ping on init error", () => {
as = new ActivityStream();
const telemetry = { handleUndesiredEvent: sandbox.spy() };
sandbox.stub(as.store, "init").throws();
sandbox.stub(as.store.feeds, "get").returns(telemetry);
try {
as.init();
} catch (e) {}
assert.calledOnce(telemetry.handleUndesiredEvent);
});
});
describe("searchs shortcuts shouldPin pref", () => {
const SEARCH_SHORTCUTS_SEARCH_ENGINES_PREF =
"improvesearch.topSiteSearchShortcuts.searchEngines";
let stub;
beforeEach(() => {
sandbox.stub(global.Services.prefs, "prefHasUserValue").returns(true);
stub = sandbox.stub(global.Services.prefs, "getStringPref");
});
it("should be an empty string when no geo is available", () => {
as._updateDynamicPrefs();
assert.equal(
PREFS_CONFIG.get(SEARCH_SHORTCUTS_SEARCH_ENGINES_PREF).value,
""
);
});
it("should be 'baidu' in China", () => {
stub.returns("CN");
as._updateDynamicPrefs();
assert.equal(
PREFS_CONFIG.get(SEARCH_SHORTCUTS_SEARCH_ENGINES_PREF).value,
"baidu"
);
});
it("should be 'yandex' in Russia, Belarus, Kazakhstan, and Turkey", () => {
const geos = ["BY", "KZ", "RU", "TR"];
for (const geo of geos) {
stub.returns(geo);
as._updateDynamicPrefs();
assert.equal(
PREFS_CONFIG.get(SEARCH_SHORTCUTS_SEARCH_ENGINES_PREF).value,
"yandex"
);
}
});
it("should be 'google,amazon' in Germany, France, the UK, Japan, Italy, and the US", () => {
const geos = ["DE", "FR", "GB", "IT", "JP", "US"];
for (const geo of geos) {
stub.returns(geo);
as._updateDynamicPrefs();
assert.equal(
PREFS_CONFIG.get(SEARCH_SHORTCUTS_SEARCH_ENGINES_PREF).value,
"google,amazon"
);
}
});
it("should be 'google' elsewhere", () => {
// A selection of other geos
const geos = ["BR", "CA", "ES", "ID", "IN"];
for (const geo of geos) {
stub.returns(geo);
as._updateDynamicPrefs();
assert.equal(
PREFS_CONFIG.get(SEARCH_SHORTCUTS_SEARCH_ENGINES_PREF).value,
"google"
);
}
});
});
});