browser/components/test/browser_bug538331.js

changeset 0
6474c204b198
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/browser/components/test/browser_bug538331.js	Wed Dec 31 06:09:35 2014 +0100
     1.3 @@ -0,0 +1,431 @@
     1.4 +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
     1.5 +/* vim: set ts=2 et sw=2 tw=80: */
     1.6 +/* Any copyright is dedicated to the Public Domain.
     1.7 + * http://creativecommons.org/publicdomain/zero/1.0/
     1.8 + */
     1.9 +
    1.10 +const PREF_POSTUPDATE = "app.update.postupdate";
    1.11 +const PREF_MSTONE = "browser.startup.homepage_override.mstone";
    1.12 +const PREF_OVERRIDE_URL = "startup.homepage_override_url";
    1.13 +
    1.14 +const DEFAULT_PREF_URL = "http://pref.example.com/";
    1.15 +const DEFAULT_UPDATE_URL = "http://example.com/";
    1.16 +
    1.17 +const XML_EMPTY = "<?xml version=\"1.0\"?><updates xmlns=" +
    1.18 +                  "\"http://www.mozilla.org/2005/app-update\"></updates>";
    1.19 +
    1.20 +const XML_PREFIX =  "<updates xmlns=\"http://www.mozilla.org/2005/app-update\"" +
    1.21 +                    "><update appVersion=\"1.0\" buildID=\"20080811053724\" " +
    1.22 +                    "channel=\"nightly\" displayVersion=\"Version 1.0\" " +
    1.23 +                    "extensionVersion=\"1.0\" installDate=\"1238441400314\" " +
    1.24 +                    "isCompleteUpdate=\"true\" name=\"Update Test 1.0\" " +
    1.25 +                    "serviceURL=\"https://example.com/\" showNeverForVersion=" +
    1.26 +                    "\"false\" showPrompt=\"false\" type=" +
    1.27 +                    "\"minor\" version=\"version 1.0\" detailsURL=" +
    1.28 +                    "\"http://example.com/\" previousAppVersion=\"1.0\" " +
    1.29 +                    "statusText=\"The Update was successfully installed\" " +
    1.30 +                    "foregroundDownload=\"true\"";
    1.31 +
    1.32 +const XML_SUFFIX = "><patch type=\"complete\" URL=\"http://example.com/\" " +
    1.33 +                   "hashFunction=\"MD5\" hashValue=" +
    1.34 +                   "\"6232cd43a1c77e30191c53a329a3f99d\" size=\"775\" " +
    1.35 +                   "selected=\"true\" state=\"succeeded\"/></update></updates>";
    1.36 +
    1.37 +// nsBrowserContentHandler.js defaultArgs tests
    1.38 +const BCH_TESTS = [
    1.39 +  {
    1.40 +    description: "no mstone change and no update",
    1.41 +    noPostUpdatePref: true,
    1.42 +    noMstoneChange: true
    1.43 +  }, {
    1.44 +    description: "mstone changed and no update",
    1.45 +    noPostUpdatePref: true,
    1.46 +    prefURL: DEFAULT_PREF_URL
    1.47 +  }, {
    1.48 +    description: "no mstone change and update with 'showURL' for actions",
    1.49 +    actions: "showURL",
    1.50 +    noMstoneChange: true
    1.51 +  }, {
    1.52 +    description: "update without actions",
    1.53 +    prefURL: DEFAULT_PREF_URL
    1.54 +  }, {
    1.55 +    description: "update with 'showURL' for actions",
    1.56 +    actions: "showURL",
    1.57 +    prefURL: DEFAULT_PREF_URL
    1.58 +  }, {
    1.59 +    description: "update with 'showURL' for actions and openURL",
    1.60 +    actions: "showURL",
    1.61 +    openURL: DEFAULT_UPDATE_URL
    1.62 +    }, {
    1.63 +    description: "update with 'showURL showAlert' for actions",
    1.64 +    actions: "showAlert showURL",
    1.65 +    prefURL: DEFAULT_PREF_URL
    1.66 +  }, {
    1.67 +    description: "update with 'showAlert showURL' for actions and openURL",
    1.68 +    actions: "showAlert showURL",
    1.69 +    openURL: DEFAULT_UPDATE_URL
    1.70 +  }, {
    1.71 +    description: "update with 'showURL showNotification' for actions",
    1.72 +    actions: "showURL showNotification",
    1.73 +    prefURL: DEFAULT_PREF_URL
    1.74 +  }, {
    1.75 +    description: "update with 'showNotification showURL' for actions and " +
    1.76 +                 "openURL",
    1.77 +    actions: "showNotification showURL",
    1.78 +    openURL: DEFAULT_UPDATE_URL
    1.79 +  }, {
    1.80 +    description: "update with 'showAlert showURL showNotification' for actions",
    1.81 +    actions: "showAlert showURL showNotification",
    1.82 +    prefURL: DEFAULT_PREF_URL
    1.83 +  }, {
    1.84 +    description: "update with 'showNotification showURL showAlert' for " +
    1.85 +                 "actions and openURL",
    1.86 +    actions: "showNotification showURL showAlert",
    1.87 +    openURL: DEFAULT_UPDATE_URL
    1.88 +  }, {
    1.89 +    description: "update with 'showAlert' for actions",
    1.90 +    actions: "showAlert"
    1.91 +  }, {
    1.92 +    description: "update with 'showAlert showNotification' for actions",
    1.93 +    actions: "showAlert showNotification"
    1.94 +  }, {
    1.95 +    description: "update with 'showNotification' for actions",
    1.96 +    actions: "showNotification"
    1.97 +  }, {
    1.98 +    description: "update with 'showNotification showAlert' for actions",
    1.99 +    actions: "showNotification showAlert"
   1.100 +  }, {
   1.101 +    description: "update with 'silent' for actions",
   1.102 +    actions: "silent"
   1.103 +  }, {
   1.104 +    description: "update with 'silent showURL showAlert showNotification' " +
   1.105 +                 "for actions and openURL",
   1.106 +    actions: "silent showURL showAlert showNotification"
   1.107 +  }
   1.108 +];
   1.109 +
   1.110 +var gOriginalMStone;
   1.111 +var gOriginalOverrideURL;
   1.112 +
   1.113 +this.__defineGetter__("gBG", function() {
   1.114 +  delete this.gBG;
   1.115 +  return this.gBG = Cc["@mozilla.org/browser/browserglue;1"].
   1.116 +                    getService(Ci.nsIBrowserGlue).
   1.117 +                    QueryInterface(Ci.nsIObserver);
   1.118 +});
   1.119 +
   1.120 +function test()
   1.121 +{
   1.122 +  waitForExplicitFinish();
   1.123 +
   1.124 +  // Reset the startup page pref since it may have been set by other tests
   1.125 +  // and we will assume it is default.
   1.126 +  Services.prefs.clearUserPref('browser.startup.page');
   1.127 +
   1.128 +  if (gPrefService.prefHasUserValue(PREF_MSTONE)) {
   1.129 +    gOriginalMStone = gPrefService.getCharPref(PREF_MSTONE);
   1.130 +  }
   1.131 +
   1.132 +  if (gPrefService.prefHasUserValue(PREF_OVERRIDE_URL)) {
   1.133 +    gOriginalOverrideURL = gPrefService.getCharPref(PREF_OVERRIDE_URL);
   1.134 +  }
   1.135 +
   1.136 +  testDefaultArgs();
   1.137 +}
   1.138 +
   1.139 +var gWindowCatcher = {
   1.140 +  windowsOpen: 0,
   1.141 +  finishCalled: false,
   1.142 +  start: function() {
   1.143 +    Services.ww.registerNotification(this);
   1.144 +  },
   1.145 +
   1.146 +  finish: function(aFunc) {
   1.147 +    Services.ww.unregisterNotification(this);
   1.148 +    this.finishFunc = aFunc;
   1.149 +    if (this.windowsOpen > 0)
   1.150 +      return;
   1.151 +
   1.152 +    this.finishFunc();
   1.153 +  },
   1.154 +
   1.155 +  closeWindow: function (win) {
   1.156 +    info("window catcher closing window: " + win.document.documentURI);
   1.157 +    win.close();
   1.158 +    this.windowsOpen--;
   1.159 +    if (this.finishFunc) {
   1.160 +      this.finish(this.finishFunc);
   1.161 +    }
   1.162 +  },
   1.163 +
   1.164 +  windowLoad: function (win) {
   1.165 +    executeSoon(this.closeWindow.bind(this, win));
   1.166 +  },
   1.167 +
   1.168 +  observe: function(subject, topic, data) {
   1.169 +    if (topic != "domwindowopened")
   1.170 +      return;
   1.171 +
   1.172 +    this.windowsOpen++;
   1.173 +    let win = subject.QueryInterface(Ci.nsIDOMWindow);
   1.174 +    info("window catcher caught window opening: " + win.document.documentURI);
   1.175 +    win.addEventListener("load", function () {
   1.176 +      win.removeEventListener("load", arguments.callee, false);
   1.177 +      gWindowCatcher.windowLoad(win);
   1.178 +    }, false);
   1.179 +  }
   1.180 +};
   1.181 +
   1.182 +function finish_test()
   1.183 +{
   1.184 +  // Reset browser.startup.homepage_override.mstone to the original value or
   1.185 +  // clear it if it didn't exist.
   1.186 +  if (gOriginalMStone) {
   1.187 +    gPrefService.setCharPref(PREF_MSTONE, gOriginalMStone);
   1.188 +  } else if (gPrefService.prefHasUserValue(PREF_MSTONE)) {
   1.189 +    gPrefService.clearUserPref(PREF_MSTONE);
   1.190 +  }
   1.191 +
   1.192 +  // Reset startup.homepage_override_url to the original value or clear it if
   1.193 +  // it didn't exist.
   1.194 +  if (gOriginalOverrideURL) {
   1.195 +    gPrefService.setCharPref(PREF_OVERRIDE_URL, gOriginalOverrideURL);
   1.196 +  } else if (gPrefService.prefHasUserValue(PREF_OVERRIDE_URL)) {
   1.197 +    gPrefService.clearUserPref(PREF_OVERRIDE_URL);
   1.198 +  }
   1.199 +
   1.200 +  writeUpdatesToXMLFile(XML_EMPTY);
   1.201 +  reloadUpdateManagerData();
   1.202 +
   1.203 +  finish();
   1.204 +}
   1.205 +
   1.206 +// Test the defaultArgs returned by nsBrowserContentHandler after an update
   1.207 +function testDefaultArgs()
   1.208 +{
   1.209 +  // Clear any pre-existing override in defaultArgs that are hanging around.
   1.210 +  // This will also set the browser.startup.homepage_override.mstone preference
   1.211 +  // if it isn't already set.
   1.212 +  Cc["@mozilla.org/browser/clh;1"].getService(Ci.nsIBrowserHandler).defaultArgs;
   1.213 +
   1.214 +  let originalMstone = gPrefService.getCharPref(PREF_MSTONE);
   1.215 +
   1.216 +  gPrefService.setCharPref(PREF_OVERRIDE_URL, DEFAULT_PREF_URL);
   1.217 +
   1.218 +  writeUpdatesToXMLFile(XML_EMPTY);
   1.219 +  reloadUpdateManagerData();
   1.220 +
   1.221 +  for (let i = 0; i < BCH_TESTS.length; i++) {
   1.222 +    let test = BCH_TESTS[i];
   1.223 +    ok(true, "Test nsBrowserContentHandler " + (i + 1) + ": " + test.description);
   1.224 +
   1.225 +    if (test.actions) {
   1.226 +      let actionsXML = " actions=\"" + test.actions + "\"";
   1.227 +      if (test.openURL) {
   1.228 +        actionsXML += " openURL=\"" + test.openURL + "\"";
   1.229 +      }
   1.230 +      writeUpdatesToXMLFile(XML_PREFIX + actionsXML + XML_SUFFIX);
   1.231 +    } else {
   1.232 +      writeUpdatesToXMLFile(XML_EMPTY);
   1.233 +    }
   1.234 +
   1.235 +    reloadUpdateManagerData();
   1.236 +
   1.237 +    let noOverrideArgs = Cc["@mozilla.org/browser/clh;1"].
   1.238 +                         getService(Ci.nsIBrowserHandler).defaultArgs;
   1.239 +
   1.240 +    let overrideArgs = "";
   1.241 +    if (test.prefURL) {
   1.242 +      overrideArgs = test.prefURL;
   1.243 +    } else if (test.openURL) {
   1.244 +      overrideArgs = test.openURL;
   1.245 +    }
   1.246 +
   1.247 +    if (overrideArgs == "" && noOverrideArgs) {
   1.248 +      overrideArgs = noOverrideArgs;
   1.249 +    } else if (noOverrideArgs) {
   1.250 +      overrideArgs += "|" + noOverrideArgs;
   1.251 +    }
   1.252 +
   1.253 +    if (test.noMstoneChange === undefined) {
   1.254 +      gPrefService.setCharPref(PREF_MSTONE, "PreviousMilestone");
   1.255 +    }
   1.256 +
   1.257 +    if (test.noPostUpdatePref == undefined) {
   1.258 +      gPrefService.setBoolPref(PREF_POSTUPDATE, true);
   1.259 +    }
   1.260 +
   1.261 +    let defaultArgs = Cc["@mozilla.org/browser/clh;1"].
   1.262 +                      getService(Ci.nsIBrowserHandler).defaultArgs;
   1.263 +    is(defaultArgs, overrideArgs, "correct value returned by defaultArgs");
   1.264 +
   1.265 +    if (test.noMstoneChange === undefined || test.noMstoneChange != true) {
   1.266 +      let newMstone = gPrefService.getCharPref(PREF_MSTONE);
   1.267 +      is(originalMstone, newMstone, "preference " + PREF_MSTONE +
   1.268 +         " should have been updated");
   1.269 +    }
   1.270 +
   1.271 +    if (gPrefService.prefHasUserValue(PREF_POSTUPDATE)) {
   1.272 +      gPrefService.clearUserPref(PREF_POSTUPDATE);
   1.273 +    }
   1.274 +  }
   1.275 +
   1.276 +  testShowNotification();
   1.277 +}
   1.278 +
   1.279 +// nsBrowserGlue.js _showUpdateNotification notification tests
   1.280 +const BG_NOTIFY_TESTS = [
   1.281 +  {
   1.282 +    description: "'silent showNotification' actions should not display a notification",
   1.283 +    actions: "silent showNotification"
   1.284 +  }, {
   1.285 +    description: "'showNotification' for actions should display a notification",
   1.286 +    actions: "showNotification"
   1.287 +  }, {
   1.288 +    description: "no actions and empty updates.xml",
   1.289 +  }, {
   1.290 +    description: "'showAlert' for actions should not display a notification",
   1.291 +    actions: "showAlert"
   1.292 +  }, {
   1.293 +    // This test MUST be the last test in the array to test opening the url
   1.294 +    // provided by the updates.xml.
   1.295 +    description: "'showNotification' for actions with custom notification " +
   1.296 +                 "attributes should display a notification",
   1.297 +    actions: "showNotification",
   1.298 +    notificationText: "notification text",
   1.299 +    notificationURL: DEFAULT_UPDATE_URL,
   1.300 +    notificationButtonLabel: "button label",
   1.301 +    notificationButtonAccessKey: "b"
   1.302 +  }
   1.303 +];
   1.304 +
   1.305 +// Test showing a notification after an update
   1.306 +// _showUpdateNotification in nsBrowserGlue.js
   1.307 +function testShowNotification()
   1.308 +{
   1.309 +  let gTestBrowser = gBrowser.selectedBrowser;
   1.310 +  let notifyBox = gBrowser.getNotificationBox(gTestBrowser);
   1.311 +
   1.312 +  // Catches any windows opened by these tests (e.g. alert windows) and closes
   1.313 +  // them
   1.314 +  gWindowCatcher.start();
   1.315 +
   1.316 +  for (let i = 0; i < BG_NOTIFY_TESTS.length; i++) {
   1.317 +    let test = BG_NOTIFY_TESTS[i];
   1.318 +    ok(true, "Test showNotification " + (i + 1) + ": " + test.description);
   1.319 +
   1.320 +    if (test.actions) {
   1.321 +      let actionsXML = " actions=\"" + test.actions + "\"";
   1.322 +      if (test.notificationText) {
   1.323 +        actionsXML += " notificationText=\"" + test.notificationText + "\"";
   1.324 +      }
   1.325 +      if (test.notificationURL) {
   1.326 +        actionsXML += " notificationURL=\"" + test.notificationURL + "\"";
   1.327 +      }
   1.328 +      if (test.notificationButtonLabel) {
   1.329 +        actionsXML += " notificationButtonLabel=\"" + test.notificationButtonLabel + "\"";
   1.330 +      }
   1.331 +      if (test.notificationButtonAccessKey) {
   1.332 +        actionsXML += " notificationButtonAccessKey=\"" + test.notificationButtonAccessKey + "\"";
   1.333 +      }
   1.334 +      writeUpdatesToXMLFile(XML_PREFIX + actionsXML + XML_SUFFIX);
   1.335 +    } else {
   1.336 +      writeUpdatesToXMLFile(XML_EMPTY);
   1.337 +    }
   1.338 +
   1.339 +    reloadUpdateManagerData();
   1.340 +    gPrefService.setBoolPref(PREF_POSTUPDATE, true);
   1.341 +
   1.342 +    gBG.observe(null, "browser-glue-test", "post-update-notification");
   1.343 +
   1.344 +    let updateBox = notifyBox.getNotificationWithValue("post-update-notification");
   1.345 +    if (test.actions && test.actions.indexOf("showNotification") != -1 &&
   1.346 +        test.actions.indexOf("silent") == -1) {
   1.347 +      ok(updateBox, "Update notification box should have been displayed");
   1.348 +      if (updateBox) {
   1.349 +        if (test.notificationText) {
   1.350 +          is(updateBox.label, test.notificationText, "Update notification box " +
   1.351 +             "should have the label provided by the update");
   1.352 +        }
   1.353 +        if (test.notificationButtonLabel) {
   1.354 +          var button = updateBox.getElementsByTagName("button").item(0);
   1.355 +          is(button.label, test.notificationButtonLabel, "Update notification " +
   1.356 +             "box button should have the label provided by the update");
   1.357 +          if (test.notificationButtonAccessKey) {
   1.358 +            let accessKey = button.getAttribute("accesskey");
   1.359 +            is(accessKey, test.notificationButtonAccessKey, "Update " +
   1.360 +               "notification box button should have the accesskey " +
   1.361 +               "provided by the update");
   1.362 +          }
   1.363 +        }
   1.364 +        // The last test opens an url and verifies the url from the updates.xml
   1.365 +        // is correct.
   1.366 +        if (i == (BG_NOTIFY_TESTS.length - 1)) {
   1.367 +          // Wait for any windows caught by the windowcatcher to close
   1.368 +          gWindowCatcher.finish(function () {
   1.369 +            button.click();
   1.370 +            gBrowser.selectedBrowser.addEventListener("load", function () {
   1.371 +              gBrowser.selectedBrowser.removeEventListener("load", arguments.callee, true);
   1.372 +              testNotificationURL();
   1.373 +            }, true);
   1.374 +          });
   1.375 +        } else {
   1.376 +          notifyBox.removeAllNotifications(true);
   1.377 +        }
   1.378 +      } else if (i == (BG_NOTIFY_TESTS.length - 1)) {
   1.379 +        // If updateBox is null the test has already reported errors so bail
   1.380 +        finish_test();
   1.381 +      }
   1.382 +    } else {
   1.383 +      ok(!updateBox, "Update notification box should not have been displayed");
   1.384 +    }
   1.385 +
   1.386 +    let prefHasUserValue = gPrefService.prefHasUserValue(PREF_POSTUPDATE);
   1.387 +    is(prefHasUserValue, false, "preference " + PREF_POSTUPDATE +
   1.388 +       " shouldn't have a user value");
   1.389 +  }
   1.390 +}
   1.391 +
   1.392 +// Test opening the url provided by the updates.xml in the last test
   1.393 +function testNotificationURL()
   1.394 +{
   1.395 +  ok(true, "Test testNotificationURL: clicking the notification button " +
   1.396 +           "opened the url specified by the update");
   1.397 +  let href = gBrowser.selectedBrowser.contentWindow.location.href;
   1.398 +  let expectedURL = BG_NOTIFY_TESTS[BG_NOTIFY_TESTS.length - 1].notificationURL;
   1.399 +  is(href, expectedURL, "The url opened from the notification should be the " +
   1.400 +     "url provided by the update");
   1.401 +  gBrowser.removeCurrentTab();
   1.402 +  window.focus();
   1.403 +  finish_test();
   1.404 +}
   1.405 +
   1.406 +/* Reloads the update metadata from disk */
   1.407 +function reloadUpdateManagerData()
   1.408 +{
   1.409 +  Cc["@mozilla.org/updates/update-manager;1"].getService(Ci.nsIUpdateManager).
   1.410 +  QueryInterface(Ci.nsIObserver).observe(null, "um-reload-update-data", "");
   1.411 +}
   1.412 +
   1.413 +
   1.414 +function writeUpdatesToXMLFile(aText)
   1.415 +{
   1.416 +  const PERMS_FILE = 0644;
   1.417 +
   1.418 +  const MODE_WRONLY   = 0x02;
   1.419 +  const MODE_CREATE   = 0x08;
   1.420 +  const MODE_TRUNCATE = 0x20;
   1.421 +
   1.422 +  let file = Cc["@mozilla.org/file/directory_service;1"].
   1.423 +             getService(Ci.nsIProperties).
   1.424 +             get("UpdRootD", Ci.nsIFile);
   1.425 +  file.append("updates.xml");
   1.426 +  let fos = Cc["@mozilla.org/network/file-output-stream;1"].
   1.427 +            createInstance(Ci.nsIFileOutputStream);
   1.428 +  if (!file.exists()) {
   1.429 +    file.create(Ci.nsILocalFile.NORMAL_FILE_TYPE, PERMS_FILE);
   1.430 +  }
   1.431 +  fos.init(file, MODE_WRONLY | MODE_CREATE | MODE_TRUNCATE, PERMS_FILE, 0);
   1.432 +  fos.write(aText, aText.length);
   1.433 +  fos.close();
   1.434 +}

mercurial