diff options
Diffstat (limited to 'browser/components/tests')
-rw-r--r-- | browser/components/tests/browser/.eslintrc.js | 7 | ||||
-rw-r--r-- | browser/components/tests/browser/browser.ini | 4 | ||||
-rw-r--r-- | browser/components/tests/browser/browser_bug538331.js | 426 | ||||
-rw-r--r-- | browser/components/tests/browser/browser_contentpermissionprompt.js | 166 | ||||
-rw-r--r-- | browser/components/tests/unit/.eslintrc.js | 7 | ||||
-rw-r--r-- | browser/components/tests/unit/data/engine-de-DE.xml | 8 | ||||
-rw-r--r-- | browser/components/tests/unit/distribution.ini | 58 | ||||
-rw-r--r-- | browser/components/tests/unit/head.js | 9 | ||||
-rw-r--r-- | browser/components/tests/unit/test_browserGlue_migration_loop_cleanup.js | 32 | ||||
-rw-r--r-- | browser/components/tests/unit/test_distribution.js | 152 | ||||
-rw-r--r-- | browser/components/tests/unit/xpcshell.ini | 10 |
11 files changed, 879 insertions, 0 deletions
diff --git a/browser/components/tests/browser/.eslintrc.js b/browser/components/tests/browser/.eslintrc.js new file mode 100644 index 000000000..c764b133d --- /dev/null +++ b/browser/components/tests/browser/.eslintrc.js @@ -0,0 +1,7 @@ +"use strict"; + +module.exports = { + "extends": [ + "../../../../testing/mochitest/browser.eslintrc.js" + ] +}; diff --git a/browser/components/tests/browser/browser.ini b/browser/components/tests/browser/browser.ini new file mode 100644 index 000000000..6d00b69fa --- /dev/null +++ b/browser/components/tests/browser/browser.ini @@ -0,0 +1,4 @@ +[DEFAULT] + +[browser_bug538331.js] +[browser_contentpermissionprompt.js] diff --git a/browser/components/tests/browser/browser_bug538331.js b/browser/components/tests/browser/browser_bug538331.js new file mode 100644 index 000000000..fce3790a0 --- /dev/null +++ b/browser/components/tests/browser/browser_bug538331.js @@ -0,0 +1,426 @@ +/* -*- indent-tabs-mode: nil; js-indent-level: 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 = "<?xml version=\"1.0\"?><updates xmlns=" + + "\"http://www.mozilla.org/2005/app-update\"></updates>"; + +const XML_PREFIX = "<updates xmlns=\"http://www.mozilla.org/2005/app-update\"" + + "><update appVersion=\"1.0\" buildID=\"20080811053724\" " + + "channel=\"nightly\" displayVersion=\"Version 1.0\" " + + "extensionVersion=\"1.0\" installDate=\"1238441400314\" " + + "isCompleteUpdate=\"true\" name=\"Update Test 1.0\" " + + "serviceURL=\"https://example.com/\" showNeverForVersion=" + + "\"false\" showPrompt=\"false\" type=" + + "\"minor\" version=\"version 1.0\" detailsURL=" + + "\"http://example.com/\" previousAppVersion=\"1.0\" " + + "statusText=\"The Update was successfully installed\" " + + "foregroundDownload=\"true\""; + +const XML_SUFFIX = "><patch type=\"complete\" URL=\"http://example.com/\" " + + "hashFunction=\"MD5\" hashValue=" + + "\"6232cd43a1c77e30191c53a329a3f99d\" size=\"775\" " + + "selected=\"true\" state=\"succeeded\"/></update></updates>"; + +// 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.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 notifyBox = document.getElementById("high-priority-global-notificationbox"); + + // 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 () { + BrowserTestUtils.waitForNewTab(gBrowser).then(testNotificationURL); + button.click(); + }); + } 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.currentURI.spec; + 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 = 0o644; + + 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(); +} diff --git a/browser/components/tests/browser/browser_contentpermissionprompt.js b/browser/components/tests/browser/browser_contentpermissionprompt.js new file mode 100644 index 000000000..054aa22e8 --- /dev/null +++ b/browser/components/tests/browser/browser_contentpermissionprompt.js @@ -0,0 +1,166 @@ +/** + * These tests test nsBrowserGlue's nsIContentPermissionPrompt + * implementation behaviour with various types of + * nsIContentPermissionRequests. + */ + +"use strict"; + +Cu.import("resource://gre/modules/XPCOMUtils.jsm"); +Cu.import("resource://gre/modules/Integration.jsm", this); + +XPCOMUtils.defineLazyServiceGetter(this, "ContentPermissionPrompt", + "@mozilla.org/content-permission/prompt;1", + "nsIContentPermissionPrompt"); + +/** + * This is a partial implementation of nsIContentPermissionType. + * + * @param {string} type + * The string defining what type of permission is being requested. + * Example: "geo", "desktop-notification". + * @return nsIContentPermissionType implementation. + */ +function MockContentPermissionType(type) { + this.type = type; +} + +MockContentPermissionType.prototype = { + QueryInterface: XPCOMUtils.generateQI([Ci.nsIContentPermissionType]), + // We expose the wrappedJSObject so that we can be sure + // in some of our tests that we're passing the right + // nsIContentPermissionType around. + wrappedJSObject: this, +}; + +/** + * This is a partial implementation of nsIContentPermissionRequest. + * + * @param {Array<nsIContentPermissionType>} typesArray + * The types to assign to this nsIContentPermissionRequest, + * in order. You probably want to use MockContentPermissionType. + * @return nsIContentPermissionRequest implementation. + */ +function MockContentPermissionRequest(typesArray) { + this.types = Cc["@mozilla.org/array;1"].createInstance(Ci.nsIMutableArray); + for (let type of typesArray) { + this.types.appendElement(type, false); + } +} + +MockContentPermissionRequest.prototype = { + QueryInterface: XPCOMUtils.generateQI([Ci.nsIContentPermissionRequest]), + // We expose the wrappedJSObject so that we can be sure + // in some of our tests that we're passing the right + // nsIContentPermissionRequest around. + wrappedJSObject: this, + // For some of our tests, we want to make sure that the + // request is cancelled, so we add some instrumentation here + // to check that cancel() is called. + cancel() { + this.cancelled = true; + }, + cancelled: false, +}; + +/** + * Tests that if the nsIContentPermissionRequest has an empty + * types array, that NS_ERROR_UNEXPECTED is thrown, and the + * request is cancelled. + */ +add_task(function* test_empty_types() { + let mockRequest = new MockContentPermissionRequest([]); + Assert.throws(() => { ContentPermissionPrompt.prompt(mockRequest); }, + /NS_ERROR_UNEXPECTED/, + "Should have thrown NS_ERROR_UNEXPECTED."); + Assert.ok(mockRequest.cancelled, "Should have cancelled the request."); +}); + +/** + * Tests that if the nsIContentPermissionRequest has more than + * one type, that NS_ERROR_UNEXPECTED is thrown, and the request + * is cancelled. + */ +add_task(function* test_multiple_types() { + let mockRequest = new MockContentPermissionRequest([ + new MockContentPermissionType("test1"), + new MockContentPermissionType("test2"), + ]); + + Assert.throws(() => { ContentPermissionPrompt.prompt(mockRequest); }, + /NS_ERROR_UNEXPECTED/); + Assert.ok(mockRequest.cancelled, "Should have cancelled the request."); +}); + +/** + * Tests that if the nsIContentPermissionRequest has a type that + * does not implement nsIContentPermissionType that NS_NOINTERFACE + * is thrown, and the request is cancelled. + */ +add_task(function* test_not_permission_type() { + let mockRequest = new MockContentPermissionRequest([ + { QueryInterface: XPCOMUtils.generateQI([Ci.nsISupports]) }, + ]); + + Assert.throws(() => { ContentPermissionPrompt.prompt(mockRequest); }, + /NS_NOINTERFACE/); + Assert.ok(mockRequest.cancelled, "Should have cancelled the request."); +}); + +/** + * Tests that if the nsIContentPermissionRequest is for a type + * that is not recognized, that NS_ERROR_FAILURE is thrown and + * the request is cancelled. + */ +add_task(function* test_unrecognized_type() { + let mockRequest = new MockContentPermissionRequest([ + new MockContentPermissionType("test1"), + ]); + + Assert.throws(() => { ContentPermissionPrompt.prompt(mockRequest); }, + /NS_ERROR_FAILURE/); + Assert.ok(mockRequest.cancelled, "Should have cancelled the request."); +}); + +/** + * Tests that if we meet the minimal requirements for a + * nsIContentPermissionRequest, that it will be passed to + * ContentPermissionIntegration's createPermissionPrompt + * method. + */ +add_task(function* test_working_request() { + let mockType = new MockContentPermissionType("test-permission-type"); + let mockRequest = new MockContentPermissionRequest([mockType]); + + // mockPermissionPrompt is what createPermissionPrompt + // will return. Returning some kind of object should be + // enough to convince nsBrowserGlue that everything went + // okay. + let didPrompt = false; + let mockPermissionPrompt = { + prompt() { + didPrompt = true; + } + }; + + let integration = (base) => ({ + createPermissionPrompt(type, request) { + Assert.equal(type, "test-permission-type"); + Assert.ok(Object.is(request.wrappedJSObject, mockRequest.wrappedJSObject)); + return mockPermissionPrompt; + }, + }); + + // Register an integration so that we can capture the + // calls into ContentPermissionIntegration. + try { + Integration.contentPermission.register(integration); + + ContentPermissionPrompt.prompt(mockRequest); + Assert.ok(!mockRequest.cancelled, + "Should not have cancelled the request."); + Assert.ok(didPrompt, "Should have tried to show the prompt"); + } finally { + Integration.contentPermission.unregister(integration); + } +}); diff --git a/browser/components/tests/unit/.eslintrc.js b/browser/components/tests/unit/.eslintrc.js new file mode 100644 index 000000000..fee088c17 --- /dev/null +++ b/browser/components/tests/unit/.eslintrc.js @@ -0,0 +1,7 @@ +"use strict"; + +module.exports = { + "extends": [ + "../../../../testing/xpcshell/xpcshell.eslintrc.js" + ] +}; diff --git a/browser/components/tests/unit/data/engine-de-DE.xml b/browser/components/tests/unit/data/engine-de-DE.xml new file mode 100644 index 000000000..b9fa0a464 --- /dev/null +++ b/browser/components/tests/unit/data/engine-de-DE.xml @@ -0,0 +1,8 @@ +<SearchPlugin xmlns="http://www.mozilla.org/2006/browser/search/"> +<ShortName>Google</ShortName> +<Description>override-de-DE</Description> +<InputEncoding>UTF-8</InputEncoding> +<Url type="text/html" method="GET" template="http://searchtest.local"> + <Param name="search" value="{searchTerms}"/> +</Url> +</SearchPlugin> diff --git a/browser/components/tests/unit/distribution.ini b/browser/components/tests/unit/distribution.ini new file mode 100644 index 000000000..d7d298808 --- /dev/null +++ b/browser/components/tests/unit/distribution.ini @@ -0,0 +1,58 @@ +# Distribution Configuration File +# Test of distribution preferences + +[Global] +id=disttest +version=1.0 +about=Test distribution file +about.en-US=Tèƨƭ δïƨƭřïβúƭïôñ ƒïℓè + +[Preferences] +distribution.test.string="Test String" +distribution.test.string.noquotes=Test String +distribution.test.int=777 +distribution.test.bool.true=true +distribution.test.bool.false=false +distribution.test.empty= + +distribution.test.pref.locale="%LOCALE%" +distribution.test.pref.language.reset="Preference Set" +distribution.test.pref.locale.reset="Preference Set" +distribution.test.pref.locale.set="Preference Set" +distribution.test.pref.language.set="Preference Set" + +[Preferences-en] +distribution.test.pref.language.en="en" +distribution.test.pref.language.reset= +distribution.test.pref.language.set="Language Set" +distribution.test.pref.locale.set="Language Set" + +[Preferences-en-US] +distribution.test.pref.locale.en-US="en-US" +distribution.test.pref.locale.reset= +distribution.test.pref.locale.set="Locale Set" + + +[Preferences-de] +distribution.test.pref.language.de="de" + +[LocalizablePreferences] +distribution.test.locale="%LOCALE%" +distribution.test.language.reset="Preference Set" +distribution.test.locale.reset="Preference Set" +distribution.test.locale.set="Preference Set" +distribution.test.language.set="Preference Set" + +[LocalizablePreferences-en] +distribution.test.language.en="en" +distribution.test.language.reset= +distribution.test.language.set="Language Set" +distribution.test.locale.set="Language Set" + +[LocalizablePreferences-en-US] +distribution.test.locale.en-US="en-US" +distribution.test.locale.reset= +distribution.test.locale.set="Locale Set" + +[LocalizablePreferences-de] +distribution.test.language.de="de" diff --git a/browser/components/tests/unit/head.js b/browser/components/tests/unit/head.js new file mode 100644 index 000000000..3d4e23452 --- /dev/null +++ b/browser/components/tests/unit/head.js @@ -0,0 +1,9 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +const {interfaces: Ci, classes: Cc, results: Cr, utils: Cu} = Components; + +Cu.import("resource://gre/modules/Services.jsm"); + +var gProfD = do_get_profile().QueryInterface(Ci.nsILocalFile); diff --git a/browser/components/tests/unit/test_browserGlue_migration_loop_cleanup.js b/browser/components/tests/unit/test_browserGlue_migration_loop_cleanup.js new file mode 100644 index 000000000..a68503db3 --- /dev/null +++ b/browser/components/tests/unit/test_browserGlue_migration_loop_cleanup.js @@ -0,0 +1,32 @@ +const UI_VERSION = 41; +const TOPIC_BROWSERGLUE_TEST = "browser-glue-test"; +const TOPICDATA_BROWSERGLUE_TEST = "force-ui-migration"; + +var gBrowserGlue = Cc["@mozilla.org/browser/browserglue;1"] + .getService(Ci.nsIObserver); + +Services.prefs.setIntPref("browser.migration.version", UI_VERSION - 1); + +add_task(function* test_check_cleanup_loop_prefs() { + Services.prefs.setBoolPref("loop.createdRoom", true); + Services.prefs.setBoolPref("loop1.createdRoom", true); + Services.prefs.setBoolPref("loo.createdRoom", true); + + // Simulate a migration. + gBrowserGlue.observe(null, TOPIC_BROWSERGLUE_TEST, TOPICDATA_BROWSERGLUE_TEST); + + Assert.throws(() => Services.prefs.getBoolPref("loop.createdRoom"), + /NS_ERROR_UNEXPECTED/, + "should have cleared old loop preference 'loop.createdRoom'"); + Assert.ok(Services.prefs.getBoolPref("loop1.createdRoom"), + "should have left non-loop pref 'loop1.createdRoom' untouched"); + Assert.ok(Services.prefs.getBoolPref("loo.createdRoom"), + "should have left non-loop pref 'loo.createdRoom' untouched"); +}); + +do_register_cleanup(() => { + Services.prefs.clearUserPref("browser.migration.version"); + Services.prefs.clearUserPref("loop.createdRoom"); + Services.prefs.clearUserPref("loop1.createdRoom"); + Services.prefs.clearUserPref("loo.createdRoom"); +}); diff --git a/browser/components/tests/unit/test_distribution.js b/browser/components/tests/unit/test_distribution.js new file mode 100644 index 000000000..183ab85d6 --- /dev/null +++ b/browser/components/tests/unit/test_distribution.js @@ -0,0 +1,152 @@ +/* Any copyright is dedicated to the Public Domain. + http://creativecommons.org/publicdomain/zero/1.0/ */ + +/** + * Tests that preferences are properly set by distribution.ini + */ + +Cu.import("resource://gre/modules/LoadContextInfo.jsm"); + +// Import common head. +var commonFile = do_get_file("../../../../toolkit/components/places/tests/head_common.js", false); +/* import-globals-from ../../../../toolkit/components/places/tests/head_common.js */ +if (commonFile) { + let uri = Services.io.newFileURI(commonFile); + Services.scriptloader.loadSubScript(uri.spec, this); +} + +const TOPICDATA_DISTRIBUTION_CUSTOMIZATION = "force-distribution-customization"; +const TOPIC_BROWSERGLUE_TEST = "browser-glue-test"; + +/** + * Copy the engine-distribution.xml engine to a fake distribution + * created in the profile, and registered with the directory service. + * Create an empty en-US directory to make sure it isn't used. + */ +function installDistributionEngine() { + const XRE_APP_DISTRIBUTION_DIR = "XREAppDist"; + + let dir = gProfD.clone(); + dir.append("distribution"); + let distDir = dir.clone(); + + dir.append("searchplugins"); + dir.create(dir.DIRECTORY_TYPE, FileUtils.PERMS_DIRECTORY); + + dir.append("locale"); + dir.create(dir.DIRECTORY_TYPE, FileUtils.PERMS_DIRECTORY); + let localeDir = dir.clone(); + + dir.append("en-US"); + dir.create(dir.DIRECTORY_TYPE, FileUtils.PERMS_DIRECTORY); + + localeDir.append("de-DE"); + localeDir.create(dir.DIRECTORY_TYPE, FileUtils.PERMS_DIRECTORY); + + do_get_file("data/engine-de-DE.xml").copyTo(localeDir, "engine-de-DE.xml"); + + Services.dirsvc.registerProvider({ + getFile: function(aProp, aPersistent) { + aPersistent.value = true; + if (aProp == XRE_APP_DISTRIBUTION_DIR) + return distDir.clone(); + return null; + } + }); +} + +function run_test() { + // Set special pref to load distribution.ini from the profile folder. + Services.prefs.setBoolPref("distribution.testing.loadFromProfile", true); + + // Copy distribution.ini file to the profile dir. + let distroDir = gProfD.clone(); + distroDir.leafName = "distribution"; + let iniFile = distroDir.clone(); + iniFile.append("distribution.ini"); + if (iniFile.exists()) { + iniFile.remove(false); + print("distribution.ini already exists, did some test forget to cleanup?"); + } + + let testDistributionFile = gTestDir.clone(); + testDistributionFile.append("distribution.ini"); + testDistributionFile.copyTo(distroDir, "distribution.ini"); + Assert.ok(testDistributionFile.exists()); + + installDistributionEngine(); + + run_next_test(); +} + +do_register_cleanup(function () { + // Remove the distribution dir, even if the test failed, otherwise all + // next tests will use it. + let distDir = gProfD.clone(); + distDir.append("distribution"); + distDir.remove(true); + Assert.ok(!distDir.exists()); +}); + +add_task(function* () { + // Force distribution. + let glue = Cc["@mozilla.org/browser/browserglue;1"].getService(Ci.nsIObserver) + glue.observe(null, TOPIC_BROWSERGLUE_TEST, TOPICDATA_DISTRIBUTION_CUSTOMIZATION); + + var defaultBranch = Services.prefs.getDefaultBranch(null); + + Assert.equal(defaultBranch.getCharPref("distribution.id"), "disttest"); + Assert.equal(defaultBranch.getCharPref("distribution.version"), "1.0"); + Assert.equal(defaultBranch.getComplexValue("distribution.about", Ci.nsISupportsString).data, "Tèƨƭ δïƨƭřïβúƭïôñ ƒïℓè"); + + Assert.equal(defaultBranch.getCharPref("distribution.test.string"), "Test String"); + Assert.equal(defaultBranch.getCharPref("distribution.test.string.noquotes"), "Test String"); + Assert.equal(defaultBranch.getIntPref("distribution.test.int"), 777); + Assert.equal(defaultBranch.getBoolPref("distribution.test.bool.true"), true); + Assert.equal(defaultBranch.getBoolPref("distribution.test.bool.false"), false); + + Assert.throws(() => defaultBranch.getCharPref("distribution.test.empty")); + Assert.throws(() => defaultBranch.getIntPref("distribution.test.empty")); + Assert.throws(() => defaultBranch.getBoolPref("distribution.test.empty")); + + Assert.equal(defaultBranch.getCharPref("distribution.test.pref.locale"), "en-US"); + Assert.equal(defaultBranch.getCharPref("distribution.test.pref.language.en"), "en"); + Assert.equal(defaultBranch.getCharPref("distribution.test.pref.locale.en-US"), "en-US"); + Assert.throws(() => defaultBranch.getCharPref("distribution.test.pref.language.de")); + // This value was never set because of the empty language specific pref + Assert.throws(() => defaultBranch.getCharPref("distribution.test.pref.language.reset")); + // This value was never set because of the empty locale specific pref + Assert.throws(() => defaultBranch.getCharPref("distribution.test.pref.locale.reset")); + // This value was overridden by a locale specific setting + Assert.equal(defaultBranch.getCharPref("distribution.test.pref.locale.set"), "Locale Set"); + // This value was overridden by a language specific setting + Assert.equal(defaultBranch.getCharPref("distribution.test.pref.language.set"), "Language Set"); + // Language should not override locale + Assert.notEqual(defaultBranch.getCharPref("distribution.test.pref.locale.set"), "Language Set"); + + Assert.equal(defaultBranch.getComplexValue("distribution.test.locale", Ci.nsIPrefLocalizedString).data, "en-US"); + Assert.equal(defaultBranch.getComplexValue("distribution.test.language.en", Ci.nsIPrefLocalizedString).data, "en"); + Assert.equal(defaultBranch.getComplexValue("distribution.test.locale.en-US", Ci.nsIPrefLocalizedString).data, "en-US"); + Assert.throws(() => defaultBranch.getComplexValue("distribution.test.language.de", Ci.nsIPrefLocalizedString)); + // This value was never set because of the empty language specific pref + Assert.throws(() => defaultBranch.getComplexValue("distribution.test.language.reset", Ci.nsIPrefLocalizedString)); + // This value was never set because of the empty locale specific pref + Assert.throws(() => defaultBranch.getComplexValue("distribution.test.locale.reset", Ci.nsIPrefLocalizedString)); + // This value was overridden by a locale specific setting + Assert.equal(defaultBranch.getComplexValue("distribution.test.locale.set", Ci.nsIPrefLocalizedString).data, "Locale Set"); + // This value was overridden by a language specific setting + Assert.equal(defaultBranch.getComplexValue("distribution.test.language.set", Ci.nsIPrefLocalizedString).data, "Language Set"); + // Language should not override locale + Assert.notEqual(defaultBranch.getComplexValue("distribution.test.locale.set", Ci.nsIPrefLocalizedString).data, "Language Set"); + + do_test_pending(); + + Services.prefs.setCharPref("distribution.searchplugins.defaultLocale", "de-DE"); + + Services.search.init(function() { + Assert.equal(Services.search.isInitialized, true); + var engine = Services.search.getEngineByName("Google"); + Assert.equal(engine.description, "override-de-DE"); + do_test_finished(); + }); +}); diff --git a/browser/components/tests/unit/xpcshell.ini b/browser/components/tests/unit/xpcshell.ini new file mode 100644 index 000000000..c2f461966 --- /dev/null +++ b/browser/components/tests/unit/xpcshell.ini @@ -0,0 +1,10 @@ +[DEFAULT] +head = head.js +firefox-appdir = browser +skip-if = toolkit == 'android' +support-files = + distribution.ini + data/engine-de-DE.xml + +[test_distribution.js] +[test_browserGlue_migration_loop_cleanup.js] |