Bug 1870138 - Add remote settings support for search overrides. r=Standard8

Differential Revision: https://phabricator.services.mozilla.com/D196490
This commit is contained in:
Mike Kaply 2024-01-05 21:20:51 +00:00
parent e0933655b5
commit 05f593b0cc
21 changed files with 650 additions and 10 deletions

View File

@ -10,6 +10,17 @@ ChromeUtils.defineESModuleGetters(lazy, {
UrlbarSearchUtils: "resource:///modules/UrlbarSearchUtils.sys.mjs",
});
// `contextId` is a unique identifier used by Contextual Services
const CONTEXT_ID_PREF = "browser.contextual-services.contextId";
ChromeUtils.defineLazyGetter(lazy, "contextId", () => {
let _contextId = Services.prefs.getStringPref(CONTEXT_ID_PREF, null);
if (!_contextId) {
_contextId = Services.uuid.generateUUID().toString();
Services.prefs.setStringPref(CONTEXT_ID_PREF, _contextId);
}
return _contextId;
});
// A map of known search origins.
// The keys of this map are used in the calling code to recordSearch, and in
// the SEARCH_COUNTS histogram.
@ -171,6 +182,10 @@ class BrowserSearchTelemetryHandler {
* @throws if source is not in the known sources list.
*/
recordSearch(browser, engine, source, details = {}) {
if (engine.clickUrl) {
this.#reportSearchInGlean(engine.clickUrl);
}
try {
if (!this.shouldRecordSearchCount(browser)) {
return;
@ -281,6 +296,33 @@ class BrowserSearchTelemetryHandler {
}
);
}
/**
* Records the search in Glean for contextual services.
*
* @param {string} reportingUrl
* The url to be sent to contextual services.
*/
#reportSearchInGlean(reportingUrl) {
let defaultValuesByGleanKey = {
contextId: lazy.contextId,
};
let sendGleanPing = valuesByGleanKey => {
valuesByGleanKey = { ...defaultValuesByGleanKey, ...valuesByGleanKey };
for (let [gleanKey, value] of Object.entries(valuesByGleanKey)) {
let glean = Glean.searchWith[gleanKey];
if (value !== undefined && value !== "") {
glean.set(value);
}
}
GleanPings.searchWith.submit();
};
sendGleanPing({
reportingUrl,
});
}
}
export var BrowserSearchTelemetry = new BrowserSearchTelemetryHandler();

View File

@ -318,3 +318,38 @@ serp:
notification_emails:
- fx-search-telemetry@mozilla.com
expires: never
search_with:
reporting_url:
type: url
description: >
The external url to report this interaction to.
bugs:
- https://bugzilla.mozilla.org/show_bug.cgi?id=1870138
data_reviews:
- https://bugzilla.mozilla.org/show_bug.cgi?id=1870138
data_sensitivity:
- web_activity
notification_emails:
- mkaply@mozilla.com
expires: never
send_in_pings:
- search-with
context_id:
type: uuid
description: >
An identifier for Contextual Services user interaction pings. This is
used internally for counting unique users as well as for anti-fraud. It
is shared with other Contextual Services. It is not shared externally.
bugs:
- https://bugzilla.mozilla.org/show_bug.cgi?id=1870138
data_reviews:
- https://bugzilla.mozilla.org/show_bug.cgi?id=1870138#c3
data_sensitivity:
- technical
notification_emails:
- mkaply@mozilla.com
expires: never
send_in_pings:
- search-with

View File

@ -0,0 +1,22 @@
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
---
$schema: moz://mozilla.org/schemas/glean/pings/2-0-0
search-with:
description: |
A ping representing a "This time, search with" event with a partner search.
Does not contain a `client_id`, preferring a `context_id` instead.
The `context_id` is used internally for counting unique sers as well as for
anti-fraud. It is shared with other Contextual Services. It is not shared
externally.
include_client_id: false
bugs:
- https://bugzilla.mozilla.org/show_bug.cgi?id=1870138
data_reviews:
- https://bugzilla.mozilla.org/show_bug.cgi?id=1870138
notification_emails:
- mkaply@mozilla.com

View File

