Bug 1258728 - keep remote newtab version in a pref r?ursula draft
authorOlivier Yiptong <olivier@olivieryiptong.com>
Thu, 24 Mar 2016 16:28:16 -0400
changeset 344561 007cbac6382b20a59726bd9d7ee89f097e5198e4
parent 344560 041217d62e81f21ee6990abb5f228bd3aaab151d
child 516984 3c4d40658540eb19adde08ebc1537408989b163f
push id13857
push userolivier@olivieryiptong.com
push dateThu, 24 Mar 2016 20:31:06 +0000
reviewersursula
bugs1258728
milestone48.0a1
Bug 1258728 - keep remote newtab version in a pref r?ursula MozReview-Commit-ID: GNk74kkxHcV
browser/app/profile/firefox.js
browser/components/newtab/NewTabPrefsProvider.jsm
browser/components/newtab/aboutNewTabService.js
browser/components/newtab/tests/xpcshell/test_AboutNewTabService.js
--- a/browser/app/profile/firefox.js
+++ b/browser/app/profile/firefox.js
@@ -1380,16 +1380,19 @@ pref("browser.newtabpage.columns", 5);
 pref("browser.newtabpage.directory.source", "https://tiles.services.mozilla.com/v3/links/fetch/%LOCALE%/%CHANNEL%");
 
 // endpoint to send newtab click and view pings
 pref("browser.newtabpage.directory.ping", "https://tiles.services.mozilla.com/v3/links/");
 
 // activates the remote-hosted newtab page
 pref("browser.newtabpage.remote", false);
 
+// remote newtab version targeted
+pref("browser.newtabpage.remote.version", "1");
+
 // Toggles endpoints allowed for remote newtab communications
 pref("browser.newtabpage.remote.mode", "production");
 
 // content-signature tests for remote newtab
 pref("browser.newtabpage.remote.content-signing-test", false);
 
 // verification keys for remote-hosted newtab page
 pref("browser.newtabpage.remote.keys", "");
