new file mode 100644
--- /dev/null
+++ b/browser/components/extensions/test/browser/browser_ext_settings_overrides_default_search.js
@@ -0,0 +1,506 @@
+/* -*- Mode: indent-tabs-mode: nil; js-indent-level: 2 -*- */
+/* vim: set sts=2 sw=2 et tw=80: */
+
+"use strict";
+
+XPCOMUtils.defineLazyGetter(this, "Management", () => {
+ const {Management} = Cu.import("resource://gre/modules/Extension.jsm", {});
+ return Management;
+});
+
+XPCOMUtils.defineLazyModuleGetter(this, "AddonManager",
+ "resource://gre/modules/AddonManager.jsm");
+
+const EXTENSION1_ID = "extension1@mozilla.com";
+const EXTENSION2_ID = "extension2@mozilla.com";
+
+function awaitEvent(eventName, id) {
+ return new Promise(resolve => {
+ let listener = (_eventName, ...args) => {
+ let extension = args[0];
+ if (_eventName === eventName &&
+ extension.id == id) {
+ Management.off(eventName, listener);
+ resolve(...args);
+ }
+ };
+
+ Management.on(eventName, listener);
+ });
+}
+
+/* This tests setting a default engine. */
+add_task(async function test_extension_setting_default_engine() {
+ let defaultEngineName = Services.search.currentEngine.name;
+
+ let ext1 = ExtensionTestUtils.loadExtension({
+ manifest: {
+ "chrome_settings_overrides": {
+ "search_provider": {
+ "name": "DuckDuckGo",
+ "search_url": "https://example.com/?q={searchTerms}",
+ "is_default": true,
+ },
+ },
+ },
+ useAddonManager: "temporary",
+ });
+
+ await ext1.startup();
+
+ is(Services.search.currentEngine.name, "DuckDuckGo", "Default engine is DuckDuckGo");
+
+ await ext1.unload();
+
+ is(Services.search.currentEngine.name, defaultEngineName, `Default engine is ${defaultEngineName}`);
+});
+
+/* This tests that using an invalid engine does nothing. */
+add_task(async function test_extension_setting_invalid_name_default_engine() {
+ let defaultEngineName = Services.search.currentEngine.name;
+
+ let ext1 = ExtensionTestUtils.loadExtension({
+ manifest: {
+ "chrome_settings_overrides": {
+ "search_provider": {
+ "name": "InvalidName",
+ "search_url": "https://example.com/?q={searchTerms}",
+ "is_default": true,
+ },
+ },
+ },
+ useAddonManager: "temporary",
+ });
+
+ await ext1.startup();
+
+ is(Services.search.currentEngine.name, defaultEngineName, `Default engine is ${defaultEngineName}`);
+
+ await ext1.unload();
+
+ is(Services.search.currentEngine.name, defaultEngineName, `Default engine is ${defaultEngineName}`);
+});
+
+/* This tests that uninstalling add-ons maintains the proper
+ * search default. */
+add_task(async function test_extension_setting_multiple_default_engine() {
+ let defaultEngineName = Services.search.currentEngine.name;
+ let ext1 = ExtensionTestUtils.loadExtension({
+ manifest: {
+ "chrome_settings_overrides": {
+ "search_provider": {
+ "name": "DuckDuckGo",
+ "search_url": "https://example.com/?q={searchTerms}",
+ "is_default": true,
+ },
+ },
+ },
+ useAddonManager: "temporary",
+ });
+
+ let ext2 = ExtensionTestUtils.loadExtension({
+ manifest: {
+ "chrome_settings_overrides": {
+ "search_provider": {
+ "name": "Twitter",
+ "search_url": "https://example.com/?q={searchTerms}",
+ "is_default": true,
+ },
+ },
+ },
+ useAddonManager: "temporary",
+ });
+
+ await ext1.startup();
+
+ is(Services.search.currentEngine.name, "DuckDuckGo", "Default engine is DuckDuckGo");
+
+ await ext2.startup();
+
+ is(Services.search.currentEngine.name, "Twitter", "Default engine is Twitter");
+
+ await ext2.unload();
+
+ is(Services.search.currentEngine.name, "DuckDuckGo", "Default engine is DuckDuckGo");
+
+ await ext1.unload();
+
+ is(Services.search.currentEngine.name, defaultEngineName, `Default engine is ${defaultEngineName}`);
+});
+
+/* This tests that uninstalling add-ons in reverse order maintains the proper
+ * search default. */
+add_task(async function test_extension_setting_multiple_default_engine_reversed() {
+ let defaultEngineName = Services.search.currentEngine.name;
+ let ext1 = ExtensionTestUtils.loadExtension({
+ manifest: {
+ "chrome_settings_overrides": {
+ "search_provider": {
+ "name": "DuckDuckGo",
+ "search_url": "https://example.com/?q={searchTerms}",
+ "is_default": true,
+ },
+ },
+ },
+ useAddonManager: "temporary",
+ });
+
+ let ext2 = ExtensionTestUtils.loadExtension({
+ manifest: {
+ "chrome_settings_overrides": {
+ "search_provider": {
+ "name": "Twitter",
+ "search_url": "https://example.com/?q={searchTerms}",
+ "is_default": true,
+ },
+ },
+ },
+ useAddonManager: "temporary",
+ });
+
+ await ext1.startup();
+
+ is(Services.search.currentEngine.name, "DuckDuckGo", "Default engine is DuckDuckGo");
+
+ await ext2.startup();
+
+ is(Services.search.currentEngine.name, "Twitter", "Default engine is Twitter");
+
+ await ext1.unload();
+
+ is(Services.search.currentEngine.name, "Twitter", "Default engine is Twitter");
+
+ await ext2.unload();
+
+ is(Services.search.currentEngine.name, defaultEngineName, `Default engine is ${defaultEngineName}`);
+});
+
+/* This tests adding an engine with one add-on and trying to make it the
+ *default with anoth. */
+add_task(async function test_extension_setting_invalid_default_engine() {
+ let defaultEngineName = Services.search.currentEngine.name;
+ let ext1 = ExtensionTestUtils.loadExtension({
+ manifest: {
+ "chrome_settings_overrides": {
+ "search_provider": {
+ "name": "MozSearch",
+ "keyword": "MozSearch",
+ "search_url": "https://example.com/?q={searchTerms}",
+ },
+ },
+ },
+ useAddonManager: "temporary",
+ });
+
+ let ext2 = ExtensionTestUtils.loadExtension({
+ manifest: {
+ "chrome_settings_overrides": {
+ "search_provider": {
+ "name": "MozSearch",
+ "search_url": "https://example.com/?q={searchTerms}",
+ "is_default": true,
+ },
+ },
+ },
+ useAddonManager: "temporary",
+ });
+
+ await ext1.startup();
+
+ is(Services.search.currentEngine.name, defaultEngineName, `Default engine is ${defaultEngineName}`);
+
+ let engine = Services.search.getEngineByName("MozSearch");
+ ok(engine, "Engine should exist.");
+
+ await ext2.startup();
+
+ is(Services.search.currentEngine.name, defaultEngineName, `Default engine is ${defaultEngineName}`);
+
+ await ext2.unload();
+
+ is(Services.search.currentEngine.name, defaultEngineName, `Default engine is ${defaultEngineName}`);
+
+ await ext1.unload();
+
+ is(Services.search.currentEngine.name, defaultEngineName, `Default engine is ${defaultEngineName}`);
+});
+
+/* This tests that when the user changes the search engine and the add-on
+ * is unistalled, search stays with the user's choice. */
+add_task(async function test_user_changing_default_engine() {
+ let ext1 = ExtensionTestUtils.loadExtension({
+ manifest: {
+ "chrome_settings_overrides": {
+ "search_provider": {
+ "name": "DuckDuckGo",
+ "search_url": "https://example.com/?q={searchTerms}",
+ "is_default": true,
+ },
+ },
+ },
+ useAddonManager: "temporary",
+ });
+
+ await ext1.startup();
+
+ is(Services.search.currentEngine.name, "DuckDuckGo", "Default engine is DuckDuckGo");
+
+ let engine = Services.search.getEngineByName("Twitter");
+ Services.search.currentEngine = engine;
+
+ await ext1.unload();
+
+ is(Services.search.currentEngine.name, "Twitter", "Default engine is Twitter");
+});
+
+/* This tests that when the user changes the search engine while it is
+ * disabled, user choice is maintained when the add-on is reenabled. */
+add_task(async function test_user_change_with_disabling() {
+ let ext1 = ExtensionTestUtils.loadExtension({
+ manifest: {
+ applications: {
+ gecko: {
+ id: EXTENSION1_ID,
+ },
+ },
+ "chrome_settings_overrides": {
+ "search_provider": {
+ "name": "DuckDuckGo",
+ "search_url": "https://example.com/?q={searchTerms}",
+ "is_default": true,
+ },
+ },
+ },
+ useAddonManager: "temporary",
+ });
+
+ await ext1.startup();
+
+ is(Services.search.currentEngine.name, "DuckDuckGo", "Default engine is DuckDuckGo");
+
+ let engine = Services.search.getEngineByName("Twitter");
+ Services.search.currentEngine = engine;
+
+ is(Services.search.currentEngine.name, "Twitter", "Default engine is Twitter");
+
+ let disabledPromise = awaitEvent("shutdown", EXTENSION1_ID);
+ let addon = await AddonManager.getAddonByID(EXTENSION1_ID);
+ addon.userDisabled = true;
+ await disabledPromise;
+
+ is(Services.search.currentEngine.name, "Twitter", "Default engine is Twitter");
+
+ let enabledPromise = awaitEvent("ready", EXTENSION1_ID);
+ addon.userDisabled = false;
+ await enabledPromise;
+
+ is(Services.search.currentEngine.name, "Twitter", "Default engine is Twitter");
+ await ext1.unload();
+});
+
+/* This tests that when two add-ons are installed that change default
+ * search and the first one is disabled, before the second one is installed,
+ * when the first one is reenabled, the second add-on keeps the search. */
+add_task(async function test_two_addons_with_first_disabled_before_second() {
+ let defaultEngineName = Services.search.currentEngine.name;
+ let ext1 = ExtensionTestUtils.loadExtension({
+ manifest: {
+ applications: {
+ gecko: {
+ id: EXTENSION1_ID,
+ },
+ },
+ "chrome_settings_overrides": {
+ "search_provider": {
+ "name": "DuckDuckGo",
+ "search_url": "https://example.com/?q={searchTerms}",
+ "is_default": true,
+ },
+ },
+ },
+ useAddonManager: "temporary",
+ });
+
+ let ext2 = ExtensionTestUtils.loadExtension({
+ manifest: {
+ applications: {
+ gecko: {
+ id: EXTENSION2_ID,
+ },
+ },
+ "chrome_settings_overrides": {
+ "search_provider": {
+ "name": "Twitter",
+ "search_url": "https://example.com/?q={searchTerms}",
+ "is_default": true,
+ },
+ },
+ },
+ useAddonManager: "temporary",
+ });
+
+ await ext1.startup();
+
+ is(Services.search.currentEngine.name, "DuckDuckGo", "Default engine is DuckDuckGo");
+
+ let disabledPromise = awaitEvent("shutdown", EXTENSION1_ID);
+ let addon1 = await AddonManager.getAddonByID(EXTENSION1_ID);
+ addon1.userDisabled = true;
+ await disabledPromise;
+
+ is(Services.search.currentEngine.name, defaultEngineName, `Default engine is ${defaultEngineName}`);
+
+ await ext2.startup();
+
+ is(Services.search.currentEngine.name, "Twitter", "Default engine is Twitter");
+
+ let enabledPromise = awaitEvent("ready", EXTENSION1_ID);
+ addon1.userDisabled = false;
+ await enabledPromise;
+
+ is(Services.search.currentEngine.name, "Twitter", "Default engine is Twitter");
+ await ext2.unload();
+
+ is(Services.search.currentEngine.name, "DuckDuckGo", "Default engine is DuckDuckGo");
+ await ext1.unload();
+
+ is(Services.search.currentEngine.name, defaultEngineName, `Default engine is ${defaultEngineName}`);
+});
+
+/* This tests that when two add-ons are installed that change default
+ * search and the first one is disabled, the second one maintains
+ * the search. */
+add_task(async function test_two_addons_with_first_disabled() {
+ let defaultEngineName = Services.search.currentEngine.name;
+ let ext1 = ExtensionTestUtils.loadExtension({
+ manifest: {
+ applications: {
+ gecko: {
+ id: EXTENSION1_ID,
+ },
+ },
+ "chrome_settings_overrides": {
+ "search_provider": {
+ "name": "DuckDuckGo",
+ "search_url": "https://example.com/?q={searchTerms}",
+ "is_default": true,
+ },
+ },
+ },
+ useAddonManager: "temporary",
+ });
+
+ let ext2 = ExtensionTestUtils.loadExtension({
+ manifest: {
+ applications: {
+ gecko: {
+ id: EXTENSION2_ID,
+ },
+ },
+ "chrome_settings_overrides": {
+ "search_provider": {
+ "name": "Twitter",
+ "search_url": "https://example.com/?q={searchTerms}",
+ "is_default": true,
+ },
+ },
+ },
+ useAddonManager: "temporary",
+ });
+
+ await ext1.startup();
+
+ is(Services.search.currentEngine.name, "DuckDuckGo", "Default engine is DuckDuckGo");
+
+ await ext2.startup();
+
+ is(Services.search.currentEngine.name, "Twitter", "Default engine is Twitter");
+
+ let disabledPromise = awaitEvent("shutdown", EXTENSION1_ID);
+ let addon1 = await AddonManager.getAddonByID(EXTENSION1_ID);
+ addon1.userDisabled = true;
+ await disabledPromise;
+
+ is(Services.search.currentEngine.name, "Twitter", "Default engine is Twitter");
+
+ let enabledPromise = awaitEvent("ready", EXTENSION1_ID);
+ addon1.userDisabled = false;
+ await enabledPromise;
+
+ is(Services.search.currentEngine.name, "Twitter", "Default engine is Twitter");
+ await ext2.unload();
+
+ is(Services.search.currentEngine.name, "DuckDuckGo", "Default engine is DuckDuckGo");
+ await ext1.unload();
+
+ is(Services.search.currentEngine.name, defaultEngineName, `Default engine is ${defaultEngineName}`);
+});
+
+/* This tests that when two add-ons are installed that change default
+ * search and the second one is disabled, the first one properly
+ * gets the search. */
+add_task(async function test_two_addons_with_second_disabled() {
+ let defaultEngineName = Services.search.currentEngine.name;
+ let ext1 = ExtensionTestUtils.loadExtension({
+ manifest: {
+ applications: {
+ gecko: {
+ id: EXTENSION1_ID,
+ },
+ },
+ "chrome_settings_overrides": {
+ "search_provider": {
+ "name": "DuckDuckGo",
+ "search_url": "https://example.com/?q={searchTerms}",
+ "is_default": true,
+ },
+ },
+ },
+ useAddonManager: "temporary",
+ });
+
+ let ext2 = ExtensionTestUtils.loadExtension({
+ manifest: {
+ applications: {
+ gecko: {
+ id: EXTENSION2_ID,
+ },
+ },
+ "chrome_settings_overrides": {
+ "search_provider": {
+ "name": "Twitter",
+ "search_url": "https://example.com/?q={searchTerms}",
+ "is_default": true,
+ },
+ },
+ },
+ useAddonManager: "temporary",
+ });
+
+ await ext1.startup();
+
+ is(Services.search.currentEngine.name, "DuckDuckGo", "Default engine is DuckDuckGo");
+
+ await ext2.startup();
+
+ is(Services.search.currentEngine.name, "Twitter", "Default engine is Twitter");
+
+ let disabledPromise = awaitEvent("shutdown", EXTENSION2_ID);
+ let addon2 = await AddonManager.getAddonByID(EXTENSION2_ID);
+ addon2.userDisabled = true;
+ await disabledPromise;
+
+ is(Services.search.currentEngine.name, "DuckDuckGo", "Default engine is DuckDuckGo");
+
+ let enabledPromise = awaitEvent("ready", EXTENSION2_ID);
+ addon2.userDisabled = false;
+ await enabledPromise;
+
+ is(Services.search.currentEngine.name, "Twitter", "Default engine is Twitter");
+ await ext2.unload();
+
+ is(Services.search.currentEngine.name, "DuckDuckGo", "Default engine is DuckDuckGo");
+ await ext1.unload();
+
+ is(Services.search.currentEngine.name, defaultEngineName, `Default engine is ${defaultEngineName}`);
+});