browser/base/content/test/general/browser_datareporting_notification.js

changeset 0
6474c204b198
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/browser/base/content/test/general/browser_datareporting_notification.js	Wed Dec 31 06:09:35 2014 +0100
     1.3 @@ -0,0 +1,198 @@
     1.4 +/* This Source Code Form is subject to the terms of the Mozilla Public
     1.5 + * License, v. 2.0. If a copy of the MPL was not distributed with this
     1.6 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
     1.7 +
     1.8 +function sendNotifyRequest(name) {
     1.9 +  let ns = {};
    1.10 +  Components.utils.import("resource://gre/modules/services/datareporting/policy.jsm", ns);
    1.11 +  Components.utils.import("resource://gre/modules/Preferences.jsm", ns);
    1.12 +
    1.13 +  let service = Components.classes["@mozilla.org/datareporting/service;1"]
    1.14 +                                  .getService(Components.interfaces.nsISupports)
    1.15 +                                  .wrappedJSObject;
    1.16 +  ok(service.healthReporter, "Health Reporter instance is available.");
    1.17 +
    1.18 +  let policyPrefs = new ns.Preferences("testing." + name + ".");
    1.19 +  ok(service._prefs, "Health Reporter prefs are available.");
    1.20 +  let hrPrefs = service._prefs;
    1.21 +
    1.22 +  let policy = new ns.DataReportingPolicy(policyPrefs, hrPrefs, service);
    1.23 +  policy.firstRunDate = new Date(Date.now() - 24 * 60 * 60 * 1000);
    1.24 +
    1.25 +  is(policy.notifyState, policy.STATE_NOTIFY_UNNOTIFIED, "Policy is in unnotified state.");
    1.26 +
    1.27 +  service.healthReporter.onInit().then(function onInit() {
    1.28 +    is(policy.ensureNotifyResponse(new Date()), false, "User has not responded to policy.");
    1.29 +  });
    1.30 +
    1.31 +  return policy;
    1.32 +}
    1.33 +
    1.34 +/**
    1.35 + * Wait for a <notification> to be closed then call the specified callback.
    1.36 + */
    1.37 +function waitForNotificationClose(notification, cb) {
    1.38 +  let parent = notification.parentNode;
    1.39 +
    1.40 +  let observer = new MutationObserver(function onMutatations(mutations) {
    1.41 +    for (let mutation of mutations) {
    1.42 +      for (let i = 0; i < mutation.removedNodes.length; i++) {
    1.43 +        let node = mutation.removedNodes.item(i);
    1.44 +
    1.45 +        if (node != notification) {
    1.46 +          continue;
    1.47 +        }
    1.48 +
    1.49 +        observer.disconnect();
    1.50 +        cb();
    1.51 +      }
    1.52 +    }
    1.53 +  });
    1.54 +
    1.55 +  observer.observe(parent, {childList: true});
    1.56 +}
    1.57 +
    1.58 +let dumpAppender, rootLogger;
    1.59 +
    1.60 +function test() {
    1.61 +  waitForExplicitFinish();
    1.62 +
    1.63 +  let ns = {};
    1.64 +  Components.utils.import("resource://gre/modules/Log.jsm", ns);
    1.65 +  rootLogger = ns.Log.repository.rootLogger;
    1.66 +  dumpAppender = new ns.Log.DumpAppender();
    1.67 +  dumpAppender.level = ns.Log.Level.All;
    1.68 +  rootLogger.addAppender(dumpAppender);
    1.69 +
    1.70 +  let notification = document.getElementById("global-notificationbox");
    1.71 +  let policy;
    1.72 +
    1.73 +  notification.addEventListener("AlertActive", function active() {
    1.74 +    notification.removeEventListener("AlertActive", active, true);
    1.75 +
    1.76 +    executeSoon(function afterNotification() {
    1.77 +      is(policy.notifyState, policy.STATE_NOTIFY_WAIT, "Policy is waiting for user response.");
    1.78 +      ok(!policy.dataSubmissionPolicyAccepted, "Data submission policy not yet accepted.");
    1.79 +
    1.80 +      waitForNotificationClose(notification.currentNotification, function onClose() {
    1.81 +        is(policy.notifyState, policy.STATE_NOTIFY_COMPLETE, "Closing info bar completes user notification.");
    1.82 +        ok(policy.dataSubmissionPolicyAccepted, "Data submission policy accepted.");
    1.83 +        is(policy.dataSubmissionPolicyResponseType, "accepted-info-bar-dismissed",
    1.84 +           "Reason for acceptance was info bar dismissal.");
    1.85 +        is(notification.allNotifications.length, 0, "No notifications remain.");
    1.86 +        test_multiple_windows();
    1.87 +      });
    1.88 +      notification.currentNotification.close();
    1.89 +    });
    1.90 +  }, true);
    1.91 +
    1.92 +  policy = sendNotifyRequest("single_window_notified");
    1.93 +}
    1.94 +
    1.95 +function test_multiple_windows() {
    1.96 +  // Ensure we see the notification on all windows and that action on one window
    1.97 +  // results in dismiss on every window.
    1.98 +  let window2 = OpenBrowserWindow();
    1.99 +  whenDelayedStartupFinished(window2, function onWindow() {
   1.100 +    let notification1 = document.getElementById("global-notificationbox");
   1.101 +    let notification2 = window2.document.getElementById("global-notificationbox");
   1.102 +    ok(notification2, "2nd window has a global notification box.");
   1.103 +
   1.104 +    let policy;
   1.105 +
   1.106 +    let displayCount = 0;
   1.107 +    let prefPaneClosed = false;
   1.108 +    let childWindowClosed = false;
   1.109 +
   1.110 +    function onAlertDisplayed() {
   1.111 +      displayCount++;
   1.112 +
   1.113 +      if (displayCount != 2) {
   1.114 +        return;
   1.115 +      }
   1.116 +
   1.117 +      ok(true, "Data reporting info bar displayed on all open windows.");
   1.118 +
   1.119 +      // We register two independent observers and we need both to clean up
   1.120 +      // properly. This handles gating for test completion.
   1.121 +      function maybeFinish() {
   1.122 +        if (!prefPaneClosed) {
   1.123 +          dump("Not finishing test yet because pref pane isn't closed.\n");
   1.124 +          return;
   1.125 +        }
   1.126 +
   1.127 +        if (!childWindowClosed) {
   1.128 +          dump("Not finishing test yet because child window isn't closed.\n");
   1.129 +          return;
   1.130 +        }
   1.131 +
   1.132 +        dump("Finishing multiple window test.\n");
   1.133 +        rootLogger.removeAppender(dumpAppender);
   1.134 +        delete dumpAppender;
   1.135 +        delete rootLogger;
   1.136 +        finish();
   1.137 +      }
   1.138 +
   1.139 +      let closeCount = 0;
   1.140 +      function onAlertClose() {
   1.141 +        closeCount++;
   1.142 +
   1.143 +        if (closeCount != 2) {
   1.144 +          return;
   1.145 +        }
   1.146 +
   1.147 +        ok(true, "Closing info bar on one window closed them on all.");
   1.148 +
   1.149 +        is(policy.notifyState, policy.STATE_NOTIFY_COMPLETE,
   1.150 +           "Closing info bar with multiple windows completes notification.");
   1.151 +        ok(policy.dataSubmissionPolicyAccepted, "Data submission policy accepted.");
   1.152 +        is(policy.dataSubmissionPolicyResponseType, "accepted-info-bar-button-pressed",
   1.153 +           "Policy records reason for acceptance was button press.");
   1.154 +        is(notification1.allNotifications.length, 0, "No notifications remain on main window.");
   1.155 +        is(notification2.allNotifications.length, 0, "No notifications remain on 2nd window.");
   1.156 +
   1.157 +        window2.close();
   1.158 +        childWindowClosed = true;
   1.159 +        maybeFinish();
   1.160 +      }
   1.161 +
   1.162 +      waitForNotificationClose(notification1.currentNotification, onAlertClose);
   1.163 +      waitForNotificationClose(notification2.currentNotification, onAlertClose);
   1.164 +
   1.165 +      // While we're here, we dual purpose this test to check that pressing the
   1.166 +      // button does the right thing.
   1.167 +      let buttons = notification2.currentNotification.getElementsByTagName("button");
   1.168 +      is(buttons.length, 1, "There is 1 button in the data reporting notification.");
   1.169 +      let button = buttons[0];
   1.170 +
   1.171 +      // Automatically close preferences window when it is opened as part of
   1.172 +      // button press.
   1.173 +      Services.obs.addObserver(function observer(prefWin, topic, data) {
   1.174 +        Services.obs.removeObserver(observer, "advanced-pane-loaded");
   1.175 +
   1.176 +        ok(true, "Pref pane opened on info bar button press.");
   1.177 +        executeSoon(function soon() {
   1.178 +          dump("Closing pref pane.\n");
   1.179 +          prefWin.close();
   1.180 +          prefPaneClosed = true;
   1.181 +          maybeFinish();
   1.182 +        });
   1.183 +      }, "advanced-pane-loaded", false);
   1.184 +
   1.185 +      button.click();
   1.186 +    }
   1.187 +
   1.188 +    notification1.addEventListener("AlertActive", function active1() {
   1.189 +      notification1.removeEventListener("AlertActive", active1, true);
   1.190 +      executeSoon(onAlertDisplayed);
   1.191 +    }, true);
   1.192 +
   1.193 +    notification2.addEventListener("AlertActive", function active2() {
   1.194 +      notification2.removeEventListener("AlertActive", active2, true);
   1.195 +      executeSoon(onAlertDisplayed);
   1.196 +    }, true);
   1.197 +
   1.198 +    policy = sendNotifyRequest("multiple_window_behavior");
   1.199 +  });
   1.200 +}
   1.201 +

mercurial