From 6bf0a5cb5034a7e684dcc3500e841785237ce2dd Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Sun, 7 Apr 2024 19:32:43 +0200 Subject: Adding upstream version 1:115.7.0. Signed-off-by: Daniel Baumann --- .../modules/test/browser/browser_PermissionUI.js | 692 +++++++++++++++++++++ 1 file changed, 692 insertions(+) create mode 100644 browser/modules/test/browser/browser_PermissionUI.js (limited to 'browser/modules/test/browser/browser_PermissionUI.js') 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); + } + ); +}); -- cgit v1.2.3