From 007d0c1340cf3b1202533037ab8ef276fe947cdf Mon Sep 17 00:00:00 2001 From: Ed Lee Date: Tue, 1 Aug 2017 17:07:50 -0700 Subject: [PATCH] fix(init): Let content know things are initialized and fix "early" issues (#3066) --- system-addon/common/Reducers.jsm | 2 +- system-addon/content-src/components/Base/Base.jsx | 3 ++- .../components/PreferencesPane/PreferencesPane.jsx | 11 +++++++---- system-addon/lib/ActivityStream.jsm | 7 ++++--- system-addon/test/unit/common/Reducers.test.js | 6 +++++- system-addon/test/unit/lib/ActivityStream.test.js | 9 +++++++++ 6 files changed, 28 insertions(+), 10 deletions(-) diff --git a/system-addon/common/Reducers.jsm b/system-addon/common/Reducers.jsm index 8aaf6eb0e8..eb37464cdf 100644 --- a/system-addon/common/Reducers.jsm +++ b/system-addon/common/Reducers.jsm @@ -37,7 +37,7 @@ const INITIAL_STATE = { function App(prevState = INITIAL_STATE.App, action) { switch (action.type) { case at.INIT: - return Object.assign({}, action.data || {}, {initialized: true}); + return Object.assign({}, prevState, action.data || {}, {initialized: true}); case at.LOCALE_UPDATED: { if (!action.data) { return prevState; diff --git a/system-addon/content-src/components/Base/Base.jsx b/system-addon/content-src/components/Base/Base.jsx index c0a5e0cce7..12f566a6fe 100644 --- a/system-addon/content-src/components/Base/Base.jsx +++ b/system-addon/content-src/components/Base/Base.jsx @@ -27,7 +27,8 @@ class Base extends React.Component { this.updateTitle(this.props.App), {once: true}); } componentWillUpdate({App}) { - if (App.locale !== this.props.App.locale) { + // Early loads might not have locale yet, so wait until we do + if (App.locale && App.locale !== this.props.App.locale) { addLocaleDataForReactIntl(App); this.updateTitle(App); } diff --git a/system-addon/content-src/components/PreferencesPane/PreferencesPane.jsx b/system-addon/content-src/components/PreferencesPane/PreferencesPane.jsx index f2094e1d2d..eb1e23c0f8 100644 --- a/system-addon/content-src/components/PreferencesPane/PreferencesPane.jsx +++ b/system-addon/content-src/components/PreferencesPane/PreferencesPane.jsx @@ -22,10 +22,13 @@ class PreferencesPane extends React.Component { this.togglePane = this.togglePane.bind(this); // TODO This is temporary until sections register their PreferenceInput component automatically - try { - this.topStoriesOptions = JSON.parse(props.Prefs.values["feeds.section.topstories.options"]); - } catch (e) { - console.error("Problem parsing feeds.section.topstories.options", e); // eslint-disable-line no-console + const optionJSON = props.Prefs.values["feeds.section.topstories.options"]; + if (optionJSON) { + try { + this.topStoriesOptions = JSON.parse(optionJSON); + } catch (e) { + console.error("Problem parsing feeds.section.topstories.options", e); // eslint-disable-line no-console + } } } componentDidMount() { diff --git a/system-addon/lib/ActivityStream.jsm b/system-addon/lib/ActivityStream.jsm index fcdde229f5..8b239b05f9 100644 --- a/system-addon/lib/ActivityStream.jsm +++ b/system-addon/lib/ActivityStream.jsm @@ -8,7 +8,7 @@ Cu.import("resource://gre/modules/Services.jsm"); // NB: Eagerly load modules that will be loaded/constructed/initialized in the // common case to avoid the overhead of wrapping and detecting lazy loading. -const {actionTypes: at} = Cu.import("resource://activity-stream/common/Actions.jsm", {}); +const {actionCreators: ac, actionTypes: at} = Cu.import("resource://activity-stream/common/Actions.jsm", {}); const {DefaultPrefs} = Cu.import("resource://activity-stream/lib/ActivityStreamPrefs.jsm", {}); const {LocalizationFeed} = Cu.import("resource://activity-stream/lib/LocalizationFeed.jsm", {}); const {ManualMigration} = Cu.import("resource://activity-stream/lib/ManualMigration.jsm", {}); @@ -197,11 +197,12 @@ this.ActivityStream = class ActivityStream { this._updateDynamicPrefs(); this._defaultPrefs.init(); + // Hook up the store and let all feeds and pages initialize this.store.init(this.feeds); - this.store.dispatch({ + this.store.dispatch(ac.BroadcastToContent({ type: at.INIT, data: {version: this.options.version} - }); + })); this.initialized = true; } diff --git a/system-addon/test/unit/common/Reducers.test.js b/system-addon/test/unit/common/Reducers.test.js index edee9a3373..aa4011926f 100644 --- a/system-addon/test/unit/common/Reducers.test.js +++ b/system-addon/test/unit/common/Reducers.test.js @@ -9,14 +9,18 @@ describe("Reducers", () => { const nextState = App(undefined, {type: "FOO"}); assert.equal(nextState, INITIAL_STATE.App); }); - it("should not set initialized to true on INIT", () => { + it("should set initialized to true on INIT", () => { const nextState = App(undefined, {type: "INIT"}); + assert.propertyVal(nextState, "initialized", true); }); it("should set initialized, version, and locale on INIT", () => { const action = {type: "INIT", data: {version: "1.2.3"}}; + const nextState = App(undefined, action); + assert.propertyVal(nextState, "version", "1.2.3"); + assert.propertyVal(nextState, "locale", INITIAL_STATE.App.locale); }); it("should not update state for empty action.data on LOCALE_UPDATED", () => { const nextState = App(undefined, {type: at.LOCALE_UPDATED}); diff --git a/system-addon/test/unit/lib/ActivityStream.test.js b/system-addon/test/unit/lib/ActivityStream.test.js index 48e7b0abf3..31300bb2f9 100644 --- a/system-addon/test/unit/lib/ActivityStream.test.js +++ b/system-addon/test/unit/lib/ActivityStream.test.js @@ -1,4 +1,5 @@ const injector = require("inject!lib/ActivityStream.jsm"); +const {CONTENT_MESSAGE_TYPE} = require("common/Actions.jsm"); const REASON_ADDON_UNINSTALL = 6; @@ -63,6 +64,14 @@ describe("ActivityStream", () => { const action = as.store.dispatch.firstCall.args[0]; assert.propertyVal(action.data, "version", "1.2.3"); }); + it("should emit an INIT event to content", () => { + sandbox.stub(as.store, "dispatch"); + + as.init(); + + const action = as.store.dispatch.firstCall.args[0]; + assert.equal(action.meta.to, CONTENT_MESSAGE_TYPE); + }); }); describe("#uninit", () => { beforeEach(() => {