summaryrefslogtreecommitdiffstats
path: root/browser/components/tests/unit
diff options
context:
space:
mode:
Diffstat (limited to 'browser/components/tests/unit')
-rw-r--r--browser/components/tests/unit/distribution.ini60
-rw-r--r--browser/components/tests/unit/head.js8
-rw-r--r--browser/components/tests/unit/test_browserGlue_migration_ctrltab_recently_used_order.js111
-rw-r--r--browser/components/tests/unit/test_browserGlue_migration_formautofill.js142
-rw-r--r--browser/components/tests/unit/test_browserGlue_migration_no_errors.js34
-rw-r--r--browser/components/tests/unit/test_browserGlue_migration_places_xulstore.js54
-rw-r--r--browser/components/tests/unit/test_browserGlue_migration_social_cleanup.js30
-rw-r--r--browser/components/tests/unit/test_distribution.js202
-rw-r--r--browser/components/tests/unit/test_distribution_cachedexistence.js131
-rw-r--r--browser/components/tests/unit/xpcshell.ini15
10 files changed, 787 insertions, 0 deletions
diff --git a/browser/components/tests/unit/distribution.ini b/browser/components/tests/unit/distribution.ini
new file mode 100644
index 0000000000..83fe19b2cc
--- /dev/null
+++ b/browser/components/tests/unit/distribution.ini
@@ -0,0 +1,60 @@
+# 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"
+
+general.useragent.locale=en-US
+
+[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 0000000000..2fb39adbd4
--- /dev/null
+++ b/browser/components/tests/unit/head.js
@@ -0,0 +1,8 @@
+/* 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/. */
+
+var { sinon } = ChromeUtils.importESModule(
+ "resource://testing-common/Sinon.sys.mjs"
+);
+var gProfD = do_get_profile().QueryInterface(Ci.nsIFile);
diff --git a/browser/components/tests/unit/test_browserGlue_migration_ctrltab_recently_used_order.js b/browser/components/tests/unit/test_browserGlue_migration_ctrltab_recently_used_order.js
new file mode 100644
index 0000000000..119d32996b
--- /dev/null
+++ b/browser/components/tests/unit/test_browserGlue_migration_ctrltab_recently_used_order.js
@@ -0,0 +1,111 @@
+/* Any copyright is dedicated to the Public Domain.
+http://creativecommons.org/publicdomain/zero/1.0/ */
+
+"use strict";
+
+const TOPIC_BROWSERGLUE_TEST = "browser-glue-test";
+const TOPICDATA_BROWSERGLUE_TEST = "force-ui-migration";
+const RECENTLY_USED_ORDER_DEFAULT = false;
+const UI_VERSION = 107;
+
+const gBrowserGlue = Cc["@mozilla.org/browser/browserglue;1"].getService(
+ Ci.nsIObserver
+);
+
+add_task(async function has_not_used_ctrl_tab_and_its_off() {
+ Services.prefs.setIntPref("browser.migration.version", UI_VERSION);
+ Services.prefs.setBoolPref("browser.engagement.ctrlTab.has-used", false);
+ Services.prefs.setBoolPref("browser.ctrlTab.recentlyUsedOrder", false);
+
+ // Simulate a migration.
+ gBrowserGlue.observe(
+ null,
+ TOPIC_BROWSERGLUE_TEST,
+ TOPICDATA_BROWSERGLUE_TEST
+ );
+
+ Assert.equal(
+ RECENTLY_USED_ORDER_DEFAULT,
+ Services.prefs.getBoolPref("browser.ctrlTab.sortByRecentlyUsed")
+ );
+});
+
+add_task(async function has_not_used_ctrl_tab_and_its_on() {
+ Services.prefs.setIntPref("browser.migration.version", UI_VERSION);
+ Services.prefs.setBoolPref("browser.engagement.ctrlTab.has-used", false);
+ Services.prefs.setBoolPref("browser.ctrlTab.recentlyUsedOrder", true);
+
+ // Simulate a migration.
+ gBrowserGlue.observe(
+ null,
+ TOPIC_BROWSERGLUE_TEST,
+ TOPICDATA_BROWSERGLUE_TEST
+ );
+
+ Assert.equal(
+ RECENTLY_USED_ORDER_DEFAULT,
+ Services.prefs.getBoolPref("browser.ctrlTab.sortByRecentlyUsed")
+ );
+});
+
+add_task(async function has_used_ctrl_tab_and_its_off() {
+ Services.prefs.setIntPref("browser.migration.version", UI_VERSION);
+ Services.prefs.setBoolPref("browser.engagement.ctrlTab.has-used", true);
+ Services.prefs.setBoolPref("browser.ctrlTab.recentlyUsedOrder", false);
+
+ // Simulate a migration.
+ gBrowserGlue.observe(
+ null,
+ TOPIC_BROWSERGLUE_TEST,
+ TOPICDATA_BROWSERGLUE_TEST
+ );
+
+ Assert.equal(
+ false,
+ Services.prefs.getBoolPref("browser.ctrlTab.sortByRecentlyUsed")
+ );
+});
+
+add_task(async function has_used_ctrl_tab_and_its_on() {
+ Services.prefs.setIntPref("browser.migration.version", UI_VERSION);
+ Services.prefs.setBoolPref("browser.engagement.ctrlTab.has-used", true);
+ Services.prefs.setBoolPref("browser.ctrlTab.recentlyUsedOrder", true);
+
+ // Simulate a migration.
+ gBrowserGlue.observe(
+ null,
+ TOPIC_BROWSERGLUE_TEST,
+ TOPICDATA_BROWSERGLUE_TEST
+ );
+
+ Assert.equal(
+ true,
+ Services.prefs.getBoolPref("browser.ctrlTab.sortByRecentlyUsed")
+ );
+});
+
+add_task(async function has_used_ctrl_tab_and_its_default() {
+ Services.prefs.setIntPref("browser.migration.version", UI_VERSION);
+ Services.prefs.setBoolPref("browser.engagement.ctrlTab.has-used", true);
+ Services.prefs.clearUserPref("browser.ctrlTab.recentlyUsedOrder");
+
+ // Simulate a migration.
+ gBrowserGlue.observe(
+ null,
+ TOPIC_BROWSERGLUE_TEST,
+ TOPICDATA_BROWSERGLUE_TEST
+ );
+
+ // Default had been true
+ Assert.equal(
+ true,
+ Services.prefs.getBoolPref("browser.ctrlTab.sortByRecentlyUsed")
+ );
+});
+
+registerCleanupFunction(() => {
+ Services.prefs.clearUserPref("browser.migration.version");
+ Services.prefs.clearUserPref("browser.engagement.ctrlTab.has-used");
+ Services.prefs.clearUserPref("browser.ctrlTab.recentlyUsedOrder");
+ Services.prefs.clearUserPref("browser.ctrlTab.sortByRecentlyUsed");
+});
diff --git a/browser/components/tests/unit/test_browserGlue_migration_formautofill.js b/browser/components/tests/unit/test_browserGlue_migration_formautofill.js
new file mode 100644
index 0000000000..7c97fa2279
--- /dev/null
+++ b/browser/components/tests/unit/test_browserGlue_migration_formautofill.js
@@ -0,0 +1,142 @@
+/* Any copyright is dedicated to the Public Domain.
+http://creativecommons.org/publicdomain/zero/1.0/ */
+
+"use strict";
+
+const TOPIC_BROWSERGLUE_TEST = "browser-glue-test";
+const TOPICDATA_BROWSERGLUE_TEST = "force-ui-migration";
+
+const gBrowserGlue = Cc["@mozilla.org/browser/browserglue;1"].getService(
+ Ci.nsIObserver
+);
+const UI_VERSION = 124;
+
+function ensureOldPrefsAreCleared() {
+ Assert.ok(
+ !Services.prefs.prefHasUserValue("extensions.formautofill.available"),
+ "main module available pref should have been cleared"
+ );
+ Assert.ok(
+ !Services.prefs.prefHasUserValue(
+ "extensions.formautofill.creditCards.available"
+ ),
+ "old credit card available pref should have been cleared"
+ );
+}
+
+add_task(async function setup() {
+ registerCleanupFunction(() => {
+ Services.prefs.clearUserPref("browser.migration.version");
+ Services.prefs.clearUserPref("extensions.formautofill.available");
+ Services.prefs.clearUserPref(
+ "extensions.formautofill.creditCards.available"
+ );
+ Services.prefs.clearUserPref(
+ "extensions.formautofill.creditCards.supported"
+ );
+ });
+});
+
+add_task(async function test_check_form_autofill_module_detect() {
+ Services.prefs.setIntPref("browser.migration.version", UI_VERSION - 1);
+ Services.prefs.setCharPref("extensions.formautofill.available", "detect");
+ // Simulate a migration.
+ gBrowserGlue.observe(
+ null,
+ TOPIC_BROWSERGLUE_TEST,
+ TOPICDATA_BROWSERGLUE_TEST
+ );
+ // old credit card available should migrate to "detect" due to
+ // "extensions.formautofill.available" being "detect".
+ Assert.equal(
+ Services.prefs.getCharPref("extensions.formautofill.creditCards.supported"),
+ "detect"
+ );
+ // old address available pref follows the main module pref
+ Assert.equal(
+ Services.prefs.getCharPref("extensions.formautofill.addresses.supported"),
+ "detect"
+ );
+ ensureOldPrefsAreCleared();
+});
+
+add_task(async function test_check_old_form_autofill_module_off() {
+ Services.prefs.setIntPref("browser.migration.version", UI_VERSION - 1);
+ Services.prefs.setCharPref("extensions.formautofill.available", "off");
+
+ // Simulate a migration.
+ gBrowserGlue.observe(
+ null,
+ TOPIC_BROWSERGLUE_TEST,
+ TOPICDATA_BROWSERGLUE_TEST
+ );
+
+ // old credit card available should migrate to off due to
+ // "extensions.formautofill.available" being off.
+ Assert.equal(
+ Services.prefs.getCharPref("extensions.formautofill.creditCards.supported"),
+ "off"
+ );
+ // old address available pref follows the main module pref
+ Assert.equal(
+ Services.prefs.getCharPref("extensions.formautofill.addresses.supported"),
+ "off"
+ );
+ ensureOldPrefsAreCleared();
+});
+
+add_task(async function test_check_old_form_autofill_module_on_cc_on() {
+ Services.prefs.setIntPref("browser.migration.version", UI_VERSION - 1);
+ Services.prefs.setCharPref("extensions.formautofill.available", "on");
+ Services.prefs.setBoolPref(
+ "extensions.formautofill.creditCards.available",
+ true
+ );
+
+ // Simulate a migration.
+ gBrowserGlue.observe(
+ null,
+ TOPIC_BROWSERGLUE_TEST,
+ TOPICDATA_BROWSERGLUE_TEST
+ );
+
+ // old credit card available should migrate to "on" due to
+ // "extensions.formautofill.available" being on and
+ // "extensions.formautofill.creditCards.available" having a default value of true.
+ Assert.equal(
+ Services.prefs.getCharPref("extensions.formautofill.creditCards.supported"),
+ "on"
+ );
+ // old address available pref follows the main module pref
+ Assert.equal(
+ Services.prefs.getCharPref("extensions.formautofill.addresses.supported"),
+ "on"
+ );
+ ensureOldPrefsAreCleared();
+});
+
+add_task(async function test_check_old_form_autofill_module_on_cc_off() {
+ Services.prefs.setIntPref("browser.migration.version", UI_VERSION - 1);
+ Services.prefs.setCharPref("extensions.formautofill.available", "on");
+ Services.prefs.setBoolPref(
+ "extensions.formautofill.creditCards.available",
+ false
+ );
+
+ // Simulate a migration.
+ gBrowserGlue.observe(
+ null,
+ TOPIC_BROWSERGLUE_TEST,
+ TOPICDATA_BROWSERGLUE_TEST
+ );
+
+ // old credit card available should migrate to "off" due to
+ // "extensions.formautofill.available" being on and
+ // "extensions.formautofill.creditCards.available" having a user set value of false.
+ Assert.equal(
+ Services.prefs.getCharPref("extensions.formautofill.creditCards.supported"),
+ "off"
+ );
+
+ ensureOldPrefsAreCleared();
+});
diff --git a/browser/components/tests/unit/test_browserGlue_migration_no_errors.js b/browser/components/tests/unit/test_browserGlue_migration_no_errors.js
new file mode 100644
index 0000000000..aed88c95fe
--- /dev/null
+++ b/browser/components/tests/unit/test_browserGlue_migration_no_errors.js
@@ -0,0 +1,34 @@
+/* Any copyright is dedicated to the Public Domain.
+ http://creativecommons.org/publicdomain/zero/1.0/ */
+
+/**
+ * Since various migrations in BrowserGlue are sometimes trivial, e.g. just
+ * clearing a pref, it does not feel necessary to write tests for each of those.
+ *
+ * However, ensuring we have at least some coverage to check for errors, e.g.
+ * typos, is a good idea, hence this test.
+ *
+ * If your migration is more complex that clearing a couple of prefs, you
+ * should consider adding your own BrowserGlue migration test.
+ */
+const TOPIC_BROWSERGLUE_TEST = "browser-glue-test";
+const TOPICDATA_BROWSERGLUE_TEST = "force-ui-migration";
+
+const gBrowserGlue = Cc["@mozilla.org/browser/browserglue;1"].getService(
+ Ci.nsIObserver
+);
+
+// Set the migration value to 1, to ensure that the migration code is called,
+// and so that this doesn't need updating every time we obsolete old tests.
+Services.prefs.setIntPref("browser.migration.version", 1);
+
+add_task(async function test_no_errors() {
+ // Simulate a migration.
+ gBrowserGlue.observe(
+ null,
+ TOPIC_BROWSERGLUE_TEST,
+ TOPICDATA_BROWSERGLUE_TEST
+ );
+
+ Assert.ok(true, "should have run the migration with no errors");
+});
diff --git a/browser/components/tests/unit/test_browserGlue_migration_places_xulstore.js b/browser/components/tests/unit/test_browserGlue_migration_places_xulstore.js
new file mode 100644
index 0000000000..7e2ae93bfe
--- /dev/null
+++ b/browser/components/tests/unit/test_browserGlue_migration_places_xulstore.js
@@ -0,0 +1,54 @@
+/* Any copyright is dedicated to the Public Domain.
+http://creativecommons.org/publicdomain/zero/1.0/ */
+
+"use strict";
+
+const TOPIC_BROWSERGLUE_TEST = "browser-glue-test";
+const TOPICDATA_BROWSERGLUE_TEST = "force-ui-migration";
+const UI_VERSION = 120;
+
+const { AppConstants } = ChromeUtils.importESModule(
+ "resource://gre/modules/AppConstants.sys.mjs"
+);
+const { PlacesUIUtils } = ChromeUtils.importESModule(
+ "resource:///modules/PlacesUIUtils.sys.mjs"
+);
+
+add_task(async function has_not_used_ctrl_tab_and_its_off() {
+ const gBrowserGlue = Cc["@mozilla.org/browser/browserglue;1"].getService(
+ Ci.nsIObserver
+ );
+ registerCleanupFunction(() => {
+ Services.prefs.clearUserPref("browser.migration.version");
+ });
+ Services.prefs.setIntPref("browser.migration.version", UI_VERSION);
+
+ Services.xulStore.setValue(
+ AppConstants.BROWSER_CHROME_URL,
+ "place:test",
+ "open",
+ "true"
+ );
+
+ // Simulate a migration.
+ gBrowserGlue.observe(
+ null,
+ TOPIC_BROWSERGLUE_TEST,
+ TOPICDATA_BROWSERGLUE_TEST
+ );
+
+ Assert.equal(
+ Services.xulStore.getValue(
+ AppConstants.BROWSER_CHROME_URL,
+ PlacesUIUtils.obfuscateUrlForXulStore("place:test"),
+ "open"
+ ),
+ "true"
+ );
+
+ Assert.greater(
+ Services.prefs.getIntPref("browser.migration.version"),
+ UI_VERSION,
+ "Check migration version has been bumped up"
+ );
+});
diff --git a/browser/components/tests/unit/test_browserGlue_migration_social_cleanup.js b/browser/components/tests/unit/test_browserGlue_migration_social_cleanup.js
new file mode 100644
index 0000000000..00b59202a4
--- /dev/null
+++ b/browser/components/tests/unit/test_browserGlue_migration_social_cleanup.js
@@ -0,0 +1,30 @@
+const UI_VERSION = 69;
+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(async function test_check_cleanup_social_prefs() {
+ Services.prefs.setStringPref("social.manifest.example-com", "example.com");
+
+ // Simulate a migration.
+ gBrowserGlue.observe(
+ null,
+ TOPIC_BROWSERGLUE_TEST,
+ TOPICDATA_BROWSERGLUE_TEST
+ );
+
+ Assert.ok(
+ !Services.prefs.prefHasUserValue("social.manifest.example-com"),
+ "should have cleared old social preference 'social.manifest.example-com'"
+ );
+});
+
+registerCleanupFunction(() => {
+ Services.prefs.clearUserPref("browser.migration.version");
+ Services.prefs.clearUserPref("social.manifest.example-com");
+});
diff --git a/browser/components/tests/unit/test_distribution.js b/browser/components/tests/unit/test_distribution.js
new file mode 100644
index 0000000000..a64bafb2b9
--- /dev/null
+++ b/browser/components/tests/unit/test_distribution.js
@@ -0,0 +1,202 @@
+/* Any copyright is dedicated to the Public Domain.
+ http://creativecommons.org/publicdomain/zero/1.0/ */
+
+/**
+ * Tests that preferences are properly set by distribution.ini
+ */
+
+const TOPICDATA_DISTRIBUTION_CUSTOMIZATION = "force-distribution-customization";
+const TOPIC_BROWSERGLUE_TEST = "browser-glue-test";
+
+registerCleanupFunction(async function () {
+ // Remove the distribution dir, even if the test failed, otherwise all
+ // next tests will use it.
+ let folderPath = PathUtils.join(PathUtils.profileDir, "distribution");
+ await IOUtils.remove(folderPath, { ignoreAbsent: true, recursive: true });
+ Assert.ok(!(await IOUtils.exists(folderPath)));
+ Services.prefs.clearUserPref("distribution.testing.loadFromProfile");
+});
+
+add_task(async function () {
+ // 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 = do_get_cwd().clone();
+ testDistributionFile.append("distribution.ini");
+ testDistributionFile.copyTo(distroDir, "distribution.ini");
+ Assert.ok(testDistributionFile.exists());
+});
+
+add_task(async 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.getStringPref("distribution.about"),
+ "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"),
+ /NS_ERROR_UNEXPECTED/
+ );
+ Assert.throws(
+ () => defaultBranch.getIntPref("distribution.test.empty"),
+ /NS_ERROR_UNEXPECTED/
+ );
+ Assert.throws(
+ () => defaultBranch.getBoolPref("distribution.test.empty"),
+ /NS_ERROR_UNEXPECTED/
+ );
+
+ 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"),
+ /NS_ERROR_UNEXPECTED/
+ );
+ // This value was never set because of the empty language specific pref
+ Assert.throws(
+ () => defaultBranch.getCharPref("distribution.test.pref.language.reset"),
+ /NS_ERROR_UNEXPECTED/
+ );
+ // This value was never set because of the empty locale specific pref
+ Assert.throws(
+ () => defaultBranch.getCharPref("distribution.test.pref.locale.reset"),
+ /NS_ERROR_UNEXPECTED/
+ );
+ // 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
+ ),
+ /NS_ERROR_UNEXPECTED/
+ );
+ // This value was never set because of the empty language specific pref
+ Assert.throws(
+ () =>
+ defaultBranch.getComplexValue(
+ "distribution.test.language.reset",
+ Ci.nsIPrefLocalizedString
+ ),
+ /NS_ERROR_UNEXPECTED/
+ );
+ // This value was never set because of the empty locale specific pref
+ Assert.throws(
+ () =>
+ defaultBranch.getComplexValue(
+ "distribution.test.locale.reset",
+ Ci.nsIPrefLocalizedString
+ ),
+ /NS_ERROR_UNEXPECTED/
+ );
+ // 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"
+ );
+ Assert.equal(defaultBranch.getCharPref("intl.locale.requested"), "en-US");
+});
diff --git a/browser/components/tests/unit/test_distribution_cachedexistence.js b/browser/components/tests/unit/test_distribution_cachedexistence.js
new file mode 100644
index 0000000000..dc10c3643c
--- /dev/null
+++ b/browser/components/tests/unit/test_distribution_cachedexistence.js
@@ -0,0 +1,131 @@
+/* Any copyright is dedicated to the Public Domain.
+ http://creativecommons.org/publicdomain/zero/1.0/ */
+
+/**
+ * Tests that DistributionCustomizer correctly caches the existence
+ * of the distribution.ini file and just rechecks it after a version
+ * update.
+ */
+
+const PREF_CACHED_FILE_EXISTENCE = "distribution.iniFile.exists.value";
+const PREF_CACHED_FILE_APPVERSION = "distribution.iniFile.exists.appversion";
+const PREF_LOAD_FROM_PROFILE = "distribution.testing.loadFromProfile";
+
+const gTestDir = do_get_cwd();
+
+const { AppConstants } = ChromeUtils.importESModule(
+ "resource://gre/modules/AppConstants.sys.mjs"
+);
+
+add_task(async function () {
+ // Start with a clean slate of the prefs that control this feature.
+ Services.prefs.clearUserPref(PREF_CACHED_FILE_APPVERSION);
+ Services.prefs.clearUserPref(PREF_CACHED_FILE_EXISTENCE);
+ setupTest();
+
+ let { DistributionCustomizer } = ChromeUtils.import(
+ "resource:///modules/distribution.js"
+ );
+ let distribution = new DistributionCustomizer();
+
+ copyDistributionToProfile();
+
+ // Check that checking for distribution.ini returns the right value and sets up
+ // the cached prefs.
+ let exists = distribution._hasDistributionIni;
+
+ Assert.ok(exists);
+ Assert.equal(
+ Services.prefs.getBoolPref(PREF_CACHED_FILE_EXISTENCE, undefined),
+ true
+ );
+ Assert.equal(
+ Services.prefs.getStringPref(PREF_CACHED_FILE_APPVERSION, "unknown"),
+ AppConstants.MOZ_APP_VERSION
+ );
+
+ // Check that calling _hasDistributionIni again will use the cached value. We do
+ // this by deleting the file and expecting it to still return true instead of false.
+ // Also, we need to delete _hasDistributionIni from the object because the getter
+ // was replaced with a stored value.
+ deleteDistribution();
+ delete distribution._hasDistributionIni;
+
+ exists = distribution._hasDistributionIni;
+ Assert.ok(exists);
+
+ // Now let's invalidate the PREF_CACHED_FILE_EXISTENCE pref to make sure the
+ // value gets recomputed correctly.
+ Services.prefs.clearUserPref(PREF_CACHED_FILE_EXISTENCE);
+ delete distribution._hasDistributionIni;
+ exists = distribution._hasDistributionIni;
+
+ // It now should return false, as well as storing false in the pref.
+ Assert.ok(!exists);
+ Assert.equal(
+ Services.prefs.getBoolPref(PREF_CACHED_FILE_EXISTENCE, undefined),
+ false
+ );
+
+ // Check now that it will use the new cached value instead of returning true in
+ // the presence of the file.
+ copyDistributionToProfile();
+ delete distribution._hasDistributionIni;
+ exists = distribution._hasDistributionIni;
+
+ Assert.ok(!exists);
+
+ // Now let's do the same, but invalidating the App Version, as if a version
+ // update occurred.
+ Services.prefs.setStringPref(PREF_CACHED_FILE_APPVERSION, "older version");
+ delete distribution._hasDistributionIni;
+ exists = distribution._hasDistributionIni;
+
+ Assert.ok(exists);
+ Assert.equal(
+ Services.prefs.getBoolPref(PREF_CACHED_FILE_EXISTENCE, undefined),
+ true
+ );
+ Assert.equal(
+ Services.prefs.getStringPref(PREF_CACHED_FILE_APPVERSION, "unknown"),
+ AppConstants.MOZ_APP_VERSION
+ );
+});
+
+/*
+ * Helper functions
+ */
+function copyDistributionToProfile() {
+ // 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());
+}
+
+function deleteDistribution() {
+ let distroDir = gProfD.clone();
+ distroDir.leafName = "distribution";
+ let iniFile = distroDir.clone();
+ iniFile.append("distribution.ini");
+ iniFile.remove(false);
+}
+
+function setupTest() {
+ // Set special pref to load distribution.ini from the profile folder.
+ Services.prefs.setBoolPref(PREF_LOAD_FROM_PROFILE, true);
+}
+
+registerCleanupFunction(function () {
+ deleteDistribution();
+ Services.prefs.clearUserPref(PREF_LOAD_FROM_PROFILE);
+});
diff --git a/browser/components/tests/unit/xpcshell.ini b/browser/components/tests/unit/xpcshell.ini
new file mode 100644
index 0000000000..7c7257282e
--- /dev/null
+++ b/browser/components/tests/unit/xpcshell.ini
@@ -0,0 +1,15 @@
+[DEFAULT]
+head = head.js
+firefox-appdir = browser
+skip-if = toolkit == 'android' # bug 1730213
+support-files =
+ distribution.ini
+
+[test_browserGlue_migration_formautofill.js]
+[test_browserGlue_migration_places_xulstore.js]
+[test_browserGlue_migration_ctrltab_recently_used_order.js]
+[test_distribution.js]
+run-sequentially = very high failure rate in parallel
+[test_distribution_cachedexistence.js]
+[test_browserGlue_migration_no_errors.js]
+[test_browserGlue_migration_social_cleanup.js]