diff -r 000000000000 -r 6474c204b198 browser/components/test/browser_bug538331.js
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/browser/components/test/browser_bug538331.js Wed Dec 31 06:09:35 2014 +0100
@@ -0,0 +1,431 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set ts=2 et sw=2 tw=80: */
+/* Any copyright is dedicated to the Public Domain.
+ * http://creativecommons.org/publicdomain/zero/1.0/
+ */
+
+const PREF_POSTUPDATE = "app.update.postupdate";
+const PREF_MSTONE = "browser.startup.homepage_override.mstone";
+const PREF_OVERRIDE_URL = "startup.homepage_override_url";
+
+const DEFAULT_PREF_URL = "http://pref.example.com/";
+const DEFAULT_UPDATE_URL = "http://example.com/";
+
+const XML_EMPTY = "";
+
+const XML_PREFIX = "";
+
+// nsBrowserContentHandler.js defaultArgs tests
+const BCH_TESTS = [
+ {
+ description: "no mstone change and no update",
+ noPostUpdatePref: true,
+ noMstoneChange: true
+ }, {
+ description: "mstone changed and no update",
+ noPostUpdatePref: true,
+ prefURL: DEFAULT_PREF_URL
+ }, {
+ description: "no mstone change and update with 'showURL' for actions",
+ actions: "showURL",
+ noMstoneChange: true
+ }, {
+ description: "update without actions",
+ prefURL: DEFAULT_PREF_URL
+ }, {
+ description: "update with 'showURL' for actions",
+ actions: "showURL",
+ prefURL: DEFAULT_PREF_URL
+ }, {
+ description: "update with 'showURL' for actions and openURL",
+ actions: "showURL",
+ openURL: DEFAULT_UPDATE_URL
+ }, {
+ description: "update with 'showURL showAlert' for actions",
+ actions: "showAlert showURL",
+ prefURL: DEFAULT_PREF_URL
+ }, {
+ description: "update with 'showAlert showURL' for actions and openURL",
+ actions: "showAlert showURL",
+ openURL: DEFAULT_UPDATE_URL
+ }, {
+ description: "update with 'showURL showNotification' for actions",
+ actions: "showURL showNotification",
+ prefURL: DEFAULT_PREF_URL
+ }, {
+ description: "update with 'showNotification showURL' for actions and " +
+ "openURL",
+ actions: "showNotification showURL",
+ openURL: DEFAULT_UPDATE_URL
+ }, {
+ description: "update with 'showAlert showURL showNotification' for actions",
+ actions: "showAlert showURL showNotification",
+ prefURL: DEFAULT_PREF_URL
+ }, {
+ description: "update with 'showNotification showURL showAlert' for " +
+ "actions and openURL",
+ actions: "showNotification showURL showAlert",
+ openURL: DEFAULT_UPDATE_URL
+ }, {
+ description: "update with 'showAlert' for actions",
+ actions: "showAlert"
+ }, {
+ description: "update with 'showAlert showNotification' for actions",
+ actions: "showAlert showNotification"
+ }, {
+ description: "update with 'showNotification' for actions",
+ actions: "showNotification"
+ }, {
+ description: "update with 'showNotification showAlert' for actions",
+ actions: "showNotification showAlert"
+ }, {
+ description: "update with 'silent' for actions",
+ actions: "silent"
+ }, {
+ description: "update with 'silent showURL showAlert showNotification' " +
+ "for actions and openURL",
+ actions: "silent showURL showAlert showNotification"
+ }
+];
+
+var gOriginalMStone;
+var gOriginalOverrideURL;
+
+this.__defineGetter__("gBG", function() {
+ delete this.gBG;
+ return this.gBG = Cc["@mozilla.org/browser/browserglue;1"].
+ getService(Ci.nsIBrowserGlue).
+ QueryInterface(Ci.nsIObserver);
+});
+
+function test()
+{
+ waitForExplicitFinish();
+
+ // Reset the startup page pref since it may have been set by other tests
+ // and we will assume it is default.
+ Services.prefs.clearUserPref('browser.startup.page');
+
+ if (gPrefService.prefHasUserValue(PREF_MSTONE)) {
+ gOriginalMStone = gPrefService.getCharPref(PREF_MSTONE);
+ }
+
+ if (gPrefService.prefHasUserValue(PREF_OVERRIDE_URL)) {
+ gOriginalOverrideURL = gPrefService.getCharPref(PREF_OVERRIDE_URL);
+ }
+
+ testDefaultArgs();
+}
+
+var gWindowCatcher = {
+ windowsOpen: 0,
+ finishCalled: false,
+ start: function() {
+ Services.ww.registerNotification(this);
+ },
+
+ finish: function(aFunc) {
+ Services.ww.unregisterNotification(this);
+ this.finishFunc = aFunc;
+ if (this.windowsOpen > 0)
+ return;
+
+ this.finishFunc();
+ },
+
+ closeWindow: function (win) {
+ info("window catcher closing window: " + win.document.documentURI);
+ win.close();
+ this.windowsOpen--;
+ if (this.finishFunc) {
+ this.finish(this.finishFunc);
+ }
+ },
+
+ windowLoad: function (win) {
+ executeSoon(this.closeWindow.bind(this, win));
+ },
+
+ observe: function(subject, topic, data) {
+ if (topic != "domwindowopened")
+ return;
+
+ this.windowsOpen++;
+ let win = subject.QueryInterface(Ci.nsIDOMWindow);
+ info("window catcher caught window opening: " + win.document.documentURI);
+ win.addEventListener("load", function () {
+ win.removeEventListener("load", arguments.callee, false);
+ gWindowCatcher.windowLoad(win);
+ }, false);
+ }
+};
+
+function finish_test()
+{
+ // Reset browser.startup.homepage_override.mstone to the original value or
+ // clear it if it didn't exist.
+ if (gOriginalMStone) {
+ gPrefService.setCharPref(PREF_MSTONE, gOriginalMStone);
+ } else if (gPrefService.prefHasUserValue(PREF_MSTONE)) {
+ gPrefService.clearUserPref(PREF_MSTONE);
+ }
+
+ // Reset startup.homepage_override_url to the original value or clear it if
+ // it didn't exist.
+ if (gOriginalOverrideURL) {
+ gPrefService.setCharPref(PREF_OVERRIDE_URL, gOriginalOverrideURL);
+ } else if (gPrefService.prefHasUserValue(PREF_OVERRIDE_URL)) {
+ gPrefService.clearUserPref(PREF_OVERRIDE_URL);
+ }
+
+ writeUpdatesToXMLFile(XML_EMPTY);
+ reloadUpdateManagerData();
+
+ finish();
+}
+
+// Test the defaultArgs returned by nsBrowserContentHandler after an update
+function testDefaultArgs()
+{
+ // Clear any pre-existing override in defaultArgs that are hanging around.
+ // This will also set the browser.startup.homepage_override.mstone preference
+ // if it isn't already set.
+ Cc["@mozilla.org/browser/clh;1"].getService(Ci.nsIBrowserHandler).defaultArgs;
+
+ let originalMstone = gPrefService.getCharPref(PREF_MSTONE);
+
+ gPrefService.setCharPref(PREF_OVERRIDE_URL, DEFAULT_PREF_URL);
+
+ writeUpdatesToXMLFile(XML_EMPTY);
+ reloadUpdateManagerData();
+
+ for (let i = 0; i < BCH_TESTS.length; i++) {
+ let test = BCH_TESTS[i];
+ ok(true, "Test nsBrowserContentHandler " + (i + 1) + ": " + test.description);
+
+ if (test.actions) {
+ let actionsXML = " actions=\"" + test.actions + "\"";
+ if (test.openURL) {
+ actionsXML += " openURL=\"" + test.openURL + "\"";
+ }
+ writeUpdatesToXMLFile(XML_PREFIX + actionsXML + XML_SUFFIX);
+ } else {
+ writeUpdatesToXMLFile(XML_EMPTY);
+ }
+
+ reloadUpdateManagerData();
+
+ let noOverrideArgs = Cc["@mozilla.org/browser/clh;1"].
+ getService(Ci.nsIBrowserHandler).defaultArgs;
+
+ let overrideArgs = "";
+ if (test.prefURL) {
+ overrideArgs = test.prefURL;
+ } else if (test.openURL) {
+ overrideArgs = test.openURL;
+ }
+
+ if (overrideArgs == "" && noOverrideArgs) {
+ overrideArgs = noOverrideArgs;
+ } else if (noOverrideArgs) {
+ overrideArgs += "|" + noOverrideArgs;
+ }
+
+ if (test.noMstoneChange === undefined) {
+ gPrefService.setCharPref(PREF_MSTONE, "PreviousMilestone");
+ }
+
+ if (test.noPostUpdatePref == undefined) {
+ gPrefService.setBoolPref(PREF_POSTUPDATE, true);
+ }
+
+ let defaultArgs = Cc["@mozilla.org/browser/clh;1"].
+ getService(Ci.nsIBrowserHandler).defaultArgs;
+ is(defaultArgs, overrideArgs, "correct value returned by defaultArgs");
+
+ if (test.noMstoneChange === undefined || test.noMstoneChange != true) {
+ let newMstone = gPrefService.getCharPref(PREF_MSTONE);
+ is(originalMstone, newMstone, "preference " + PREF_MSTONE +
+ " should have been updated");
+ }
+
+ if (gPrefService.prefHasUserValue(PREF_POSTUPDATE)) {
+ gPrefService.clearUserPref(PREF_POSTUPDATE);
+ }
+ }
+
+ testShowNotification();
+}
+
+// nsBrowserGlue.js _showUpdateNotification notification tests
+const BG_NOTIFY_TESTS = [
+ {
+ description: "'silent showNotification' actions should not display a notification",
+ actions: "silent showNotification"
+ }, {
+ description: "'showNotification' for actions should display a notification",
+ actions: "showNotification"
+ }, {
+ description: "no actions and empty updates.xml",
+ }, {
+ description: "'showAlert' for actions should not display a notification",
+ actions: "showAlert"
+ }, {
+ // This test MUST be the last test in the array to test opening the url
+ // provided by the updates.xml.
+ description: "'showNotification' for actions with custom notification " +
+ "attributes should display a notification",
+ actions: "showNotification",
+ notificationText: "notification text",
+ notificationURL: DEFAULT_UPDATE_URL,
+ notificationButtonLabel: "button label",
+ notificationButtonAccessKey: "b"
+ }
+];
+
+// Test showing a notification after an update
+// _showUpdateNotification in nsBrowserGlue.js
+function testShowNotification()
+{
+ let gTestBrowser = gBrowser.selectedBrowser;
+ let notifyBox = gBrowser.getNotificationBox(gTestBrowser);
+
+ // Catches any windows opened by these tests (e.g. alert windows) and closes
+ // them
+ gWindowCatcher.start();
+
+ for (let i = 0; i < BG_NOTIFY_TESTS.length; i++) {
+ let test = BG_NOTIFY_TESTS[i];
+ ok(true, "Test showNotification " + (i + 1) + ": " + test.description);
+
+ if (test.actions) {
+ let actionsXML = " actions=\"" + test.actions + "\"";
+ if (test.notificationText) {
+ actionsXML += " notificationText=\"" + test.notificationText + "\"";
+ }
+ if (test.notificationURL) {
+ actionsXML += " notificationURL=\"" + test.notificationURL + "\"";
+ }
+ if (test.notificationButtonLabel) {
+ actionsXML += " notificationButtonLabel=\"" + test.notificationButtonLabel + "\"";
+ }
+ if (test.notificationButtonAccessKey) {
+ actionsXML += " notificationButtonAccessKey=\"" + test.notificationButtonAccessKey + "\"";
+ }
+ writeUpdatesToXMLFile(XML_PREFIX + actionsXML + XML_SUFFIX);
+ } else {
+ writeUpdatesToXMLFile(XML_EMPTY);
+ }
+
+ reloadUpdateManagerData();
+ gPrefService.setBoolPref(PREF_POSTUPDATE, true);
+
+ gBG.observe(null, "browser-glue-test", "post-update-notification");
+
+ let updateBox = notifyBox.getNotificationWithValue("post-update-notification");
+ if (test.actions && test.actions.indexOf("showNotification") != -1 &&
+ test.actions.indexOf("silent") == -1) {
+ ok(updateBox, "Update notification box should have been displayed");
+ if (updateBox) {
+ if (test.notificationText) {
+ is(updateBox.label, test.notificationText, "Update notification box " +
+ "should have the label provided by the update");
+ }
+ if (test.notificationButtonLabel) {
+ var button = updateBox.getElementsByTagName("button").item(0);
+ is(button.label, test.notificationButtonLabel, "Update notification " +
+ "box button should have the label provided by the update");
+ if (test.notificationButtonAccessKey) {
+ let accessKey = button.getAttribute("accesskey");
+ is(accessKey, test.notificationButtonAccessKey, "Update " +
+ "notification box button should have the accesskey " +
+ "provided by the update");
+ }
+ }
+ // The last test opens an url and verifies the url from the updates.xml
+ // is correct.
+ if (i == (BG_NOTIFY_TESTS.length - 1)) {
+ // Wait for any windows caught by the windowcatcher to close
+ gWindowCatcher.finish(function () {
+ button.click();
+ gBrowser.selectedBrowser.addEventListener("load", function () {
+ gBrowser.selectedBrowser.removeEventListener("load", arguments.callee, true);
+ testNotificationURL();
+ }, true);
+ });
+ } else {
+ notifyBox.removeAllNotifications(true);
+ }
+ } else if (i == (BG_NOTIFY_TESTS.length - 1)) {
+ // If updateBox is null the test has already reported errors so bail
+ finish_test();
+ }
+ } else {
+ ok(!updateBox, "Update notification box should not have been displayed");
+ }
+
+ let prefHasUserValue = gPrefService.prefHasUserValue(PREF_POSTUPDATE);
+ is(prefHasUserValue, false, "preference " + PREF_POSTUPDATE +
+ " shouldn't have a user value");
+ }
+}
+
+// Test opening the url provided by the updates.xml in the last test
+function testNotificationURL()
+{
+ ok(true, "Test testNotificationURL: clicking the notification button " +
+ "opened the url specified by the update");
+ let href = gBrowser.selectedBrowser.contentWindow.location.href;
+ let expectedURL = BG_NOTIFY_TESTS[BG_NOTIFY_TESTS.length - 1].notificationURL;
+ is(href, expectedURL, "The url opened from the notification should be the " +
+ "url provided by the update");
+ gBrowser.removeCurrentTab();
+ window.focus();
+ finish_test();
+}
+
+/* Reloads the update metadata from disk */
+function reloadUpdateManagerData()
+{
+ Cc["@mozilla.org/updates/update-manager;1"].getService(Ci.nsIUpdateManager).
+ QueryInterface(Ci.nsIObserver).observe(null, "um-reload-update-data", "");
+}
+
+
+function writeUpdatesToXMLFile(aText)
+{
+ const PERMS_FILE = 0644;
+
+ const MODE_WRONLY = 0x02;
+ const MODE_CREATE = 0x08;
+ const MODE_TRUNCATE = 0x20;
+
+ let file = Cc["@mozilla.org/file/directory_service;1"].
+ getService(Ci.nsIProperties).
+ get("UpdRootD", Ci.nsIFile);
+ file.append("updates.xml");
+ let fos = Cc["@mozilla.org/network/file-output-stream;1"].
+ createInstance(Ci.nsIFileOutputStream);
+ if (!file.exists()) {
+ file.create(Ci.nsILocalFile.NORMAL_FILE_TYPE, PERMS_FILE);
+ }
+ fos.init(file, MODE_WRONLY | MODE_CREATE | MODE_TRUNCATE, PERMS_FILE, 0);
+ fos.write(aText, aText.length);
+ fos.close();
+}