зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1799632: Refactor `testOpenProto` to accept a callback to trigger protocol loads. r=Gijs
Currently this function uses six different booleans to decide which code to run to trigger the load (many of which are used in just one test) and elsewhere I need to add more cases. This changes the function to instead take a callback function so individual tests can just pass their one-off functions. For the few that are shared global functions are used to share those. Differential Revision: https://phabricator.services.mozilla.com/D161588
This commit is contained in:
Родитель
ddc86a0a4b
Коммит
7239bae84b
|
@ -48,8 +48,6 @@ const NULL_PRINCIPAL_SCHEME = Services.scriptSecurityManager
|
|||
.createNullPrincipal({})
|
||||
.scheme.toLowerCase();
|
||||
|
||||
let testExtension;
|
||||
|
||||
/**
|
||||
* Get the open protocol handler permission key for a given protocol scheme.
|
||||
* @param {string} aProtocolScheme - Scheme of protocol to construct permission
|
||||
|
@ -106,106 +104,13 @@ function testAlwaysAsk(scheme, ask) {
|
|||
}
|
||||
|
||||
/**
|
||||
* Open a test URL with the desired scheme.
|
||||
* By default the load is triggered by the content principal of the browser.
|
||||
* @param {MozBrowser} browser - Browser to load the test URL in.
|
||||
* @param {string} scheme - Scheme of the test URL.
|
||||
* @param {Object} [opts] - Options for the triggering principal.
|
||||
* @param {nsIPrincipal} [opts.triggeringPrincipal] - Principal to trigger the
|
||||
* load with. Defaults to the browsers content principal.
|
||||
* @param {boolean} [opts.useNullPrincipal] - If true, we will trigger the load
|
||||
* with a null principal.
|
||||
* @param {boolean} [opts.useExtensionPrincipal] - If true, we will trigger the
|
||||
* load with an extension.
|
||||
* @param {boolean} [opts.omitTriggeringPrincipal] - If true, we will directly
|
||||
* call the protocol handler dialogs without a principal.
|
||||
* Triggers the load via a server redirect.
|
||||
* @param {string} serverRedirect - The redirect type.
|
||||
*/
|
||||
async function triggerOpenProto(
|
||||
browser,
|
||||
scheme,
|
||||
{
|
||||
triggeringPrincipal = browser.contentPrincipal,
|
||||
useNullPrincipal = false,
|
||||
useExtensionPrincipal = false,
|
||||
omitTriggeringPrincipal = false,
|
||||
useJSRedirect = false,
|
||||
serverRedirect = "",
|
||||
linkToRedirect = false,
|
||||
customHandlerInfo,
|
||||
} = {}
|
||||
) {
|
||||
let uri = `${scheme}://test`;
|
||||
function useServerRedirect(serverRedirect) {
|
||||
return async (browser, scheme) => {
|
||||
let uri = `${scheme}://test`;
|
||||
|
||||
if (useNullPrincipal) {
|
||||
// Create and load iframe with data URI.
|
||||
// This will be a null principal.
|
||||
ContentTask.spawn(browser, { uri }, args => {
|
||||
let frame = content.document.createElement("iframe");
|
||||
frame.src = `data:text/html,<script>location.href="${args.uri}"</script>`;
|
||||
content.document.body.appendChild(frame);
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
if (useExtensionPrincipal) {
|
||||
const EXTENSION_DATA = {
|
||||
manifest: {
|
||||
content_scripts: [
|
||||
{
|
||||
matches: [browser.currentURI.spec],
|
||||
js: ["navigate.js"],
|
||||
},
|
||||
],
|
||||
},
|
||||
files: {
|
||||
"navigate.js": `window.location.href = "${uri}";`,
|
||||
},
|
||||
};
|
||||
|
||||
testExtension = ExtensionTestUtils.loadExtension(EXTENSION_DATA);
|
||||
await testExtension.startup();
|
||||
return;
|
||||
}
|
||||
|
||||
if (omitTriggeringPrincipal) {
|
||||
// Directly call ContentDispatchChooser without a triggering principal
|
||||
let contentDispatchChooser = Cc[
|
||||
"@mozilla.org/content-dispatch-chooser;1"
|
||||
].createInstance(Ci.nsIContentDispatchChooser);
|
||||
|
||||
let handler =
|
||||
customHandlerInfo || HandlerServiceTestUtils.getHandlerInfo(scheme);
|
||||
|
||||
contentDispatchChooser.handleURI(
|
||||
handler,
|
||||
Services.io.newURI(uri),
|
||||
null,
|
||||
browser.browsingContext
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
if (useJSRedirect) {
|
||||
let innerParams = new URLSearchParams();
|
||||
innerParams.set("uri", uri);
|
||||
let params = new URLSearchParams();
|
||||
params.set(
|
||||
"uri",
|
||||
"https://example.com/" +
|
||||
ROOT_PATH +
|
||||
"script_redirect.html?" +
|
||||
innerParams.toString()
|
||||
);
|
||||
uri =
|
||||
"https://example.org/" +
|
||||
ROOT_PATH +
|
||||
"script_redirect.html?" +
|
||||
params.toString();
|
||||
BrowserTestUtils.loadURI(browser, uri);
|
||||
return;
|
||||
}
|
||||
|
||||
if (serverRedirect) {
|
||||
let innerParams = new URLSearchParams();
|
||||
innerParams.set("uri", uri);
|
||||
innerParams.set("redirectType", serverRedirect);
|
||||
|
@ -223,29 +128,22 @@ async function triggerOpenProto(
|
|||
"redirect_helper.sjs?" +
|
||||
params.toString();
|
||||
BrowserTestUtils.loadURI(browser, uri);
|
||||
return;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
if (linkToRedirect) {
|
||||
let params = new URLSearchParams();
|
||||
params.set("uri", uri);
|
||||
uri =
|
||||
"https://example.com/" +
|
||||
ROOT_PATH +
|
||||
"redirect_helper.sjs?" +
|
||||
params.toString();
|
||||
await ContentTask.spawn(browser, { uri }, args => {
|
||||
let textLink = content.document.createElement("a");
|
||||
textLink.href = args.uri;
|
||||
textLink.textContent = "click me";
|
||||
content.document.body.appendChild(textLink);
|
||||
textLink.click();
|
||||
});
|
||||
return;
|
||||
}
|
||||
/**
|
||||
* Triggers the load with a specific principal or the browser's current
|
||||
* principal.
|
||||
* @param {nsIPrincipal} [principal] - Principal to use to trigger the load.
|
||||
*/
|
||||
function useTriggeringPrincipal(principal = undefined) {
|
||||
return async (browser, scheme) => {
|
||||
let uri = `${scheme}://test`;
|
||||
let triggeringPrincipal = principal ?? browser.contentPrincipal;
|
||||
|
||||
info("Loading uri: " + uri);
|
||||
browser.loadURI(uri, { triggeringPrincipal });
|
||||
info("Loading uri: " + uri);
|
||||
browser.loadURI(uri, { triggeringPrincipal });
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -258,8 +156,8 @@ async function triggerOpenProto(
|
|||
* dialog. If defined, we expect this dialog to be shown.
|
||||
* @param {Object} [options.chooserDialogOptions] - Test options for the chooser
|
||||
* dialog. If defined, we expect this dialog to be shown.
|
||||
* @param {Object} [options.loadOptions] - Options for triggering the protocol
|
||||
* load which causes the dialog to show.
|
||||
* @param {Function} [options.triggerLoad] - An async callback function to
|
||||
* trigger the load. Will be passed the browser and scheme to use.
|
||||
* @param {nsIPrincipal} [options.triggeringPrincipal] - Principal to trigger
|
||||
* the load with. Defaults to the browsers content principal.
|
||||
* @returns {Promise} - A promise which resolves once the test is complete.
|
||||
|
@ -267,7 +165,11 @@ async function triggerOpenProto(
|
|||
async function testOpenProto(
|
||||
browser,
|
||||
scheme,
|
||||
{ permDialogOptions, chooserDialogOptions, loadOptions } = {}
|
||||
{
|
||||
permDialogOptions,
|
||||
chooserDialogOptions,
|
||||
triggerLoad = useTriggeringPrincipal(),
|
||||
} = {}
|
||||
) {
|
||||
let permDialogOpenPromise;
|
||||
let chooserDialogOpenPromise;
|
||||
|
@ -281,7 +183,7 @@ async function testOpenProto(
|
|||
info("Should see chooser dialog");
|
||||
chooserDialogOpenPromise = waitForProtocolAppChooserDialog(browser, true);
|
||||
}
|
||||
await triggerOpenProto(browser, scheme, loadOptions);
|
||||
await triggerLoad(browser, scheme);
|
||||
let webHandlerLoadedPromise;
|
||||
|
||||
let webHandlerShouldOpen =
|
||||
|
@ -384,13 +286,6 @@ async function testOpenProto(
|
|||
} else {
|
||||
info("Web handler open canceled");
|
||||
}
|
||||
|
||||
// Clean up test extension if needed.
|
||||
if (testExtension) {
|
||||
await testExtension.unload();
|
||||
// Don't try to unload it again later!
|
||||
testExtension = null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -711,9 +606,9 @@ add_task(async function test_permission_system_principal() {
|
|||
await BrowserTestUtils.withNewTab(ORIGIN1, async browser => {
|
||||
await testOpenProto(browser, scheme, {
|
||||
chooserDialogOptions: { hasCheckbox: true, actionConfirm: false },
|
||||
loadOptions: {
|
||||
triggeringPrincipal: Services.scriptSecurityManager.getSystemPrincipal(),
|
||||
},
|
||||
triggerLoad: useTriggeringPrincipal(
|
||||
Services.scriptSecurityManager.getSystemPrincipal()
|
||||
),
|
||||
});
|
||||
});
|
||||
});
|
||||
|
@ -795,8 +690,13 @@ add_task(async function test_null_principal() {
|
|||
|
||||
await BrowserTestUtils.withNewTab(ORIGIN1, async browser => {
|
||||
await testOpenProto(browser, scheme, {
|
||||
loadOptions: {
|
||||
useNullPrincipal: true,
|
||||
triggerLoad: () => {
|
||||
let uri = `${scheme}://test`;
|
||||
ContentTask.spawn(browser, { uri }, args => {
|
||||
let frame = content.document.createElement("iframe");
|
||||
frame.src = `data:text/html,<script>location.href="${args.uri}"</script>`;
|
||||
content.document.body.appendChild(frame);
|
||||
});
|
||||
},
|
||||
permDialogOptions: {
|
||||
hasCheckbox: false,
|
||||
|
@ -821,8 +721,21 @@ add_task(async function test_no_principal() {
|
|||
|
||||
await BrowserTestUtils.withNewTab(ORIGIN1, async browser => {
|
||||
await testOpenProto(browser, scheme, {
|
||||
loadOptions: {
|
||||
omitTriggeringPrincipal: true,
|
||||
triggerLoad: () => {
|
||||
let uri = `${scheme}://test`;
|
||||
|
||||
let contentDispatchChooser = Cc[
|
||||
"@mozilla.org/content-dispatch-chooser;1"
|
||||
].createInstance(Ci.nsIContentDispatchChooser);
|
||||
|
||||
let handler = HandlerServiceTestUtils.getHandlerInfo(scheme);
|
||||
|
||||
contentDispatchChooser.handleURI(
|
||||
handler,
|
||||
Services.io.newURI(uri),
|
||||
null,
|
||||
browser.browsingContext
|
||||
);
|
||||
},
|
||||
permDialogOptions: {
|
||||
hasCheckbox: false,
|
||||
|
@ -856,9 +769,6 @@ add_task(async function test_non_standard_protocol() {
|
|||
|
||||
await BrowserTestUtils.withNewTab(ORIGIN1, async browser => {
|
||||
await testOpenProto(browser, scheme, {
|
||||
loadOptions: {
|
||||
customHandlerInfo: HandlerServiceTestUtils.getHandlerInfo(scheme),
|
||||
},
|
||||
permDialogOptions: {
|
||||
hasCheckbox: true,
|
||||
hasChangeApp: true,
|
||||
|
@ -875,15 +785,36 @@ add_task(async function test_non_standard_protocol() {
|
|||
add_task(async function test_extension_principal() {
|
||||
let scheme = TEST_PROTOS[0];
|
||||
await BrowserTestUtils.withNewTab(ORIGIN1, async browser => {
|
||||
let testExtension;
|
||||
|
||||
await testOpenProto(browser, scheme, {
|
||||
loadOptions: {
|
||||
useExtensionPrincipal: true,
|
||||
triggerLoad: async () => {
|
||||
let uri = `${scheme}://test`;
|
||||
|
||||
const EXTENSION_DATA = {
|
||||
manifest: {
|
||||
content_scripts: [
|
||||
{
|
||||
matches: [browser.currentURI.spec],
|
||||
js: ["navigate.js"],
|
||||
},
|
||||
],
|
||||
},
|
||||
files: {
|
||||
"navigate.js": `window.location.href = "${uri}";`,
|
||||
},
|
||||
};
|
||||
|
||||
testExtension = ExtensionTestUtils.loadExtension(EXTENSION_DATA);
|
||||
await testExtension.startup();
|
||||
},
|
||||
chooserDialogOptions: {
|
||||
hasCheckbox: true,
|
||||
actionConfirm: false, // Cancel dialog
|
||||
},
|
||||
});
|
||||
|
||||
await testExtension.unload();
|
||||
});
|
||||
});
|
||||
|
||||
|
@ -894,9 +825,7 @@ add_task(async function test_redirect_principal() {
|
|||
let scheme = TEST_PROTOS[0];
|
||||
await BrowserTestUtils.withNewTab("about:blank", async browser => {
|
||||
await testOpenProto(browser, scheme, {
|
||||
loadOptions: {
|
||||
serverRedirect: "location",
|
||||
},
|
||||
triggerLoad: useServerRedirect("location"),
|
||||
permDialogOptions: {
|
||||
checkboxOrigin: ORIGIN1,
|
||||
chooserIsNext: true,
|
||||
|
@ -914,9 +843,7 @@ add_task(async function test_redirect_principal() {
|
|||
let scheme = TEST_PROTOS[0];
|
||||
await BrowserTestUtils.withNewTab("about:blank", async browser => {
|
||||
await testOpenProto(browser, scheme, {
|
||||
loadOptions: {
|
||||
serverRedirect: "refresh",
|
||||
},
|
||||
triggerLoad: useServerRedirect("refresh"),
|
||||
permDialogOptions: {
|
||||
checkboxOrigin: ORIGIN1,
|
||||
chooserIsNext: true,
|
||||
|
@ -934,9 +861,7 @@ add_task(async function test_redirect_principal() {
|
|||
let scheme = TEST_PROTOS[0];
|
||||
await BrowserTestUtils.withNewTab("about:blank", async browser => {
|
||||
await testOpenProto(browser, scheme, {
|
||||
loadOptions: {
|
||||
serverRedirect: "meta-refresh",
|
||||
},
|
||||
triggerLoad: useServerRedirect("meta-refresh"),
|
||||
permDialogOptions: {
|
||||
checkboxOrigin: ORIGIN1,
|
||||
chooserIsNext: true,
|
||||
|
@ -954,8 +879,25 @@ add_task(async function test_redirect_principal_js() {
|
|||
let scheme = TEST_PROTOS[0];
|
||||
await BrowserTestUtils.withNewTab("about:blank", async browser => {
|
||||
await testOpenProto(browser, scheme, {
|
||||
loadOptions: {
|
||||
useJSRedirect: true,
|
||||
triggerLoad: () => {
|
||||
let uri = `${scheme}://test`;
|
||||
|
||||
let innerParams = new URLSearchParams();
|
||||
innerParams.set("uri", uri);
|
||||
let params = new URLSearchParams();
|
||||
params.set(
|
||||
"uri",
|
||||
"https://example.com/" +
|
||||
ROOT_PATH +
|
||||
"script_redirect.html?" +
|
||||
innerParams.toString()
|
||||
);
|
||||
uri =
|
||||
"https://example.org/" +
|
||||
ROOT_PATH +
|
||||
"script_redirect.html?" +
|
||||
params.toString();
|
||||
BrowserTestUtils.loadURI(browser, uri);
|
||||
},
|
||||
permDialogOptions: {
|
||||
checkboxOrigin: ORIGIN1,
|
||||
|
@ -974,8 +916,23 @@ add_task(async function test_redirect_principal_links() {
|
|||
let scheme = TEST_PROTOS[0];
|
||||
await BrowserTestUtils.withNewTab("about:blank", async browser => {
|
||||
await testOpenProto(browser, scheme, {
|
||||
loadOptions: {
|
||||
linkToRedirect: true,
|
||||
triggerLoad: async () => {
|
||||
let uri = `${scheme}://test`;
|
||||
|
||||
let params = new URLSearchParams();
|
||||
params.set("uri", uri);
|
||||
uri =
|
||||
"https://example.com/" +
|
||||
ROOT_PATH +
|
||||
"redirect_helper.sjs?" +
|
||||
params.toString();
|
||||
await ContentTask.spawn(browser, { uri }, args => {
|
||||
let textLink = content.document.createElement("a");
|
||||
textLink.href = args.uri;
|
||||
textLink.textContent = "click me";
|
||||
content.document.body.appendChild(textLink);
|
||||
textLink.click();
|
||||
});
|
||||
},
|
||||
permDialogOptions: {
|
||||
checkboxOrigin: ORIGIN1,
|
||||
|
|
Загрузка…
Ссылка в новой задаче