summaryrefslogtreecommitdiffstats
path: root/browser/modules/test/browser/browser_PermissionUI.js
diff options
context:
space:
mode:
Diffstat (limited to 'browser/modules/test/browser/browser_PermissionUI.js')
-rw-r--r--browser/modules/test/browser/browser_PermissionUI.js692
1 files changed, 692 insertions, 0 deletions
diff --git a/browser/modules/test/browser/browser_PermissionUI.js b/browser/modules/test/browser/browser_PermissionUI.js
new file mode 100644
index 0000000000..8b66734093
--- /dev/null
+++ b/browser/modules/test/browser/browser_PermissionUI.js
@@ -0,0 +1,692 @@
+/**
+ * These tests test the ability for the PermissionUI module to open
+ * permission prompts to the user. It also tests to ensure that
+ * add-ons can introduce their own permission prompts.
+ */
+
+"use strict";
+
+const { PermissionUI } = ChromeUtils.importESModule(
+ "resource:///modules/PermissionUI.sys.mjs"
+);
+
+const { PermissionTestUtils } = ChromeUtils.importESModule(
+ "resource://testing-common/PermissionTestUtils.sys.mjs"
+);
+
+/**
+ * Tests the PermissionPromptForRequest prototype to ensure that a prompt
+ * can be displayed. Does not test permission handling.
+ */
+add_task(async function test_permission_prompt_for_request() {
+ await BrowserTestUtils.withNewTab(
+ {
+ gBrowser,
+ url: "http://example.com/",
+ },
+ async function (browser) {
+ const kTestNotificationID = "test-notification";
+ const kTestMessage = "Test message";
+ let mainAction = {
+ label: "Main",
+ accessKey: "M",
+ };
+ let secondaryAction = {
+ label: "Secondary",
+ accessKey: "S",
+ };
+
+ let mockRequest = makeMockPermissionRequest(browser);
+ class TestPrompt extends PermissionUI.PermissionPromptForRequest {
+ get request() {
+ return mockRequest;
+ }
+ get notificationID() {
+ return kTestNotificationID;
+ }
+ get message() {
+ return kTestMessage;
+ }
+ get promptActions() {
+ return [mainAction, secondaryAction];
+ }
+ }
+ let shownPromise = BrowserTestUtils.waitForEvent(
+ PopupNotifications.panel,
+ "popupshown"
+ );
+ new TestPrompt().prompt();
+ await shownPromise;
+ let notification = PopupNotifications.getNotification(
+ kTestNotificationID,
+ browser
+ );
+ Assert.ok(notification, "Should have gotten the notification");
+
+ Assert.equal(
+ notification.message,
+ kTestMessage,
+ "Should be showing the right message"
+ );
+ Assert.equal(
+ notification.mainAction.label,
+ mainAction.label,
+ "The main action should have the right label"
+ );
+ Assert.equal(
+ notification.mainAction.accessKey,
+ mainAction.accessKey,
+ "The main action should have the right access key"
+ );
+ Assert.equal(
+ notification.secondaryActions.length,
+ 1,
+ "There should only be 1 secondary action"
+ );
+ Assert.equal(
+ notification.secondaryActions[0].label,
+ secondaryAction.label,
+ "The secondary action should have the right label"
+ );
+ Assert.equal(
+ notification.secondaryActions[0].accessKey,
+ secondaryAction.accessKey,
+ "The secondary action should have the right access key"
+ );
+ Assert.ok(
+ notification.options.displayURI.equals(mockRequest.principal.URI),
+ "Should be showing the URI of the requesting page"
+ );
+
+ let removePromise = BrowserTestUtils.waitForEvent(
+ PopupNotifications.panel,
+ "popuphidden"
+ );
+ notification.remove();
+ await removePromise;
+ }
+ );
+});
+
+/**
+ * Tests that if the PermissionPrompt sets displayURI to false in popupOptions,
+ * then there is no URI shown on the popupnotification.
+ */
+add_task(async function test_permission_prompt_for_popupOptions() {
+ await BrowserTestUtils.withNewTab(
+ {
+ gBrowser,
+ url: "http://example.com/",
+ },
+ async function (browser) {
+ const kTestNotificationID = "test-notification";
+ const kTestMessage = "Test message";
+ let mainAction = {
+ label: "Main",
+ accessKey: "M",
+ };
+ let secondaryAction = {
+ label: "Secondary",
+ accessKey: "S",
+ };
+
+ let mockRequest = makeMockPermissionRequest(browser);
+ class TestPrompt extends PermissionUI.PermissionPromptForRequest {
+ get request() {
+ return mockRequest;
+ }
+ get notificationID() {
+ return kTestNotificationID;
+ }
+ get message() {
+ return kTestMessage;
+ }
+ get promptActions() {
+ return [mainAction, secondaryAction];
+ }
+ get popupOptions() {
+ return {
+ displayURI: false,
+ };
+ }
+ }
+ let shownPromise = BrowserTestUtils.waitForEvent(
+ PopupNotifications.panel,
+ "popupshown"
+ );
+ new TestPrompt().prompt();
+ await shownPromise;
+ let notification = PopupNotifications.getNotification(
+ kTestNotificationID,
+ browser
+ );
+
+ Assert.ok(
+ !notification.options.displayURI,
+ "Should not show the URI of the requesting page"
+ );
+
+ let removePromise = BrowserTestUtils.waitForEvent(
+ PopupNotifications.panel,
+ "popuphidden"
+ );
+ notification.remove();
+ await removePromise;
+ }
+ );
+});
+
+/**
+ * Tests that if the PermissionPrompt has the permissionKey
+ * set that permissions can be set properly by the user. Also
+ * ensures that callbacks for promptActions are properly fired.
+ */
+add_task(async function test_with_permission_key() {
+ await BrowserTestUtils.withNewTab(
+ {
+ gBrowser,
+ url: "http://example.com",
+ },
+ async function (browser) {
+ const kTestNotificationID = "test-notification";
+ const kTestMessage = "Test message";
+ const kTestPermissionKey = "test-permission-key";
+
+ let allowed = false;
+ let mainAction = {
+ label: "Allow",
+ accessKey: "M",
+ action: SitePermissions.ALLOW,
+ callback() {
+ allowed = true;
+ },
+ };
+
+ let denied = false;
+ let secondaryAction = {
+ label: "Deny",
+ accessKey: "D",
+ action: SitePermissions.BLOCK,
+ callback() {
+ denied = true;
+ },
+ };
+
+ let mockRequest = makeMockPermissionRequest(browser);
+ let principal = mockRequest.principal;
+ registerCleanupFunction(function () {
+ PermissionTestUtils.remove(principal.URI, kTestPermissionKey);
+ });
+ class TestPrompt extends PermissionUI.PermissionPromptForRequest {
+ get request() {
+ return mockRequest;
+ }
+ get notificationID() {
+ return kTestNotificationID;
+ }
+ get permissionKey() {
+ return kTestPermissionKey;
+ }
+ get message() {
+ return kTestMessage;
+ }
+ get promptActions() {
+ return [mainAction, secondaryAction];
+ }
+ get popupOptions() {
+ return {
+ checkbox: {
+ label: "Remember this decision",
+ show: true,
+ checked: true,
+ },
+ };
+ }
+ }
+ let shownPromise = BrowserTestUtils.waitForEvent(
+ PopupNotifications.panel,
+ "popupshown"
+ );
+ new TestPrompt().prompt();
+ await shownPromise;
+ let notification = PopupNotifications.getNotification(
+ kTestNotificationID,
+ browser
+ );
+ Assert.ok(notification, "Should have gotten the notification");
+
+ let curPerm = SitePermissions.getForPrincipal(
+ principal,
+ kTestPermissionKey,
+ browser
+ );
+ Assert.equal(
+ curPerm.state,
+ SitePermissions.UNKNOWN,
+ "Should be no permission set to begin with."
+ );
+
+ // First test denying the permission request without the checkbox checked.
+ let popupNotification = getPopupNotificationNode();
+ popupNotification.checkbox.checked = false;
+
+ Assert.equal(
+ notification.secondaryActions.length,
+ 1,
+ "There should only be 1 secondary action"
+ );
+ await clickSecondaryAction();
+ curPerm = SitePermissions.getForPrincipal(
+ principal,
+ kTestPermissionKey,
+ browser
+ );
+ Assert.deepEqual(
+ curPerm,
+ {
+ state: SitePermissions.BLOCK,
+ scope: SitePermissions.SCOPE_TEMPORARY,
+ },
+ "Should have denied the action temporarily"
+ );
+ // Try getting the permission without passing the browser object (should fail).
+ curPerm = PermissionTestUtils.getPermissionObject(
+ principal.URI,
+ kTestPermissionKey
+ );
+ Assert.equal(
+ curPerm,
+ null,
+ "Should have made no permanent permission entry"
+ );
+ Assert.ok(denied, "The secondaryAction callback should have fired");
+ Assert.ok(!allowed, "The mainAction callback should not have fired");
+ Assert.ok(
+ mockRequest._cancelled,
+ "The request should have been cancelled"
+ );
+ Assert.ok(
+ !mockRequest._allowed,
+ "The request should not have been allowed"
+ );
+
+ // Clear the permission and pretend we never denied
+ SitePermissions.removeFromPrincipal(
+ principal,
+ kTestPermissionKey,
+ browser
+ );
+ denied = false;
+ mockRequest._cancelled = false;
+
+ // Bring the PopupNotification back up now...
+ shownPromise = BrowserTestUtils.waitForEvent(
+ PopupNotifications.panel,
+ "popupshown"
+ );
+ new TestPrompt().prompt();
+ await shownPromise;
+
+ // Test denying the permission request.
+ Assert.equal(
+ notification.secondaryActions.length,
+ 1,
+ "There should only be 1 secondary action"
+ );
+ await clickSecondaryAction();
+ curPerm = PermissionTestUtils.getPermissionObject(
+ principal.URI,
+ kTestPermissionKey
+ );
+ Assert.equal(
+ curPerm.capability,
+ Services.perms.DENY_ACTION,
+ "Should have denied the action"
+ );
+ Assert.equal(curPerm.expireTime, 0, "Deny should be permanent");
+ Assert.ok(denied, "The secondaryAction callback should have fired");
+ Assert.ok(!allowed, "The mainAction callback should not have fired");
+ Assert.ok(
+ mockRequest._cancelled,
+ "The request should have been cancelled"
+ );
+ Assert.ok(
+ !mockRequest._allowed,
+ "The request should not have been allowed"
+ );
+
+ // Clear the permission and pretend we never denied
+ PermissionTestUtils.remove(principal.URI, kTestPermissionKey);
+ denied = false;
+ mockRequest._cancelled = false;
+
+ // Bring the PopupNotification back up now...
+ shownPromise = BrowserTestUtils.waitForEvent(
+ PopupNotifications.panel,
+ "popupshown"
+ );
+ new TestPrompt().prompt();
+ await shownPromise;
+
+ // Test allowing the permission request.
+ await clickMainAction();
+ curPerm = PermissionTestUtils.getPermissionObject(
+ principal.URI,
+ kTestPermissionKey
+ );
+ Assert.equal(
+ curPerm.capability,
+ Services.perms.ALLOW_ACTION,
+ "Should have allowed the action"
+ );
+ Assert.equal(curPerm.expireTime, 0, "Allow should be permanent");
+ Assert.ok(!denied, "The secondaryAction callback should not have fired");
+ Assert.ok(allowed, "The mainAction callback should have fired");
+ Assert.ok(
+ !mockRequest._cancelled,
+ "The request should not have been cancelled"
+ );
+ Assert.ok(mockRequest._allowed, "The request should have been allowed");
+ }
+ );
+});
+
+/**
+ * Tests that the onBeforeShow method will be called before
+ * the popup appears.
+ */
+add_task(async function test_on_before_show() {
+ await BrowserTestUtils.withNewTab(
+ {
+ gBrowser,
+ url: "http://example.com",
+ },
+ async function (browser) {
+ const kTestNotificationID = "test-notification";
+ const kTestMessage = "Test message";
+
+ let mainAction = {
+ label: "Test action",
+ accessKey: "T",
+ };
+
+ let mockRequest = makeMockPermissionRequest(browser);
+ let beforeShown = false;
+ class TestPrompt extends PermissionUI.PermissionPromptForRequest {
+ get request() {
+ return mockRequest;
+ }
+ get notificationID() {
+ return kTestNotificationID;
+ }
+ get message() {
+ return kTestMessage;
+ }
+ get promptActions() {
+ return [mainAction];
+ }
+ get popupOptions() {
+ return {
+ checkbox: {
+ label: "Remember this decision",
+ show: true,
+ checked: true,
+ },
+ };
+ }
+ onBeforeShow() {
+ beforeShown = true;
+ return true;
+ }
+ }
+ let shownPromise = BrowserTestUtils.waitForEvent(
+ PopupNotifications.panel,
+ "popupshown"
+ );
+ new TestPrompt().prompt();
+ Assert.ok(beforeShown, "Should have called onBeforeShown");
+ await shownPromise;
+ let notification = PopupNotifications.getNotification(
+ kTestNotificationID,
+ browser
+ );
+
+ let removePromise = BrowserTestUtils.waitForEvent(
+ PopupNotifications.panel,
+ "popuphidden"
+ );
+ notification.remove();
+ await removePromise;
+ }
+ );
+});
+
+/**
+ * Tests that we can open a PermissionPrompt without wrapping a
+ * nsIContentPermissionRequest.
+ */
+add_task(async function test_no_request() {
+ await BrowserTestUtils.withNewTab(
+ {
+ gBrowser,
+ url: "http://example.com",
+ },
+ async function (browser) {
+ const kTestNotificationID = "test-notification";
+ let allowed = false;
+ let mainAction = {
+ label: "Allow",
+ accessKey: "M",
+ callback() {
+ allowed = true;
+ },
+ };
+
+ let denied = false;
+ let secondaryAction = {
+ label: "Deny",
+ accessKey: "D",
+ callback() {
+ denied = true;
+ },
+ };
+
+ const kTestMessage = "Test message with no request";
+ let principal = browser.contentPrincipal;
+ let beforeShown = false;
+ class TestPrompt extends PermissionUI.PermissionPromptForRequest {
+ get notificationID() {
+ return kTestNotificationID;
+ }
+ get principal() {
+ return principal;
+ }
+ get browser() {
+ return browser;
+ }
+ get message() {
+ return kTestMessage;
+ }
+ get promptActions() {
+ return [mainAction, secondaryAction];
+ }
+ onBeforeShow() {
+ beforeShown = true;
+ return true;
+ }
+ }
+
+ let shownPromise = BrowserTestUtils.waitForEvent(
+ PopupNotifications.panel,
+ "popupshown"
+ );
+ new TestPrompt().prompt();
+ Assert.ok(beforeShown, "Should have called onBeforeShown");
+ await shownPromise;
+ let notification = PopupNotifications.getNotification(
+ kTestNotificationID,
+ browser
+ );
+
+ Assert.equal(
+ notification.message,
+ kTestMessage,
+ "Should be showing the right message"
+ );
+ Assert.equal(
+ notification.mainAction.label,
+ mainAction.label,
+ "The main action should have the right label"
+ );
+ Assert.equal(
+ notification.mainAction.accessKey,
+ mainAction.accessKey,
+ "The main action should have the right access key"
+ );
+ Assert.equal(
+ notification.secondaryActions.length,
+ 1,
+ "There should only be 1 secondary action"
+ );
+ Assert.equal(
+ notification.secondaryActions[0].label,
+ secondaryAction.label,
+ "The secondary action should have the right label"
+ );
+ Assert.equal(
+ notification.secondaryActions[0].accessKey,
+ secondaryAction.accessKey,
+ "The secondary action should have the right access key"
+ );
+ Assert.ok(
+ notification.options.displayURI.equals(principal.URI),
+ "Should be showing the URI of the requesting page"
+ );
+
+ // First test denying the permission request.
+ Assert.equal(
+ notification.secondaryActions.length,
+ 1,
+ "There should only be 1 secondary action"
+ );
+ await clickSecondaryAction();
+ Assert.ok(denied, "The secondaryAction callback should have fired");
+ Assert.ok(!allowed, "The mainAction callback should not have fired");
+
+ shownPromise = BrowserTestUtils.waitForEvent(
+ PopupNotifications.panel,
+ "popupshown"
+ );
+ new TestPrompt().prompt();
+ await shownPromise;
+
+ // Next test allowing the permission request.
+ await clickMainAction();
+ Assert.ok(allowed, "The mainAction callback should have fired");
+ }
+ );
+});
+
+/**
+ * Tests that when the tab is moved to a different window, the notification
+ * is transferred to the new window.
+ */
+add_task(async function test_window_swap() {
+ await BrowserTestUtils.withNewTab(
+ {
+ gBrowser,
+ url: "http://example.com",
+ },
+ async function (browser) {
+ const kTestNotificationID = "test-notification";
+ const kTestMessage = "Test message";
+
+ let mainAction = {
+ label: "Test action",
+ accessKey: "T",
+ };
+ let secondaryAction = {
+ label: "Secondary",
+ accessKey: "S",
+ };
+
+ let mockRequest = makeMockPermissionRequest(browser);
+ class TestPrompt extends PermissionUI.PermissionPromptForRequest {
+ get request() {
+ return mockRequest;
+ }
+ get notificationID() {
+ return kTestNotificationID;
+ }
+ get message() {
+ return kTestMessage;
+ }
+ get promptActions() {
+ return [mainAction, secondaryAction];
+ }
+ }
+ let shownPromise = BrowserTestUtils.waitForEvent(
+ PopupNotifications.panel,
+ "popupshown"
+ );
+ new TestPrompt().prompt();
+ await shownPromise;
+
+ let newWindowOpened = BrowserTestUtils.waitForNewWindow();
+ gBrowser.replaceTabWithWindow(gBrowser.selectedTab);
+ let newWindow = await newWindowOpened;
+ // We may have already opened the panel, because it was open before we moved the tab.
+ if (newWindow.PopupNotifications.panel.state != "open") {
+ shownPromise = BrowserTestUtils.waitForEvent(
+ newWindow.PopupNotifications.panel,
+ "popupshown"
+ );
+ new TestPrompt().prompt();
+ await shownPromise;
+ }
+
+ let notification = newWindow.PopupNotifications.getNotification(
+ kTestNotificationID,
+ newWindow.gBrowser.selectedBrowser
+ );
+ Assert.ok(notification, "Should have gotten the notification");
+
+ Assert.equal(
+ notification.message,
+ kTestMessage,
+ "Should be showing the right message"
+ );
+ Assert.equal(
+ notification.mainAction.label,
+ mainAction.label,
+ "The main action should have the right label"
+ );
+ Assert.equal(
+ notification.mainAction.accessKey,
+ mainAction.accessKey,
+ "The main action should have the right access key"
+ );
+ Assert.equal(
+ notification.secondaryActions.length,
+ 1,
+ "There should only be 1 secondary action"
+ );
+ Assert.equal(
+ notification.secondaryActions[0].label,
+ secondaryAction.label,
+ "The secondary action should have the right label"
+ );
+ Assert.equal(
+ notification.secondaryActions[0].accessKey,
+ secondaryAction.accessKey,
+ "The secondary action should have the right access key"
+ );
+ Assert.ok(
+ notification.options.displayURI.equals(mockRequest.principal.URI),
+ "Should be showing the URI of the requesting page"
+ );
+
+ await BrowserTestUtils.closeWindow(newWindow);
+ }
+ );
+});