Bug 1322785 - Add tests for geolocation and desktop notification prompts. r=Paolo draft
authorJohann Hofmann <jhofmann@mozilla.com>
Tue, 17 Jan 2017 12:28:04 +0100
changeset 462426 bf5dcea47072aa27876090170f14ba743fbcc8d4
parent 462402 3e275d37a06236981bff399b7d7aa0646be3fee7
child 542389 c059a739d94768e4dfce5b0b153baf829757663d
push id41747
push userbmo:jhofmann@mozilla.com
push dateTue, 17 Jan 2017 11:28:47 +0000
reviewersPaolo
bugs1322785
milestone53.0a1
Bug 1322785 - Add tests for geolocation and desktop notification prompts. r=Paolo MozReview-Commit-ID: 3SbeGvTRr2t
browser/modules/test/browser.ini
browser/modules/test/browser_PermissionUI.js
browser/modules/test/browser_PermissionUI_prompts.js
browser/modules/test/head.js
--- a/browser/modules/test/browser.ini
+++ b/browser/modules/test/browser.ini
@@ -13,16 +13,17 @@ support-files =
   contentSearch.js
   contentSearchBadImage.xml
   contentSearchSuggestions.sjs
   contentSearchSuggestions.xml
   !/browser/components/search/test/head.js
   !/browser/components/search/test/testEngine.xml
 [browser_NetworkPrioritizer.js]
 [browser_PermissionUI.js]
+[browser_PermissionUI_prompts.js]
 [browser_ProcessHangNotifications.js]
 skip-if = !e10s
 [browser_SelfSupportBackend.js]
 support-files =
   ../../components/uitour/test/uitour.html
   ../../components/uitour/UITour-lib.js
 [browser_SitePermissions.js]
 [browser_SitePermissions_combinations.js]
@@ -40,9 +41,9 @@ support-files =
   usageTelemetrySearchSuggestions.xml
 [browser_UsageTelemetry_searchbar.js]
 support-files =
   usageTelemetrySearchSuggestions.sjs
   usageTelemetrySearchSuggestions.xml
 [browser_UsageTelemetry_content.js]
 [browser_UsageTelemetry_content_aboutHome.js]
 [browser_urlBar_zoom.js]