@ -12,6 +12,8 @@ FINAL_TARGET_FILES.defaults.settings.main += [
"language-dictionaries.json",
"password-recipes.json",
"password-rules.json",
"search-config-overrides-v2.json",
"search-config-overrides.json",
"search-config-v2.json",
"search-config.json",
"search-default-override-allowlist.json",

View File

@ -0,0 +1,4 @@
{
"data": [],
"timestamp": 1704379586890
}

View File

@ -0,0 +1,4 @@
{
"data": [],
"timestamp": 1704379586619
}

View File

@ -113,6 +113,7 @@ gecko_pings = [
firefox_desktop_pings = [
"browser/components/newtab/pings.yaml",
"browser/components/pocket/pings.yaml",
"browser/components/search/pings.yaml",
"browser/components/urlbar/pings.yaml",
"toolkit/components/crashes/pings.yaml",
"toolkit/components/telemetry/pings.yaml",

View File

@ -1008,6 +1008,10 @@ export class SearchEngine {
this._urls.push(trending);
}
if (configuration.clickUrl) {
this.clickUrl = configuration.clickUrl;
}
if (details.encoding) {
this._queryCharset = details.encoding;
}

View File

@ -28,8 +28,13 @@ export class SearchEngineSelector {
*/
constructor(listener) {
this._remoteConfig = lazy.RemoteSettings(lazy.SearchUtils.NEW_SETTINGS_KEY);
this._remoteConfigOverrides = lazy.RemoteSettings(
lazy.SearchUtils.NEW_SETTINGS_OVERRIDES_KEY
);
this._listenerAdded = false;
this._onConfigurationUpdated = this._onConfigurationUpdated.bind(this);
this._onConfigurationOverridesUpdated =
this._onConfigurationOverridesUpdated.bind(this);
this._changeListener = listener;
}
@ -41,8 +46,13 @@ export class SearchEngineSelector {
return this._getConfigurationPromise;
}
this._configuration = await (this._getConfigurationPromise =
this._getConfiguration());
this._getConfigurationPromise = Promise.all([
this._getConfiguration(),
this._getConfigurationOverrides(),
]);
let remoteSettingsData = await this._getConfigurationPromise;
this._configuration = remoteSettingsData[0];
this._configurationOverrides = remoteSettingsData[1];
delete this._getConfigurationPromise;
if (!this._configuration?.length) {
@ -54,12 +64,24 @@ export class SearchEngineSelector {
if (!this._listenerAdded) {
this._remoteConfig.on("sync", this._onConfigurationUpdated);
this._remoteConfigOverrides.on(
"sync",
this._onConfigurationOverridesUpdated
);
this._listenerAdded = true;
}
return this._configuration;
}
/**
* Used by tests to get the configuration overrides.
*/
async getEngineConfigurationOverrides() {
await this.getEngineConfiguration();
return this._configurationOverrides;
}
/**
* Obtains the configuration from remote settings. This includes
* verifying the signature of the record within the database.
@ -119,6 +141,42 @@ export class SearchEngineSelector {
}
}
/**
* Handles updating of the configuration. Note that the search service is
* only updated after a period where the user is observed to be idle.
*
* @param {object} options
* The options object
* @param {object} options.data
* The data to update
* @param {Array} options.data.current
* The new configuration object
*/
_onConfigurationOverridesUpdated({ data: { current } }) {
this._configurationOverrides = current;
lazy.logConsole.debug("Search configuration overrides updated remotely");
if (this._changeListener) {
this._changeListener();
}
}
/**
* Obtains the configuration overrides from remote settings.
*
* @returns {Array}
* An array of objects in the database, or an empty array if none
* could be obtained.
*/
async _getConfigurationOverrides() {
let result = [];
try {
result = await this._remoteConfigOverrides.get();
} catch (ex) {
// This data is remote only, so we just return an empty array if it fails.
}
return result;
}
/**
* @param {object} options
* The options object
@ -205,6 +263,12 @@ export class SearchEngineSelector {
engine = this.#deepCopyObject(engine, variant);
}
for (let override of this._configurationOverrides) {
if (override.identifier == engine.identifier) {
engine = this.#deepCopyObject(engine, override);
}
}
engines.push(engine);
}

View File

@ -73,8 +73,13 @@ export class SearchEngineSelectorOld {
constructor(listener) {
this.QueryInterface = ChromeUtils.generateQI(["nsIObserver"]);
this._remoteConfig = lazy.RemoteSettings(lazy.SearchUtils.OLD_SETTINGS_KEY);
this._remoteConfigOverrides = lazy.RemoteSettings(
lazy.SearchUtils.OLD_SETTINGS_OVERRIDES_KEY
);
this._listenerAdded = false;
this._onConfigurationUpdated = this._onConfigurationUpdated.bind(this);
this._onConfigurationOverridesUpdated =
this._onConfigurationOverridesUpdated.bind(this);
this._changeListener = listener;
}
@ -86,8 +91,13 @@ export class SearchEngineSelectorOld {
return this._getConfigurationPromise;
}
this._configuration = await (this._getConfigurationPromise =
this._getConfiguration());
this._getConfigurationPromise = Promise.all([
this._getConfiguration(),
this._getConfigurationOverrides(),
]);
let remoteSettingsData = await this._getConfigurationPromise;
this._configuration = remoteSettingsData[0];
this._configurationOverrides = remoteSettingsData[1];
delete this._getConfigurationPromise;
if (!this._configuration?.length) {
@ -99,12 +109,24 @@ export class SearchEngineSelectorOld {
if (!this._listenerAdded) {
this._remoteConfig.on("sync", this._onConfigurationUpdated);
this._remoteConfigOverrides.on(
"sync",
this._onConfigurationOverridesUpdated
);
this._listenerAdded = true;
}
return this._configuration;
}
/**
* Used by tests to get the configuration overrides.
*/
async getEngineConfigurationOverrides() {
await this.getEngineConfiguration();
return this._configurationOverrides;
}
/**
* Obtains the configuration from remote settings. This includes
* verifying the signature of the record within the database.
@ -164,6 +186,42 @@ export class SearchEngineSelectorOld {
}
}
/**
* Handles updating of the configuration. Note that the search service is
* only updated after a period where the user is observed to be idle.
*
* @param {object} options
* The options object
* @param {object} options.data
* The data to update
* @param {Array} options.data.current
* The new configuration object
*/
_onConfigurationOverridesUpdated({ data: { current } }) {
this._configurationOverrides = current;
lazy.logConsole.debug("Search configuration overrides updated remotely");
if (this._changeListener) {
this._changeListener();
}
}
/**
* Obtains the configuration overrides from remote settings.
*
* @returns {Array}
* An array of objects in the database, or an empty array if none
* could be obtained.
*/
async _getConfigurationOverrides() {
let result = [];
try {
result = await this._remoteConfigOverrides.get();
} catch (ex) {
// This data is remote only, so we just return an empty array if it fails.
}
return result;
}
/**
* @param {object} options
* The options object
@ -314,6 +372,22 @@ export class SearchEngineSelectorOld {
) {
defaultEngine = engine;
}
if (engine.telemetryId) {
for (let override of this._configurationOverrides) {
if (override.telemetryId == engine.telemetryId) {
engine.params = this._copyObject(
engine.params || {},
override.params
);
if (override.clickUrl) {
engine.clickUrl = override.clickUrl;
}
if (override.telemetrySuffix) {
engine.telemetryId += `-${override.telemetrySuffix}`;
}
}
}
}
if (
"defaultPrivate" in engine &&
shouldPrefer(
@ -387,7 +461,7 @@ export class SearchEngineSelectorOld {
* Object.assign but ignore some keys
*
* @param {object} target - Object to copy to.
* @param {object} source - Object top copy from.
* @param {object} source - Object to copy from.
* @returns {object} - The source object.
*/
_copyObject(target, source) {

View File

@ -139,6 +139,20 @@ export var SearchUtils = {
*/
NEW_SETTINGS_KEY: "search-config-v2",
/**
* This is the Remote Settings key for getting the overrides for the
* older search engine configuration. Tests may use `SETTINGS_OVERRIDES_KEY`
* for the current configuration according to the preference.
*/
OLD_SETTINGS_OVERRIDES_KEY: "search-config-overrides",
/**
* This is the Remote Settings key for getting the overrides for the
* newer search engine configuration. Tests may use `SETTINGS_OVERRIDES_KEY`
* for the current configuration according to the preference.
*/
NEW_SETTINGS_OVERRIDES_KEY: "search-config-overrides-v2",
/**
* This is the Remote Settings key that we use to get the search engine
* configurations.
@ -151,6 +165,18 @@ export var SearchUtils = {
: SearchUtils.OLD_SETTINGS_KEY;
},
/**
* This is the Remote Settings key that we use to get the search engine
* configuration overrides.
*
* @returns {string}
*/
get SETTINGS_OVERRIDES_KEY() {
return SearchUtils.newSearchConfigEnabled
? SearchUtils.NEW_SETTINGS_OVERRIDES_KEY
: SearchUtils.OLD_SETTINGS_OVERRIDES_KEY;
},
/**
* Topic used for events involving the service itself.
*/

View File

@ -199,12 +199,18 @@ interface nsISearchEngine : nsISupports
readonly attribute boolean isGeneralPurposeEngine;
/**
* The domain from which search results are returned for this engine.
*
* @return the domain of the the search URL.
*/
readonly attribute AString searchUrlDomain;
* The domain from which search results are returned for this engine.
*
* @return the domain of the the search URL.
*/
readonly attribute AString searchUrlDomain;
/**
* The URL to report the search to.
*
* @return the reporting URL.
*/
readonly attribute AString clickUrl;
};
[scriptable, uuid(0dc93e51-a7bf-4a16-862d-4b3469ff6206)]

View File

@ -0,0 +1,64 @@
{
"title": "Search Engine Overrides Schema",
"description": "This schema contains the details for overriding application provided search engines defined in search-config. The associated remote settings collection is search-config-overrides.",
"type": "object",
"required": ["telemetryId"],
"properties": {
"telemetryId": {
"type": "string",
"title": "Telemetry Id",
"description": "The telemetry Id used to match the engine that this record will override.",
"pattern": "^[a-zA-Z0-9-$_]{0,100}$"
},
"params": {
"$ref": "#/definitions/params"
},
"clickUrl": {
"type": "string",
"format": "uri",
"description": "The url used to for reporting clicks."
},
"telemetrySuffix": {
"type": "string",
"title": "Telemetry Suffix",
"description": "Suffix that is appended to the search engine identifier following a dash, i.e. `<identifier>-<suffix>`.",
"pattern": "^[a-zA-Z0-9-]*$"
}
},
"definitions": {
"searchUrlCodes": {
"type": "array",
"title": "Codes",
"description": "A array of objects - map of parameter name to the parameter value.",
"items": {
"type": "object",
"properties": {
"name": {
"type": "string",
"title": "Name",
"pattern": "^[a-zA-Z0-9.-]{0,100}$",
"description": "Name of the parameter that will be used in the query"
},
"value": {
"type": "string",
"title": "Value",
"pattern": "^[a-zA-Z0-9_{}:/.-]{0,100}$",
"description": "The value of parameter (pref or purpose)"
}
}
}
},
"params": {
"type": "object",
"title": "Parameters",
"description": "Various parameters for the search engines",
"properties": {
"searchUrlGetParams": {
"title": "Search URL GET Parameters",
"description": "Extra parameters for search URLs (e.g. 'pc=foo').",
"$ref": "#/definitions/searchUrlCodes"
}
}
}
}
}

View File

@ -0,0 +1,79 @@
{
"title": "Search Engine Overrides Schema",
"description": "This schema contains the details for overriding application provided search engines defined in search-config-v2. The associated remote settings collection is search-config-overrides-v2.",
"definitions": {
"partnerCode": {
"title": "Partner Code",
"description": "The partner code for the engine or variant. This will be inserted into parameters which include '{partnerCode}'",
"type": "string",
"pattern": "^[a-zA-Z0-9-_]*$"
},
"urls": {
"title": "URLs",
"description": "The URLs associated with the search engine.",
"type": "object",
"properties": {
"search": {
"title": "Search URL",
"description": "The URL to use for searches",
"$ref": "#/definitions/url"
}
}
},
"url": {
"type": "object",
"properties": {
"base": {
"title": "Base",
"description": "The PrePath and FilePath of the URL. May include variables for engines which have a variable FilePath, e.g. {searchTerm} for when a search term is within the path of the url.",
"type": "string"
},
"params": {
"title": "Parameters",
"description": "The parameters for this URL.",
"type": "array",
"items": {
"type": "object",
"title": "Parameter",
"properties": {
"name": {
"title": "Name",
"description": "The parameter name",
"type": "string",
"pattern": "^[a-zA-Z0-9-_]*$"
},
"value": {
"title": "Value",
"description": "The parameter value, this may be a static value, or additionally contain a parameter replacement, e.g. {inputEncoding}. For the partner code parameter, this field should be {pc}.",
"type": "string",
"pattern": "^[a-zA-Z0-9-_{}]*$"
}
},
"required": ["name", "value"]
}
}
}
}
},
"type": "object",
"properties": {
"identifier": {
"title": "Identifier",
"description": "This is the identifier of the search engine in search-config-v2 that this record will override. It may be extended by telemetrySuffix.",
"type": "string",
"pattern": "^[a-zA-Z0-9-_]*$"
},
"partnerCode": {
"$ref": "#/definitions/partnerCode"
},
"telemetrySuffix": {
"title": "Telemetry Suffix",
"description": "Suffix that is appended to the search engine identifier following a dash, i.e. `<identifier>-<suffix>`. There should always be a suffix supplied if the partner code is different.",
"type": "string",
"pattern": "^[a-zA-Z0-9-]*$"
},
"urls": {
"$ref": "#/definitions/urls"
}
}
}

View File

@ -103,6 +103,29 @@ async function checkSearchConfigValidates(schema, searchConfig) {
}
}
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_task(async function test_search_config_validates_to_schema_v1() {
let selector = new SearchEngineSelectorOld(() => {});
let searchConfig = await selector.getEngineConfiguration();
@ -118,6 +141,19 @@ add_task(async function test_ui_schema_valid_v1() {
await checkUISchemaValid(searchConfigSchemaV1, uiSchema);
});
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
);
});
if (SearchUtils.newSearchConfigEnabled) {
add_task(async function test_search_config_validates_to_schema() {
delete SearchUtils.newSearchConfigEnabled;
@ -136,4 +172,21 @@ if (SearchUtils.newSearchConfigEnabled) {
await checkUISchemaValid(searchConfigSchema, uiSchema);
});
add_task(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
);
});
}

View File

@ -42,6 +42,8 @@ requesttimeoutfactor = 2
["test_searchconfig_validates.js"]
support-files = [
"../../../schema/search-config-overrides-schema.json",
"../../../schema/search-config-overrides-v2-schema.json",
"../../../schema/search-config-schema.json",
"../../../schema/search-config-ui-schema.json",
"../../../schema/search-config-v2-schema.json",

View File

@ -174,7 +174,9 @@ const CONFIG_DEFAULTS_OVERRIDE = [
const engineSelector = new SearchEngineSelector();
let settings;
let settingOverrides;
let configStub;
let overrideStub;
/**
* This function asserts if the actual engine identifiers returned equals
@ -222,6 +224,11 @@ async function assertActualEnginesEqualsExpected(
add_setup(async function () {
settings = await RemoteSettings(SearchUtils.NEW_SETTINGS_KEY);
configStub = sinon.stub(settings, "get");
settingOverrides = await RemoteSettings(
SearchUtils.NEW_SETTINGS_OVERRIDES_KEY
);
overrideStub = sinon.stub(settingOverrides, "get");
overrideStub.returns([]);
});
add_task(async function test_default_engines() {

View File

@ -225,7 +225,9 @@ const DEFAULTS_CONFIG = [
const engineSelector = new SearchEngineSelector();
let settings;
let settingOverrides;
let configStub;
let overrideStub;
/**
* This function asserts if the actual engine identifiers returned equals
@ -259,6 +261,11 @@ async function assertActualEnginesEqualsExpected(
add_setup(async function () {
settings = await RemoteSettings(SearchUtils.NEW_SETTINGS_KEY);
configStub = sinon.stub(settings, "get");
settingOverrides = await RemoteSettings(
SearchUtils.NEW_SETTINGS_OVERRIDES_KEY
);
overrideStub = sinon.stub(settingOverrides, "get");
overrideStub.returns([]);
});
add_task(async function test_selector_match_engine_orders() {

View File

@ -338,7 +338,9 @@ const CONFIG_VERSIONS = [
const engineSelector = new SearchEngineSelector();
let settings;
let settingOverrides;
let configStub;
let overrideStub;
/**
* This function asserts if the actual engine identifiers returned equals
@ -370,6 +372,11 @@ async function assertActualEnginesEqualsExpected(
add_setup(async function () {
settings = await RemoteSettings(SearchUtils.NEW_SETTINGS_KEY);
configStub = sinon.stub(settings, "get");
settingOverrides = await RemoteSettings(
SearchUtils.NEW_SETTINGS_OVERRIDES_KEY
);
overrideStub = sinon.stub(settingOverrides, "get");
overrideStub.returns([]);
});
add_task(async function test_selector_match_experiment() {

View File

@ -0,0 +1,135 @@
/* Any copyright is dedicated to the Public Domain.
* http://creativecommons.org/publicdomain/zero/1.0/ */
"use strict";
ChromeUtils.defineESModuleGetters(this, {
SearchEngineSelectorOld:
"resource://gre/modules/SearchEngineSelectorOld.sys.mjs",
SearchEngineSelector: "resource://gre/modules/SearchEngineSelector.sys.mjs",
});
const TEST_CONFIG_OLD = [
{
engineName: "aol",
telemetryId: "aol",
appliesTo: [
{
included: { everywhere: true },
},
],
params: {
searchUrlGetParams: [
{
name: "original_param",
value: "original_value",
},
],
},
},
];
const TEST_CONFIG_OVERRIDE_OLD = [
{
telemetryId: "aol",
telemetrySuffix: "tsfx",
params: {
searchUrlGetParams: [
{
name: "new_param",
value: "new_value",
},
],
},
},
];
const TEST_CONFIG = [
{
base: {
urls: {
search: {
base: "https://www.bing.com/search",
params: [
{
name: "old_param",
value: "old_value",
},
],
searchTermParamName: "q",
},
},
},
variants: [
{
environment: {
locales: ["en-US"],
},
},
],
identifier: "aol",
recordType: "engine",
},
{
recordType: "defaultEngines",
globalDefault: "aol",
specificDefaults: [],
},
{
orders: [],
recordType: "engineOrders",
},
];
const TEST_CONFIG_OVERRIDE = [
{
identifier: "aol",
urls: {
search: {
params: [{ name: "new_param", value: "new_value" }],
},
},
telemetrySuffix: "tsfx",
clickUrl: "https://aol.url",
},
];
const engineSelectorOld = new SearchEngineSelectorOld();
const engineSelector = new SearchEngineSelector();
add_setup(async function () {
const settingsOld = await RemoteSettings(SearchUtils.OLD_SETTINGS_KEY);
sinon.stub(settingsOld, "get").returns(TEST_CONFIG_OLD);
const overridesOld = await RemoteSettings(
SearchUtils.OLD_SETTINGS_OVERRIDES_KEY
);
sinon.stub(overridesOld, "get").returns(TEST_CONFIG_OVERRIDE_OLD);
const settings = await RemoteSettings(SearchUtils.NEW_SETTINGS_KEY);
sinon.stub(settings, "get").returns(TEST_CONFIG);
const overrides = await RemoteSettings(
SearchUtils.NEW_SETTINGS_OVERRIDES_KEY
);
sinon.stub(overrides, "get").returns(TEST_CONFIG_OVERRIDE);
});
add_task(async function test_engine_selector_old() {
let { engines } = await engineSelectorOld.fetchEngineConfiguration({
locale: "en-US",
region: "us",
});
Assert.equal(engines[0].telemetryId, "aol-tsfx");
Assert.equal(engines[0].params.searchUrlGetParams[0].name, "new_param");
Assert.equal(engines[0].params.searchUrlGetParams[0].value, "new_value");
});
add_task(async function test_engine_selector() {
let { engines } = await engineSelector.fetchEngineConfiguration({
locale: "en-US",
region: "us",
});
Assert.equal(engines[0].telemetrySuffix, "tsfx");
Assert.equal(engines[0].clickUrl, "https://aol.url");
Assert.equal(engines[0].urls.search.params[0].name, "new_param");
Assert.equal(engines[0].urls.search.params[0].value, "new_value");
});

View File

@ -119,6 +119,8 @@ support-files = [
["test_engine_selector_remote_settings.js"]
tags = "remotesettings searchmain"
["test_engine_selector_remote_override.js"]
["test_engine_set_alias.js"]
["test_getSubmission_encoding.js"]