--- a/browser/components/newtab/NewTabPrefsProvider.jsm
+++ b/browser/components/newtab/NewTabPrefsProvider.jsm
@@ -14,16 +14,17 @@ XPCOMUtils.defineLazyGetter(this, "Event
   const {EventEmitter} = Cu.import("resource://devtools/shared/event-emitter.js", {});
   return EventEmitter;
 });
 
 // Supported prefs and data type
 const gPrefsMap = new Map([
   ["browser.newtabpage.remote", "bool"],
   ["browser.newtabpage.remote.mode", "str"],
+  ["browser.newtabpage.remote.version", "str"],
   ["browser.newtabpage.enabled", "bool"],
   ["browser.newtabpage.enhanced", "bool"],
   ["browser.newtabpage.introShown", "bool"],
   ["browser.newtabpage.updateIntroShown", "bool"],
   ["browser.newtabpage.pinned", "str"],
   ["browser.newtabpage.blocked", "str"],
   ["intl.locale.matchOS", "bool"],
   ["general.useragent.locale", "localized"],
--- a/browser/components/newtab/aboutNewTabService.js
+++ b/browser/components/newtab/aboutNewTabService.js
@@ -39,19 +39,20 @@ const PREF_REMOTE_CS_TEST = "browser.new
 const PREF_MATCH_OS_LOCALE = "intl.locale.matchOS";
 
 // The preference that tells what locale the user selected
 const PREF_SELECTED_LOCALE = "general.useragent.locale";
 
 // The preference that tells what remote mode is enabled.
 const PREF_REMOTE_MODE = "browser.newtabpage.remote.mode";
 
-const VALID_CHANNELS = new Set(["esr", "release", "beta", "aurora", "nightly"]);
+// The preference that tells which remote version is expected.
+const PREF_REMOTE_VERSION = "browser.newtabpage.remote.version";
 
-const REMOTE_NEWTAB_VERSION = "0";
+const VALID_CHANNELS = new Set(["esr", "release", "beta", "aurora", "nightly"]);
 
 function AboutNewTabService() {
   NewTabPrefsProvider.prefs.on(PREF_REMOTE_ENABLED, this._handleToggleEvent.bind(this));
 
   this._updateRemoteMaybe = this._updateRemoteMaybe.bind(this);
 
   // trigger remote change if needed, according to pref
   this.toggleRemote(Services.prefs.getBoolPref(PREF_REMOTE_ENABLED));
@@ -140,36 +141,40 @@ AboutNewTabService.prototype = {
         PREF_SELECTED_LOCALE,
         this._updateRemoteMaybe);
       NewTabPrefsProvider.prefs.on(
         PREF_MATCH_OS_LOCALE,
         this._updateRemoteMaybe);
       NewTabPrefsProvider.prefs.on(
         PREF_REMOTE_MODE,
         this._updateRemoteMaybe);
+      NewTabPrefsProvider.prefs.on(
+        PREF_REMOTE_VERSION,
+        this._updateRemoteMaybe);
       this._remoteEnabled = true;
     } else {
       NewTabPrefsProvider.prefs.off(PREF_SELECTED_LOCALE, this._updateRemoteMaybe);
       NewTabPrefsProvider.prefs.off(PREF_MATCH_OS_LOCALE, this._updateRemoteMaybe);
       NewTabPrefsProvider.prefs.off(PREF_REMOTE_MODE, this._updateRemoteMaybe);
+      NewTabPrefsProvider.prefs.off(PREF_REMOTE_VERSION, this._updateRemoteMaybe);
       this._remoteEnabled = false;
     }
     if (!csTest) {
       this._newTabURL = ABOUT_URL;
     }
     return true;
   },
 
   /*
    * Generate a default url based on remote mode, version, locale and update channel
    */
   generateRemoteURL() {
     let releaseName = this.releaseFromUpdateChannel(UpdateUtils.UpdateChannel);
     let path = REMOTE_NEWTAB_PATH
-      .replace("%VERSION%", REMOTE_NEWTAB_VERSION)
+      .replace("%VERSION%", this.remoteVersion)
       .replace("%LOCALE%", Locale.getLocale())
       .replace("%CHANNEL%", releaseName);
     let mode = Services.prefs.getCharPref(PREF_REMOTE_MODE, "production");
     if (!(mode in NewTabRemoteResources.MODE_CHANNEL_MAP)) {
       mode = "production";
     }
     return NewTabRemoteResources.MODE_CHANNEL_MAP[mode].origin + path;
   },
@@ -219,17 +224,17 @@ AboutNewTabService.prototype = {
     return VALID_CHANNELS.has(channelName) ? channelName : "nightly";
   },
 
   get newTabURL() {
     return this._newTabURL;
   },
 
   get remoteVersion() {
-    return REMOTE_NEWTAB_VERSION;
+    return Services.prefs.getCharPref(PREF_REMOTE_VERSION, "1");
   },
 
   get remoteReleaseName() {
     return this.releaseFromUpdateChannel(UpdateUtils.UpdateChannel);
   },
 
   set newTabURL(aNewTabURL) {
     let csTest = Services.prefs.getBoolPref(PREF_REMOTE_CS_TEST);
--- a/browser/components/newtab/tests/xpcshell/test_AboutNewTabService.js
+++ b/browser/components/newtab/tests/xpcshell/test_AboutNewTabService.js
@@ -13,22 +13,27 @@ Cu.import("resource://gre/modules/Prefer
 
 XPCOMUtils.defineLazyModuleGetter(this, "NewTabPrefsProvider",
                                   "resource:///modules/NewTabPrefsProvider.jsm");
 
 XPCOMUtils.defineLazyServiceGetter(this, "aboutNewTabService",
                                    "@mozilla.org/browser/aboutnewtab-service;1",
                                    "nsIAboutNewTabService");
 
+XPCOMUtils.defineLazyModuleGetter(this, "Locale",
+                                  "resource://gre/modules/Locale.jsm");
+
 const DEFAULT_HREF = aboutNewTabService.generateRemoteURL();
 const DEFAULT_CHROME_URL = "chrome://browser/content/newtab/newTab.xhtml";
 const DOWNLOADS_URL = "chrome://browser/content/downloads/contentAreaDownloadsView.xul";
+const DEFAULT_VERSION = aboutNewTabService.remoteVersion;
 
 function cleanup() {
   Services.prefs.setBoolPref("browser.newtabpage.remote", false);
+  Services.prefs.setCharPref("browser.newtabpage.remote.version", DEFAULT_VERSION);
   aboutNewTabService.resetNewTabURL();
   NewTabPrefsProvider.prefs.uninit();
 }
 
 do_register_cleanup(cleanup);
 
 /**
  * Test the overriding of the default URL
@@ -102,17 +107,18 @@ add_task(function* test_updates() {
    * Simulates a "cold-boot" situation, with some pref already set before testing a series
    * of changes.
    */
   Preferences.set("browser.newtabpage.remote", true);
   aboutNewTabService.resetNewTabURL(); // need to set manually because pref notifs are off
   let notificationPromise;
   let productionModeBaseUrl = "https://content.cdn.mozilla.net";
   let testModeBaseUrl = "https://example.com";
-  let expectedPath = `/v${aboutNewTabService.remoteVersion}` +
+  let expectedPath = `/newtab` +
+                     `/v${aboutNewTabService.remoteVersion}` +
                      `/${aboutNewTabService.remoteReleaseName}` +
                      "/en-GB" +
                      "/index.html";
   let expectedHref = productionModeBaseUrl + expectedPath;
   Preferences.set("intl.locale.matchOS", true);
   Preferences.set("general.useragent.locale", "en-GB");
   Preferences.set("browser.newtabpage.remote.mode", "production");
   NewTabPrefsProvider.prefs.init();
@@ -188,16 +194,42 @@ add_task(function* test_release_names() 
   }
 
   for (let channel of invalid_channels) {
     Assert.equal("nightly", aboutNewTabService.releaseFromUpdateChannel(channel),
           "release == nightly when invalid");
   }
 });
 
+/**
+ * Verifies that remote version updates changes the remote newtab url
+ */
+add_task(function* test_version_update() {
+  NewTabPrefsProvider.prefs.init();
+
+  Services.prefs.setBoolPref("browser.newtabpage.remote", true);
+  Assert.ok(aboutNewTabService.remoteEnabled, "remote mode enabled");
+
+  let productionModeBaseUrl = "https://content.cdn.mozilla.net";
+  let version_incr = String(parseInt(DEFAULT_VERSION) + 1);
+  let expectedPath = `/newtab` +
+                     `/v${version_incr}` +
+                     `/${aboutNewTabService.remoteReleaseName}` +
+                     `/${Locale.getLocale()}` +
+                     `/index.html`;
+  let expectedHref = productionModeBaseUrl + expectedPath;
+
+  let notificationPromise;
+  notificationPromise = nextChangeNotificationPromise(expectedHref);
+  Preferences.set("browser.newtabpage.remote.version", version_incr);
+  yield notificationPromise;
+
+  cleanup();
+});
+
 function nextChangeNotificationPromise(aNewURL, testMessage) {
   return new Promise(resolve => {
     Services.obs.addObserver(function observer(aSubject, aTopic, aData) {  // jshint unused:false
       Services.obs.removeObserver(observer, aTopic);
       Assert.equal(aData, aNewURL, testMessage);
       resolve();
     }, "newtab-url-changed", false);
   });