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

Fri, 16 Jan 2015 18:13:44 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Fri, 16 Jan 2015 18:13:44 +0100
branch
TOR_BUG_9701
changeset 14
925c144e1f1f
permissions
-rw-r--r--

Integrate suggestion from review to improve consistency with existing code.

michael@0 1 /* This Source Code Form is subject to the terms of the Mozilla Public
michael@0 2 * License, v. 2.0. If a copy of the MPL was not distributed with this
michael@0 3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
michael@0 4
michael@0 5 function sendNotifyRequest(name) {
michael@0 6 let ns = {};
michael@0 7 Components.utils.import("resource://gre/modules/services/datareporting/policy.jsm", ns);
michael@0 8 Components.utils.import("resource://gre/modules/Preferences.jsm", ns);
michael@0 9
michael@0 10 let service = Components.classes["@mozilla.org/datareporting/service;1"]
michael@0 11 .getService(Components.interfaces.nsISupports)
michael@0 12 .wrappedJSObject;
michael@0 13 ok(service.healthReporter, "Health Reporter instance is available.");
michael@0 14
michael@0 15 let policyPrefs = new ns.Preferences("testing." + name + ".");
michael@0 16 ok(service._prefs, "Health Reporter prefs are available.");
michael@0 17 let hrPrefs = service._prefs;
michael@0 18
michael@0 19 let policy = new ns.DataReportingPolicy(policyPrefs, hrPrefs, service);
michael@0 20 policy.firstRunDate = new Date(Date.now() - 24 * 60 * 60 * 1000);
michael@0 21
michael@0 22 is(policy.notifyState, policy.STATE_NOTIFY_UNNOTIFIED, "Policy is in unnotified state.");
michael@0 23
michael@0 24 service.healthReporter.onInit().then(function onInit() {
michael@0 25 is(policy.ensureNotifyResponse(new Date()), false, "User has not responded to policy.");
michael@0 26 });
michael@0 27
michael@0 28 return policy;
michael@0 29 }
michael@0 30
michael@0 31 /**
michael@0 32 * Wait for a <notification> to be closed then call the specified callback.
michael@0 33 */
michael@0 34 function waitForNotificationClose(notification, cb) {
michael@0 35 let parent = notification.parentNode;
michael@0 36
michael@0 37 let observer = new MutationObserver(function onMutatations(mutations) {
michael@0 38 for (let mutation of mutations) {
michael@0 39 for (let i = 0; i < mutation.removedNodes.length; i++) {
michael@0 40 let node = mutation.removedNodes.item(i);
michael@0 41
michael@0 42 if (node != notification) {
michael@0 43 continue;
michael@0 44 }
michael@0 45
michael@0 46 observer.disconnect();
michael@0 47 cb();
michael@0 48 }
michael@0 49 }
michael@0 50 });
michael@0 51
michael@0 52 observer.observe(parent, {childList: true});
michael@0 53 }
michael@0 54
michael@0 55 let dumpAppender, rootLogger;
michael@0 56
michael@0 57 function test() {
michael@0 58 waitForExplicitFinish();
michael@0 59
michael@0 60 let ns = {};
michael@0 61 Components.utils.import("resource://gre/modules/Log.jsm", ns);
michael@0 62 rootLogger = ns.Log.repository.rootLogger;
michael@0 63 dumpAppender = new ns.Log.DumpAppender();
michael@0 64 dumpAppender.level = ns.Log.Level.All;
michael@0 65 rootLogger.addAppender(dumpAppender);
michael@0 66
michael@0 67 let notification = document.getElementById("global-notificationbox");
michael@0 68 let policy;
michael@0 69
michael@0 70 notification.addEventListener("AlertActive", function active() {
michael@0 71 notification.removeEventListener("AlertActive", active, true);
michael@0 72
michael@0 73 executeSoon(function afterNotification() {
michael@0 74 is(policy.notifyState, policy.STATE_NOTIFY_WAIT, "Policy is waiting for user response.");
michael@0 75 ok(!policy.dataSubmissionPolicyAccepted, "Data submission policy not yet accepted.");
michael@0 76
michael@0 77 waitForNotificationClose(notification.currentNotification, function onClose() {
michael@0 78 is(policy.notifyState, policy.STATE_NOTIFY_COMPLETE, "Closing info bar completes user notification.");
michael@0 79 ok(policy.dataSubmissionPolicyAccepted, "Data submission policy accepted.");
michael@0 80 is(policy.dataSubmissionPolicyResponseType, "accepted-info-bar-dismissed",
michael@0 81 "Reason for acceptance was info bar dismissal.");
michael@0 82 is(notification.allNotifications.length, 0, "No notifications remain.");
michael@0 83 test_multiple_windows();
michael@0 84 });
michael@0 85 notification.currentNotification.close();
michael@0 86 });
michael@0 87 }, true);
michael@0 88
michael@0 89 policy = sendNotifyRequest("single_window_notified");
michael@0 90 }
michael@0 91
michael@0 92 function test_multiple_windows() {
michael@0 93 // Ensure we see the notification on all windows and that action on one window
michael@0 94 // results in dismiss on every window.
michael@0 95 let window2 = OpenBrowserWindow();
michael@0 96 whenDelayedStartupFinished(window2, function onWindow() {
michael@0 97 let notification1 = document.getElementById("global-notificationbox");
michael@0 98 let notification2 = window2.document.getElementById("global-notificationbox");
michael@0 99 ok(notification2, "2nd window has a global notification box.");
michael@0 100
michael@0 101 let policy;
michael@0 102
michael@0 103 let displayCount = 0;
michael@0 104 let prefPaneClosed = false;
michael@0 105 let childWindowClosed = false;
michael@0 106
michael@0 107 function onAlertDisplayed() {
michael@0 108 displayCount++;
michael@0 109
michael@0 110 if (displayCount != 2) {
michael@0 111 return;
michael@0 112 }
michael@0 113
michael@0 114 ok(true, "Data reporting info bar displayed on all open windows.");
michael@0 115
michael@0 116 // We register two independent observers and we need both to clean up
michael@0 117 // properly. This handles gating for test completion.
michael@0 118 function maybeFinish() {
michael@0 119 if (!prefPaneClosed) {
michael@0 120 dump("Not finishing test yet because pref pane isn't closed.\n");
michael@0 121 return;
michael@0 122 }
michael@0 123
michael@0 124 if (!childWindowClosed) {
michael@0 125 dump("Not finishing test yet because child window isn't closed.\n");
michael@0 126 return;
michael@0 127 }
michael@0 128
michael@0 129 dump("Finishing multiple window test.\n");
michael@0 130 rootLogger.removeAppender(dumpAppender);
michael@0 131 delete dumpAppender;
michael@0 132 delete rootLogger;
michael@0 133 finish();
michael@0 134 }
michael@0 135
michael@0 136 let closeCount = 0;
michael@0 137 function onAlertClose() {
michael@0 138 closeCount++;
michael@0 139
michael@0 140 if (closeCount != 2) {
michael@0 141 return;
michael@0 142 }
michael@0 143
michael@0 144 ok(true, "Closing info bar on one window closed them on all.");
michael@0 145
michael@0 146 is(policy.notifyState, policy.STATE_NOTIFY_COMPLETE,
michael@0 147 "Closing info bar with multiple windows completes notification.");
michael@0 148 ok(policy.dataSubmissionPolicyAccepted, "Data submission policy accepted.");
michael@0 149 is(policy.dataSubmissionPolicyResponseType, "accepted-info-bar-button-pressed",
michael@0 150 "Policy records reason for acceptance was button press.");
michael@0 151 is(notification1.allNotifications.length, 0, "No notifications remain on main window.");
michael@0 152 is(notification2.allNotifications.length, 0, "No notifications remain on 2nd window.");
michael@0 153
michael@0 154 window2.close();
michael@0 155 childWindowClosed = true;
michael@0 156 maybeFinish();
michael@0 157 }
michael@0 158
michael@0 159 waitForNotificationClose(notification1.currentNotification, onAlertClose);
michael@0 160 waitForNotificationClose(notification2.currentNotification, onAlertClose);
michael@0 161
michael@0 162 // While we're here, we dual purpose this test to check that pressing the
michael@0 163 // button does the right thing.
michael@0 164 let buttons = notification2.currentNotification.getElementsByTagName("button");
michael@0 165 is(buttons.length, 1, "There is 1 button in the data reporting notification.");
michael@0 166 let button = buttons[0];
michael@0 167
michael@0 168 // Automatically close preferences window when it is opened as part of
michael@0 169 // button press.
michael@0 170 Services.obs.addObserver(function observer(prefWin, topic, data) {
michael@0 171 Services.obs.removeObserver(observer, "advanced-pane-loaded");
michael@0 172
michael@0 173 ok(true, "Pref pane opened on info bar button press.");
michael@0 174 executeSoon(function soon() {
michael@0 175 dump("Closing pref pane.\n");
michael@0 176 prefWin.close();
michael@0 177 prefPaneClosed = true;
michael@0 178 maybeFinish();
michael@0 179 });
michael@0 180 }, "advanced-pane-loaded", false);
michael@0 181
michael@0 182 button.click();
michael@0 183 }
michael@0 184
michael@0 185 notification1.addEventListener("AlertActive", function active1() {
michael@0 186 notification1.removeEventListener("AlertActive", active1, true);
michael@0 187 executeSoon(onAlertDisplayed);
michael@0 188 }, true);
michael@0 189
michael@0 190 notification2.addEventListener("AlertActive", function active2() {
michael@0 191 notification2.removeEventListener("AlertActive", active2, true);
michael@0 192 executeSoon(onAlertDisplayed);
michael@0 193 }, true);
michael@0 194
michael@0 195 policy = sendNotifyRequest("multiple_window_behavior");
michael@0 196 });
michael@0 197 }
michael@0 198

mercurial