diff options
Diffstat (limited to 'browser/base/content/test/browser_datareporting_notification.js')
-rw-r--r-- | browser/base/content/test/browser_datareporting_notification.js | 198 |
1 files changed, 198 insertions, 0 deletions
diff --git a/browser/base/content/test/browser_datareporting_notification.js b/browser/base/content/test/browser_datareporting_notification.js new file mode 100644 index 000000000..b892bd009 --- /dev/null +++ b/browser/base/content/test/browser_datareporting_notification.js @@ -0,0 +1,198 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +function sendNotifyRequest(name) { + let ns = {}; + Components.utils.import("resource://gre/modules/services/datareporting/policy.jsm", ns); + Components.utils.import("resource://gre/modules/Preferences.jsm", ns); + + let service = Components.classes["@mozilla.org/datareporting/service;1"] + .getService(Components.interfaces.nsISupports) + .wrappedJSObject; + ok(service.healthReporter, "Health Reporter instance is available."); + + let policyPrefs = new ns.Preferences("testing." + name + "."); + ok(service._prefs, "Health Reporter prefs are available."); + let hrPrefs = service._prefs; + + let policy = new ns.DataReportingPolicy(policyPrefs, hrPrefs, service); + policy.firstRunDate = new Date(Date.now() - 24 * 60 * 60 * 1000); + + is(policy.notifyState, policy.STATE_NOTIFY_UNNOTIFIED, "Policy is in unnotified state."); + + service.healthReporter.onInit().then(function onInit() { + is(policy.ensureNotifyResponse(new Date()), false, "User has not responded to policy."); + }); + + return policy; +} + +/** + * Wait for a <notification> to be closed then call the specified callback. + */ +function waitForNotificationClose(notification, cb) { + let parent = notification.parentNode; + + let observer = new MutationObserver(function onMutatations(mutations) { + for (let mutation of mutations) { + for (let i = 0; i < mutation.removedNodes.length; i++) { + let node = mutation.removedNodes.item(i); + + if (node != notification) { + continue; + } + + observer.disconnect(); + cb(); + } + } + }); + + observer.observe(parent, {childList: true}); +} + +let dumpAppender, rootLogger; + +function test() { + waitForExplicitFinish(); + + let ns = {}; + Components.utils.import("resource://services-common/log4moz.js", ns); + rootLogger = ns.Log4Moz.repository.rootLogger; + dumpAppender = new ns.Log4Moz.DumpAppender(); + dumpAppender.level = ns.Log4Moz.Level.All; + rootLogger.addAppender(dumpAppender); + + let notification = document.getElementById("global-notificationbox"); + let policy; + + notification.addEventListener("AlertActive", function active() { + notification.removeEventListener("AlertActive", active, true); + + executeSoon(function afterNotification() { + is(policy.notifyState, policy.STATE_NOTIFY_WAIT, "Policy is waiting for user response."); + ok(!policy.dataSubmissionPolicyAccepted, "Data submission policy not yet accepted."); + + waitForNotificationClose(notification.currentNotification, function onClose() { + is(policy.notifyState, policy.STATE_NOTIFY_COMPLETE, "Closing info bar completes user notification."); + ok(policy.dataSubmissionPolicyAccepted, "Data submission policy accepted."); + is(policy.dataSubmissionPolicyResponseType, "accepted-info-bar-dismissed", + "Reason for acceptance was info bar dismissal."); + is(notification.allNotifications.length, 0, "No notifications remain."); + test_multiple_windows(); + }); + notification.currentNotification.close(); + }); + }, true); + + policy = sendNotifyRequest("single_window_notified"); +} + +function test_multiple_windows() { + // Ensure we see the notification on all windows and that action on one window + // results in dismiss on every window. + let window2 = OpenBrowserWindow(); + whenDelayedStartupFinished(window2, function onWindow() { + let notification1 = document.getElementById("global-notificationbox"); + let notification2 = window2.document.getElementById("global-notificationbox"); + ok(notification2, "2nd window has a global notification box."); + + let policy; + + let displayCount = 0; + let prefPaneClosed = false; + let childWindowClosed = false; + + function onAlertDisplayed() { + displayCount++; + + if (displayCount != 2) { + return; + } + + ok(true, "Data reporting info bar displayed on all open windows."); + + // We register two independent observers and we need both to clean up + // properly. This handles gating for test completion. + function maybeFinish() { + if (!prefPaneClosed) { + dump("Not finishing test yet because pref pane isn't closed.\n"); + return; + } + + if (!childWindowClosed) { + dump("Not finishing test yet because child window isn't closed.\n"); + return; + } + + dump("Finishing multiple window test.\n"); + rootLogger.removeAppender(dumpAppender); + delete dumpAppender; + delete rootLogger; + finish(); + } + + let closeCount = 0; + function onAlertClose() { + closeCount++; + + if (closeCount != 2) { + return; + } + + ok(true, "Closing info bar on one window closed them on all."); + + is(policy.notifyState, policy.STATE_NOTIFY_COMPLETE, + "Closing info bar with multiple windows completes notification."); + ok(policy.dataSubmissionPolicyAccepted, "Data submission policy accepted."); + is(policy.dataSubmissionPolicyResponseType, "accepted-info-bar-button-pressed", + "Policy records reason for acceptance was button press."); + is(notification1.allNotifications.length, 0, "No notifications remain on main window."); + is(notification2.allNotifications.length, 0, "No notifications remain on 2nd window."); + + window2.close(); + childWindowClosed = true; + maybeFinish(); + } + + waitForNotificationClose(notification1.currentNotification, onAlertClose); + waitForNotificationClose(notification2.currentNotification, onAlertClose); + + // While we're here, we dual purpose this test to check that pressing the + // button does the right thing. + let buttons = notification2.currentNotification.getElementsByTagName("button"); + is(buttons.length, 1, "There is 1 button in the data reporting notification."); + let button = buttons[0]; + + // Automatically close preferences window when it is opened as part of + // button press. + Services.obs.addObserver(function observer(prefWin, topic, data) { + Services.obs.removeObserver(observer, "advanced-pane-loaded"); + + ok(true, "Pref pane opened on info bar button press."); + executeSoon(function soon() { + dump("Closing pref pane.\n"); + prefWin.close(); + prefPaneClosed = true; + maybeFinish(); + }); + }, "advanced-pane-loaded", false); + + button.click(); + } + + notification1.addEventListener("AlertActive", function active1() { + notification1.removeEventListener("AlertActive", active1, true); + executeSoon(onAlertDisplayed); + }, true); + + notification2.addEventListener("AlertActive", function active2() { + notification2.removeEventListener("AlertActive", active2, true); + executeSoon(onAlertDisplayed); + }, true); + + policy = sendNotifyRequest("multiple_window_behavior"); + }); +} + |