browser/components/test/browser_bug538331.js

Thu, 22 Jan 2015 13:21:57 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Thu, 22 Jan 2015 13:21:57 +0100
branch
TOR_BUG_9701
changeset 15
b8a032363ba2
permissions
-rw-r--r--

Incorporate requested changes from Mozilla in review:
https://bugzilla.mozilla.org/show_bug.cgi?id=1123480#c6

michael@0 1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
michael@0 2 /* vim: set ts=2 et sw=2 tw=80: */
michael@0 3 /* Any copyright is dedicated to the Public Domain.
michael@0 4 * http://creativecommons.org/publicdomain/zero/1.0/
michael@0 5 */
michael@0 6
michael@0 7 const PREF_POSTUPDATE = "app.update.postupdate";
michael@0 8 const PREF_MSTONE = "browser.startup.homepage_override.mstone";
michael@0 9 const PREF_OVERRIDE_URL = "startup.homepage_override_url";
michael@0 10
michael@0 11 const DEFAULT_PREF_URL = "http://pref.example.com/";
michael@0 12 const DEFAULT_UPDATE_URL = "http://example.com/";
michael@0 13
michael@0 14 const XML_EMPTY = "<?xml version=\"1.0\"?><updates xmlns=" +
michael@0 15 "\"http://www.mozilla.org/2005/app-update\"></updates>";
michael@0 16
michael@0 17 const XML_PREFIX = "<updates xmlns=\"http://www.mozilla.org/2005/app-update\"" +
michael@0 18 "><update appVersion=\"1.0\" buildID=\"20080811053724\" " +
michael@0 19 "channel=\"nightly\" displayVersion=\"Version 1.0\" " +
michael@0 20 "extensionVersion=\"1.0\" installDate=\"1238441400314\" " +
michael@0 21 "isCompleteUpdate=\"true\" name=\"Update Test 1.0\" " +
michael@0 22 "serviceURL=\"https://example.com/\" showNeverForVersion=" +
michael@0 23 "\"false\" showPrompt=\"false\" type=" +
michael@0 24 "\"minor\" version=\"version 1.0\" detailsURL=" +
michael@0 25 "\"http://example.com/\" previousAppVersion=\"1.0\" " +
michael@0 26 "statusText=\"The Update was successfully installed\" " +
michael@0 27 "foregroundDownload=\"true\"";
michael@0 28
michael@0 29 const XML_SUFFIX = "><patch type=\"complete\" URL=\"http://example.com/\" " +
michael@0 30 "hashFunction=\"MD5\" hashValue=" +
michael@0 31 "\"6232cd43a1c77e30191c53a329a3f99d\" size=\"775\" " +
michael@0 32 "selected=\"true\" state=\"succeeded\"/></update></updates>";
michael@0 33
michael@0 34 // nsBrowserContentHandler.js defaultArgs tests
michael@0 35 const BCH_TESTS = [
michael@0 36 {
michael@0 37 description: "no mstone change and no update",
michael@0 38 noPostUpdatePref: true,
michael@0 39 noMstoneChange: true
michael@0 40 }, {
michael@0 41 description: "mstone changed and no update",
michael@0 42 noPostUpdatePref: true,
michael@0 43 prefURL: DEFAULT_PREF_URL
michael@0 44 }, {
michael@0 45 description: "no mstone change and update with 'showURL' for actions",
michael@0 46 actions: "showURL",
michael@0 47 noMstoneChange: true
michael@0 48 }, {
michael@0 49 description: "update without actions",
michael@0 50 prefURL: DEFAULT_PREF_URL
michael@0 51 }, {
michael@0 52 description: "update with 'showURL' for actions",
michael@0 53 actions: "showURL",
michael@0 54 prefURL: DEFAULT_PREF_URL
michael@0 55 }, {
michael@0 56 description: "update with 'showURL' for actions and openURL",
michael@0 57 actions: "showURL",
michael@0 58 openURL: DEFAULT_UPDATE_URL
michael@0 59 }, {
michael@0 60 description: "update with 'showURL showAlert' for actions",
michael@0 61 actions: "showAlert showURL",
michael@0 62 prefURL: DEFAULT_PREF_URL
michael@0 63 }, {
michael@0 64 description: "update with 'showAlert showURL' for actions and openURL",
michael@0 65 actions: "showAlert showURL",
michael@0 66 openURL: DEFAULT_UPDATE_URL
michael@0 67 }, {
michael@0 68 description: "update with 'showURL showNotification' for actions",
michael@0 69 actions: "showURL showNotification",
michael@0 70 prefURL: DEFAULT_PREF_URL
michael@0 71 }, {
michael@0 72 description: "update with 'showNotification showURL' for actions and " +
michael@0 73 "openURL",
michael@0 74 actions: "showNotification showURL",
michael@0 75 openURL: DEFAULT_UPDATE_URL
michael@0 76 }, {
michael@0 77 description: "update with 'showAlert showURL showNotification' for actions",
michael@0 78 actions: "showAlert showURL showNotification",
michael@0 79 prefURL: DEFAULT_PREF_URL
michael@0 80 }, {
michael@0 81 description: "update with 'showNotification showURL showAlert' for " +
michael@0 82 "actions and openURL",
michael@0 83 actions: "showNotification showURL showAlert",
michael@0 84 openURL: DEFAULT_UPDATE_URL
michael@0 85 }, {
michael@0 86 description: "update with 'showAlert' for actions",
michael@0 87 actions: "showAlert"
michael@0 88 }, {
michael@0 89 description: "update with 'showAlert showNotification' for actions",
michael@0 90 actions: "showAlert showNotification"
michael@0 91 }, {
michael@0 92 description: "update with 'showNotification' for actions",
michael@0 93 actions: "showNotification"
michael@0 94 }, {
michael@0 95 description: "update with 'showNotification showAlert' for actions",
michael@0 96 actions: "showNotification showAlert"
michael@0 97 }, {
michael@0 98 description: "update with 'silent' for actions",
michael@0 99 actions: "silent"
michael@0 100 }, {
michael@0 101 description: "update with 'silent showURL showAlert showNotification' " +
michael@0 102 "for actions and openURL",
michael@0 103 actions: "silent showURL showAlert showNotification"
michael@0 104 }
michael@0 105 ];
michael@0 106
michael@0 107 var gOriginalMStone;
michael@0 108 var gOriginalOverrideURL;
michael@0 109
michael@0 110 this.__defineGetter__("gBG", function() {
michael@0 111 delete this.gBG;
michael@0 112 return this.gBG = Cc["@mozilla.org/browser/browserglue;1"].
michael@0 113 getService(Ci.nsIBrowserGlue).
michael@0 114 QueryInterface(Ci.nsIObserver);
michael@0 115 });
michael@0 116
michael@0 117 function test()
michael@0 118 {
michael@0 119 waitForExplicitFinish();
michael@0 120
michael@0 121 // Reset the startup page pref since it may have been set by other tests
michael@0 122 // and we will assume it is default.
michael@0 123 Services.prefs.clearUserPref('browser.startup.page');
michael@0 124
michael@0 125 if (gPrefService.prefHasUserValue(PREF_MSTONE)) {
michael@0 126 gOriginalMStone = gPrefService.getCharPref(PREF_MSTONE);
michael@0 127 }
michael@0 128
michael@0 129 if (gPrefService.prefHasUserValue(PREF_OVERRIDE_URL)) {
michael@0 130 gOriginalOverrideURL = gPrefService.getCharPref(PREF_OVERRIDE_URL);
michael@0 131 }
michael@0 132
michael@0 133 testDefaultArgs();
michael@0 134 }
michael@0 135
michael@0 136 var gWindowCatcher = {
michael@0 137 windowsOpen: 0,
michael@0 138 finishCalled: false,
michael@0 139 start: function() {
michael@0 140 Services.ww.registerNotification(this);
michael@0 141 },
michael@0 142
michael@0 143 finish: function(aFunc) {
michael@0 144 Services.ww.unregisterNotification(this);
michael@0 145 this.finishFunc = aFunc;
michael@0 146 if (this.windowsOpen > 0)
michael@0 147 return;
michael@0 148
michael@0 149 this.finishFunc();
michael@0 150 },
michael@0 151
michael@0 152 closeWindow: function (win) {
michael@0 153 info("window catcher closing window: " + win.document.documentURI);
michael@0 154 win.close();
michael@0 155 this.windowsOpen--;
michael@0 156 if (this.finishFunc) {
michael@0 157 this.finish(this.finishFunc);
michael@0 158 }
michael@0 159 },
michael@0 160
michael@0 161 windowLoad: function (win) {
michael@0 162 executeSoon(this.closeWindow.bind(this, win));
michael@0 163 },
michael@0 164
michael@0 165 observe: function(subject, topic, data) {
michael@0 166 if (topic != "domwindowopened")
michael@0 167 return;
michael@0 168
michael@0 169 this.windowsOpen++;
michael@0 170 let win = subject.QueryInterface(Ci.nsIDOMWindow);
michael@0 171 info("window catcher caught window opening: " + win.document.documentURI);
michael@0 172 win.addEventListener("load", function () {
michael@0 173 win.removeEventListener("load", arguments.callee, false);
michael@0 174 gWindowCatcher.windowLoad(win);
michael@0 175 }, false);
michael@0 176 }
michael@0 177 };
michael@0 178
michael@0 179 function finish_test()
michael@0 180 {
michael@0 181 // Reset browser.startup.homepage_override.mstone to the original value or
michael@0 182 // clear it if it didn't exist.
michael@0 183 if (gOriginalMStone) {
michael@0 184 gPrefService.setCharPref(PREF_MSTONE, gOriginalMStone);
michael@0 185 } else if (gPrefService.prefHasUserValue(PREF_MSTONE)) {
michael@0 186 gPrefService.clearUserPref(PREF_MSTONE);
michael@0 187 }
michael@0 188
michael@0 189 // Reset startup.homepage_override_url to the original value or clear it if
michael@0 190 // it didn't exist.
michael@0 191 if (gOriginalOverrideURL) {
michael@0 192 gPrefService.setCharPref(PREF_OVERRIDE_URL, gOriginalOverrideURL);
michael@0 193 } else if (gPrefService.prefHasUserValue(PREF_OVERRIDE_URL)) {
michael@0 194 gPrefService.clearUserPref(PREF_OVERRIDE_URL);
michael@0 195 }
michael@0 196
michael@0 197 writeUpdatesToXMLFile(XML_EMPTY);
michael@0 198 reloadUpdateManagerData();
michael@0 199
michael@0 200 finish();
michael@0 201 }
michael@0 202
michael@0 203 // Test the defaultArgs returned by nsBrowserContentHandler after an update
michael@0 204 function testDefaultArgs()
michael@0 205 {
michael@0 206 // Clear any pre-existing override in defaultArgs that are hanging around.
michael@0 207 // This will also set the browser.startup.homepage_override.mstone preference
michael@0 208 // if it isn't already set.
michael@0 209 Cc["@mozilla.org/browser/clh;1"].getService(Ci.nsIBrowserHandler).defaultArgs;
michael@0 210
michael@0 211 let originalMstone = gPrefService.getCharPref(PREF_MSTONE);
michael@0 212
michael@0 213 gPrefService.setCharPref(PREF_OVERRIDE_URL, DEFAULT_PREF_URL);
michael@0 214
michael@0 215 writeUpdatesToXMLFile(XML_EMPTY);
michael@0 216 reloadUpdateManagerData();
michael@0 217
michael@0 218 for (let i = 0; i < BCH_TESTS.length; i++) {
michael@0 219 let test = BCH_TESTS[i];
michael@0 220 ok(true, "Test nsBrowserContentHandler " + (i + 1) + ": " + test.description);
michael@0 221
michael@0 222 if (test.actions) {
michael@0 223 let actionsXML = " actions=\"" + test.actions + "\"";
michael@0 224 if (test.openURL) {
michael@0 225 actionsXML += " openURL=\"" + test.openURL + "\"";
michael@0 226 }
michael@0 227 writeUpdatesToXMLFile(XML_PREFIX + actionsXML + XML_SUFFIX);
michael@0 228 } else {
michael@0 229 writeUpdatesToXMLFile(XML_EMPTY);
michael@0 230 }
michael@0 231
michael@0 232 reloadUpdateManagerData();
michael@0 233
michael@0 234 let noOverrideArgs = Cc["@mozilla.org/browser/clh;1"].
michael@0 235 getService(Ci.nsIBrowserHandler).defaultArgs;
michael@0 236
michael@0 237 let overrideArgs = "";
michael@0 238 if (test.prefURL) {
michael@0 239 overrideArgs = test.prefURL;
michael@0 240 } else if (test.openURL) {
michael@0 241 overrideArgs = test.openURL;
michael@0 242 }
michael@0 243
michael@0 244 if (overrideArgs == "" && noOverrideArgs) {
michael@0 245 overrideArgs = noOverrideArgs;
michael@0 246 } else if (noOverrideArgs) {
michael@0 247 overrideArgs += "|" + noOverrideArgs;
michael@0 248 }
michael@0 249
michael@0 250 if (test.noMstoneChange === undefined) {
michael@0 251 gPrefService.setCharPref(PREF_MSTONE, "PreviousMilestone");
michael@0 252 }
michael@0 253
michael@0 254 if (test.noPostUpdatePref == undefined) {
michael@0 255 gPrefService.setBoolPref(PREF_POSTUPDATE, true);
michael@0 256 }
michael@0 257
michael@0 258 let defaultArgs = Cc["@mozilla.org/browser/clh;1"].
michael@0 259 getService(Ci.nsIBrowserHandler).defaultArgs;
michael@0 260 is(defaultArgs, overrideArgs, "correct value returned by defaultArgs");
michael@0 261
michael@0 262 if (test.noMstoneChange === undefined || test.noMstoneChange != true) {
michael@0 263 let newMstone = gPrefService.getCharPref(PREF_MSTONE);
michael@0 264 is(originalMstone, newMstone, "preference " + PREF_MSTONE +
michael@0 265 " should have been updated");
michael@0 266 }
michael@0 267
michael@0 268 if (gPrefService.prefHasUserValue(PREF_POSTUPDATE)) {
michael@0 269 gPrefService.clearUserPref(PREF_POSTUPDATE);
michael@0 270 }
michael@0 271 }
michael@0 272
michael@0 273 testShowNotification();
michael@0 274 }
michael@0 275
michael@0 276 // nsBrowserGlue.js _showUpdateNotification notification tests
michael@0 277 const BG_NOTIFY_TESTS = [
michael@0 278 {
michael@0 279 description: "'silent showNotification' actions should not display a notification",
michael@0 280 actions: "silent showNotification"
michael@0 281 }, {
michael@0 282 description: "'showNotification' for actions should display a notification",
michael@0 283 actions: "showNotification"
michael@0 284 }, {
michael@0 285 description: "no actions and empty updates.xml",
michael@0 286 }, {
michael@0 287 description: "'showAlert' for actions should not display a notification",
michael@0 288 actions: "showAlert"
michael@0 289 }, {
michael@0 290 // This test MUST be the last test in the array to test opening the url
michael@0 291 // provided by the updates.xml.
michael@0 292 description: "'showNotification' for actions with custom notification " +
michael@0 293 "attributes should display a notification",
michael@0 294 actions: "showNotification",
michael@0 295 notificationText: "notification text",
michael@0 296 notificationURL: DEFAULT_UPDATE_URL,
michael@0 297 notificationButtonLabel: "button label",
michael@0 298 notificationButtonAccessKey: "b"
michael@0 299 }
michael@0 300 ];
michael@0 301
michael@0 302 // Test showing a notification after an update
michael@0 303 // _showUpdateNotification in nsBrowserGlue.js
michael@0 304 function testShowNotification()
michael@0 305 {
michael@0 306 let gTestBrowser = gBrowser.selectedBrowser;
michael@0 307 let notifyBox = gBrowser.getNotificationBox(gTestBrowser);
michael@0 308
michael@0 309 // Catches any windows opened by these tests (e.g. alert windows) and closes
michael@0 310 // them
michael@0 311 gWindowCatcher.start();
michael@0 312
michael@0 313 for (let i = 0; i < BG_NOTIFY_TESTS.length; i++) {
michael@0 314 let test = BG_NOTIFY_TESTS[i];
michael@0 315 ok(true, "Test showNotification " + (i + 1) + ": " + test.description);
michael@0 316
michael@0 317 if (test.actions) {
michael@0 318 let actionsXML = " actions=\"" + test.actions + "\"";
michael@0 319 if (test.notificationText) {
michael@0 320 actionsXML += " notificationText=\"" + test.notificationText + "\"";
michael@0 321 }
michael@0 322 if (test.notificationURL) {
michael@0 323 actionsXML += " notificationURL=\"" + test.notificationURL + "\"";
michael@0 324 }
michael@0 325 if (test.notificationButtonLabel) {
michael@0 326 actionsXML += " notificationButtonLabel=\"" + test.notificationButtonLabel + "\"";
michael@0 327 }
michael@0 328 if (test.notificationButtonAccessKey) {
michael@0 329 actionsXML += " notificationButtonAccessKey=\"" + test.notificationButtonAccessKey + "\"";
michael@0 330 }
michael@0 331 writeUpdatesToXMLFile(XML_PREFIX + actionsXML + XML_SUFFIX);
michael@0 332 } else {
michael@0 333 writeUpdatesToXMLFile(XML_EMPTY);
michael@0 334 }
michael@0 335
michael@0 336 reloadUpdateManagerData();
michael@0 337 gPrefService.setBoolPref(PREF_POSTUPDATE, true);
michael@0 338
michael@0 339 gBG.observe(null, "browser-glue-test", "post-update-notification");
michael@0 340
michael@0 341 let updateBox = notifyBox.getNotificationWithValue("post-update-notification");
michael@0 342 if (test.actions && test.actions.indexOf("showNotification") != -1 &&
michael@0 343 test.actions.indexOf("silent") == -1) {
michael@0 344 ok(updateBox, "Update notification box should have been displayed");
michael@0 345 if (updateBox) {
michael@0 346 if (test.notificationText) {
michael@0 347 is(updateBox.label, test.notificationText, "Update notification box " +
michael@0 348 "should have the label provided by the update");
michael@0 349 }
michael@0 350 if (test.notificationButtonLabel) {
michael@0 351 var button = updateBox.getElementsByTagName("button").item(0);
michael@0 352 is(button.label, test.notificationButtonLabel, "Update notification " +
michael@0 353 "box button should have the label provided by the update");
michael@0 354 if (test.notificationButtonAccessKey) {
michael@0 355 let accessKey = button.getAttribute("accesskey");
michael@0 356 is(accessKey, test.notificationButtonAccessKey, "Update " +
michael@0 357 "notification box button should have the accesskey " +
michael@0 358 "provided by the update");
michael@0 359 }
michael@0 360 }
michael@0 361 // The last test opens an url and verifies the url from the updates.xml
michael@0 362 // is correct.
michael@0 363 if (i == (BG_NOTIFY_TESTS.length - 1)) {
michael@0 364 // Wait for any windows caught by the windowcatcher to close
michael@0 365 gWindowCatcher.finish(function () {
michael@0 366 button.click();
michael@0 367 gBrowser.selectedBrowser.addEventListener("load", function () {
michael@0 368 gBrowser.selectedBrowser.removeEventListener("load", arguments.callee, true);
michael@0 369 testNotificationURL();
michael@0 370 }, true);
michael@0 371 });
michael@0 372 } else {
michael@0 373 notifyBox.removeAllNotifications(true);
michael@0 374 }
michael@0 375 } else if (i == (BG_NOTIFY_TESTS.length - 1)) {
michael@0 376 // If updateBox is null the test has already reported errors so bail
michael@0 377 finish_test();
michael@0 378 }
michael@0 379 } else {
michael@0 380 ok(!updateBox, "Update notification box should not have been displayed");
michael@0 381 }
michael@0 382
michael@0 383 let prefHasUserValue = gPrefService.prefHasUserValue(PREF_POSTUPDATE);
michael@0 384 is(prefHasUserValue, false, "preference " + PREF_POSTUPDATE +
michael@0 385 " shouldn't have a user value");
michael@0 386 }
michael@0 387 }
michael@0 388
michael@0 389 // Test opening the url provided by the updates.xml in the last test
michael@0 390 function testNotificationURL()
michael@0 391 {
michael@0 392 ok(true, "Test testNotificationURL: clicking the notification button " +
michael@0 393 "opened the url specified by the update");
michael@0 394 let href = gBrowser.selectedBrowser.contentWindow.location.href;
michael@0 395 let expectedURL = BG_NOTIFY_TESTS[BG_NOTIFY_TESTS.length - 1].notificationURL;
michael@0 396 is(href, expectedURL, "The url opened from the notification should be the " +
michael@0 397 "url provided by the update");
michael@0 398 gBrowser.removeCurrentTab();
michael@0 399 window.focus();
michael@0 400 finish_test();
michael@0 401 }
michael@0 402
michael@0 403 /* Reloads the update metadata from disk */
michael@0 404 function reloadUpdateManagerData()
michael@0 405 {
michael@0 406 Cc["@mozilla.org/updates/update-manager;1"].getService(Ci.nsIUpdateManager).
michael@0 407 QueryInterface(Ci.nsIObserver).observe(null, "um-reload-update-data", "");
michael@0 408 }
michael@0 409
michael@0 410
michael@0 411 function writeUpdatesToXMLFile(aText)
michael@0 412 {
michael@0 413 const PERMS_FILE = 0644;
michael@0 414
michael@0 415 const MODE_WRONLY = 0x02;
michael@0 416 const MODE_CREATE = 0x08;
michael@0 417 const MODE_TRUNCATE = 0x20;
michael@0 418
michael@0 419 let file = Cc["@mozilla.org/file/directory_service;1"].
michael@0 420 getService(Ci.nsIProperties).
michael@0 421 get("UpdRootD", Ci.nsIFile);
michael@0 422 file.append("updates.xml");
michael@0 423 let fos = Cc["@mozilla.org/network/file-output-stream;1"].
michael@0 424 createInstance(Ci.nsIFileOutputStream);
michael@0 425 if (!file.exists()) {
michael@0 426 file.create(Ci.nsILocalFile.NORMAL_FILE_TYPE, PERMS_FILE);
michael@0 427 }
michael@0 428 fos.init(file, MODE_WRONLY | MODE_CREATE | MODE_TRUNCATE, PERMS_FILE, 0);
michael@0 429 fos.write(aText, aText.length);
michael@0 430 fos.close();
michael@0 431 }

mercurial