mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-28 07:13:20 +00:00
Bug 1736684 - Part 2: Add test coverage for the search-detection built-in add-on (server side). r=rpl
- `test_redirect_{final,two_hops,three_hops}` correspond to SSR #1 - `test_no_event_when_search_engine_not_used` corresponds to SSR #2 - `test_redirect_chain_does_not_start_on_first_request` corresponds to SSR #3 - `test_two_extensions_reported` corresponds to SSR #4 Differential Revision: https://phabricator.services.mozilla.com/D129176
This commit is contained in:
parent
51c0ff21e5
commit
2771da7b40
@ -1,4 +1,7 @@
|
||||
[DEFAULT]
|
||||
support-files =
|
||||
redirect.sjs
|
||||
|
||||
[browser_client_side_redirection.js]
|
||||
[browser_extension_loaded.js]
|
||||
[browser_server_side_redirection.js]
|
||||
|
@ -1,6 +1,5 @@
|
||||
/* 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/. */
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
* http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
"use strict";
|
||||
|
||||
|
@ -0,0 +1,260 @@
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
* http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
"use strict";
|
||||
|
||||
const { AddonTestUtils } = ChromeUtils.import(
|
||||
"resource://testing-common/AddonTestUtils.jsm"
|
||||
);
|
||||
|
||||
const { TelemetryTestUtils } = ChromeUtils.import(
|
||||
"resource://testing-common/TelemetryTestUtils.jsm"
|
||||
);
|
||||
|
||||
AddonTestUtils.initMochitest(this);
|
||||
|
||||
const TELEMETRY_EVENTS_FILTERS = {
|
||||
category: "addonsSearchDetection",
|
||||
method: "etld_change",
|
||||
};
|
||||
|
||||
// The search-detection built-in add-on registers dynamic events.
|
||||
const TELEMETRY_TEST_UTILS_OPTIONS = { clear: true, process: "dynamic" };
|
||||
|
||||
const REDIRECT_SJS =
|
||||
"browser/browser/extensions/search-detection/tests/browser/redirect.sjs?q={searchTerms}";
|
||||
// This URL will redirect to `example.net`, which is different than
|
||||
// `*.example.com`. That will be the final URL of a redirect chain:
|
||||
// www.example.com -> example.net
|
||||
const SEARCH_URL_WWW = `https://www.example.com/${REDIRECT_SJS}`;
|
||||
// This URL will redirect to `www.example.com`, which will create a redirect
|
||||
// chain with two hops:
|
||||
// test2.example.com -> www.example.com -> example.net
|
||||
const SEARCH_URL_TEST2 = `https://test2.example.com/${REDIRECT_SJS}`;
|
||||
// This URL will redirect to `test2.example.com`, which will create a redirect
|
||||
// chain with three hops:
|
||||
// test1.example.com -> test2.example.com -> www.example.com -> example.net
|
||||
const SEARCH_URL_TEST1 = `https://test1.example.com/${REDIRECT_SJS}`;
|
||||
|
||||
const TEST_SEARCH_ENGINE_ADDON_ID = "some@addon-id";
|
||||
const TEST_SEARCH_ENGINE_ADDON_VERSION = "4.5.6";
|
||||
|
||||
const testServerSideRedirect = async ({
|
||||
searchURL,
|
||||
expectedEvents,
|
||||
tabURL,
|
||||
}) => {
|
||||
Services.telemetry.clearEvents();
|
||||
|
||||
const searchEngineName = "test search engine";
|
||||
// Load a default search engine because the add-on we are testing here
|
||||
// monitors the search engines.
|
||||
const searchEngine = ExtensionTestUtils.loadExtension({
|
||||
manifest: {
|
||||
version: TEST_SEARCH_ENGINE_ADDON_VERSION,
|
||||
browser_specific_settings: {
|
||||
gecko: { id: TEST_SEARCH_ENGINE_ADDON_ID },
|
||||
},
|
||||
chrome_settings_overrides: {
|
||||
search_provider: {
|
||||
name: searchEngineName,
|
||||
keyword: "test",
|
||||
search_url: searchURL,
|
||||
},
|
||||
},
|
||||
},
|
||||
useAddonManager: "temporary",
|
||||
});
|
||||
|
||||
await searchEngine.startup();
|
||||
ok(
|
||||
Services.search.getEngineByName(searchEngineName),
|
||||
"test search engine registered"
|
||||
);
|
||||
await AddonTestUtils.waitForSearchProviderStartup(searchEngine);
|
||||
|
||||
// Simulate a search (with the test search engine) by navigating to it.
|
||||
const url = tabURL || searchURL.replace("{searchTerms}", "some terms");
|
||||
await BrowserTestUtils.withNewTab("about:blank", async browser => {
|
||||
// Wait for the tab to be fully loaded.
|
||||
let loaded = BrowserTestUtils.browserLoaded(browser);
|
||||
BrowserTestUtils.loadURI(browser, url);
|
||||
await loaded;
|
||||
});
|
||||
|
||||
await searchEngine.unload();
|
||||
ok(
|
||||
!Services.search.getEngineByName(searchEngineName),
|
||||
"test search engine unregistered"
|
||||
);
|
||||
|
||||
TelemetryTestUtils.assertEvents(
|
||||
expectedEvents,
|
||||
TELEMETRY_EVENTS_FILTERS,
|
||||
TELEMETRY_TEST_UTILS_OPTIONS
|
||||
);
|
||||
};
|
||||
|
||||
add_task(function test_redirect_final() {
|
||||
return testServerSideRedirect({
|
||||
// www.example.com -> example.net
|
||||
searchURL: SEARCH_URL_WWW,
|
||||
expectedEvents: [
|
||||
{
|
||||
object: "other",
|
||||
value: "server",
|
||||
extra: {
|
||||
addonId: TEST_SEARCH_ENGINE_ADDON_ID,
|
||||
addonVersion: TEST_SEARCH_ENGINE_ADDON_VERSION,
|
||||
from: "example.com",
|
||||
to: "example.net",
|
||||
},
|
||||
},
|
||||
],
|
||||
});
|
||||
});
|
||||
|
||||
add_task(function test_redirect_two_hops() {
|
||||
return testServerSideRedirect({
|
||||
// test2.example.com -> www.example.com -> example.net
|
||||
searchURL: SEARCH_URL_TEST2,
|
||||
expectedEvents: [
|
||||
{
|
||||
object: "other",
|
||||
value: "server",
|
||||
extra: {
|
||||
addonId: TEST_SEARCH_ENGINE_ADDON_ID,
|
||||
addonVersion: TEST_SEARCH_ENGINE_ADDON_VERSION,
|
||||
from: "example.com",
|
||||
to: "example.net",
|
||||
},
|
||||
},
|
||||
],
|
||||
});
|
||||
});
|
||||
|
||||
add_task(function test_redirect_three_hops() {
|
||||
return testServerSideRedirect({
|
||||
// test1.example.com -> test2.example.com -> www.example.com -> example.net
|
||||
searchURL: SEARCH_URL_TEST1,
|
||||
expectedEvents: [
|
||||
{
|
||||
object: "other",
|
||||
value: "server",
|
||||
extra: {
|
||||
addonId: TEST_SEARCH_ENGINE_ADDON_ID,
|
||||
addonVersion: TEST_SEARCH_ENGINE_ADDON_VERSION,
|
||||
from: "example.com",
|
||||
to: "example.net",
|
||||
},
|
||||
},
|
||||
],
|
||||
});
|
||||
});
|
||||
|
||||
add_task(function test_no_event_when_search_engine_not_used() {
|
||||
return testServerSideRedirect({
|
||||
// www.example.com -> example.net
|
||||
searchURL: SEARCH_URL_WWW,
|
||||
// We do not expect any events because the user is not using the search
|
||||
// engine that was registered.
|
||||
tabURL: "http://mochi.test:8888/search?q=foobar",
|
||||
expectedEvents: [],
|
||||
});
|
||||
});
|
||||
|
||||
add_task(function test_redirect_chain_does_not_start_on_first_request() {
|
||||
return testServerSideRedirect({
|
||||
// www.example.com -> example.net
|
||||
searchURL: SEARCH_URL_WWW,
|
||||
// User first navigates to an URL that isn't monitored and will be
|
||||
// redirected to another URL that is monitored.
|
||||
tabURL: `http://mochi.test:8888/browser/browser/extensions/search-detection/tests/browser/redirect.sjs?q={searchTerms}`,
|
||||
expectedEvents: [
|
||||
{
|
||||
object: "other",
|
||||
value: "server",
|
||||
extra: {
|
||||
addonId: TEST_SEARCH_ENGINE_ADDON_ID,
|
||||
addonVersion: TEST_SEARCH_ENGINE_ADDON_VERSION,
|
||||
// We expect this and not `mochi.test` because we do not monitor
|
||||
// `mochi.test`, only `example.com`, which is coming from the search
|
||||
// engine registered in the test setup.
|
||||
from: "example.com",
|
||||
to: "example.net",
|
||||
},
|
||||
},
|
||||
],
|
||||
});
|
||||
});
|
||||
|
||||
add_task(async function test_two_extensions_reported() {
|
||||
Services.telemetry.clearEvents();
|
||||
|
||||
const searchEngines = [];
|
||||
for (const [addonId, addonVersion, isDefault] of [
|
||||
["1-addon@guid", "1.2", false],
|
||||
["2-addon@guid", "3.4", true],
|
||||
]) {
|
||||
const searchEngine = ExtensionTestUtils.loadExtension({
|
||||
manifest: {
|
||||
version: addonVersion,
|
||||
browser_specific_settings: {
|
||||
gecko: { id: addonId },
|
||||
},
|
||||
chrome_settings_overrides: {
|
||||
search_provider: {
|
||||
is_default: isDefault,
|
||||
name: `test search engine - ${addonId}`,
|
||||
keyword: "test",
|
||||
search_url: `${SEARCH_URL_WWW}&id=${addonId}`,
|
||||
},
|
||||
},
|
||||
},
|
||||
useAddonManager: "temporary",
|
||||
});
|
||||
|
||||
await searchEngine.startup();
|
||||
await AddonTestUtils.waitForSearchProviderStartup(searchEngine);
|
||||
|
||||
searchEngines.push(searchEngine);
|
||||
}
|
||||
|
||||
// Simulate a search by navigating to it.
|
||||
const url = SEARCH_URL_WWW.replace("{searchTerms}", "some terms");
|
||||
await BrowserTestUtils.withNewTab("about:blank", async browser => {
|
||||
// Wait for the tab to be fully loaded.
|
||||
let loaded = BrowserTestUtils.browserLoaded(browser);
|
||||
BrowserTestUtils.loadURI(browser, url);
|
||||
await loaded;
|
||||
});
|
||||
|
||||
await Promise.all(searchEngines.map(engine => engine.unload()));
|
||||
|
||||
TelemetryTestUtils.assertEvents(
|
||||
[
|
||||
{
|
||||
object: "other",
|
||||
value: "server",
|
||||
extra: {
|
||||
addonId: "1-addon@guid",
|
||||
addonVersion: "1.2",
|
||||
from: "example.com",
|
||||
to: "example.net",
|
||||
},
|
||||
},
|
||||
{
|
||||
object: "other",
|
||||
value: "server",
|
||||
extra: {
|
||||
addonId: "2-addon@guid",
|
||||
addonVersion: "3.4",
|
||||
from: "example.com",
|
||||
to: "example.net",
|
||||
},
|
||||
},
|
||||
],
|
||||
TELEMETRY_EVENTS_FILTERS,
|
||||
TELEMETRY_TEST_UTILS_OPTIONS
|
||||
);
|
||||
});
|
@ -0,0 +1,32 @@
|
||||
const REDIRECT_SJS =
|
||||
"browser/browser/extensions/search-detection/tests/browser/redirect.sjs";
|
||||
|
||||
// This handler is used to create redirect chains with multiple sub-domains,
|
||||
// and the next hop is defined by the current `host`.
|
||||
function handleRequest(request, response) {
|
||||
let newLocation;
|
||||
|
||||
// test1.example.com -> test2.example.com -> www.example.com -> example.net
|
||||
switch (request.host) {
|
||||
case "test1.example.com":
|
||||
newLocation = `https://test2.example.com/${REDIRECT_SJS}`;
|
||||
break;
|
||||
case "test2.example.com":
|
||||
newLocation = `https://www.example.com/${REDIRECT_SJS}`;
|
||||
break;
|
||||
case "www.example.com":
|
||||
newLocation = "https://example.net/";
|
||||
break;
|
||||
// We redirect `mochi.test` to `www` in
|
||||
// `test_redirect_chain_does_not_start_on_first_request()`.
|
||||
case "mochi.test":
|
||||
newLocation = `https://www.example.com/${REDIRECT_SJS}`;
|
||||
break;
|
||||
default:
|
||||
// Redirect to a different website in case of unexpected events.
|
||||
newLocation = "https://mozilla.org/";
|
||||
}
|
||||
|
||||
response.setStatusLine(request.httpVersion, 302, "Found");
|
||||
response.setHeader("Location", newLocation);
|
||||
}
|
Loading…
Reference in New Issue
Block a user