-[browser_bug1319078.js]
\ No newline at end of file
+[browser_bug1319078.js]
--- a/browser/modules/test/browser_PermissionUI.js
+++ b/browser/modules/test/browser_PermissionUI.js
@@ -6,101 +6,16 @@
 
 "use strict";
 
 Cu.import("resource://gre/modules/Integration.jsm", this);
 Cu.import("resource:///modules/PermissionUI.jsm", this);
 Cu.import("resource:///modules/SitePermissions.jsm", this);
 
 /**
- * Given a <xul:browser> at some non-internal web page,
- * return something that resembles an nsIContentPermissionRequest,
- * using the browsers currently loaded document to get a principal.
- *
- * @param browser (<xul:browser>)
- *        The browser that we'll create a nsIContentPermissionRequest
- *        for.
- * @returns A nsIContentPermissionRequest-ish object.
- */
-function makeMockPermissionRequest(browser) {
-  let result = {
-    types: null,
-    principal: browser.contentPrincipal,
-    requester: null,
-    _cancelled: false,
-    cancel() {
-      this._cancelled = true;
-    },
-    _allowed: false,
-    allow() {
-      this._allowed = true;
-    },
-    QueryInterface: XPCOMUtils.generateQI([Ci.nsIContentPermissionRequest]),
-  };
-
-  // In the e10s-case, nsIContentPermissionRequest will have
-  // element defined. window is defined otherwise.
-  if (browser.isRemoteBrowser) {
-    result.element = browser;
-  } else {
-    result.window = browser.contentWindow;
-  }
-
-  return result;
-}
-
-/**
- * For an opened PopupNotification, clicks on the main action,
- * and waits for the panel to fully close.
- *
- * @return {Promise}
- *         Resolves once the panel has fired the "popuphidden"
- *         event.
- */
-function clickMainAction() {
-  let removePromise =
-    BrowserTestUtils.waitForEvent(PopupNotifications.panel, "popuphidden");
-  let popupNotification = getPopupNotificationNode();
-  popupNotification.button.click();
-  return removePromise;
-}
-
-/**
- * For an opened PopupNotification, clicks on the secondary action,
- * and waits for the panel to fully close.
- *
- * @return {Promise}
- *         Resolves once the panel has fired the "popuphidden"
- *         event.
- */
-function clickSecondaryAction() {
-  let removePromise =
-    BrowserTestUtils.waitForEvent(PopupNotifications.panel, "popuphidden");
-  let popupNotification = getPopupNotificationNode();
-  popupNotification.secondaryButton.click();
-  return removePromise;
-}
-
-/**
- * Makes sure that 1 (and only 1) <xul:popupnotification> is being displayed
- * by PopupNotification, and then returns that <xul:popupnotification>.
- *
- * @return {<xul:popupnotification>}
- */
-function getPopupNotificationNode() {
-  // PopupNotification is a bit overloaded here, so to be
-  // clear, popupNotifications is a list of <xul:popupnotification>
-  // nodes.
-  let popupNotifications = PopupNotifications.panel.childNodes;
-  Assert.equal(popupNotifications.length, 1,
-               "Should be showing a <xul:popupnotification>");
-  return popupNotifications[0];
-}
-
-/**
  * Tests the PermissionPromptForRequest prototype to ensure that a prompt
  * can be displayed. Does not test permission handling.
  */
 add_task(function* test_permission_prompt_for_request() {
   yield BrowserTestUtils.withNewTab({
     gBrowser,
     url: "http://example.com/",
   }, function*(browser) {
new file mode 100644
--- /dev/null
+++ b/browser/modules/test/browser_PermissionUI_prompts.js
@@ -0,0 +1,118 @@
+/**
+ * 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";
+
+Cu.import("resource://gre/modules/Integration.jsm", this);
+Cu.import("resource:///modules/PermissionUI.jsm", this);
+Cu.import("resource:///modules/SitePermissions.jsm", this);
+
+// Tests that GeolocationPermissionPrompt works as expected
+add_task(function* test_geo_permission_prompt() {
+  yield testPrompt(PermissionUI.GeolocationPermissionPrompt);
+});
+
+// Tests that DesktopNotificationPermissionPrompt works as expected
+add_task(function* test_desktop_notification_permission_prompt() {
+  yield testPrompt(PermissionUI.DesktopNotificationPermissionPrompt);
+});
+
+function* testPrompt(Prompt) {
+  yield BrowserTestUtils.withNewTab({
+    gBrowser,
+    url: "http://example.com",
+  }, function*(browser) {
+    let mockRequest = makeMockPermissionRequest(browser);
+    let principal = mockRequest.principal;
+    let TestPrompt = new Prompt(mockRequest);
+    let permissionKey = TestPrompt.permissionKey;
+
+    registerCleanupFunction(function() {
+      SitePermissions.remove(principal.URI, permissionKey);
+    });
+
+    let shownPromise =
+      BrowserTestUtils.waitForEvent(PopupNotifications.panel, "popupshown");
+    TestPrompt.prompt();
+    yield shownPromise;
+    let notification =
+      PopupNotifications.getNotification(TestPrompt.notificationID, browser);
+    Assert.ok(notification, "Should have gotten the notification");
+
+    let curPerm = SitePermissions.get(principal.URI, permissionKey, 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");
+    yield clickSecondaryAction();
+    curPerm = SitePermissions.get(principal.URI, permissionKey, browser);
+    Assert.deepEqual(curPerm, {
+                       state: SitePermissions.BLOCK,
+                       scope: SitePermissions.SCOPE_TEMPORARY,
+                     }, "Should have denied the action temporarily");
+
+    Assert.ok(mockRequest._cancelled,
+              "The request should have been cancelled");
+    Assert.ok(!mockRequest._allowed,
+              "The request should not have been allowed");
+
+    SitePermissions.remove(principal.URI, permissionKey, browser);
+    mockRequest._cancelled = false;
+
+    // Bring the PopupNotification back up now...
+    shownPromise =
+      BrowserTestUtils.waitForEvent(PopupNotifications.panel, "popupshown");
+    TestPrompt.prompt();
+    yield shownPromise;
+
+    // Test denying the permission request with the checkbox checked.
+    popupNotification = getPopupNotificationNode();
+    popupNotification.checkbox.checked = true;
+
+    Assert.equal(notification.secondaryActions.length, 1,
+                 "There should only be 1 secondary action");
+    yield clickSecondaryAction();
+    curPerm = SitePermissions.get(principal.URI, permissionKey);
+    Assert.deepEqual(curPerm, {
+                       state: SitePermissions.BLOCK,
+                       scope: SitePermissions.SCOPE_PERSISTENT
+                     }, "Should have denied the action permanently");
+    Assert.ok(mockRequest._cancelled,
+              "The request should have been cancelled");
+    Assert.ok(!mockRequest._allowed,
+              "The request should not have been allowed");
+
+    SitePermissions.remove(principal.URI, permissionKey);
+    mockRequest._cancelled = false;
+
+    // Bring the PopupNotification back up now...
+    shownPromise =
+      BrowserTestUtils.waitForEvent(PopupNotifications.panel, "popupshown");
+    TestPrompt.prompt();
+    yield shownPromise;
+
+    // Test allowing the permission request with the checkbox checked.
+    popupNotification = getPopupNotificationNode();
+    popupNotification.checkbox.checked = true;
+
+    yield clickMainAction();
+    curPerm = SitePermissions.get(principal.URI, permissionKey);
+    Assert.deepEqual(curPerm, {
+                       state: SitePermissions.ALLOW,
+                       scope: SitePermissions.SCOPE_PERSISTENT
+                     }, "Should have allowed the action permanently");
+    Assert.ok(!mockRequest._cancelled,
+              "The request should not have been cancelled");
+    Assert.ok(mockRequest._allowed,
+              "The request should have been allowed");
+  });
+}
+
--- a/browser/modules/test/head.js
+++ b/browser/modules/test/head.js
@@ -115,8 +115,94 @@ function checkEvents(events, expectedEve
 
   // Strip timestamps from the events for easier comparison.
   events = events.map(e => e.slice(1));
 
   for (let i = 0; i < events.length; ++i) {
     Assert.deepEqual(events[i], expectedEvents[i], "Events should match.");
   }
 }
+
+/**
+ * Given a <xul:browser> at some non-internal web page,
+ * return something that resembles an nsIContentPermissionRequest,
+ * using the browsers currently loaded document to get a principal.
+ *
+ * @param browser (<xul:browser>)
+ *        The browser that we'll create a nsIContentPermissionRequest
+ *        for.
+ * @returns A nsIContentPermissionRequest-ish object.
+ */
+function makeMockPermissionRequest(browser) {
+  let result = {
+    types: null,
+    principal: browser.contentPrincipal,
+    requester: null,
+    _cancelled: false,
+    cancel() {
+      this._cancelled = true;
+    },
+    _allowed: false,
+    allow() {
+      this._allowed = true;
+    },
+    QueryInterface: XPCOMUtils.generateQI([Ci.nsIContentPermissionRequest]),
+  };
+
+  // In the e10s-case, nsIContentPermissionRequest will have
+  // element defined. window is defined otherwise.
+  if (browser.isRemoteBrowser) {
+    result.element = browser;
+  } else {
+    result.window = browser.contentWindow;
+  }
+
+  return result;
+}
+
+/**
+ * For an opened PopupNotification, clicks on the main action,
+ * and waits for the panel to fully close.
+ *
+ * @return {Promise}
+ *         Resolves once the panel has fired the "popuphidden"
+ *         event.
+ */
+function clickMainAction() {
+  let removePromise =
+    BrowserTestUtils.waitForEvent(PopupNotifications.panel, "popuphidden");
+  let popupNotification = getPopupNotificationNode();
+  popupNotification.button.click();
+  return removePromise;
+}
+
+/**
+ * For an opened PopupNotification, clicks on the secondary action,
+ * and waits for the panel to fully close.
+ *
+ * @return {Promise}
+ *         Resolves once the panel has fired the "popuphidden"
+ *         event.
+ */
+function clickSecondaryAction() {
+  let removePromise =
+    BrowserTestUtils.waitForEvent(PopupNotifications.panel, "popuphidden");
+  let popupNotification = getPopupNotificationNode();
+  popupNotification.secondaryButton.click();
+  return removePromise;
+}
+
+/**
+ * Makes sure that 1 (and only 1) <xul:popupnotification> is being displayed
+ * by PopupNotification, and then returns that <xul:popupnotification>.
+ *
+ * @return {<xul:popupnotification>}
+ */
+function getPopupNotificationNode() {
+  // PopupNotification is a bit overloaded here, so to be
+  // clear, popupNotifications is a list of <xul:popupnotification>
+  // nodes.
+  let popupNotifications = PopupNotifications.panel.childNodes;
+  Assert.equal(popupNotifications.length, 1,
+               "Should be showing a <xul:popupnotification>");
+  return popupNotifications[0];
+}
+