diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-19 01:13:27 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-19 01:13:27 +0000 |
commit | 40a355a42d4a9444dc753c04c6608dade2f06a23 (patch) | |
tree | 871fc667d2de662f171103ce5ec067014ef85e61 /toolkit/components/search/tests | |
parent | Adding upstream version 124.0.1. (diff) | |
download | firefox-40a355a42d4a9444dc753c04c6608dade2f06a23.tar.xz firefox-40a355a42d4a9444dc753c04c6608dade2f06a23.zip |
Adding upstream version 125.0.1.upstream/125.0.1
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'toolkit/components/search/tests')
38 files changed, 2412 insertions, 345 deletions
diff --git a/toolkit/components/search/tests/SearchTestUtils.sys.mjs b/toolkit/components/search/tests/SearchTestUtils.sys.mjs index 8922070154..c3577d2887 100644 --- a/toolkit/components/search/tests/SearchTestUtils.sys.mjs +++ b/toolkit/components/search/tests/SearchTestUtils.sys.mjs @@ -429,6 +429,8 @@ export var SearchTestUtils = { * * @param {object} [options] * The options for the manifest. + * @param {object} [options.icons] + * The icons to use for the WebExtension. * @param {string} [options.id] * The id to use for the WebExtension. * @param {string} [options.name] @@ -478,6 +480,10 @@ export var SearchTestUtils = { }, }; + if (options.icons) { + manifest.icons = options.icons; + } + if (options.default_locale) { manifest.default_locale = options.default_locale; } @@ -541,11 +547,11 @@ export var SearchTestUtils = { QueryInterface: ChromeUtils.generateQI(["nsIUserIdleService"]), idleTime: 19999, - addIdleObserver(observer, time) { + addIdleObserver(observer) { this._observers.add(observer); }, - removeIdleObserver(observer, time) { + removeIdleObserver(observer) { this._observers.delete(observer); }, }, diff --git a/toolkit/components/search/tests/xpcshell/data/search-config-v2-no-order-hint.json b/toolkit/components/search/tests/xpcshell/data/search-config-v2-no-order-hint.json new file mode 100644 index 0000000000..6371a328f3 --- /dev/null +++ b/toolkit/components/search/tests/xpcshell/data/search-config-v2-no-order-hint.json @@ -0,0 +1,207 @@ +{ + "data": [ + { + "recordType": "engine", + "identifier": "engine", + "base": { + "name": "Test search engine", + "urls": { + "search": { + "base": "https://www.google.com/search", + "params": [ + { + "name": "channel", + "searchAccessPoint": { + "addressbar": "fflb", + "contextmenu": "rcs" + } + } + ], + "searchTermParamName": "q" + }, + "suggestions": { + "base": "https://suggestqueries.google.com/complete/search?output=firefox&client=firefox&hl={moz:locale}", + "searchTermParamName": "q" + } + } + }, + "variants": [ + { + "environment": { "excludedLocales": ["gd"] } + } + ] + }, + { + "recordType": "engine", + "identifier": "engine-rel-searchform-purpose", + "base": { + "name": "engine-rel-searchform-purpose", + "urls": { + "search": { + "base": "https://www.google.com/search", + "params": [ + { + "name": "channel", + "searchAccessPoint": { + "addressbar": "fflb", + "contextmenu": "rcs", + "searchbar": "sb" + } + } + ], + "searchTermParamName": "q" + } + } + }, + "variants": [ + { + "environment": { "excludedLocales": ["de", "fr"] } + } + ] + }, + { + "recordType": "engine", + "identifier": "engine-chromeicon", + "base": { + "name": "engine-chromeicon", + "urls": { + "search": { + "base": "https://www.google.com/search", + "searchTermParamName": "q" + } + } + }, + "variants": [ + { + "environment": { "excludedLocales": ["de", "fr"] } + }, + { + "environment": { "regions": ["ru"] } + } + ] + }, + { + "recordType": "engine", + "identifier": "engine-resourceicon", + "base": { + "name": "engine-resourceicon", + "urls": { + "search": { + "base": "https://www.google.com/search", + "searchTermParamName": "q" + } + } + }, + "variants": [ + { + "environment": { + "excludedRegions": ["ru"], + "locales": ["en-US", "fr"] + } + } + ] + }, + { + "recordType": "engine", + "identifier": "engine-resourceicon-gd", + "base": { + "name": "engine-resourceicon-gd", + "urls": { + "search": { + "base": "https://www.google.com/search", + "searchTermParamName": "q" + } + } + }, + "variants": [ + { + "environment": { + "locales": ["gd"] + } + } + ] + }, + { + "recordType": "engine", + "identifier": "engine-reordered", + "base": { + "name": "Test search engine (Reordered)", + "urls": { + "search": { + "base": "https://www.google.com/search", + "params": [ + { + "name": "channel", + "searchAccessPoint": { + "addressbar": "fflb", + "contextmenu": "rcs" + } + } + ], + "searchTermParamName": "q" + }, + "suggestions": { + "base": "https://suggestqueries.google.com/complete/search?output=firefox&client=firefox&hl={moz:locale}", + "searchTermParamName": "q" + } + } + }, + "variants": [ + { + "environment": { "excludedLocales": ["de", "fr"] } + } + ] + }, + { + "recordType": "engine", + "identifier": "engine-pref", + "base": { + "name": "engine-pref", + "urls": { + "search": { + "base": "https://www.google.com/search", + "params": [ + { + "name": "code", + "experimentConfig": "code" + }, + { + "name": "test", + "experimentConfig": "test" + } + ], + "searchTermParamName": "q" + } + } + }, + "variants": [ + { + "environment": { "excludedLocales": ["de"] } + } + ] + }, + { + "recordType": "defaultEngines", + "globalDefault": "engine", + "specificDefaults": [ + { + "defaultPrivate": "engine-pref", + "environment": { "excludedLocales": ["de"] } + }, + { + "default": "engine-resourceicon-gd", + "environment": { "locales": ["gd"] } + } + ] + }, + { + "recordType": "engineOrders", + "orders": [ + { + "environment": { "allRegionsAndLocales": true }, + "order": ["engine-chromeicon", "engine-rel-searchform-purpose"] + } + ] + } + ] +} diff --git a/toolkit/components/search/tests/xpcshell/data/search-config-v2.json b/toolkit/components/search/tests/xpcshell/data/search-config-v2.json new file mode 100644 index 0000000000..569e16dfe4 --- /dev/null +++ b/toolkit/components/search/tests/xpcshell/data/search-config-v2.json @@ -0,0 +1,223 @@ +{ + "data": [ + { + "recordType": "engine", + "identifier": "engine", + "base": { + "name": "Test search engine", + "urls": { + "search": { + "base": "https://www.google.com/search", + "params": [ + { + "name": "channel", + "searchAccessPoint": { + "addressbar": "fflb", + "contextmenu": "rcs" + } + } + ], + "searchTermParamName": "q" + }, + "suggestions": { + "base": "https://suggestqueries.google.com/complete/search?output=firefox&client=firefox&hl={moz:locale}", + "searchTermParamName": "q" + } + } + }, + "variants": [ + { + "environment": { "excludedLocales": ["gd"] } + } + ] + }, + { + "recordType": "engine", + "identifier": "engine-pref", + "base": { + "name": "engine-pref", + "urls": { + "search": { + "base": "https://www.google.com/search", + "params": [ + { + "name": "code", + "experimentConfig": "code" + }, + { + "name": "test", + "experimentConfig": "test" + } + ], + "searchTermParamName": "q" + } + } + }, + "variants": [ + { + "environment": { "excludedLocales": ["de"] } + } + ] + }, + { + "recordType": "engine", + "identifier": "engine-rel-searchform-purpose", + "base": { + "name": "engine-rel-searchform-purpose", + "urls": { + "search": { + "base": "https://www.google.com/search", + "params": [ + { + "name": "channel", + "searchAccessPoint": { + "addressbar": "fflb", + "contextmenu": "rcs", + "searchbar": "sb" + } + } + ], + "searchTermParamName": "q" + } + } + }, + "variants": [ + { + "environment": { "excludedLocales": ["de", "fr"] } + } + ] + }, + { + "recordType": "engine", + "identifier": "engine-chromeicon", + "base": { + "name": "engine-chromeicon", + "urls": { + "search": { + "base": "https://www.google.com/search", + "searchTermParamName": "q" + } + } + }, + "variants": [ + { + "environment": { "excludedLocales": ["de", "fr"] } + }, + { + "environment": { "regions": ["ru"] } + } + ] + }, + { + "recordType": "engine", + "identifier": "engine-resourceicon", + "base": { + "name": "engine-resourceicon", + "urls": { + "search": { + "base": "https://www.google.com/search", + "searchTermParamName": "q" + } + } + }, + "variants": [ + { + "environment": { + "excludedRegions": ["ru"], + "locales": ["en-US", "fr"] + } + } + ] + }, + { + "recordType": "engine", + "identifier": "engine-resourceicon-gd", + "base": { + "name": "engine-resourceicon-gd", + "urls": { + "search": { + "base": "https://www.google.com/search", + "searchTermParamName": "q" + } + } + }, + "variants": [ + { + "environment": { "locales": ["gd"] } + } + ] + }, + { + "recordType": "engine", + "identifier": "engine-reordered", + "base": { + "name": "Test search engine (Reordered)", + "urls": { + "search": { + "base": "https://www.google.com/search", + "params": [ + { + "name": "channel", + "searchAccessPoint": { + "addressbar": "fflb", + "contextmenu": "rcs" + } + } + ], + "searchTermParamName": "q" + }, + "suggestions": { + "base": "https://suggestqueries.google.com/complete/search?output=firefox&client=firefox&hl={moz:locale}", + "searchTermParamName": "q" + } + } + }, + "variants": [ + { + "environment": { "excludedLocales": ["de", "fr"] } + } + ] + }, + { + "recordType": "defaultEngines", + "globalDefault": "engine", + "specificDefaults": [ + { + "defaultPrivate": "engine-pref", + "environment": { "excludedLocales": ["de"] } + }, + { + "default": "engine-resourceicon-gd", + "environment": { "locales": ["gd"] } + } + ] + }, + { + "recordType": "engineOrders", + "orders": [ + { + "environment": { "allRegionsAndLocales": true }, + "order": [ + "engine", + "engine-resourceicon", + "engine-chromeicon", + "engine-pref", + "engine-rel-searchform-purpose", + "engine-reordered" + ] + }, + { + "environment": { "locales": ["gd"] }, + "order": [ + "engine", + "engine-rel-searchform-purpose", + "engine-resourceicon", + "engine-chromeicon", + "engine-pref", + "engine-reordered" + ] + } + ] + } + ] +} diff --git a/toolkit/components/search/tests/xpcshell/method-extensions/search-config-v2.json b/toolkit/components/search/tests/xpcshell/method-extensions/search-config-v2.json new file mode 100644 index 0000000000..a8d3fcc515 --- /dev/null +++ b/toolkit/components/search/tests/xpcshell/method-extensions/search-config-v2.json @@ -0,0 +1,83 @@ +{ + "data": [ + { + "recordType": "engine", + "identifier": "get", + "base": { + "name": "Get Engine", + "urls": { + "search": { + "base": "https://example.com", + "params": [ + { + "name": "config", + "value": "1" + } + ], + "searchTermParamName": "search" + }, + "suggestions": { + "base": "https://example.com", + "params": [ + { + "name": "config", + "value": "1" + } + ], + "searchTermParamName": "suggest" + } + } + }, + "variants": [ + { + "environment": { "allRegionsAndLocales": true } + } + ] + }, + { + "recordType": "engine", + "identifier": "post", + "base": { + "name": "Post Engine", + "urls": { + "search": { + "base": "https://example.com", + "method": "POST", + "params": [ + { + "name": "config", + "value": "1" + } + ], + "searchTermParamName": "search" + }, + "suggestions": { + "base": "https://example.com", + "method": "POST", + "params": [ + { + "name": "config", + "value": "1" + } + ], + "searchTermParamName": "suggest" + } + } + }, + "variants": [ + { + "environment": { "allRegionsAndLocales": true } + } + ] + }, + { + "recordType": "defaultEngines", + "globalDefault": "get", + "specificDefaults": [] + }, + { + "recordType": "engineOrders", + "orders": [] + } + ] +} diff --git a/toolkit/components/search/tests/xpcshell/searchconfigs/test_searchconfig_ui_schemas_valid.js b/toolkit/components/search/tests/xpcshell/searchconfigs/test_searchconfig_ui_schemas_valid.js new file mode 100644 index 0000000000..3315bf974f --- /dev/null +++ b/toolkit/components/search/tests/xpcshell/searchconfigs/test_searchconfig_ui_schemas_valid.js @@ -0,0 +1,36 @@ +/* Any copyright is dedicated to the Public Domain. + http://creativecommons.org/publicdomain/zero/1.0/ */ + +"use strict"; + +let schemas = [ + ["search-config-schema.json", "search-config-ui-schema.json"], + ["search-config-v2-schema.json", "search-config-v2-ui-schema.json"], + ["search-config-icons-schema.json", "search-config-icons-ui-schema.json"], + [ + "search-config-overrides-schema.json", + "search-config-overrides-ui-schema.json", + ], + [ + "search-config-overrides-v2-schema.json", + "search-config-overrides-v2-ui-schema.json", + ], + [ + "search-default-override-allowlist-schema.json", + "search-default-override-allowlist-ui-schema.json", + ], +]; + +add_task(async function test_ui_schemas_valid() { + for (let [schema, uiSchema] of schemas) { + info(`Validating ${uiSchema} has every top-level from ${schema}`); + let schemaData = await IOUtils.readJSON( + PathUtils.join(do_get_cwd().path, schema) + ); + let uiSchemaData = await IOUtils.readJSON( + PathUtils.join(do_get_cwd().path, uiSchema) + ); + + await checkUISchemaValid(schemaData, uiSchemaData); + } +}); diff --git a/toolkit/components/search/tests/xpcshell/searchconfigs/test_searchconfig_validates.js b/toolkit/components/search/tests/xpcshell/searchconfigs/test_searchconfig_validates.js index 51e71ff573..86686b62f7 100644 --- a/toolkit/components/search/tests/xpcshell/searchconfigs/test_searchconfig_validates.js +++ b/toolkit/components/search/tests/xpcshell/searchconfigs/test_searchconfig_validates.js @@ -65,103 +65,79 @@ function disallowAdditionalProperties(section) { } } -let searchConfigSchemaV1; -let searchConfigSchema; - -add_setup(async function () { - searchConfigSchemaV1 = await IOUtils.readJSON( - PathUtils.join(do_get_cwd().path, "search-config-schema.json") - ); - searchConfigSchema = await IOUtils.readJSON( - PathUtils.join(do_get_cwd().path, "search-config-v2-schema.json") +/** + * Asserts the remote setting collection validates against the schema. + * + * @param {object} options + * The options for the assertion. + * @param {string} options.collectionName + * The name of the collection under validation. + * @param {object[]} options.collectionData + * The collection data to validate. + * @param {string[]} [options.ignoreFields=[]] + * A list of fields to ignore in the collection data, e.g. where remote + * settings itself adds extra fields. `schema`, `id`, and `last_modified` are + * always ignored. + * @param {Function} [options.extraAssertsFn] + * An optional function to run additional assertions on each entry in the + * collection. + * @param {Function} options.getEntryId + * A function to get the identifier for each entry in the collection. + */ +async function assertSearchConfigValidates({ + collectionName, + collectionData, + ignoreFields = [], + extraAssertsFn, + getEntryId, +}) { + let schema = await IOUtils.readJSON( + PathUtils.join(do_get_cwd().path, `${collectionName}-schema.json`) ); -}); -async function checkSearchConfigValidates(schema, searchConfig) { disallowAdditionalProperties(schema); let validator = new JsonSchema.Validator(schema); - for (let entry of searchConfig) { + for (let entry of collectionData) { // Records in Remote Settings contain additional properties independent of // the schema. Hence, we don't want to validate their presence. - delete entry.schema; - delete entry.id; - delete entry.last_modified; + for (let field of [...ignoreFields, "schema", "id", "last_modified"]) { + delete entry[field]; + } let result = validator.validate(entry); - // entry.webExtension.id supports search-config v1. - let message = `Should validate ${ - entry.identifier ?? entry.recordType ?? entry.webExtension.id - }`; + let message = `Should validate ${getEntryId(entry)}`; if (!result.valid) { message += `:\n${JSON.stringify(result.errors, null, 2)}`; } Assert.ok(result.valid, message); - // All engine objects should have the base URL defined for each entry in - // entry.base.urls. - // Unfortunately this is difficult to enforce in the schema as it would - // need a `required` field that works across multiple levels. - if (entry.recordType == "engine") { - for (let urlEntry of Object.values(entry.base.urls)) { - Assert.ok( - urlEntry.base, - "Should have a base url for every URL defined on the top-level base object." - ); - } - } + extraAssertsFn?.(entry); } } -async function checkSearchConfigOverrideValidates( - schema, - searchConfigOverride -) { - let validator = new JsonSchema.Validator(schema); - - for (let entry of searchConfigOverride) { - // Records in Remote Settings contain additional properties independent of - // the schema. Hence, we don't want to validate their presence. - delete entry.schema; - delete entry.id; - delete entry.last_modified; - - let result = validator.validate(entry); - - let message = `Should validate ${entry.identifier ?? entry.telemetryId}`; - if (!result.valid) { - message += `:\n${JSON.stringify(result.errors, null, 2)}`; - } - Assert.ok(result.valid, message); - } -} +add_setup(async function () { + updateAppInfo({ ID: "{ec8030f7-c20a-464f-9b0e-13a3a9e97384}" }); +}); add_task(async function test_search_config_validates_to_schema_v1() { let selector = new SearchEngineSelectorOld(() => {}); - let searchConfig = await selector.getEngineConfiguration(); - await checkSearchConfigValidates(searchConfigSchemaV1, searchConfig); -}); - -add_task(async function test_ui_schema_valid_v1() { - let uiSchema = await IOUtils.readJSON( - PathUtils.join(do_get_cwd().path, "search-config-ui-schema.json") - ); - - await checkUISchemaValid(searchConfigSchemaV1, uiSchema); + await assertSearchConfigValidates({ + collectionName: "search-config", + collectionData: await selector.getEngineConfiguration(), + getEntryId: entry => entry.webExtension.id, + }); }); add_task(async function test_search_config_override_validates_to_schema_v1() { let selector = new SearchEngineSelectorOld(() => {}); - let searchConfigOverrides = await selector.getEngineConfigurationOverrides(); - let overrideSchema = await IOUtils.readJSON( - PathUtils.join(do_get_cwd().path, "search-config-overrides-schema.json") - ); - await checkSearchConfigOverrideValidates( - overrideSchema, - searchConfigOverrides - ); + await assertSearchConfigValidates({ + collectionName: "search-config-overrides", + collectionData: await selector.getEngineConfigurationOverrides(), + getEntryId: entry => entry.telemetryId, + }); }); add_task( @@ -171,20 +147,26 @@ add_task( SearchUtils.newSearchConfigEnabled = true; let selector = new SearchEngineSelector(() => {}); - let searchConfig = await selector.getEngineConfiguration(); - - await checkSearchConfigValidates(searchConfigSchema, searchConfig); - } -); - -add_task( - { skip_if: () => !SearchUtils.newSearchConfigEnabled }, - async function test_ui_schema_valid() { - let uiSchema = await IOUtils.readJSON( - PathUtils.join(do_get_cwd().path, "search-config-v2-ui-schema.json") - ); - await checkUISchemaValid(searchConfigSchema, uiSchema); + await assertSearchConfigValidates({ + collectionName: "search-config-v2", + collectionData: await selector.getEngineConfiguration(), + getEntryId: entry => entry.identifier, + extraAssertsFn: entry => { + // All engine objects should have the base URL defined for each entry in + // entry.base.urls. + // Unfortunately this is difficult to enforce in the schema as it would + // need a `required` field that works across multiple levels. + if (entry.recordType == "engine") { + for (let urlEntry of Object.values(entry.base.urls)) { + Assert.ok( + urlEntry.base, + "Should have a base url for every URL defined on the top-level base object." + ); + } + } + }, + }); } ); @@ -192,18 +174,33 @@ add_task( { skip_if: () => !SearchUtils.newSearchConfigEnabled }, async function test_search_config_override_validates_to_schema() { let selector = new SearchEngineSelector(() => {}); - let searchConfigOverrides = - await selector.getEngineConfigurationOverrides(); - let overrideSchema = await IOUtils.readJSON( - PathUtils.join( - do_get_cwd().path, - "search-config-overrides-v2-schema.json" - ) - ); - - await checkSearchConfigOverrideValidates( - overrideSchema, - searchConfigOverrides - ); + + await assertSearchConfigValidates({ + collectionName: "search-config-overrides-v2", + collectionData: await selector.getEngineConfigurationOverrides(), + getEntryId: entry => entry.identifier, + }); } ); + +add_task(async function test_search_config_icons_validates_to_schema() { + let searchIcons = RemoteSettings("search-config-icons"); + + await assertSearchConfigValidates({ + collectionName: "search-config-icons", + collectionData: await searchIcons.get(), + ignoreFields: ["attachment"], + getEntryId: entry => entry.engineIdentifiers[0], + }); +}); + +add_task(async function test_search_default_override_allowlist_validates() { + let allowlist = RemoteSettings("search-default-override-allowlist"); + + await assertSearchConfigValidates({ + collectionName: "search-default-override-allowlist", + collectionData: await allowlist.get(), + ignoreFields: ["attachment"], + getEntryId: entry => entry.engineName || entry.thirdPartyId, + }); +}); diff --git a/toolkit/components/search/tests/xpcshell/searchconfigs/test_searchicons_validates.js b/toolkit/components/search/tests/xpcshell/searchconfigs/test_searchicons_validates.js deleted file mode 100644 index c830bb7ade..0000000000 --- a/toolkit/components/search/tests/xpcshell/searchconfigs/test_searchicons_validates.js +++ /dev/null @@ -1,20 +0,0 @@ -/* Any copyright is dedicated to the Public Domain. - http://creativecommons.org/publicdomain/zero/1.0/ */ - -"use strict"; - -let searchIconsSchema; - -add_setup(async function () { - searchIconsSchema = await IOUtils.readJSON( - PathUtils.join(do_get_cwd().path, "search-config-icons-schema.json") - ); -}); - -add_task(async function test_ui_schema_valid() { - let uiSchema = await IOUtils.readJSON( - PathUtils.join(do_get_cwd().path, "search-config-icons-ui-schema.json") - ); - - await checkUISchemaValid(searchIconsSchema, uiSchema); -}); diff --git a/toolkit/components/search/tests/xpcshell/searchconfigs/xpcshell.toml b/toolkit/components/search/tests/xpcshell/searchconfigs/xpcshell.toml index 8baff2a38d..07567005d6 100644 --- a/toolkit/components/search/tests/xpcshell/searchconfigs/xpcshell.toml +++ b/toolkit/components/search/tests/xpcshell/searchconfigs/xpcshell.toml @@ -40,20 +40,30 @@ requesttimeoutfactor = 2 ["test_rakuten.js"] -["test_searchconfig_validates.js"] +["test_searchconfig_ui_schemas_valid.js"] support-files = [ + "../../../schema/search-config-icons-schema.json", + "../../../schema/search-config-icons-ui-schema.json", "../../../schema/search-config-overrides-schema.json", + "../../../schema/search-config-overrides-ui-schema.json", "../../../schema/search-config-overrides-v2-schema.json", + "../../../schema/search-config-overrides-v2-ui-schema.json", "../../../schema/search-config-schema.json", "../../../schema/search-config-ui-schema.json", "../../../schema/search-config-v2-schema.json", "../../../schema/search-config-v2-ui-schema.json", + "../../../schema/search-default-override-allowlist-schema.json", + "../../../schema/search-default-override-allowlist-ui-schema.json", ] -["test_searchicons_validates.js"] +["test_searchconfig_validates.js"] support-files = [ "../../../schema/search-config-icons-schema.json", - "../../../schema/search-config-icons-ui-schema.json", + "../../../schema/search-config-overrides-schema.json", + "../../../schema/search-config-overrides-v2-schema.json", + "../../../schema/search-config-schema.json", + "../../../schema/search-config-v2-schema.json", + "../../../schema/search-default-override-allowlist-schema.json", ] ["test_selector_db_out_of_date.js"] diff --git a/toolkit/components/search/tests/xpcshell/test-extensions/search-config-v2.json b/toolkit/components/search/tests/xpcshell/test-extensions/search-config-v2.json new file mode 100644 index 0000000000..4f2e88a05b --- /dev/null +++ b/toolkit/components/search/tests/xpcshell/test-extensions/search-config-v2.json @@ -0,0 +1,139 @@ +{ + "data": [ + { + "recordType": "engine", + "identifier": "plainengine", + "base": { + "name": "Plain", + "urls": { + "search": { + "base": "https://duckduckgo.com/", + "params": [ + { + "name": "t", + "searchAccessPoint": { + "newtab": "ffnt", + "homepage": "ffhp", + "searchbar": "ffsb", + "addressbar": "ffab", + "contextmenu": "ffcm" + } + } + ], + "searchTermParamName": "q" + }, + "suggestions": { + "base": "https://ac.duckduckgo.com/ac/q={searchTerms}&type=list" + } + } + }, + "variants": [ + { + "environment": { "allRegionsAndLocales": true } + } + ] + }, + { + "recordType": "engine", + "identifier": "special-engine", + "base": { + "name": "Special", + "urls": { + "search": { + "base": "https://www.google.com/search", + "params": [ + { + "name": "client", + "searchAccessPoint": { + "searchbar": "firefox-b-1", + "addressbar": "firefox-b-1-ab" + } + } + ], + "searchTermParamName": "q" + }, + "suggestions": { + "base": "https://www.google.com/complete/search?client=firefox&q={searchTerms}" + } + } + }, + "variants": [ + { + "environment": { "allRegionsAndLocales": true } + } + ] + }, + { + "recordType": "engine", + "identifier": "multilocale-an", + "base": { + "name": "Multilocale AN", + "urls": { + "search": { + "base": "https://an.wikipedia.org/wiki/Especial:Mirar", + "searchTermParamName": "q" + }, + "suggestions": { + "base": "https://an.wikipedia.org/w/api.php", + "searchTermParamName": "q" + } + } + }, + "variants": [ + { + "environment": { "regions": ["an"] } + } + ] + }, + { + "recordType": "engine", + "identifier": "multilocale-af", + "base": { + "name": "Multilocale AF", + "urls": { + "search": { + "base": "https://af.wikipedia.org/wiki/Spesiaal:Soek", + "searchTermParamName": "q" + }, + "suggestions": { + "base": "https://af.wikipedia.org/w/api.php", + "searchTermParamName": "q" + } + } + }, + "variants": [ + { + "environment": { "regions": ["af"] } + } + ] + }, + { + "recordType": "defaultEngines", + "globalDefault": "plainengine", + "specificDefaults": [ + { + "default": "special-engine", + "environment": { "regions": ["tr"] } + }, + { + "default": "multilocale-an", + "environment": { "regions": ["an"] } + } + ] + }, + { + "recordType": "engineOrders", + "orders": [ + { + "order": [ + "plainengine", + "special-engine", + "multilocale-af", + "multilocale-an" + ], + "environment": { "allRegionsAndLocales": true } + } + ] + } + ] +} diff --git a/toolkit/components/search/tests/xpcshell/test_appProvided_icons.js b/toolkit/components/search/tests/xpcshell/test_appProvided_icons.js new file mode 100644 index 0000000000..e4d8033993 --- /dev/null +++ b/toolkit/components/search/tests/xpcshell/test_appProvided_icons.js @@ -0,0 +1,211 @@ +/* Any copyright is dedicated to the Public Domain. + http://creativecommons.org/publicdomain/zero/1.0/ */ + +/** + * Tests to ensure that icons for application provided engines are correctly + * loaded from remote settings. + */ + +"use strict"; + +// A skeleton configuration that gets filled in from TESTS during `add_setup`. +let CONFIG = [ + { + recordType: "defaultEngines", + globalDefault: "engine_no_icon", + specificDefaults: [], + }, + { + recordType: "engineOrders", + orders: [], + }, +]; + +let TESTS = [ + { + engineId: "engine_no_icon", + expectedIcon: null, + }, + { + engineId: "engine_exact_match", + icons: [ + { + filename: "remoteIcon.ico", + engineIdentifiers: ["engine_exact_match"], + imageSize: 16, + }, + ], + expectedIcon: "remoteIcon.ico", + }, + { + engineId: "engine_begins_with", + icons: [ + { + filename: "remoteIcon.ico", + engineIdentifiers: ["engine_begins*"], + imageSize: 16, + }, + ], + expectedIcon: "remoteIcon.ico", + }, + { + engineId: "engine_non_default_sized_icon", + icons: [ + { + filename: "remoteIcon.ico", + engineIdentifiers: ["engine_non_default_sized_icon"], + imageSize: 32, + }, + ], + expectedIcon: "remoteIcon.ico", + }, + { + engineId: "engine_multiple_icons", + icons: [ + { + filename: "bigIcon.ico", + engineIdentifiers: ["engine_multiple_icons"], + imageSize: 16, + }, + { + filename: "remoteIcon.ico", + engineIdentifiers: ["engine_multiple_icons"], + imageSize: 32, + }, + ], + expectedIcon: "bigIcon.ico", + }, +]; + +async function getFileDataBuffer(filename) { + let data = await IOUtils.read( + PathUtils.join(do_get_cwd().path, "data", filename) + ); + return new TextEncoder().encode(data).buffer; +} + +async function mockRecordWithAttachment({ + filename, + engineIdentifiers, + imageSize, +}) { + let buffer = await getFileDataBuffer(filename); + + let stream = Cc["@mozilla.org/io/arraybuffer-input-stream;1"].createInstance( + Ci.nsIArrayBufferInputStream + ); + stream.setData(buffer, 0, buffer.byteLength); + + // Generate a hash. + let hasher = Cc["@mozilla.org/security/hash;1"].createInstance( + Ci.nsICryptoHash + ); + hasher.init(Ci.nsICryptoHash.SHA256); + hasher.updateFromStream(stream, -1); + let hash = hasher.finish(false); + hash = Array.from(hash, (_, i) => + ("0" + hash.charCodeAt(i).toString(16)).slice(-2) + ).join(""); + + let record = { + id: Services.uuid.generateUUID().toString(), + engineIdentifiers, + imageSize, + attachment: { + hash, + location: `main-workspace/search-config-icons/${filename}`, + filename, + size: buffer.byteLength, + mimetype: "application/json", + }, + }; + + let attachment = { + record, + blob: new Blob([buffer]), + }; + + return { record, attachment }; +} + +async function insertRecordIntoCollection(client, db, item) { + let { record, attachment } = await mockRecordWithAttachment(item); + await db.create(record); + await client.attachments.cacheImpl.set(record.id, attachment); + await db.importChanges({}, Date.now()); +} + +add_setup(async function () { + let client = RemoteSettings("search-config-icons"); + let db = client.db; + + await db.clear(); + + for (let test of TESTS) { + CONFIG.push({ + identifier: test.engineId, + recordType: "engine", + base: { + name: test.engineId + " name", + urls: { + search: { + base: "https://example.com/" + test.engineId, + searchTermParamName: "q", + }, + }, + }, + variants: [{ environment: { allRegionsAndLocales: true } }], + }); + + if ("icons" in test) { + for (let icon of test.icons) { + await insertRecordIntoCollection(client, db, { + ...icon, + id: test.engineId, + }); + } + } + } + + await SearchTestUtils.useTestEngines("simple-engines", null, CONFIG); + await Services.search.init(); +}); + +for (let test of TESTS) { + add_task(async function () { + info("Testing engine: " + test.engineId); + + let engine = Services.search.getEngineByName(test.engineId + " name"); + if (test.expectedIcon) { + let engineIconURL = await engine.getIconURL(16); + Assert.notEqual( + engineIconURL, + null, + "Should have an icon URL for the engine." + ); + + let response = await fetch(engineIconURL); + let buffer = new Uint8Array(await response.arrayBuffer()); + + let expectedBuffer = new Uint8Array( + await getFileDataBuffer(test.expectedIcon) + ); + + Assert.equal( + buffer.length, + expectedBuffer.length, + "Should have received matching buffer lengths for the expected icon" + ); + Assert.ok( + buffer.every((value, index) => value === expectedBuffer[index]), + "Should have received matching data for the expected icon" + ); + } else { + Assert.equal( + await engine.getIconURL(), + null, + "Should not have an icon URL for the engine." + ); + } + }); +} diff --git a/toolkit/components/search/tests/xpcshell/test_defaultPrivateEngine.js b/toolkit/components/search/tests/xpcshell/test_defaultPrivateEngine.js index 053d91fe48..392700d84a 100644 --- a/toolkit/components/search/tests/xpcshell/test_defaultPrivateEngine.js +++ b/toolkit/components/search/tests/xpcshell/test_defaultPrivateEngine.js @@ -108,7 +108,9 @@ add_task(async function test_defaultPrivateEngine() { loadPath: SearchUtils.newSearchConfigEnabled ? "[app]engine-rel-searchform-purpose@search.mozilla.org" : "[addon]engine-rel-searchform-purpose@search.mozilla.org", - submissionUrl: "https://www.google.com/search?q=&channel=sb", + submissionUrl: SearchUtils.newSearchConfigEnabled + ? "https://www.google.com/search?channel=sb&q=" + : "https://www.google.com/search?q=&channel=sb", verified: "default", }, }); diff --git a/toolkit/components/search/tests/xpcshell/test_engine_ids.js b/toolkit/components/search/tests/xpcshell/test_engine_ids.js index cef6a17c92..57b9ad26cf 100644 --- a/toolkit/components/search/tests/xpcshell/test_engine_ids.js +++ b/toolkit/components/search/tests/xpcshell/test_engine_ids.js @@ -47,9 +47,56 @@ const CONFIG = [ }, ]; +const CONFIG_V2 = [ + { + recordType: "engine", + identifier: "engine", + base: { + name: "Test search engine", + urls: { + search: { + base: "https://www.google.com/search", + params: [ + { + name: "channel", + searchAccessPoint: { + addressbar: "fflb", + contextmenu: "rcs", + }, + }, + ], + searchTermParamName: "q", + }, + suggestions: { + base: "https://suggestqueries.google.com/complete/search?output=firefox&client=firefox&hl={moz:locale}", + searchTermParamName: "q", + }, + }, + }, + variants: [ + { + environment: { allRegionsAndLocales: true }, + }, + ], + }, + { + recordType: "defaultEngines", + globalDefault: "engine", + specificDefaults: [], + }, + { + recordType: "engineOrders", + orders: [], + }, +]; + add_setup(async function () { useHttpServer("opensearch"); - await SearchTestUtils.useTestEngines("data", null, CONFIG); + await SearchTestUtils.useTestEngines( + "data", + null, + SearchUtils.newSearchConfigEnabled ? CONFIG_V2 : CONFIG + ); await AddonTestUtils.promiseStartupManager(); await Services.search.init(); }); diff --git a/toolkit/components/search/tests/xpcshell/test_engine_set_alias.js b/toolkit/components/search/tests/xpcshell/test_engine_set_alias.js index ec79fe6783..f15e257996 100644 --- a/toolkit/components/search/tests/xpcshell/test_engine_set_alias.js +++ b/toolkit/components/search/tests/xpcshell/test_engine_set_alias.js @@ -119,7 +119,7 @@ add_task(async function test_engine_change_alias() { ); let observed = false; - Services.obs.addObserver(function observer(aSubject, aTopic, aData) { + Services.obs.addObserver(function observer() { observed = true; }, SearchUtils.TOPIC_ENGINE_MODIFIED); diff --git a/toolkit/components/search/tests/xpcshell/test_getSubmission_params_pref.js b/toolkit/components/search/tests/xpcshell/test_getSubmission_params_pref.js index 5283207394..54fd028474 100644 --- a/toolkit/components/search/tests/xpcshell/test_getSubmission_params_pref.js +++ b/toolkit/components/search/tests/xpcshell/test_getSubmission_params_pref.js @@ -14,6 +14,7 @@ const defaultBranch = Services.prefs.getDefaultBranch( SearchUtils.BROWSER_SEARCH_PREF ); const baseURL = "https://www.google.com/search?q=foo"; +const baseURLSearchConfigV2 = "https://www.google.com/search?"; add_setup(async function () { // The test engines used in this test need to be recognized as 'default' @@ -40,7 +41,9 @@ add_task(async function test_pref_initial_value() { const engine = Services.search.getEngineByName("engine-pref"); Assert.equal( engine.getSubmission("foo").uri.spec, - baseURL + "&code=good%26id%3Dunique", + SearchUtils.newSearchConfigEnabled + ? baseURLSearchConfigV2 + "code=good%26id%3Dunique&q=foo" + : baseURL + "&code=good%26id%3Dunique", "Should have got the submission URL with the correct code" ); @@ -59,7 +62,9 @@ add_task(async function test_pref_updated() { const engine = Services.search.getEngineByName("engine-pref"); Assert.equal( engine.getSubmission("foo").uri.spec, - baseURL + "&code=supergood%26id%3Dunique123456", + SearchUtils.newSearchConfigEnabled + ? baseURLSearchConfigV2 + "code=supergood%26id%3Dunique123456&q=foo" + : baseURL + "&code=supergood%26id%3Dunique123456", "Should have got the submission URL with the updated code" ); }); diff --git a/toolkit/components/search/tests/xpcshell/test_getSubmission_params_prefNimbus.js b/toolkit/components/search/tests/xpcshell/test_getSubmission_params_prefNimbus.js index e9b55ff3dc..3963a07368 100644 --- a/toolkit/components/search/tests/xpcshell/test_getSubmission_params_prefNimbus.js +++ b/toolkit/components/search/tests/xpcshell/test_getSubmission_params_prefNimbus.js @@ -11,6 +11,7 @@ const { NimbusFeatures } = ChromeUtils.importESModule( ); const baseURL = "https://www.google.com/search?q=foo"; +const baseURLSearchConfigV2 = "https://www.google.com/search?"; let getVariableStub; let updateStub; @@ -48,7 +49,9 @@ add_task(async function test_pref_initial_value() { const engine = Services.search.getEngineByName("engine-pref"); Assert.equal( engine.getSubmission("foo").uri.spec, - baseURL + "&code=good%26id%3Dunique", + SearchUtils.newSearchConfigEnabled + ? baseURLSearchConfigV2 + "code=good%26id%3Dunique&q=foo" + : baseURL + "&code=good%26id%3Dunique", "Should have got the submission URL with the correct code" ); }); @@ -68,7 +71,9 @@ add_task(async function test_pref_updated() { const engine = Services.search.getEngineByName("engine-pref"); Assert.equal( engine.getSubmission("foo").uri.spec, - baseURL + "&code=supergood%26id%3Dunique123456", + SearchUtils.newSearchConfigEnabled + ? baseURLSearchConfigV2 + "code=supergood%26id%3Dunique123456&q=foo" + : baseURL + "&code=supergood%26id%3Dunique123456", "Should have got the submission URL with the updated code" ); }); @@ -90,7 +95,9 @@ add_task(async function test_multiple_params() { let engine = Services.search.getEngineByName("engine-pref"); Assert.equal( engine.getSubmission("foo").uri.spec, - baseURL + "&code=sng&test=sup", + SearchUtils.newSearchConfigEnabled + ? baseURLSearchConfigV2 + "code=sng&test=sup&q=foo" + : baseURL + "&code=sng&test=sup", "Should have got the submission URL with both parameters" ); @@ -107,7 +114,9 @@ add_task(async function test_multiple_params() { engine = Services.search.getEngineByName("engine-pref"); Assert.equal( engine.getSubmission("foo").uri.spec, - baseURL + "&code=sng", + SearchUtils.newSearchConfigEnabled + ? baseURLSearchConfigV2 + "code=sng&q=foo" + : baseURL + "&code=sng", "Should have got the submission URL with one parameter" ); }); diff --git a/toolkit/components/search/tests/xpcshell/test_getSubmission_params_prefNimbus_invalid.js b/toolkit/components/search/tests/xpcshell/test_getSubmission_params_prefNimbus_invalid.js index e519a74c64..090b108acf 100644 --- a/toolkit/components/search/tests/xpcshell/test_getSubmission_params_prefNimbus_invalid.js +++ b/toolkit/components/search/tests/xpcshell/test_getSubmission_params_prefNimbus_invalid.js @@ -15,6 +15,7 @@ const { NimbusFeatures } = ChromeUtils.importESModule( ); const baseURL = "https://www.google.com/search?q=foo"; +const baseURLSearchConfigV2 = "https://www.google.com/search?"; let getVariableStub; let updateStub; @@ -66,7 +67,9 @@ add_task(async function test_switch_to_good_nimbus_setting() { const engine = Services.search.getEngineByName("engine-pref"); Assert.equal( engine.getSubmission("foo").uri.spec, - baseURL + "&code=supergood%26id%3Dunique123456", + SearchUtils.newSearchConfigEnabled + ? baseURLSearchConfigV2 + "code=supergood%26id%3Dunique123456&q=foo" + : baseURL + "&code=supergood%26id%3Dunique123456", "Should have got the submission URL with the updated code" ); }); diff --git a/toolkit/components/search/tests/xpcshell/test_initialization.js b/toolkit/components/search/tests/xpcshell/test_initialization.js index c89f3cfcb3..57894e1e55 100644 --- a/toolkit/components/search/tests/xpcshell/test_initialization.js +++ b/toolkit/components/search/tests/xpcshell/test_initialization.js @@ -43,13 +43,60 @@ const CONFIG = [ }, ]; +const CONFIG_V2 = [ + { + recordType: "engine", + identifier: "engine", + base: { + name: "Test search engine", + urls: { + search: { + base: "https://www.google.com/search", + params: [ + { + name: "channel", + searchAccessPoint: { + addressbar: "fflb", + contextmenu: "rcs", + }, + }, + ], + searchTermParamName: "q", + }, + suggestions: { + base: "https://suggestqueries.google.com/complete/search?output=firefox&client=firefox&hl={moz:locale}", + searchTermParamName: "q", + }, + }, + }, + variants: [ + { + environment: { allRegionsAndLocales: true }, + }, + ], + }, + { + recordType: "defaultEngines", + globalDefault: "engine", + specificDefaults: [], + }, + { + recordType: "engineOrders", + orders: [], + }, +]; + add_setup(() => { do_get_profile(); Services.fog.initializeFOG(); }); add_task(async function test_initialization_delayed_addon_manager() { - let stub = await SearchTestUtils.useTestEngines("data", null, CONFIG); + let stub = await SearchTestUtils.useTestEngines( + "data", + null, + SearchUtils.newSearchConfigEnabled ? CONFIG_V2 : CONFIG + ); // Wait until the search service gets its configuration before starting // to initialise the add-on manager. This simulates the add-on manager // starting late which used to cause the search service to fail to load any @@ -58,7 +105,7 @@ add_task(async function test_initialization_delayed_addon_manager() { Services.tm.dispatchToMainThread(() => { AddonTestUtils.promiseStartupManager(); }); - return CONFIG; + return SearchUtils.newSearchConfigEnabled ? CONFIG_V2 : CONFIG; }); await Services.search.init(); diff --git a/toolkit/components/search/tests/xpcshell/test_initialization_with_region.js b/toolkit/components/search/tests/xpcshell/test_initialization_with_region.js index fb9cee5124..377772c6e1 100644 --- a/toolkit/components/search/tests/xpcshell/test_initialization_with_region.js +++ b/toolkit/components/search/tests/xpcshell/test_initialization_with_region.js @@ -76,6 +76,87 @@ const CONFIG = [ }, ]; +const CONFIG_V2 = [ + { + recordType: "engine", + identifier: "engine", + base: { + name: "Test search engine", + urls: { + search: { + base: "https://www.google.com/search", + params: [ + { + name: "channel", + searchAccessPoint: { + addressbar: "fflb", + contextmenu: "rcs", + }, + }, + ], + searchTermParamName: "q", + }, + suggestions: { + base: "https://suggestqueries.google.com/complete/search?output=firefox&client=firefox&hl={moz:locale}", + searchTermParamName: "q", + }, + }, + }, + variants: [ + { + environment: { excludedRegions: ["FR"] }, + }, + ], + }, + { + recordType: "engine", + identifier: "engine-pref", + base: { + name: "engine-pref", + urls: { + search: { + base: "https://www.google.com/search", + params: [ + { + name: "code", + experimentConfig: "code", + }, + { + name: "test", + experimentConfig: "test", + }, + ], + searchTermParamName: "q", + }, + }, + }, + variants: [ + { + environment: { allRegionsAndLocales: true }, + }, + ], + }, + { + recordType: "defaultEngines", + specificDefaults: [ + { + default: "engine", + defaultPrivate: "engine", + environment: { excludedRegions: ["FR"] }, + }, + { + default: "engine-pref", + defaultPrivate: "engine-pref", + environment: { regions: ["FR"] }, + }, + ], + }, + { + recordType: "engineOrders", + orders: [], + }, +]; + // Default engine with no region defined. const DEFAULT = "Test search engine"; // Default engine with region set to FR. @@ -104,7 +185,11 @@ add_setup(async function () { ); SearchTestUtils.useMockIdleService(); - await SearchTestUtils.useTestEngines("data", null, CONFIG); + await SearchTestUtils.useTestEngines( + "data", + null, + SearchUtils.newSearchConfigEnabled ? CONFIG_V2 : CONFIG + ); await AddonTestUtils.promiseStartupManager(); }); diff --git a/toolkit/components/search/tests/xpcshell/test_maybereloadengine_order.js b/toolkit/components/search/tests/xpcshell/test_maybereloadengine_order.js index 663b7205a7..bdb8510812 100644 --- a/toolkit/components/search/tests/xpcshell/test_maybereloadengine_order.js +++ b/toolkit/components/search/tests/xpcshell/test_maybereloadengine_order.js @@ -1,56 +1,14 @@ /* Any copyright is dedicated to the Public Domain. http://creativecommons.org/publicdomain/zero/1.0/ */ -"use strict"; +/* + * Test engine order is not set after engine reload. + */ -const TEST_CONFIG = [ - { - webExtension: { - id: "plainengine@search.mozilla.org", - name: "Plain", - search_url: "https://duckduckgo.com/", - params: [ - { - name: "q", - value: "{searchTerms}", - }, - ], - suggest_url: "https://ac.duckduckgo.com/ac/q={searchTerms}&type=list", - }, - appliesTo: [{ included: { everywhere: true } }], - }, - { - webExtension: { - id: "special-engine@search.mozilla.org", - name: "Special", - search_url: "https://www.google.com/search", - params: [ - { - name: "q", - value: "{searchTerms}", - }, - { - name: "client", - condition: "purpose", - purpose: "keyword", - value: "firefox-b-1-ab", - }, - { - name: "client", - condition: "purpose", - purpose: "searchbar", - value: "firefox-b-1", - }, - ], - suggest_url: - "https://www.google.com/complete/search?client=firefox&q={searchTerms}", - }, - appliesTo: [{ default: "yes", included: { regions: ["FR"] } }], - }, -]; +"use strict"; add_setup(async function () { - await SearchTestUtils.useTestEngines("test-extensions", null, TEST_CONFIG); + await SearchTestUtils.useTestEngines("test-extensions"); await AddonTestUtils.promiseStartupManager(); registerCleanupFunction(AddonTestUtils.promiseShutdownManager); @@ -59,7 +17,7 @@ add_setup(async function () { add_task(async function basic_multilocale_test() { let resolver; let initPromise = new Promise(resolve => (resolver = resolve)); - useCustomGeoServer("FR", initPromise); + useCustomGeoServer("TR", initPromise); await Services.search.init(); await Services.search.getAppProvidedEngines(); diff --git a/toolkit/components/search/tests/xpcshell/test_missing_engine.js b/toolkit/components/search/tests/xpcshell/test_missing_engine.js index 3da9fe14a6..259baf9c1a 100644 --- a/toolkit/components/search/tests/xpcshell/test_missing_engine.js +++ b/toolkit/components/search/tests/xpcshell/test_missing_engine.js @@ -55,6 +55,48 @@ const BAD_CONFIG = [ }, ]; +const CONFIG_V2 = [ + { + recordType: "engine", + identifier: "engine", + base: { + name: "Test search engine", + urls: { + search: { + base: "https://www.google.com/search", + params: [ + { + name: "channel", + searchAccessPoint: { + addressbar: "fflb", + contextmenu: "rcs", + }, + }, + ], + searchTermParamName: "q", + }, + suggestions: { + base: "https://suggestqueries.google.com/complete/search?output=firefox&client=firefox&hl={moz:locale}", + searchTermParamName: "q", + }, + }, + }, + variants: [ + { + environment: { allRegionsAndLocales: true }, + }, + ], + }, + { + recordType: "defaultEngines", + specificDefaults: [], + }, + { + recordType: "engineOrders", + orders: [], + }, +]; + add_setup(async function () { SearchTestUtils.useMockIdleService(); await AddonTestUtils.promiseStartupManager(); @@ -66,7 +108,11 @@ add_setup(async function () { }); add_task(async function test_startup_with_missing() { - await SearchTestUtils.useTestEngines("data", null, BAD_CONFIG); + await SearchTestUtils.useTestEngines( + "data", + null, + SearchUtils.newSearchConfigEnabled ? CONFIG_V2 : BAD_CONFIG + ); const result = await Services.search.init(); Assert.ok( @@ -89,7 +135,7 @@ add_task(async function test_update_with_missing() { await RemoteSettings(SearchUtils.SETTINGS_KEY).emit("sync", { data: { - current: GOOD_CONFIG, + current: SearchUtils.newSearchConfigEnabled ? CONFIG_V2 : GOOD_CONFIG, }, }); @@ -110,7 +156,7 @@ add_task(async function test_update_with_missing() { await RemoteSettings(SearchUtils.SETTINGS_KEY).emit("sync", { data: { - current: BAD_CONFIG, + current: SearchUtils.newSearchConfigEnabled ? CONFIG_V2 : BAD_CONFIG, }, }); diff --git a/toolkit/components/search/tests/xpcshell/test_opensearch_icon.js b/toolkit/components/search/tests/xpcshell/test_opensearch_icon.js index 68cd9577c1..23f2d9d575 100644 --- a/toolkit/components/search/tests/xpcshell/test_opensearch_icon.js +++ b/toolkit/components/search/tests/xpcshell/test_opensearch_icon.js @@ -56,9 +56,9 @@ add_task(async function test_icon_types() { engine.QueryInterface(Ci.nsISearchEngine); await promiseEngineChanged; - Assert.ok(engine.getIconURL(), `${test.name} engine has an icon`); + Assert.ok(await engine.getIconURL(), `${test.name} engine has an icon`); Assert.ok( - engine.getIconURL().startsWith(test.expected), + (await engine.getIconURL()).startsWith(test.expected), `${test.name} iconURI starts with the expected information` ); } @@ -69,13 +69,13 @@ add_task(async function test_multiple_icons_in_file() { url: `${gDataUrl}engineImages.xml`, }); - Assert.ok(engine.getIconURL().includes("ico16")); - Assert.ok(engine.getIconURL(16).includes("ico16")); - Assert.ok(engine.getIconURL(32).includes("ico32")); - Assert.ok(engine.getIconURL(74).includes("ico74")); + Assert.ok((await engine.getIconURL()).includes("ico16")); + Assert.ok((await engine.getIconURL(16)).includes("ico16")); + Assert.ok((await engine.getIconURL(32)).includes("ico32")); + Assert.ok((await engine.getIconURL(74)).includes("ico74")); info("Invalid dimensions should return null until bug 1655070 is fixed."); - Assert.equal(null, engine.getIconURL(50)); + Assert.equal(null, await engine.getIconURL(50)); }); add_task(async function test_icon_not_in_opensearch_file() { @@ -86,6 +86,6 @@ add_task(async function test_icon_not_in_opensearch_file() { ); // Even though the icon wasn't specified inside the XML file, it should be - // available both in the iconURI attribute and with getIconURLBySize. - Assert.ok(engine.getIconURL(16).includes("ico16")); + // available. + Assert.ok((await engine.getIconURL(16)).includes("ico16")); }); diff --git a/toolkit/components/search/tests/xpcshell/test_opensearch_icons_invalid.js b/toolkit/components/search/tests/xpcshell/test_opensearch_icons_invalid.js index 6db13a0da8..744d46052e 100644 --- a/toolkit/components/search/tests/xpcshell/test_opensearch_icons_invalid.js +++ b/toolkit/components/search/tests/xpcshell/test_opensearch_icons_invalid.js @@ -21,8 +21,8 @@ add_task(async function test_installedresourceicon() { url: `${gDataUrl}opensearch/chromeicon.xml`, }); - Assert.equal(undefined, engine1.getIconURL()); - Assert.equal(undefined, engine2.getIconURL()); + Assert.equal(undefined, await engine1.getIconURL()); + Assert.equal(undefined, await engine2.getIconURL()); }); add_task(async function test_installedhttpplace() { @@ -50,7 +50,7 @@ add_task(async function test_installedhttpplace() { Assert.equal( undefined, - engine.getIconURL(), + await engine.getIconURL(), "Should not have set an iconURI" ); }); diff --git a/toolkit/components/search/tests/xpcshell/test_override_allowlist_switch.js b/toolkit/components/search/tests/xpcshell/test_override_allowlist_switch.js index cd51e7bdee..5ec485c4ec 100644 --- a/toolkit/components/search/tests/xpcshell/test_override_allowlist_switch.js +++ b/toolkit/components/search/tests/xpcshell/test_override_allowlist_switch.js @@ -306,8 +306,16 @@ add_task(async function test_app_provided_engine_deployment_extended() { await assertCorrectlySwitchedWhenRemoved(async () => { info("Change configuration to remove engine from user's environment"); - await SearchTestUtils.updateRemoteSettingsConfig(CONFIG_SIMPLE_LOCALE_DE); - configStub.returns(CONFIG_SIMPLE_LOCALE_DE); + await SearchTestUtils.updateRemoteSettingsConfig( + SearchUtils.newSearchConfigEnabled + ? CONFIG_SIMPLE_LOCALE_DE_V2 + : CONFIG_SIMPLE_LOCALE_DE + ); + configStub.returns( + SearchUtils.newSearchConfigEnabled + ? CONFIG_SIMPLE_LOCALE_DE_V2 + : CONFIG_SIMPLE_LOCALE_DE + ); }); }); diff --git a/toolkit/components/search/tests/xpcshell/test_reload_engines.js b/toolkit/components/search/tests/xpcshell/test_reload_engines.js index ac63b62e59..60cd3c2a13 100644 --- a/toolkit/components/search/tests/xpcshell/test_reload_engines.js +++ b/toolkit/components/search/tests/xpcshell/test_reload_engines.js @@ -238,6 +238,260 @@ const CONFIG = [ }, ]; +const CONFIG_V2 = [ + { + recordType: "engine", + identifier: "engine", + base: { + name: "Test search engine", + urls: { + search: { + base: "https://www.google.com/search", + params: [ + { + name: "channel", + searchAccessPoint: { + addressbar: "fflb", + contextmenu: "rcs", + }, + }, + ], + searchTermParamName: "q", + }, + suggestions: { + base: "https://suggestqueries.google.com/complete/search?output=firefox&client=firefox&hl={moz:locale}", + searchTermParamName: "q", + }, + }, + }, + variants: [ + { + environment: { allRegionsAndLocales: true }, + }, + ], + }, + { + recordType: "engine", + identifier: "engine-pref", + base: { + name: "engine-pref", + urls: { + search: { + base: "https://www.google.com/search", + params: [ + { + name: "code", + experimentConfig: "code", + }, + { + name: "test", + experimentConfig: "test", + }, + ], + searchTermParamName: "q", + }, + }, + }, + variants: [ + { + environment: { allRegionsAndLocales: true }, + }, + ], + }, + { + recordType: "engine", + identifier: "engine-chromeicon", + base: { + name: "engine-chromeicon", + urls: { + search: { + base: "https://www.google.com/search", + searchTermParamName: "q", + }, + }, + }, + variants: [ + { + environment: { allRegionsAndLocales: true }, + }, + { + environment: { regions: ["FR"] }, + urls: { + search: { + base: "https://www.google.com/search", + params: [ + { + name: "c", + value: "my-test", + }, + ], + searchTermParamName: "q1", + }, + }, + }, + ], + }, + { + recordType: "engine", + identifier: "engine-rel-searchform-purpose", + base: { + name: "engine-rel-searchform-purpose", + urls: { + search: { + base: "https://www.google.com/search", + searchTermParamName: "q", + }, + }, + }, + variants: [ + { + environment: { excludedRegions: ["FR"] }, + urls: { + search: { + params: [ + { + name: "channel", + searchAccessPoint: { + addressbar: "fflb", + contextmenu: "rcs", + searchbar: "sb", + }, + }, + ], + }, + }, + }, + ], + }, + { + recordType: "engine", + identifier: "engine-reordered", + base: { + name: "Test search engine (Reordered)", + urls: { + search: { + base: "https://www.google.com/search", + params: [ + { + name: "channel", + searchAccessPoint: { + addressbar: "fflb", + contextmenu: "rcs", + }, + }, + ], + searchTermParamName: "q", + }, + suggestions: { + base: "https://suggestqueries.google.com/complete/search?output=firefox&client=firefox&hl={moz:locale}", + searchTermParamName: "q", + }, + }, + }, + variants: [ + { + environment: { regions: ["FR"] }, + }, + ], + }, + { + recordType: "engine", + identifier: "engine-resourceicon", + base: { + name: "engine-resourceicon", + urls: { + search: { + base: "https://www.google.com/search", + searchTermParamName: "q", + }, + }, + }, + variants: [ + { + environment: { excludedRegions: ["FR"] }, + }, + ], + }, + { + recordType: "engine", + identifier: "engine-resourceicon-gd", + base: { + name: "engine-resourceicon-gd", + urls: { + search: { + base: "https://www.google.com/search", + searchTermParamName: "q", + }, + }, + }, + variants: [ + { + environment: { regions: ["FR"] }, + }, + ], + }, + { + recordType: "engine", + identifier: "engine-same-name", + base: { + name: "engine-same-name", + urls: { + search: { + base: "https://www.google.com/search", + searchTermParamName: "q", + }, + }, + }, + variants: [ + { + environment: { excludedRegions: ["FR"] }, + }, + ], + }, + { + recordType: "engine", + identifier: "engine-same-name-gd", + base: { + name: "engine-same-name-gd", + urls: { + search: { + base: "https://www.example.com/search", + searchTermParamName: "q", + }, + }, + }, + variants: [ + { + environment: { regions: ["FR"] }, + }, + ], + }, + { + recordType: "defaultEngines", + specificDefaults: [ + { + default: "engine", + defaultPrivate: "engine", + environment: { excludedRegions: ["FR"] }, + }, + { + default: "engine-pref", + defaultPrivate: "engine-pref", + environment: { regions: ["FR"] }, + }, + ], + }, + { + recordType: "engineOrders", + orders: [ + { + order: ["engine-resourceicon-gd"], + environment: { regions: ["FR"] }, + }, + ], + }, +]; + async function visibleEngines() { return (await Services.search.getVisibleEngines()).map(e => e.identifier); } @@ -250,7 +504,11 @@ add_setup(async function () { ); SearchTestUtils.useMockIdleService(); - await SearchTestUtils.useTestEngines("data", null, CONFIG); + await SearchTestUtils.useTestEngines( + "data", + null, + SearchUtils.newSearchConfigEnabled ? CONFIG_V2 : CONFIG + ); await AddonTestUtils.promiseStartupManager(); }); @@ -325,23 +583,47 @@ add_task(async function test_config_updated_engine_changes() { await reloadObserved; Services.obs.removeObserver(enginesObs, SearchUtils.TOPIC_ENGINE_MODIFIED); - Assert.deepEqual( - enginesAdded, - ["engine-resourceicon-gd", "engine-reordered"], - "Should have added the correct engines" - ); - - Assert.deepEqual( - enginesModified.sort(), - ["engine", "engine-chromeicon", "engine-pref", "engine-same-name-gd"], - "Should have modified the expected engines" - ); - - Assert.deepEqual( - enginesRemoved, - ["engine-rel-searchform-purpose", "engine-resourceicon"], - "Should have removed the expected engine" - ); + if (SearchUtils.newSearchConfigEnabled) { + Assert.deepEqual( + enginesAdded, + ["engine-resourceicon-gd", "engine-reordered", "engine-same-name-gd"], + "Should have added the correct engines" + ); + + Assert.deepEqual( + enginesModified.sort(), + ["engine", "engine-chromeicon", "engine-pref"], + "Should have modified the expected engines" + ); + + Assert.deepEqual( + enginesRemoved, + [ + "engine-rel-searchform-purpose", + "engine-resourceicon", + "engine-same-name", + ], + "Should have removed the expected engine" + ); + } else { + Assert.deepEqual( + enginesAdded, + ["engine-resourceicon-gd", "engine-reordered"], + "Should have added the correct engines" + ); + + Assert.deepEqual( + enginesModified.sort(), + ["engine", "engine-chromeicon", "engine-pref", "engine-same-name-gd"], + "Should have modified the expected engines" + ); + + Assert.deepEqual( + enginesRemoved, + ["engine-rel-searchform-purpose", "engine-resourceicon"], + "Should have removed the expected engine" + ); + } const installedEngines = await Services.search.getAppProvidedEngines(); @@ -382,7 +664,9 @@ add_task(async function test_config_updated_engine_changes() { ); const engineWithSameName = await Services.search.getEngineByName( - "engine-same-name" + SearchUtils.newSearchConfigEnabled + ? "engine-same-name-gd" + : "engine-same-name" ); Assert.equal( engineWithSameName.getSubmission("test").uri.spec, diff --git a/toolkit/components/search/tests/xpcshell/test_reload_engines_experiment.js b/toolkit/components/search/tests/xpcshell/test_reload_engines_experiment.js index ea5cdee3e5..5edcb6081b 100644 --- a/toolkit/components/search/tests/xpcshell/test_reload_engines_experiment.js +++ b/toolkit/components/search/tests/xpcshell/test_reload_engines_experiment.js @@ -72,8 +72,87 @@ const CONFIG = [ }, ]; +const CONFIG_V2 = [ + { + recordType: "engine", + identifier: "engine", + base: { + name: "Test search engine", + urls: { + search: { + base: "https://www.google.com/search", + params: [ + { + name: "channel", + searchAccessPoint: { + addressbar: "fflb", + contextmenu: "rcs", + }, + }, + ], + searchTermParamName: "q", + }, + }, + }, + variants: [ + { + environment: { allRegionsAndLocales: true }, + }, + ], + }, + { + recordType: "engine", + identifier: "engine-same-name-en", + base: { + name: "engine-same-name", + urls: { + search: { + base: "https://www.google.com/search", + searchTermParamName: "q", + }, + }, + }, + variants: [ + { + environment: { allRegionsAndLocales: true }, + }, + ], + }, + { + recordType: "engine", + identifier: "engine-same-name-gd", + base: { + name: "engine-same-name", + urls: { + search: { + base: "https://www.example.com/search", + searchTermParamName: "q", + }, + }, + }, + variants: [ + { + environment: { allRegionsAndLocales: true, experiment: "xpcshell" }, + }, + ], + }, + { + recordType: "defaultEngines", + globalDefault: "engine", + specificDefaults: [], + }, + { + recordType: "engineOrders", + orders: [], + }, +]; + add_setup(async function () { - await SearchTestUtils.useTestEngines("data", null, CONFIG); + await SearchTestUtils.useTestEngines( + "data", + null, + SearchUtils.newSearchConfigEnabled ? CONFIG_V2 : CONFIG + ); await AddonTestUtils.promiseStartupManager(); }); @@ -125,19 +204,42 @@ add_task(async function test_config_updated_engine_changes() { await reloadObserved; Services.obs.removeObserver(enginesObs, SearchUtils.TOPIC_ENGINE_MODIFIED); - Assert.deepEqual(enginesAdded, [], "Should have added the correct engines"); + if (SearchUtils.newSearchConfigEnabled) { + // In the new config, engine-same-name-en and engine-same-name-gd are two + // different engine configs and they will be treated as different engines + // and not the same. That's the reason why the assertions are different below. + Assert.deepEqual( + enginesAdded, + ["engine-same-name-gd"], + "Should have added the correct engines" + ); - Assert.deepEqual( - enginesModified.sort(), - ["engine", "engine-same-name-gd"], - "Should have modified the expected engines" - ); + Assert.deepEqual( + enginesModified.sort(), + ["engine", "engine-same-name-en"], + "Should have modified the expected engines" + ); - Assert.deepEqual( - enginesRemoved, - [], - "Should have removed the expected engine" - ); + Assert.deepEqual( + enginesRemoved, + ["engine-same-name"], + "Should have removed the expected engine" + ); + } else { + Assert.deepEqual(enginesAdded, [], "Should have added the correct engines"); + + Assert.deepEqual( + enginesModified.sort(), + ["engine", "engine-same-name-gd"], + "Should have modified the expected engines" + ); + + Assert.deepEqual( + enginesRemoved, + [], + "Should have removed the expected engine" + ); + } const installedEngines = await Services.search.getAppProvidedEngines(); diff --git a/toolkit/components/search/tests/xpcshell/test_reload_engines_locales.js b/toolkit/components/search/tests/xpcshell/test_reload_engines_locales.js index 6fa277655d..ed516c5a15 100644 --- a/toolkit/components/search/tests/xpcshell/test_reload_engines_locales.js +++ b/toolkit/components/search/tests/xpcshell/test_reload_engines_locales.js @@ -72,6 +72,85 @@ const CONFIG = [ }, ]; +const CONFIG_V2 = [ + { + recordType: "engine", + identifier: "engine", + base: { + name: "Test search engine", + urls: { + search: { + base: "https://www.google.com/search", + params: [ + { + name: "channel", + searchAccessPoint: { + addressbar: "fflb", + contextmenu: "rcs", + }, + }, + ], + searchTermParamName: "q", + }, + suggestions: { + base: "https://suggestqueries.google.com/complete/search?output=firefox&client=firefox&hl={moz:locale}", + searchTermParamName: "q", + }, + }, + }, + variants: [ + { + environment: { allRegionsAndLocales: true }, + }, + ], + }, + { + recordType: "engine", + identifier: "engine-diff-name-en", + base: { + name: "engine-diff-name-en", + urls: { + search: { + base: "https://en.wikipedia.com/search", + searchTermParamName: "q", + }, + }, + }, + variants: [ + { + environment: { excludedLocales: ["gd"] }, + }, + ], + }, + { + recordType: "engine", + identifier: "engine-diff-name-gd", + base: { + name: "engine-diff-name-gd", + urls: { + search: { + base: "https://gd.wikipedia.com/search", + searchTermParamName: "q", + }, + }, + }, + variants: [ + { + environment: { locales: ["gd"] }, + }, + ], + }, + { + recordType: "defaultEngines", + globalDefault: "engine", + specificDefaults: [], + }, + { + recordType: "engineOrders", + orders: [], + }, +]; + add_setup(async () => { Services.locale.availableLocales = [ ...Services.locale.availableLocales, @@ -80,7 +159,11 @@ add_setup(async () => { ]; Services.locale.requestedLocales = ["gd"]; - await SearchTestUtils.useTestEngines("data", null, CONFIG); + await SearchTestUtils.useTestEngines( + "data", + null, + SearchUtils.newSearchConfigEnabled ? CONFIG_V2 : CONFIG + ); await AddonTestUtils.promiseStartupManager(); await Services.search.init(); }); @@ -101,7 +184,9 @@ add_task(async function test_config_updated_engine_changes() { ); Assert.equal( engine.getSubmission("test").uri.spec, - "https://gd.wikipedia.com/search", + SearchUtils.newSearchConfigEnabled + ? "https://gd.wikipedia.com/search?q=test" + : "https://gd.wikipedia.com/search", "Should have the gd search url" ); @@ -122,7 +207,9 @@ add_task(async function test_config_updated_engine_changes() { ); Assert.equal( engine.getSubmission("test").uri.spec, - "https://en.wikipedia.com/search", + SearchUtils.newSearchConfigEnabled + ? "https://en.wikipedia.com/search?q=test" + : "https://en.wikipedia.com/search", "Should have the en search url" ); }); diff --git a/toolkit/components/search/tests/xpcshell/test_remove_engine_notification_box.js b/toolkit/components/search/tests/xpcshell/test_remove_engine_notification_box.js index 0222334255..d5b1366b93 100644 --- a/toolkit/components/search/tests/xpcshell/test_remove_engine_notification_box.js +++ b/toolkit/components/search/tests/xpcshell/test_remove_engine_notification_box.js @@ -57,6 +57,100 @@ const CONFIG_UPDATED = CONFIG.filter(r => r.webExtension.id.startsWith("engine-pref") ); +const CONFIG_V2 = [ + { + recordType: "engine", + identifier: "engine", + base: { + name: "Test search engine", + urls: { + search: { + base: "https://www.google.com/search", + searchTermParamName: "q", + }, + }, + }, + variants: [ + { + environment: { allRegionsAndLocales: true }, + }, + ], + }, + { + recordType: "engine", + identifier: "engine-pref", + base: { + name: "engine-pref", + urls: { + search: { + base: "https://www.google.com/search", + searchTermParamName: "q", + }, + }, + }, + variants: [ + { + environment: { allRegionsAndLocales: true }, + }, + ], + }, + { + recordType: "defaultEngines", + specificDefaults: [ + { + default: "engine", + environment: { excludedRegions: ["FR"] }, + }, + { + default: "engine-pref", + environment: { regions: ["FR"] }, + }, + ], + }, + { + recordType: "engineOrders", + orders: [], + }, +]; + +const CONFIG_V2_UPDATED = [ + { + recordType: "engine", + identifier: "engine-pref", + base: { + name: "engine-pref", + urls: { + search: { + base: "https://www.google.com/search", + searchTermParamName: "q", + }, + }, + }, + variants: [ + { + environment: { allRegionsAndLocales: true }, + }, + ], + }, + { + recordType: "defaultEngines", + specificDefaults: [ + { + default: "engine", + environment: { excludedRegions: ["FR"] }, + }, + { + default: "engine-pref", + environment: { regions: ["FR"] }, + }, + ], + }, + { + recordType: "engineOrders", + orders: [], + }, +]; + let stub; let settingsFilePath; let userSettings; @@ -64,7 +158,11 @@ let userSettings; add_setup(async function () { SearchSettings.SETTINGS_INVALIDATION_DELAY = 100; SearchTestUtils.useMockIdleService(); - await SearchTestUtils.useTestEngines("data", null, CONFIG); + await SearchTestUtils.useTestEngines( + "data", + null, + SearchUtils.newSearchConfigEnabled ? CONFIG_V2 : CONFIG + ); await AddonTestUtils.promiseStartupManager(); stub = sinon.stub( @@ -246,7 +344,9 @@ add_task(async function test_default_engine_changed_and_metadata_unchanged() { }; // Update config by removing the app default engine - await setConfigToLoad(CONFIG_UPDATED); + await setConfigToLoad( + SearchUtils.newSearchConfigEnabled ? CONFIG_V2_UPDATED : CONFIG_UPDATED + ); await reloadEngines(structuredClone(userSettings)); Assert.ok( @@ -293,7 +393,9 @@ add_task(async function test_app_default_engine_changed_on_start_up() { settings.metaData.current = ""; // Update config by removing the app default engine - await setConfigToLoad(CONFIG_UPDATED); + await setConfigToLoad( + SearchUtils.newSearchConfigEnabled ? CONFIG_V2_UPDATED : CONFIG_UPDATED + ); await loadEngines(settings); Assert.ok( @@ -311,7 +413,9 @@ add_task(async function test_app_default_engine_change_start_up_still_exists() { settings.metaData.current = ""; settings.metaData.appDefaultEngine = "Test search engine"; - await setConfigToLoad(CONFIG); + await setConfigToLoad( + SearchUtils.newSearchConfigEnabled ? CONFIG_V2 : CONFIG + ); await loadEngines(settings); Assert.ok( diff --git a/toolkit/components/search/tests/xpcshell/test_searchSuggest.js b/toolkit/components/search/tests/xpcshell/test_searchSuggest.js index 48769be41e..4a30eb741a 100644 --- a/toolkit/components/search/tests/xpcshell/test_searchSuggest.js +++ b/toolkit/components/search/tests/xpcshell/test_searchSuggest.js @@ -581,7 +581,7 @@ add_task(async function stop_search() { let histogram = TelemetryTestUtils.getAndClearKeyedHistogram( SEARCH_TELEMETRY_LATENCY ); - let controller = new SearchSuggestionController(result => { + let controller = new SearchSuggestionController(() => { do_throw("The callback shouldn't be called after stop()"); }); let resultPromise = controller.fetch("mo", false, getEngine); diff --git a/toolkit/components/search/tests/xpcshell/test_searchSuggest_cookies.js b/toolkit/components/search/tests/xpcshell/test_searchSuggest_cookies.js index cfa9e56144..042c74d86a 100644 --- a/toolkit/components/search/tests/xpcshell/test_searchSuggest_cookies.js +++ b/toolkit/components/search/tests/xpcshell/test_searchSuggest_cookies.js @@ -28,7 +28,7 @@ function countCacheEntries() { ); storage.asyncVisitStorage( { - onCacheStorageInfo(num, consumption) { + onCacheStorageInfo(num) { this._num = num; }, onCacheEntryInfo(uri) { diff --git a/toolkit/components/search/tests/xpcshell/test_searchSuggest_extraParams.js b/toolkit/components/search/tests/xpcshell/test_searchSuggest_extraParams.js index 8ecf4b02f3..3261174ebf 100644 --- a/toolkit/components/search/tests/xpcshell/test_searchSuggest_extraParams.js +++ b/toolkit/components/search/tests/xpcshell/test_searchSuggest_extraParams.js @@ -22,8 +22,62 @@ const TEST_CONFIG = [ }, ]; +const TEST_CONFIG_V2 = [ + { + recordType: "engine", + identifier: "get", + base: { + name: "Get Engine", + urls: { + search: { + base: "https://example.com", + params: [ + { + name: "webExtension", + value: "1", + }, + ], + searchTermParamName: "search", + }, + suggestions: { + base: "https://example.com", + params: [ + { + name: "custom_param", + experimentConfig: "test_pref_param", + }, + { + name: "webExtension", + value: "1", + }, + ], + searchTermParamName: "suggest", + }, + }, + }, + variants: [ + { + environment: { allRegionsAndLocales: true }, + }, + ], + }, + { + recordType: "defaultEngines", + globalDefault: "get", + specificDefaults: [], + }, + { + recordType: "engineOrders", + orders: [], + }, +]; + add_setup(async function () { - await SearchTestUtils.useTestEngines("method-extensions", null, TEST_CONFIG); + await SearchTestUtils.useTestEngines( + "method-extensions", + null, + SearchUtils.newSearchConfigEnabled ? TEST_CONFIG_V2 : TEST_CONFIG + ); await AddonTestUtils.promiseStartupManager(); await Services.search.init(); }); diff --git a/toolkit/components/search/tests/xpcshell/test_searchTermFromResult.js b/toolkit/components/search/tests/xpcshell/test_searchTermFromResult.js index 700c6a3450..ea040aacd4 100644 --- a/toolkit/components/search/tests/xpcshell/test_searchTermFromResult.js +++ b/toolkit/components/search/tests/xpcshell/test_searchTermFromResult.js @@ -6,6 +6,53 @@ * Tests searchTermFromResult API. */ +let CONFIG_V2 = [ + { + recordType: "engine", + identifier: "engine-purposes", + base: { + name: "Test Engine With Purposes", + urls: { + search: { + base: "https://www.example.com/search", + params: [ + { name: "pc", value: "FIREFOX" }, + { + name: "form", + searchAccessPoint: { + newtab: "MOZNEWTAB", + homepage: "MOZHOMEPAGE", + searchbar: "MOZSEARCHBAR", + addressbar: "MOZKEYWORD", + contextmenu: "MOZCONTEXT", + }, + }, + { + name: "channel", + experimentConfig: "testChannelEnabled", + }, + ], + searchTermParamName: "q", + }, + }, + }, + variants: [ + { + environment: { allRegionsAndLocales: true }, + }, + ], + }, + { + recordType: "defaultEngines", + globalDefault: "engine-purpose", + specificDefaults: [], + }, + { + recordType: "engineOrders", + orders: [], + }, +]; + let defaultEngine; // The test string contains special characters to ensure @@ -14,66 +61,72 @@ const TERM = "c;,?:@&=+$-_.!~*'()# d\u00E8f"; const TERM_ENCODED = "c%3B%2C%3F%3A%40%26%3D%2B%24-_.!~*'()%23+d%C3%A8f"; add_setup(async function () { - await SearchTestUtils.useTestEngines("data", null, [ - { - webExtension: { - id: "engine-purposes@search.mozilla.org", - name: "Test Engine With Purposes", - search_url: "https://www.example.com/search", - params: [ - { - name: "form", - condition: "purpose", - purpose: "keyword", - value: "MOZKEYWORD", - }, - { - name: "form", - condition: "purpose", - purpose: "contextmenu", - value: "MOZCONTEXT", - }, + await SearchTestUtils.useTestEngines( + "data", + null, + SearchUtils.newSearchConfigEnabled + ? CONFIG_V2 + : [ { - name: "form", - condition: "purpose", - purpose: "newtab", - value: "MOZNEWTAB", + webExtension: { + id: "engine-purposes@search.mozilla.org", + name: "Test Engine With Purposes", + search_url: "https://www.example.com/search", + params: [ + { + name: "form", + condition: "purpose", + purpose: "keyword", + value: "MOZKEYWORD", + }, + { + name: "form", + condition: "purpose", + purpose: "contextmenu", + value: "MOZCONTEXT", + }, + { + name: "form", + condition: "purpose", + purpose: "newtab", + value: "MOZNEWTAB", + }, + { + name: "form", + condition: "purpose", + purpose: "searchbar", + value: "MOZSEARCHBAR", + }, + { + name: "form", + condition: "purpose", + purpose: "homepage", + value: "MOZHOMEPAGE", + }, + { + name: "pc", + value: "FIREFOX", + }, + { + name: "channel", + condition: "pref", + pref: "testChannelEnabled", + }, + { + name: "q", + value: "{searchTerms}", + }, + ], + }, + appliesTo: [ + { + included: { everywhere: true }, + default: "yes", + }, + ], }, - { - name: "form", - condition: "purpose", - purpose: "searchbar", - value: "MOZSEARCHBAR", - }, - { - name: "form", - condition: "purpose", - purpose: "homepage", - value: "MOZHOMEPAGE", - }, - { - name: "pc", - value: "FIREFOX", - }, - { - name: "channel", - condition: "pref", - pref: "testChannelEnabled", - }, - { - name: "q", - value: "{searchTerms}", - }, - ], - }, - appliesTo: [ - { - included: { everywhere: true }, - default: "yes", - }, - ], - }, - ]); + ] + ); await AddonTestUtils.promiseStartupManager(); await Services.search.init(); diff --git a/toolkit/components/search/tests/xpcshell/test_settings_persist.js b/toolkit/components/search/tests/xpcshell/test_settings_persist.js index bed6771554..5c2cbd85c4 100644 --- a/toolkit/components/search/tests/xpcshell/test_settings_persist.js +++ b/toolkit/components/search/tests/xpcshell/test_settings_persist.js @@ -1,9 +1,13 @@ /* Any copyright is dedicated to the Public Domain. http://creativecommons.org/publicdomain/zero/1.0/ */ +/** + * Tests the removal of an engine is persisted in search settings. + */ + "use strict"; -const CONFIG_DEFAULT = [ +const CONFIG_UPDATED = [ { webExtension: { id: "plainengine@search.mozilla.org", @@ -18,26 +22,38 @@ const CONFIG_DEFAULT = [ }, appliesTo: [{ included: { everywhere: true } }], }, +]; + +const SEARCH_CONFIG_V2_UPDATED = [ { - webExtension: { - id: "special-engine@search.mozilla.org", - name: "Special", - search_url: "https://www.google.com/search", - params: [ - { - name: "q", - value: "{searchTerms}", + recordType: "engine", + identifier: "plainengine", + base: { + name: "Plain", + urls: { + search: { + base: "https://duckduckgo.com/", + searchTermParamName: "q", }, - ], + }, }, - appliesTo: [{ included: { everywhere: true } }], + variants: [ + { + environment: { allRegionsAndLocales: true }, + }, + ], + }, + { + recordType: "defaultEngines", + globalDefault: "plainengine", + specificDefaults: [], + }, + { + recordType: "engineOrders", + orders: [], }, ]; -const CONFIG_UPDATED = CONFIG_DEFAULT.filter(r => - r.webExtension.id.startsWith("plainengine") -); - async function startup() { let settingsFileWritten = promiseAfterSettings(); let ss = new SearchService(); @@ -50,7 +66,10 @@ async function startup() { async function updateConfig(config) { const settings = await RemoteSettings(SearchUtils.SETTINGS_KEY); settings.get.restore(); - sinon.stub(settings, "get").returns(config); + + config == "test-extensions" + ? await SearchTestUtils.useTestEngines("test-extensions") + : sinon.stub(settings, "get").returns(config); } async function visibleEngines(ss) { @@ -58,7 +77,7 @@ async function visibleEngines(ss) { } add_setup(async function () { - await SearchTestUtils.useTestEngines("test-extensions", null, CONFIG_DEFAULT); + await SearchTestUtils.useTestEngines("test-extensions"); registerCleanupFunction(AddonTestUtils.promiseShutdownManager); await AddonTestUtils.promiseStartupManager(); // This is only needed as otherwise events will not be properly notified @@ -87,7 +106,11 @@ add_task(async function () { ); ss._removeObservers(); - updateConfig(CONFIG_UPDATED); + await updateConfig( + SearchUtils.newSearchConfigEnabled + ? SEARCH_CONFIG_V2_UPDATED + : CONFIG_UPDATED + ); ss = await startup(); Assert.ok( @@ -96,7 +119,8 @@ add_task(async function () { ); ss._removeObservers(); - updateConfig(CONFIG_DEFAULT); + await updateConfig("test-extensions"); + ss = await startup(); Assert.ok( diff --git a/toolkit/components/search/tests/xpcshell/test_sort_orders-no-hints.js b/toolkit/components/search/tests/xpcshell/test_sort_orders-no-hints.js index d2a2d7dd93..cb7e314fd4 100644 --- a/toolkit/components/search/tests/xpcshell/test_sort_orders-no-hints.js +++ b/toolkit/components/search/tests/xpcshell/test_sort_orders-no-hints.js @@ -15,7 +15,13 @@ add_setup(async function () { "data", null, ( - await readJSONFile(do_get_file("data/engines-no-order-hint.json")) + await readJSONFile( + do_get_file( + SearchUtils.newSearchConfigEnabled + ? "data/search-config-v2-no-order-hint.json" + : "data/engines-no-order-hint.json" + ) + ) ).data ); diff --git a/toolkit/components/search/tests/xpcshell/test_telemetry_event_default.js b/toolkit/components/search/tests/xpcshell/test_telemetry_event_default.js index 84bd1be9cc..f1b6208326 100644 --- a/toolkit/components/search/tests/xpcshell/test_telemetry_event_default.js +++ b/toolkit/components/search/tests/xpcshell/test_telemetry_event_default.js @@ -45,6 +45,49 @@ const BASE_CONFIG = [ default: "yes", }, ]; + +const BASE_CONFIG_V2 = [ + { + recordType: "engine", + identifier: "engine", + base: { + name: "Test search engine", + urls: { + search: { + base: "https://www.google.com/search", + params: [ + { + name: "channel", + searchAccessPoint: { + addressbar: "fflb", + contextmenu: "rcs", + }, + }, + ], + searchTermParamName: "q", + }, + suggestions: { + base: "https://suggestqueries.google.com/complete/search?output=firefox&client=firefox&hl={moz:locale}", + searchTermParamName: "q", + }, + }, + }, + variants: [ + { + environment: { allRegionsAndLocales: true }, + }, + ], + }, + { + recordType: "defaultEngines", + globalDefault: "engine", + specificDefaults: [], + }, + { + recordType: "engineOrders", + orders: [], + }, +]; const MAIN_CONFIG = [ { webExtension: { @@ -78,7 +121,6 @@ const MAIN_CONFIG = [ { webExtension: { id: "engine-chromeicon@search.mozilla.org", - name: "engine-chromeicon", search_url: "https://www.google.com/search", params: [ @@ -163,6 +205,154 @@ const MAIN_CONFIG = [ }, ]; +const MAIN_CONFIG_V2 = [ + { + recordType: "engine", + identifier: "engine", + base: { + name: "Test search engine", + urls: { + search: { + base: "https://www.google.com/search", + params: [ + { + name: "channel", + searchAccessPoint: { + addressbar: "fflb", + contextmenu: "rcs", + }, + }, + ], + searchTermParamName: "q", + }, + suggestions: { + base: "https://suggestqueries.google.com/complete/search?output=firefox&client=firefox&hl={moz:locale}", + searchTermParamName: "q", + }, + }, + }, + variants: [ + { + environment: { allRegionsAndLocales: true }, + }, + ], + }, + { + recordType: "engine", + identifier: "engine-chromeicon", + base: { + name: "engine-chromeicon", + urls: { + search: { + base: "https://www.google.com/search", + searchTermParamName: "q", + }, + }, + }, + variants: [ + { + environment: { allRegionsAndLocales: true }, + }, + ], + }, + { + recordType: "engine", + identifier: "engine-fr", + base: { + name: "Test search engine (fr)", + urls: { + search: { + base: "https://www.google.fr/search", + params: [ + { + name: "ie", + value: "iso-8859-1", + }, + { + name: "oe", + value: "iso-8859-1", + }, + ], + searchTermParamName: "q", + }, + }, + }, + variants: [ + { + environment: { allRegionsAndLocales: true }, + }, + ], + }, + { + recordType: "engine", + identifier: "engine-pref", + base: { + name: "engine-pref", + urls: { + search: { + base: "https://www.google.com/search", + params: [ + { + name: "code", + experimentConfig: "code", + }, + { + name: "test", + experimentConfig: "test", + }, + ], + searchTermParamName: "q", + }, + }, + }, + variants: [ + { + environment: { allRegionsAndLocales: true }, + }, + ], + }, + { + recordType: "engine", + identifier: "engine2", + base: { + name: "A second test engine", + urls: { + search: { + base: "https://duckduckgo.com/", + searchTermParamName: "q", + }, + }, + }, + variants: [ + { + environment: { allRegionsAndLocales: true }, + }, + ], + }, + { + recordType: "defaultEngines", + globalDefault: "engine-chromeicon", + specificDefaults: [ + { + default: "engine-fr", + environment: { excludedRegions: ["DE"], locales: ["fr"] }, + }, + { + default: "engine-pref", + environment: { regions: ["DE"] }, + }, + { + default: "engine2", + environment: { experiment: "test1" }, + }, + ], + }, + { + recordType: "engineOrders", + orders: [], + }, +]; + const testSearchEngine = { id: "engine", name: "Test search engine", @@ -186,7 +376,9 @@ const testFrEngine = { loadPath: SearchUtils.newSearchConfigEnabled ? "[app]engine-fr@search.mozilla.org" : "[addon]engine-fr@search.mozilla.org", - submissionURL: "https://www.google.fr/search?q=&ie=iso-8859-1&oe=iso-8859-1", + submissionURL: SearchUtils.newSearchConfigEnabled + ? "https://www.google.fr/search?ie=iso-8859-1&oe=iso-8859-1&q=" + : "https://www.google.fr/search?q=&ie=iso-8859-1&oe=iso-8859-1", }; const testPrefEngine = { id: "engine-pref", @@ -335,7 +527,11 @@ add_setup(async () => { "_showRemovalOfSearchEngineNotificationBox" ); - await SearchTestUtils.useTestEngines("data", null, BASE_CONFIG); + await SearchTestUtils.useTestEngines( + "data", + null, + SearchUtils.newSearchConfigEnabled ? BASE_CONFIG_V2 : BASE_CONFIG + ); await AddonTestUtils.promiseStartupManager(); await Services.search.init(); @@ -344,7 +540,9 @@ add_setup(async () => { add_task(async function test_configuration_changes_default() { clearTelemetry(); - await SearchTestUtils.updateRemoteSettingsConfig(MAIN_CONFIG); + await SearchTestUtils.updateRemoteSettingsConfig( + SearchUtils.newSearchConfigEnabled ? MAIN_CONFIG_V2 : MAIN_CONFIG + ); await checkTelemetry( "config", diff --git a/toolkit/components/search/tests/xpcshell/test_validate_engines.js b/toolkit/components/search/tests/xpcshell/test_validate_engines.js index 8a25216057..d311253183 100644 --- a/toolkit/components/search/tests/xpcshell/test_validate_engines.js +++ b/toolkit/components/search/tests/xpcshell/test_validate_engines.js @@ -15,18 +15,52 @@ const ss = new SearchService(); add_task(async function test_validate_engines() { let settings = RemoteSettings(SearchUtils.SETTINGS_KEY); let config = await settings.get(); - config = config.map(e => { - return { - appliesTo: [ - { - included: { - everywhere: true, + + if (SearchUtils.newSearchConfigEnabled) { + // We do not load engines with the same name. However, in search-config-v2 + // we have multiple engines named eBay, so we error out. + // We never deploy more than one eBay in each environment so this issue + // won't be a problem. + // Ignore the error and test the configs can be created to engine objects. + consoleAllowList.push("Could not load engine"); + config = config.map(obj => { + if (obj.recordType == "engine") { + return { + recordType: "engine", + identifier: obj.identifier, + base: { + name: obj.base.name, + urls: { + search: { + base: obj.base.urls.search.base || "", + searchTermParamName: "q", + }, + }, + }, + variants: [ + { + environment: { allRegionsAndLocales: true }, + }, + ], + }; + } + + return obj; + }); + } else { + config = config.map(e => { + return { + appliesTo: [ + { + included: { + everywhere: true, + }, }, - }, - ], - webExtension: e.webExtension, - }; - }); + ], + webExtension: e.webExtension, + }; + }); + } sinon.stub(settings, "get").returns(config); await AddonTestUtils.promiseStartupManager(); diff --git a/toolkit/components/search/tests/xpcshell/test_webextensions_install.js b/toolkit/components/search/tests/xpcshell/test_webextensions_install.js index 6183d6f95a..a05218824a 100644 --- a/toolkit/components/search/tests/xpcshell/test_webextensions_install.js +++ b/toolkit/components/search/tests/xpcshell/test_webextensions_install.js @@ -80,7 +80,9 @@ add_task(async function test_install_duplicate_engine() { let submission = engine.getSubmission("foo"); Assert.equal( submission.uri.spec, - "https://duckduckgo.com/?q=foo&t=ffsb", + SearchUtils.newSearchConfigEnabled + ? "https://duckduckgo.com/?t=ffsb&q=foo" + : "https://duckduckgo.com/?q=foo&t=ffsb", "Should have not changed the app provided engine." ); @@ -127,7 +129,7 @@ add_task( let engine = await Services.search.getEngineByName("Multilocale AN"); Assert.ok( - engine.getIconURL().endsWith("favicon-an.ico"), + (await engine.getIconURL()).endsWith("favicon-an.ico"), "Should have the correct favicon for an extension of one locale using a different locale." ); Assert.equal( @@ -156,7 +158,11 @@ add_task(async function test_load_favicon_invalid() { await observed; let engine = await Services.search.getEngineByName("Example"); - Assert.equal(null, engine.getIconURL(), "Should not have set an iconURI"); + Assert.equal( + null, + await engine.getIconURL(), + "Should not have set an iconURI" + ); // User uninstalls their engine await extension.awaitStartup(); @@ -182,7 +188,11 @@ add_task(async function test_load_favicon_invalid_redirect() { await observed; let engine = await Services.search.getEngineByName("Example"); - Assert.equal(null, engine.getIconURL(), "Should not have set an iconURI"); + Assert.equal( + null, + await engine.getIconURL(), + "Should not have set an iconURI" + ); // User uninstalls their engine await extension.awaitStartup(); @@ -208,9 +218,9 @@ add_task(async function test_load_favicon_redirect() { await promiseEngineChanged; - Assert.ok(engine.getIconURL(), "Should have set an iconURI"); + Assert.ok(await engine.getIconURL(), "Should have set an iconURI"); Assert.ok( - engine.getIconURL().startsWith("data:image/x-icon;base64,"), + (await engine.getIconURL()).startsWith("data:image/x-icon;base64,"), "Should have saved the expected content type for the icon" ); diff --git a/toolkit/components/search/tests/xpcshell/test_webextensions_startup_duplicate.js b/toolkit/components/search/tests/xpcshell/test_webextensions_startup_duplicate.js index 3e42fdee13..eb7e67e66e 100644 --- a/toolkit/components/search/tests/xpcshell/test_webextensions_startup_duplicate.js +++ b/toolkit/components/search/tests/xpcshell/test_webextensions_startup_duplicate.js @@ -27,7 +27,7 @@ add_task(async function test_install_duplicate_engine_startup() { let name = "Plain"; let id = "plain@tests.mozilla.org"; consoleAllowList.push( - `#installExtensionEngine failed for ${id}`, + `#createAndAddAddonEngine failed for ${id}`, `An engine called ${name} already exists` ); // Do not use SearchTestUtils.installSearchExtension, as we need to manually @@ -51,7 +51,9 @@ add_task(async function test_install_duplicate_engine_startup() { let submission = engine.getSubmission("foo"); Assert.equal( submission.uri.spec, - "https://duckduckgo.com/?q=foo&t=ffsb", + SearchUtils.newSearchConfigEnabled + ? "https://duckduckgo.com/?t=ffsb&q=foo" + : "https://duckduckgo.com/?q=foo&t=ffsb", "Should have not changed the app provided engine." ); diff --git a/toolkit/components/search/tests/xpcshell/xpcshell.toml b/toolkit/components/search/tests/xpcshell/xpcshell.toml index 47847c93de..7dd023cbec 100644 --- a/toolkit/components/search/tests/xpcshell/xpcshell.toml +++ b/toolkit/components/search/tests/xpcshell/xpcshell.toml @@ -33,6 +33,8 @@ support-files = [ "data/engine-same-name/_locales/gd/messages.json", "data/engines-no-order-hint.json", "data/engines.json", + "data/search-config-v2.json", + "data/search-config-v2-no-order-hint.json", "data/iconsRedirect.sjs", "data/search.json", "data/search-legacy.json", @@ -60,6 +62,7 @@ support-files = [ "simple-engines/basic/manifest.json", "simple-engines/simple/manifest.json", "test-extensions/engines.json", + "test-extensions/search-config-v2.json", "test-extensions/plainengine/favicon.ico", "test-extensions/plainengine/manifest.json", "test-extensions/special-engine/favicon.ico", @@ -75,6 +78,9 @@ support-files = [ ["test_appDefaultEngine.js"] +["test_appProvided_icons.js"] +prefs = ["browser.search.newSearchConfig.enabled=true"] + ["test_async.js"] ["test_config_engine_params.js"] @@ -82,6 +88,7 @@ support-files = [ "method-extensions/get/manifest.json", "method-extensions/post/manifest.json", "method-extensions/engines.json", + "method-extensions/search-config-v2.json", ] ["test_defaultEngine.js"] @@ -110,15 +117,15 @@ support-files = [ ["test_engine_old_selector_override.js"] +["test_engine_old_selector_remote_override.js"] + ["test_engine_old_selector_remote_settings.js"] tags = "remotesettings searchmain" -["test_engine_old_selector_remote_override.js"] +["test_engine_selector_defaults.js"] ["test_engine_selector_engine_orders.js"] -["test_engine_selector_defaults.js"] - ["test_engine_selector_environment.js"] ["test_engine_selector_variants.js"] |