Source code
Revision control
Copy as Markdown
Other Tools
Test Info: Warnings
- This test gets skipped with pattern: os == 'android'
- Manifest: toolkit/components/search/tests/xpcshell/xpcshell.toml
/* 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
/*
* Tests searchTermFromResult API.
*/
let CONFIG_V2 = [
{
recordType: "engine",
identifier: "engine-purposes",
base: {
name: "Test Engine With Purposes",
urls: {
search: {
params: [
{ name: "pc", value: "FIREFOX" },
{
name: "channel",
experimentConfig: "testChannelEnabled",
},
],
searchTermParamName: "q",
},
},
},
variants: [
{
environment: { allRegionsAndLocales: true },
},
],
},
];
let defaultEngine;
// The test string contains special characters to ensure
// that they are encoded/decoded properly.
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 () {
SearchTestUtils.setRemoteSettingsConfig(CONFIG_V2);
await Services.search.init();
defaultEngine = Services.search.getEngineByName("Test Engine With Purposes");
});
add_task(async function test_searchTermFromResult() {
// Internationalized Domain Name search engine.
await SearchTestUtils.installSearchExtension({
name: "idn_addParam",
keyword: "idn_addParam",
});
let engineEscapedIDN = Services.search.getEngineByName("idn_addParam");
// Setup server for french engine.
await useHttpServer("");
// For ISO-8859-1 encoding testing.
let engineISOCharset = await SearchTestUtils.installOpenSearchEngine({
url: `${gHttpURL}/opensearch/fr-domain-iso8859-1.xml`,
});
// For Windows-1252 encoding testing.
await SearchTestUtils.installSearchExtension({
name: "bacon_addParam",
keyword: "bacon_addParam",
encoding: "windows-1252",
});
let engineWinCharset = Services.search.getEngineByName("bacon_addParam");
// Verify getValidEngineUrl returns a URL that can return a search term.
let testUrl = getValidEngineUrl();
Assert.equal(
getTerm(testUrl),
TERM,
"Should get term from a url generated by getSubmission."
);
testUrl = getValidEngineUrl();
testUrl.pathname = "/SEARCH";
Assert.equal(
getTerm(testUrl),
TERM,
"Should get term even if path is not the same case as the engine."
);
Assert.equal(
getTerm(url, engineEscapedIDN),
TERM,
"Should get term from IDNs urls."
);
Assert.equal(
getTerm(url, engineISOCharset),
"caf\u00E8 au lait",
"Should get term from ISO-8859-1 encoded url containing a search term."
);
Assert.equal(
getTerm(url, engineISOCharset),
"",
"Should get a blank string from ISO-8859-1 encoded url missing a search term"
);
Assert.equal(
getTerm(url, engineWinCharset),
"caf\u00E8 au lait",
"Should get term from Windows-1252 encoded url containing a search term."
);
Assert.equal(
getTerm(url, engineWinCharset),
"",
"Should get a blank string from Windows-1252 encoded url missing a search term."
);
url = "about:blank";
Assert.equal(getTerm(url), "", "Should get a blank string from about:blank.");
url = "about:newtab";
Assert.equal(
getTerm(url),
"",
"Should get a blank string from about:newtab."
);
});
// Use a version of the url that should return a term and make minute
// modifications that should cause it to return a blank value.
add_task(async function test_searchTermFromResult_blank() {
let url = getValidEngineUrl();
url.searchParams.set("hello", "world");
Assert.equal(
getTerm(url),
"",
"Should get a blank string from url containing query param name not recognized by the engine."
);
url = getValidEngineUrl();
url.protocol = "http";
Assert.equal(
getTerm(url),
"",
"Should get a blank string from url that has a different scheme from the engine."
);
url = getValidEngineUrl();
url.protocol = "http";
Assert.equal(
getTerm(url),
"",
"Should get a blank string from url that has a different path from the engine."
);
url = getValidEngineUrl();
url.host = "images.example.com";
Assert.equal(
getTerm(url),
"",
"Should get a blank string from url that has a different host from the engine."
);
url = getValidEngineUrl();
url.host = "example.com";
Assert.equal(
getTerm(url),
"",
"Should get a blank string from url that has a different host from the engine."
);
url = getValidEngineUrl();
url.searchParams.set("form", "MOZUNKNOWN");
Assert.equal(
getTerm(url),
"",
"Should get a blank string from a url that has an un-recognized form value."
);
url = getValidEngineUrl();
url.searchParams.set("q", "");
Assert.equal(
getTerm(url),
"",
"Should get a blank string from a url with a missing search query value."
);
url = getValidEngineUrl();
url.searchParams.delete("q");
Assert.equal(
getTerm(url),
"",
"Should get a blank string from a url with a missing search query name."
);
url = getValidEngineUrl();
url.searchParams.delete("pc");
Assert.equal(
getTerm(url),
"",
"Should get a blank string from a url with a missing a query parameter."
);
});
add_task(async function test_searchTermFromResult_prefParam() {
const defaultBranch = Services.prefs.getDefaultBranch(
SearchUtils.BROWSER_SEARCH_PREF
);
defaultBranch.setCharPref("param.testChannelEnabled", "yes");
let url = getValidEngineUrl(true);
Assert.equal(getTerm(url), TERM, "Should get term after pref is turned on.");
url.searchParams.delete("channel");
Assert.equal(
getTerm(url),
"",
"Should get a blank string if pref is on and channel param is missing."
);
defaultBranch.setCharPref("param.testChannelEnabled", "");
url = getValidEngineUrl(true);
Assert.equal(getTerm(url), TERM, "Should get term after pref is turned off.");
url.searchParams.set("channel", "yes");
Assert.equal(
getTerm(url),
"",
"Should get a blank string if pref is turned off but channel param is present."
);
});
// searchTermFromResult attempts to look into the template of a search
// engine if query params aren't present in the url.params, so make sure
// it works properly and fails gracefully.
add_task(async function test_searchTermFromResult_paramsInSearchUrl() {
await SearchTestUtils.installSearchExtension({
name: "engine_params_in_search_url",
search_url_get_params: "",
});
let testEngine = Services.search.getEngineByName(
"engine_params_in_search_url"
);
Assert.equal(
getTerm(url, testEngine),
TERM,
"Should get term from an engine with params in its search url."
);
Assert.equal(
getTerm(url, testEngine),
"",
"Should get a blank string when not all params are present."
);
await SearchTestUtils.installSearchExtension({
name: "engine_params_in_search_url_without_delimiter",
search_url_get_params: "",
});
testEngine = Services.search.getEngineByName(
"engine_params_in_search_url_without_delimiter"
);
Assert.equal(
getTerm(url, testEngine),
"",
"Should get a blank string from an engine with no params and no delimiter in its url."
);
});
add_task(async function test_searchTermFrom_skipParamMatching() {
info(
"Reuse engine that has a partner code and parameter corresponding to a search."
);
let testEngine = Services.search.getEngineByName(
"engine_params_in_search_url"
);
info("Enable skip param matching.");
const SKIP_PARAM_MATCHING = true;
Assert.equal(
getTerm(url, testEngine, SKIP_PARAM_MATCHING),
TERM,
"Should get term when all known params are present."
);
Assert.equal(
getTerm(url, testEngine, SKIP_PARAM_MATCHING),
TERM,
"Should get term even when missing a known non-search query param."
);
Assert.equal(
getTerm(url, testEngine, SKIP_PARAM_MATCHING),
TERM,
"Should get term when an unknown param is added."
);
Assert.equal(
getTerm(url, testEngine, SKIP_PARAM_MATCHING),
"",
"Should not get term when the search query is missing."
);
Assert.equal(
getTerm(url, testEngine, SKIP_PARAM_MATCHING),
"",
"Should not get term when the input origin differs."
);
});
function getTerm(url, searchEngine = defaultEngine, skipParamMatching) {
return searchEngine.searchTermFromResult(
Services.io.newURI(url.toString()),
skipParamMatching
);
}
// Return a new instance of a submission URL so that it can modified
// and tested again. Allow callers to force the cache to update, especially
// if the engine is expected to have updated.
function getValidEngineUrl(updateCache = false) {
if (updateCache || !this._submissionUrl) {
this._submissionUrl = defaultEngine.getSubmission(TERM, null).uri.spec;
}
return new URL(this._submissionUrl);
}