summaryrefslogtreecommitdiffstats
path: root/uriloader/exthandler/tests/mochitest/browser_protocol_ask_dialog_external.js
diff options
context:
space:
mode:
Diffstat (limited to 'uriloader/exthandler/tests/mochitest/browser_protocol_ask_dialog_external.js')
-rw-r--r--uriloader/exthandler/tests/mochitest/browser_protocol_ask_dialog_external.js199
1 files changed, 199 insertions, 0 deletions
diff --git a/uriloader/exthandler/tests/mochitest/browser_protocol_ask_dialog_external.js b/uriloader/exthandler/tests/mochitest/browser_protocol_ask_dialog_external.js
new file mode 100644
index 0000000000..591f1afbc5
--- /dev/null
+++ b/uriloader/exthandler/tests/mochitest/browser_protocol_ask_dialog_external.js
@@ -0,0 +1,199 @@
+/* Any copyright is dedicated to the Public Domain.
+ http://creativecommons.org/publicdomain/zero/1.0/ */
+
+"use strict";
+
+let gHandlerService = Cc["@mozilla.org/uriloader/handler-service;1"].getService(
+ Ci.nsIHandlerService
+);
+
+const TEST_PATH = getRootDirectory(gTestPath).replace(
+ "chrome://mochitests/content",
+ "https://example.com"
+);
+
+/**
+ * Creates dummy protocol handler
+ */
+function initTestHandlers() {
+ let handlerInfoThatAsks =
+ HandlerServiceTestUtils.getBlankHandlerInfo("local-app-test");
+
+ let appHandler = Cc[
+ "@mozilla.org/uriloader/local-handler-app;1"
+ ].createInstance(Ci.nsILocalHandlerApp);
+ // This is a dir and not executable, but that's enough for here.
+ appHandler.executable = Services.dirsvc.get("XCurProcD", Ci.nsIFile);
+ handlerInfoThatAsks.possibleApplicationHandlers.appendElement(appHandler);
+ handlerInfoThatAsks.preferredApplicationHandler = appHandler;
+ handlerInfoThatAsks.preferredAction = handlerInfoThatAsks.useHelperApp;
+ handlerInfoThatAsks.alwaysAskBeforeHandling = false;
+ gHandlerService.store(handlerInfoThatAsks);
+
+ let webHandlerInfo =
+ HandlerServiceTestUtils.getBlankHandlerInfo("web+somesite");
+ let webHandler = Cc[
+ "@mozilla.org/uriloader/web-handler-app;1"
+ ].createInstance(Ci.nsIWebHandlerApp);
+ webHandler.name = "Somesite";
+ webHandler.uriTemplate = "https://example.com/handle_url?u=%s";
+ webHandlerInfo.possibleApplicationHandlers.appendElement(webHandler);
+ webHandlerInfo.preferredApplicationHandler = webHandler;
+ webHandlerInfo.preferredAction = webHandlerInfo.useHelperApp;
+ webHandlerInfo.alwaysAskBeforeHandling = false;
+ gHandlerService.store(webHandlerInfo);
+
+ registerCleanupFunction(() => {
+ gHandlerService.remove(webHandlerInfo);
+ gHandlerService.remove(handlerInfoThatAsks);
+ });
+}
+
+function makeCmdLineHelper(url) {
+ return Cu.createCommandLine(
+ ["-url", url],
+ null,
+ Ci.nsICommandLine.STATE_REMOTE_EXPLICIT
+ );
+}
+
+add_setup(async function () {
+ await SpecialPowers.pushPrefEnv({
+ set: [["network.protocol-handler.prompt-from-external", true]],
+ });
+ initTestHandlers();
+});
+
+/**
+ * Check that if we get a direct request from another app / the OS to open a
+ * link, we always prompt, even if we think we know what the correct answer
+ * is. This is to avoid infinite loops in such situations where the OS and
+ * Firefox have conflicting ideas about the default handler, or where our
+ * checks with the OS don't work (Linux and/or Snap, at time of this comment).
+ */
+add_task(async function test_external_asks_anyway() {
+ let cmdLineHandler = Cc["@mozilla.org/browser/final-clh;1"].getService(
+ Ci.nsICommandLineHandler
+ );
+ let chooserDialogOpenPromise = waitForProtocolAppChooserDialog(
+ gBrowser,
+ true
+ );
+ let fakeCmdLine = makeCmdLineHelper("local-app-test:dummy");
+ cmdLineHandler.handle(fakeCmdLine);
+ let dialog = await chooserDialogOpenPromise;
+ ok(dialog, "Should have prompted.");
+
+ let dialogClosedPromise = waitForProtocolAppChooserDialog(
+ gBrowser.selectedBrowser,
+ false
+ );
+ let dialogEl = dialog._frame.contentDocument.querySelector("dialog");
+ dialogEl.cancelDialog();
+ await dialogClosedPromise;
+ // We will have opened a tab; close it.
+ BrowserTestUtils.removeTab(gBrowser.selectedTab);
+});
+
+/**
+ * Like the previous test, but avoid asking for web and extension handlers,
+ * as we can open those ourselves without looping.
+ */
+add_task(async function test_web_app_doesnt_ask() {
+ // Listen for a dialog open and fail the test if it does:
+ let dialogOpenListener = () => ok(false, "Shouldn't have opened a dialog!");
+ document.documentElement.addEventListener("dialogopen", dialogOpenListener);
+ registerCleanupFunction(() =>
+ document.documentElement.removeEventListener(
+ "dialogopen",
+ dialogOpenListener
+ )
+ );
+
+ // Set up a promise for a tab to open with the right URL:
+ const kURL = "web+somesite:dummy";
+ const kLoadedURL =
+ "https://example.com/handle_url?u=" + encodeURIComponent(kURL);
+ let tabPromise = BrowserTestUtils.waitForNewTab(gBrowser, kLoadedURL);
+
+ // Load the URL:
+ let cmdLineHandler = Cc["@mozilla.org/browser/final-clh;1"].getService(
+ Ci.nsICommandLineHandler
+ );
+ let fakeCmdLine = makeCmdLineHelper(kURL);
+ cmdLineHandler.handle(fakeCmdLine);
+
+ // Check that the tab loaded. If instead the dialog opened, the dialogopen handler
+ // will fail the test.
+ let tab = await tabPromise;
+ is(
+ tab.linkedBrowser.currentURI.spec,
+ kLoadedURL,
+ "Should have opened the right URL."
+ );
+ BrowserTestUtils.removeTab(tab);
+
+ // We do this both here and in cleanup so it's easy to add tasks to this test,
+ // and so we clean up correctly if the test aborts before we get here.
+ document.documentElement.removeEventListener(
+ "dialogopen",
+ dialogOpenListener
+ );
+});
+
+add_task(async function external_https_redirect_doesnt_ask() {
+ Services.perms.addFromPrincipal(
+ Services.scriptSecurityManager.createContentPrincipalFromOrigin(
+ "https://example.com"
+ ),
+ "open-protocol-handler^local-app-test",
+ Services.perms.ALLOW_ACTION
+ );
+ // Listen for a dialog open and fail the test if it does:
+ let dialogOpenListener = () => ok(false, "Shouldn't have opened a dialog!");
+ document.documentElement.addEventListener("dialogopen", dialogOpenListener);
+ registerCleanupFunction(() => {
+ document.documentElement.removeEventListener(
+ "dialogopen",
+ dialogOpenListener
+ );
+ Services.perms.removeAll();
+ });
+
+ let initialTab = gBrowser.selectedTab;
+
+ gHandlerService.wrappedJSObject.mockProtocolHandler("local-app-test");
+ registerCleanupFunction(() =>
+ gHandlerService.wrappedJSObject.mockProtocolHandler()
+ );
+
+ // Set up a promise for an app to have launched with the right URI:
+ let loadPromise = TestUtils.topicObserved("mocked-protocol-handler");
+
+ // Load the URL:
+ const kURL = "local-app-test:redirect";
+ let cmdLineHandler = Cc["@mozilla.org/browser/final-clh;1"].getService(
+ Ci.nsICommandLineHandler
+ );
+ let fakeCmdLine = makeCmdLineHelper(
+ TEST_PATH + "redirect_helper.sjs?uri=" + encodeURIComponent(kURL)
+ );
+ cmdLineHandler.handle(fakeCmdLine);
+
+ // Check that the mock app was launched. If the dialog showed instead,
+ // the test will fail.
+ let [uri] = await loadPromise;
+ is(uri.spec, "local-app-test:redirect", "Should have seen correct URI.");
+ // We might have opened a blank tab, see bug 1718104 and friends.
+ if (gBrowser.selectedTab != initialTab) {
+ BrowserTestUtils.removeTab(gBrowser.selectedTab);
+ }
+
+ // We do this both here and in cleanup so it's easy to add tasks to this test,
+ // and so we clean up correctly if the test aborts before we get here.
+ document.documentElement.removeEventListener(
+ "dialogopen",
+ dialogOpenListener
+ );
+ gHandlerService.wrappedJSObject.mockProtocolHandler();
+});