Skip to content
This repository has been archived by the owner on Feb 29, 2020. It is now read-only.

Commit

Permalink
feat(topstories): Get new recommendations on locale|options change (#…
Browse files Browse the repository at this point in the history
  • Loading branch information
csadilek authored and Mardak committed Jul 31, 2017
1 parent 3f5d043 commit c260e0a
Show file tree
Hide file tree
Showing 3 changed files with 36 additions and 37 deletions.
4 changes: 2 additions & 2 deletions system-addon/lib/ActivityStream.jsm
Original file line number Diff line number Diff line change
Expand Up @@ -44,10 +44,10 @@ const PREFS_CONFIG = new Map([
provider_icon: "pocket",
provider_name: "Pocket",
read_more_endpoint: "https://getpocket.com/explore/trending?src=ff_new_tab",
stories_endpoint: "https://getpocket.com/v3/firefox/global-recs?consumer_key=$apiKey&locale_lang=$locale",
stories_endpoint: `https://getpocket.com/v3/firefox/global-recs?consumer_key=$apiKey&locale_lang=${args.locale}`,
stories_referrer: "https://getpocket.com/recommendations",
survey_link: "https://www.surveymonkey.com/r/newtabffx",
topics_endpoint: "https://getpocket.com/v3/firefox/trending-topics?consumer_key=$apiKey&locale_lang=$locale"
topics_endpoint: `https://getpocket.com/v3/firefox/trending-topics?consumer_key=$apiKey&locale_lang=${args.locale}`
})
}],
["migrationExpired", {
Expand Down
34 changes: 19 additions & 15 deletions system-addon/lib/TopStoriesFeed.jsm
Original file line number Diff line number Diff line change
Expand Up @@ -16,21 +16,21 @@ const STORIES_UPDATE_TIME = 30 * 60 * 1000; // 30 minutes
const TOPICS_UPDATE_TIME = 3 * 60 * 60 * 1000; // 3 hours
const STORIES_NOW_THRESHOLD = 24 * 60 * 60 * 1000; // 24 hours
const SECTION_ID = "TopStories";
const FEED_PREF = "feeds.section.topstories";
const SECTION_OPTIONS_PREF = "feeds.section.topstories.options";

this.TopStoriesFeed = class TopStoriesFeed {
constructor() {
this.storiesLastUpdated = 0;
this.topicsLastUpdated = 0;
}

init() {
try {
this.storiesLastUpdated = 0;
this.topicsLastUpdated = 0;

const prefs = new Prefs();
const options = JSON.parse(prefs.get("feeds.section.topstories.options"));
const options = JSON.parse(prefs.get(SECTION_OPTIONS_PREF));
const apiKey = this._getApiKeyFromPref(options.api_key_pref);
const locale = Services.locale.getRequestedLocale();
this.stories_endpoint = this._produceFinalEndpointUrl(options.stories_endpoint, apiKey, locale);
this.topics_endpoint = this._produceFinalEndpointUrl(options.topics_endpoint, apiKey, locale);
this.stories_endpoint = this._produceFinalEndpointUrl(options.stories_endpoint, apiKey);
this.topics_endpoint = this._produceFinalEndpointUrl(options.topics_endpoint, apiKey);

this.read_more_endpoint = options.read_more_endpoint;
this.stories_referrer = options.stories_referrer;
Expand Down Expand Up @@ -141,17 +141,14 @@ this.TopStoriesFeed = class TopStoriesFeed {
return new Prefs().get(apiKeyPref) || Services.prefs.getCharPref(apiKeyPref);
}

_produceFinalEndpointUrl(url, apiKey, locale) {
_produceFinalEndpointUrl(url, apiKey) {
if (!url) {
return url;
}
if (url.includes("$apiKey") && !apiKey) {
throw new Error(`An API key was specified but none configured: ${url}`);
}
if (url.includes("$locale") && !locale) {
throw new Error(`A locale was specified but none detected: ${url}`);
}
return url.replace("$apiKey", apiKey).replace("$locale", locale);
return url.replace("$apiKey", apiKey);
}

// Need to remove parenthesis from image URLs as React will otherwise
Expand Down Expand Up @@ -188,7 +185,12 @@ this.TopStoriesFeed = class TopStoriesFeed {
this.uninit();
break;
case at.FEED_INIT:
if (action.data === "feeds.section.topstories") {
if (action.data === FEED_PREF) {
this.init();
}
break;
case at.PREF_CHANGED:
if (action.data.name === SECTION_OPTIONS_PREF) {
this.init();
}
break;
Expand All @@ -199,4 +201,6 @@ this.TopStoriesFeed = class TopStoriesFeed {
this.STORIES_UPDATE_TIME = STORIES_UPDATE_TIME;
this.TOPICS_UPDATE_TIME = TOPICS_UPDATE_TIME;
this.SECTION_ID = SECTION_ID;
this.EXPORTED_SYMBOLS = ["TopStoriesFeed", "STORIES_UPDATE_TIME", "TOPICS_UPDATE_TIME", "SECTION_ID"];
this.FEED_PREF = FEED_PREF;
this.SECTION_OPTIONS_PREF = SECTION_OPTIONS_PREF;
this.EXPORTED_SYMBOLS = ["TopStoriesFeed", "STORIES_UPDATE_TIME", "TOPICS_UPDATE_TIME", "SECTION_ID", "FEED_PREF", "SECTION_OPTIONS_PREF"];
35 changes: 15 additions & 20 deletions system-addon/test/unit/lib/TopStoriesFeed.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,15 +9,17 @@ describe("Top Stories Feed", () => {
let STORIES_UPDATE_TIME;
let TOPICS_UPDATE_TIME;
let SECTION_ID;
let FEED_PREF;
let SECTION_OPTIONS_PREF;
let instance;
let clock;
let globals;

beforeEach(() => {
FakePrefs.prototype.prefs["feeds.section.topstories.options"] = `{
"stories_endpoint": "https://somedomain.org/stories?key=$apiKey&locale=$locale",
"stories_endpoint": "https://somedomain.org/stories?key=$apiKey",
"stories_referrer": "https://somedomain.org/referrer",
"topics_endpoint": "https://somedomain.org/topics?key=$apiKey&locale=$locale",
"topics_endpoint": "https://somedomain.org/topics?key=$apiKey",
"survey_link": "https://www.surveymonkey.com/r/newtabffx",
"api_key_pref": "apiKeyPref",
"provider_name": "test-provider",
Expand All @@ -30,9 +32,11 @@ describe("Top Stories Feed", () => {
globals.set("Services", {locale: {getRequestedLocale: () => "en-CA"}});
clock = sinon.useFakeTimers();

({TopStoriesFeed, STORIES_UPDATE_TIME, TOPICS_UPDATE_TIME, SECTION_ID} = injector({"lib/ActivityStreamPrefs.jsm": {Prefs: FakePrefs}}));
({TopStoriesFeed, STORIES_UPDATE_TIME, TOPICS_UPDATE_TIME, SECTION_ID, FEED_PREF, SECTION_OPTIONS_PREF} = injector({"lib/ActivityStreamPrefs.jsm": {Prefs: FakePrefs}}));
instance = new TopStoriesFeed();
instance.store = {getState() { return {}; }, dispatch: sinon.spy()};
instance.storiesLastUpdated = 0;
instance.topicsLastUpdated = 0;
});
afterEach(() => {
globals.restore();
Expand All @@ -44,9 +48,9 @@ describe("Top Stories Feed", () => {
});
it("should initialize endpoints based on prefs", () => {
instance.onAction({type: at.INIT});
assert.equal("https://somedomain.org/stories?key=test-api-key&locale=en-CA", instance.stories_endpoint);
assert.equal("https://somedomain.org/stories?key=test-api-key", instance.stories_endpoint);
assert.equal("https://somedomain.org/referrer", instance.stories_referrer);
assert.equal("https://somedomain.org/topics?key=test-api-key&locale=en-CA", instance.topics_endpoint);
assert.equal("https://somedomain.org/topics?key=test-api-key", instance.topics_endpoint);
});
it("should register section", () => {
const expectedSectionOptions = {
Expand Down Expand Up @@ -117,18 +121,6 @@ describe("Top Stories Feed", () => {

assert.called(Components.utils.reportError);
});
it("should report error for missing locale", () => {
let fakeServices = {locale: {getRequestedLocale: sinon.spy()}};
globals.set("Services", fakeServices);
globals.sandbox.spy(global.Components.utils, "reportError");
FakePrefs.prototype.prefs["feeds.section.topstories.options"] = `{
"stories_endpoint": "https://somedomain.org/stories?locale=$locale",
"topics_endpoint": "https://somedomain.org/topics?locale=$locale"
}`;
instance.init();

assert.called(Components.utils.reportError);
});
it("should deregister section", () => {
instance.onAction({type: at.UNINIT});
assert.calledOnce(instance.store.dispatch);
Expand All @@ -139,7 +131,12 @@ describe("Top Stories Feed", () => {
});
it("should initialize on FEED_INIT", () => {
instance.init = sinon.spy();
instance.onAction({type: at.FEED_INIT, data: "feeds.section.topstories"});
instance.onAction({type: at.FEED_INIT, data: FEED_PREF});
assert.calledOnce(instance.init);
});
it("should initialize on PREF_CHANGED", () => {
instance.init = sinon.spy();
instance.onAction({type: at.PREF_CHANGED, data: {name: SECTION_OPTIONS_PREF}});
assert.calledOnce(instance.init);
});
});
Expand Down Expand Up @@ -278,7 +275,6 @@ describe("Top Stories Feed", () => {
describe("#update", () => {
it("should fetch stories after update interval", () => {
instance.fetchStories = sinon.spy();
instance.fetchTopics = sinon.spy();
instance.onAction({type: at.SYSTEM_TICK});
assert.notCalled(instance.fetchStories);

Expand All @@ -287,7 +283,6 @@ describe("Top Stories Feed", () => {
assert.calledOnce(instance.fetchStories);
});
it("should fetch topics after update interval", () => {
instance.fetchStories = sinon.spy();
instance.fetchTopics = sinon.spy();
instance.onAction({type: at.SYSTEM_TICK});
assert.notCalled(instance.fetchTopics);
Expand Down

0 comments on commit c260e0a

Please sign in to comment.