Bug 1210478 - Add Meta URL resolution in RemoteNewTabLocation r=mconley

This commit is contained in:
Olivier Yiptong 2015-11-13 05:36:21 -05:00
parent 629487a554
commit 3d81b4bb55
3 changed files with 229 additions and 27 deletions

View File

@ -43,6 +43,7 @@ let RemoteAboutNewTab = {
* Initialize the RemotePageManager and add all message listeners for this page
*/
init: function() {
RemoteNewTabLocation.init();
this.pageListener = new RemotePages("about:remote-newtab");
this.pageListener.addMessageListener("NewTab:InitializeGrid", this.initializeGrid.bind(this));
this.pageListener.addMessageListener("NewTab:UpdateGrid", this.updateGrid.bind(this));
@ -292,6 +293,7 @@ let RemoteAboutNewTab = {
Ci.nsISupportsWeakReference]),
uninit: function() {
RemoteNewTabLocation.uninit();
this._removeObservers();
this.pageListener.destroy();
this.pageListener = null;

View File

@ -1,17 +1,49 @@
/* globals Services */
/* globals Services, UpdateUtils, XPCOMUtils, URL, NewTabPrefsProvider, Locale */
/* exported RemoteNewTabLocation */
"use strict";
this.EXPORTED_SYMBOLS = ["RemoteNewTabLocation"];
Components.utils.import("resource://gre/modules/Services.jsm");
Components.utils.importGlobalProperties(["URL"]);
const {utils: Cu} = Components;
Cu.import("resource://gre/modules/Services.jsm");
Cu.import("resource://gre/modules/XPCOMUtils.jsm");
Cu.importGlobalProperties(["URL"]);
// TODO: will get dynamically set in bug 1210478
const DEFAULT_PAGE_LOCATION = "https://newtab.cdn.mozilla.net/v0/nightly/en-US/index.html";
XPCOMUtils.defineLazyModuleGetter(this, "UpdateUtils",
"resource://gre/modules/UpdateUtils.jsm");
XPCOMUtils.defineLazyModuleGetter(this, "NewTabPrefsProvider",
"resource:///modules/NewTabPrefsProvider.jsm");
XPCOMUtils.defineLazyModuleGetter(this, "Locale",
"resource://gre/modules/Locale.jsm");
this.RemoteNewTabLocation = {
_url: new URL(DEFAULT_PAGE_LOCATION),
// The preference that tells whether to match the OS locale
const PREF_MATCH_OS_LOCALE = "intl.locale.matchOS";
// The preference that tells what locale the user selected
const PREF_SELECTED_LOCALE = "general.useragent.locale";
const DEFAULT_PAGE_LOCATION = "https://newtab.cdn.mozilla.net/" +
"v%VERSION%/%CHANNEL%/%LOCALE%/index.html";
const VALID_CHANNELS = new Set(["esr", "release", "beta", "aurora", "nightly"]);
const NEWTAB_VERSION = "0";
let RemoteNewTabLocation = {
/*
* Generate a default url based on locale and update channel
*/
_generateDefaultURL() {
let releaseName = this._releaseFromUpdateChannel(UpdateUtils.UpdateChannel);
let uri = DEFAULT_PAGE_LOCATION
.replace("%VERSION%", this.version)
.replace("%LOCALE%", Locale.getLocale())
.replace("%CHANNEL%", releaseName);
return new URL(uri);
},
_url: null,
_overridden: false,
get href() {
@ -26,17 +58,84 @@ this.RemoteNewTabLocation = {
return this._overridden;
},
override: function(newURL) {
this._url = new URL(newURL);
this._overridden = true;
Services.obs.notifyObservers(null, "remote-new-tab-location-changed",
this._url.href);
get version() {
return NEWTAB_VERSION;
},
reset: function() {
this._url = new URL(DEFAULT_PAGE_LOCATION);
get channels() {
return VALID_CHANNELS;
},
/**
* Returns the release name from an Update Channel name
*
* @return {String} a release name based on the update channel. Defaults to nightly
*/
_releaseFromUpdateChannel(channel) {
let result = "nightly";
if (VALID_CHANNELS.has(channel)) {
result = channel;
}
return result;
},
/*
* Updates the location when the page is not overriden.
* Useful when there is a pref change
*/
_updateMaybe() {
if (!this.overridden) {
let url = this._generateDefaultURL();
if (url.href !== this._url.href) {
this._url = url;
Services.obs.notifyObservers(null, "remote-new-tab-location-changed",
this._url.href);
}
}
},
/*
* Override the Remote newtab page location.
*/
override(newURL) {
let url = new URL(newURL);
if (url.href !== this._url.href) {
this._overridden = true;
this._url = url;
Services.obs.notifyObservers(null, "remote-new-tab-location-changed",
this._url.href);
}
},
/*
* Reset the newtab page location to the default value
*/
reset() {
let url = this._generateDefaultURL();
if (url.href !== this._url.href) {
this._url = url;
this._overridden = false;
Services.obs.notifyObservers(null, "remote-new-tab-location-changed",
this._url.href);
}
},
init() {
NewTabPrefsProvider.prefs.on(
PREF_SELECTED_LOCALE,
this._updateMaybe.bind(this));
NewTabPrefsProvider.prefs.on(
PREF_MATCH_OS_LOCALE,
this._updateMaybe.bind(this));
this._url = this._generateDefaultURL();
},
uninit() {
this._url = null;
this._overridden = false;
Services.obs.notifyObservers(null, "remote-new-tab-location-changed",
this._url.href);
NewTabPrefsProvider.prefs.off(PREF_SELECTED_LOCALE, this._updateMaybe);
NewTabPrefsProvider.prefs.off(PREF_MATCH_OS_LOCALE, this._updateMaybe);
}
};

View File

@ -1,39 +1,140 @@
/* globals ok, equal, RemoteNewTabLocation, Services */
/* globals ok, equal, RemoteNewTabLocation, NewTabPrefsProvider, Services, Preferences */
/* jscs:disable requireCamelCaseOrUpperCaseIdentifiers */
"use strict";
Components.utils.import("resource:///modules/RemoteNewTabLocation.jsm");
Components.utils.import("resource:///modules/NewTabPrefsProvider.jsm");
Components.utils.import("resource://gre/modules/Services.jsm");
Components.utils.import("resource://gre/modules/Preferences.jsm");
Components.utils.importGlobalProperties(["URL"]);
add_task(function* () {
var notificationPromise;
let defaultHref = RemoteNewTabLocation.href;
RemoteNewTabLocation.init();
const DEFAULT_HREF = RemoteNewTabLocation.href;
RemoteNewTabLocation.uninit();
add_task(function* test_defaults() {
RemoteNewTabLocation.init();
ok(RemoteNewTabLocation.href, "Default location has an href");
ok(RemoteNewTabLocation.origin, "Default location has an origin");
ok(!RemoteNewTabLocation.overridden, "Default location is not overridden");
RemoteNewTabLocation.uninit();
});
/**
* Tests the overriding of the default URL
*/
add_task(function* test_overrides() {
RemoteNewTabLocation.init();
let testURL = new URL("https://example.com/");
let notificationPromise;
notificationPromise = changeNotificationPromise(testURL.href);
notificationPromise = nextChangeNotificationPromise(
testURL.href, "Remote Location should change");
RemoteNewTabLocation.override(testURL.href);
yield notificationPromise;
ok(RemoteNewTabLocation.overridden, "Remote location should be overridden");
equal(RemoteNewTabLocation.href, testURL.href, "Remote href should be the custom URL");
equal(RemoteNewTabLocation.origin, testURL.origin, "Remote origin should be the custom URL");
equal(RemoteNewTabLocation.href, testURL.href,
"Remote href should be the custom URL");
equal(RemoteNewTabLocation.origin, testURL.origin,
"Remote origin should be the custom URL");
notificationPromise = changeNotificationPromise(defaultHref);
notificationPromise = nextChangeNotificationPromise(
DEFAULT_HREF, "Remote href should be reset");
RemoteNewTabLocation.reset();
yield notificationPromise;
ok(!RemoteNewTabLocation.overridden, "Newtab URL should not be overridden");
equal(RemoteNewTabLocation.href, defaultHref, "Remote href should be reset");
RemoteNewTabLocation.uninit();
});
function changeNotificationPromise(aNewURL) {
/**
* Tests how RemoteNewTabLocation responds to updates to prefs
*/
add_task(function* test_updates() {
RemoteNewTabLocation.init();
let notificationPromise;
let expectedHref = "https://newtab.cdn.mozilla.net" +
`/v${RemoteNewTabLocation.version}` +
"/nightly" +
"/en-GB" +
"/index.html";
Preferences.set("intl.locale.matchOS", true);
Preferences.set("general.useragent.locale", "en-GB");
NewTabPrefsProvider.prefs.init();
// test update checks for prefs
notificationPromise = nextChangeNotificationPromise(
expectedHref, "Remote href should be updated");
Preferences.set("intl.locale.matchOS", false);
yield notificationPromise;
notificationPromise = nextChangeNotificationPromise(
DEFAULT_HREF, "Remote href changes back to default");
Preferences.set("general.useragent.locale", "en-US");
yield notificationPromise;
// test update fires on override and reset
let testURL = new URL("https://example.com/");
notificationPromise = nextChangeNotificationPromise(
testURL.href, "a notification occurs on override");
RemoteNewTabLocation.override(testURL.href);
yield notificationPromise;
// from overridden to default
notificationPromise = nextChangeNotificationPromise(
DEFAULT_HREF, "a notification occurs on reset");
RemoteNewTabLocation.reset();
yield notificationPromise;
// override to default URL from default URL
notificationPromise = nextChangeNotificationPromise(
testURL.href, "a notification only occurs for a change in overridden urls");
RemoteNewTabLocation.override(DEFAULT_HREF);
RemoteNewTabLocation.override(testURL.href);
yield notificationPromise;
// reset twice, only one notification for default URL
notificationPromise = nextChangeNotificationPromise(
DEFAULT_HREF, "reset occurs");
RemoteNewTabLocation.reset();
yield notificationPromise;
notificationPromise = nextChangeNotificationPromise(
testURL.href, "a notification only occurs for a change in reset urls");
RemoteNewTabLocation.reset();
RemoteNewTabLocation.override(testURL.href);
yield notificationPromise;
NewTabPrefsProvider.prefs.uninit();
RemoteNewTabLocation.uninit();
});
/**
* Verifies that RemoteNewTabLocation's _releaseFromUpdateChannel
* Returns the correct release names
*/
add_task(function* test_release_names() {
RemoteNewTabLocation.init();
let valid_channels = RemoteNewTabLocation.channels;
let invalid_channels = new Set(["default", "invalid"]);
for (let channel of valid_channels) {
equal(channel, RemoteNewTabLocation._releaseFromUpdateChannel(channel),
"release == channel name when valid");
}
for (let channel of invalid_channels) {
equal("nightly", RemoteNewTabLocation._releaseFromUpdateChannel(channel),
"release == nightly when invalid");
}
RemoteNewTabLocation.uninit();
});
function nextChangeNotificationPromise(aNewURL, testMessage) {
return new Promise(resolve => {
Services.obs.addObserver(function observer(aSubject, aTopic, aData) { // jshint ignore:line
Services.obs.removeObserver(observer, aTopic);
equal(aData, aNewURL, "remote-new-tab-location-changed data should be new URL.");
equal(aData, aNewURL, testMessage);
resolve();
}, "remote-new-tab-location-changed", false);
});