Bug 1555610 - Add whats new page test for code in BrowserContentHandler.jsm. r=bytesized,jaws
authorRobert Strong <robert.bugzilla@gmail.com>
Fri, 31 May 2019 04:03:06 +0000
changeset 476317 a2ec4ac648cfd975770679be53525cb104368400
parent 476316 66cee597c19dc2cb3a2e52b0174d701572825312
child 476318 f2b37969fe0b44b5e811caa4e8f0e1ef347f4371
push id36092
push userarchaeopteryx@coole-files.de
push dateFri, 31 May 2019 17:03:46 +0000
treeherdermozilla-central@8384972e1f6a [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersbytesized, jaws
bugs1555610, 538331
milestone69.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1555610 - Add whats new page test for code in BrowserContentHandler.jsm. r=bytesized,jaws Changes UpdateService.jsm so it is possible to have an alternate update directory for tests similar to how enterprise policies does it. Removes BUG_COMPONENT in moz.build for browser_bug538331.js since that test is for BrowserContentHandler.jsm code. Differential Revision: https://phabricator.services.mozilla.com/D33225
browser/components/moz.build
browser/components/tests/browser/whats_new_page/active-update.xml
browser/components/tests/browser/whats_new_page/browser.ini
browser/components/tests/browser/whats_new_page/browser_whats_new_page.js
browser/components/tests/browser/whats_new_page/updates/0/update.status
toolkit/mozapps/update/UpdateService.jsm
toolkit/mozapps/update/UpdateServiceStub.jsm
--- a/browser/components/moz.build
+++ b/browser/components/moz.build
@@ -8,19 +8,16 @@ with Files("**"):
     BUG_COMPONENT = ("Firefox", "General")
 
 with Files("distribution.js"):
     BUG_COMPONENT = ("Firefox", "Distributions")
 
 with Files("tests/**"):
     BUG_COMPONENT = ("Firefox", "General")
 
-with Files("tests/browser/browser_bug538331.js"):
-    BUG_COMPONENT = ("Toolkit", "Application Update")
-
 with Files("tests/browser/browser_contentpermissionprompt.js"):
     BUG_COMPONENT = ("Firefox", "Site Identity and Permission Panels")
 
 with Files("tests/unit/test_distribution.js"):
     BUG_COMPONENT = ("Firefox", "Distributions")
 
 with Files("safebrowsing/**"):
     BUG_COMPONENT = ("Toolkit", "Safe Browsing")
@@ -89,14 +86,15 @@ EXTRA_COMPONENTS += [
 EXTRA_JS_MODULES += [
     'BrowserContentHandler.jsm',
     'BrowserGlue.jsm',
     'distribution.js',
 ]
 
 BROWSER_CHROME_MANIFESTS += [
     'safebrowsing/content/test/browser.ini',
-    'tests/browser/browser.ini'
+    'tests/browser/browser.ini',
+    'tests/browser/whats_new_page/browser.ini'
 ]
 
 XPCSHELL_TESTS_MANIFESTS += [
     'tests/unit/xpcshell.ini'
 ]
new file mode 100644
--- /dev/null
+++ b/browser/components/tests/browser/whats_new_page/active-update.xml
@@ -0,0 +1,1 @@
+<?xml version="1.0"?><updates xmlns="http://www.mozilla.org/2005/app-update"><update xmlns="http://www.mozilla.org/2005/app-update" appVersion="99999999.0" buildID="20990101111111" channel="test" detailsURL="https://127.0.0.1/" displayVersion="1.0" installDate="1555716429454" isCompleteUpdate="true" name="What's New Page Test" previousAppVersion="60.0" serviceURL="https://127.0.0.1/update.xml" type="minor" platformVersion="99999999.0" actions="showURL" openURL="https://example.com/|https://example.com/"><patch size="1" type="complete" URL="https://127.0.0.1/complete.mar" selected="true" state="pending"/></update></updates>
new file mode 100644
--- /dev/null
+++ b/browser/components/tests/browser/whats_new_page/browser.ini
@@ -0,0 +1,12 @@
+[DEFAULT]
+skip-if = verify
+reason = This is a startup test. Verify runs tests multiple times after startup.
+support-files =
+  active-update.xml
+  updates/0/update.status
+prefs =
+  app.update.altUpdateDirPath='<test-root>/browser/components/tests/browser/whats_new_page'
+  app.update.disabledForTesting=false
+  browser.startup.homepage_override.mstone="60.0"
+
+[browser_whats_new_page.js]
new file mode 100644
--- /dev/null
+++ b/browser/components/tests/browser/whats_new_page/browser_whats_new_page.js
@@ -0,0 +1,86 @@
+/* Any copyright is dedicated to the Public Domain.
+ * http://creativecommons.org/publicdomain/zero/1.0/ */
+
+"use strict";
+
+add_task(async function whats_new_page() {
+  // BrowserContentHandler.jsm should have cleared the app.update.postupdate
+  // preference.
+  ok(!Services.prefs.prefHasUserValue("app.update.postupdate"),
+     "The app.update.postupdate preference should not have a user value");
+  // The test harness will use the current tab and remove the tab's history.
+  // Since the page that is tested is opened prior to the test harness taking
+  // over the current tab the active-update.xml specifies two pages to open by
+  // having 'https://example.com/|https://example.com/' for the value of openURL
+  // and then uses the first tab for the test.
+  gBrowser.selectedTab = gBrowser.tabs[0];
+  // The test harness also changes the page to about:blank so go back to the
+  // page that was originally opened.
+  gBrowser.goBack();
+  // Wait for the page to go back to the original page.
+  await TestUtils.waitForCondition(() =>
+    (gBrowser.selectedBrowser && gBrowser.selectedBrowser.currentURI &&
+     gBrowser.selectedBrowser.currentURI.spec == "https://example.com/"),
+    "Waiting for the expected page to reopen");
+  is(gBrowser.selectedBrowser.currentURI.spec, "https://example.com/",
+           "The what's new page's url should equal https://example.com/");
+  gBrowser.removeTab(gBrowser.selectedTab);
+
+  // Leave no trace. Since this test modifies its support files put them back in
+  // their original state.
+  let alternatePath =
+    Services.prefs.getCharPref("app.update.altUpdateDirPath");
+  let testRoot = Services.prefs.getCharPref("mochitest.testRoot");
+  let relativePath = alternatePath.substring("<test-root>".length);
+  if (AppConstants.platform == "win") {
+    relativePath = relativePath.replace(/\//g, "\\");
+  }
+  alternatePath = testRoot + relativePath;
+  let updateDir = Cc["@mozilla.org/file/local;1"].createInstance(Ci.nsIFile);
+  updateDir.initWithPath(alternatePath);
+
+  let activeUpdateFile = updateDir.clone();
+  activeUpdateFile.append("active-update.xml");
+  await TestUtils.waitForCondition(() =>
+    (!activeUpdateFile.exists()),
+    "Waiting until the active-update.xml file does not exist");
+
+  let updatesFile = updateDir.clone();
+  updatesFile.append("updates.xml");
+  await TestUtils.waitForCondition(() =>
+    (updatesFile.exists()),
+    "Waiting until the updates.xml file exists");
+
+  let fos = Cc["@mozilla.org/network/file-output-stream;1"].
+            createInstance(Ci.nsIFileOutputStream);
+  let flags = FileUtils.MODE_WRONLY | FileUtils.MODE_CREATE |
+              FileUtils.MODE_TRUNCATE;
+
+  let stateSucceeded = "succeeded\n";
+  let updateStatusFile = updateDir.clone();
+  updateStatusFile.append("updates");
+  updateStatusFile.append("0");
+  updateStatusFile.append("update.status");
+  updateStatusFile.create(Ci.nsIFile.NORMAL_FILE_TYPE, FileUtils.PERMS_FILE);
+  fos.init(updateStatusFile, flags, FileUtils.PERMS_FILE, 0);
+  fos.write(stateSucceeded, stateSucceeded.length);
+  fos.close();
+
+  let xmlContents =
+    "<?xml version=\"1.0\"?><updates xmlns=\"http://www.mozilla.org/2005/" +
+    "app-update\"><update xmlns=\"http://www.mozilla.org/2005/app-update\" " +
+    "appVersion=\"99999999.0\" buildID=\"20990101111111\" channel=\"test\" " +
+    "detailsURL=\"https://127.0.0.1/\" displayVersion=\"1.0\" installDate=\"" +
+    "1555716429454\" isCompleteUpdate=\"true\" name=\"What's New Page Test\" " +
+    "previousAppVersion=\"60.0\" serviceURL=\"https://127.0.0.1/update.xml\" " +
+    "type=\"minor\" platformVersion=\"99999999.0\" actions=\"showURL\" " +
+    "openURL=\"https://example.com/|https://example.com/\"><patch size=\"1\" " +
+    "type=\"complete\" URL=\"https://127.0.0.1/complete.mar\" " +
+    "selected=\"true\" state=\"pending\"/></update></updates>\n";
+  activeUpdateFile.create(Ci.nsIFile.NORMAL_FILE_TYPE, FileUtils.PERMS_FILE);
+  fos.init(activeUpdateFile, flags, FileUtils.PERMS_FILE, 0);
+  fos.write(xmlContents, xmlContents.length);
+  fos.close();
+
+  updatesFile.remove(false);
+});
new file mode 100644
--- /dev/null
+++ b/browser/components/tests/browser/whats_new_page/updates/0/update.status
@@ -0,0 +1,1 @@
+succeeded
--- a/toolkit/mozapps/update/UpdateService.jsm
+++ b/toolkit/mozapps/update/UpdateService.jsm
@@ -24,32 +24,33 @@ XPCOMUtils.defineLazyModuleGetters(this,
   DeferredTask: "resource://gre/modules/DeferredTask.jsm",
   OS: "resource://gre/modules/osfile.jsm",
   UpdateUtils: "resource://gre/modules/UpdateUtils.jsm",
   WindowsRegistry: "resource://gre/modules/WindowsRegistry.jsm",
 });
 
 const UPDATESERVICE_CID = Components.ID("{B3C290A6-3943-4B89-8BBE-C01EB7B3B311}");
 
+const PREF_APP_UPDATE_ALTUPDATEDIRPATH     = "app.update.altUpdateDirPath";
 const PREF_APP_UPDATE_ALTWINDOWTYPE        = "app.update.altwindowtype";
 const PREF_APP_UPDATE_BACKGROUNDERRORS     = "app.update.backgroundErrors";
 const PREF_APP_UPDATE_BACKGROUNDMAXERRORS  = "app.update.backgroundMaxErrors";
 const PREF_APP_UPDATE_BITS_ENABLED         = "app.update.BITS.enabled";
 const PREF_APP_UPDATE_BITS_INTRIALGROUP    = "app.update.BITS.inTrialGroup";
 const PREF_APP_UPDATE_CANCELATIONS         = "app.update.cancelations";
 const PREF_APP_UPDATE_CANCELATIONS_OSX     = "app.update.cancelations.osx";
 const PREF_APP_UPDATE_CANCELATIONS_OSX_MAX = "app.update.cancelations.osx.max";
+const PREF_APP_UPDATE_DISABLEDFORTESTING   = "app.update.disabledForTesting";
 const PREF_APP_UPDATE_DOORHANGER           = "app.update.doorhanger";
 const PREF_APP_UPDATE_DOWNLOAD_ATTEMPTS    = "app.update.download.attempts";
 const PREF_APP_UPDATE_DOWNLOAD_MAXATTEMPTS = "app.update.download.maxAttempts";
 const PREF_APP_UPDATE_ELEVATE_NEVER        = "app.update.elevate.never";
 const PREF_APP_UPDATE_ELEVATE_VERSION      = "app.update.elevate.version";
 const PREF_APP_UPDATE_ELEVATE_ATTEMPTS     = "app.update.elevate.attempts";
 const PREF_APP_UPDATE_ELEVATE_MAXATTEMPTS  = "app.update.elevate.maxAttempts";
-const PREF_APP_UPDATE_DISABLEDFORTESTING   = "app.update.disabledForTesting";
 const PREF_APP_UPDATE_IDLETIME             = "app.update.idletime";
 const PREF_APP_UPDATE_LOG                  = "app.update.log";
 const PREF_APP_UPDATE_LOG_FILE             = "app.update.log.file";
 const PREF_APP_UPDATE_NOTIFIEDUNSUPPORTED  = "app.update.notifiedUnsupported";
 const PREF_APP_UPDATE_POSTUPDATE           = "app.update.postupdate";
 const PREF_APP_UPDATE_PROMPTWAITTIME       = "app.update.promptWaitTime";
 const PREF_APP_UPDATE_SERVICE_ENABLED      = "app.update.service.enabled";
 const PREF_APP_UPDATE_SERVICE_ERRORS       = "app.update.service.errors";
@@ -671,16 +672,39 @@ function LOG(string) {
  * Gets the specified directory at the specified hierarchy under the
  * update root directory and creates it if it doesn't exist.
  * @param   pathArray
  *          An array of path components to locate beneath the directory
  *          specified by |key|
  * @return  nsIFile object for the location specified.
  */
 function getUpdateDirCreate(pathArray) {
+  if (Cu.isInAutomation) {
+    // This allows tests to use an alternate updates directory so they can test
+    // startup behavior.
+    const MAGIC_TEST_ROOT_PREFIX = "<test-root>";
+    const PREF_TEST_ROOT = "mochitest.testRoot";
+    let alternatePath =
+      Services.prefs.getCharPref(PREF_APP_UPDATE_ALTUPDATEDIRPATH, null);
+    if (alternatePath && alternatePath.startsWith(MAGIC_TEST_ROOT_PREFIX)) {
+      let testRoot = Services.prefs.getCharPref(PREF_TEST_ROOT);
+      let relativePath = alternatePath.substring(MAGIC_TEST_ROOT_PREFIX.length);
+      if (AppConstants.platform == "win") {
+        relativePath = relativePath.replace(/\//g, "\\");
+      }
+      alternatePath = testRoot + relativePath;
+      let updateDir = Cc["@mozilla.org/file/local;1"].createInstance(Ci.nsIFile);
+      updateDir.initWithPath(alternatePath);
+      for (let i = 0; i < pathArray.length; ++i) {
+        updateDir.append(pathArray[i]);
+      }
+      return updateDir;
+    }
+  }
+
   return FileUtils.getDir(KEY_UPDROOT, pathArray, true);
 }
 
 /**
  * Gets the application base directory.
  *
  * @return  nsIFile object for the application base directory.
  */
@@ -4028,17 +4052,17 @@ Downloader.prototype = {
       // update agent might cause BITS to falsely report an error, causing an
       // unnecessary fallback to nsIIncrementalDownload.
       let monitorTimeout = Math.max(10 * monitorInterval, 10 * 60 * 1000);
       if (this.hasDownloadListeners) {
         monitorInterval = BITS_ACTIVE_POLL_RATE_MS;
         this._bitsActiveNotifications = true;
       }
 
-      let updateRootDir = FileUtils.getDir("UpdRootD", [], true);
+      let updateRootDir = FileUtils.getDir(KEY_UPDROOT, [], true);
       let jobName = "MozillaUpdate " + updateRootDir.leafName;
       let updatePath = updateDir.path;
       if (!Bits.initialized) {
         Bits.init(jobName, updatePath, monitorTimeout);
       }
 
       this._cancelPromise = null;
 
--- a/toolkit/mozapps/update/UpdateServiceStub.jsm
+++ b/toolkit/mozapps/update/UpdateServiceStub.jsm
@@ -20,25 +20,52 @@ const FILE_BACKUP_MESSAGES   = "update_m
 const KEY_UPDROOT         = "UpdRootD";
 const KEY_OLD_UPDROOT     = "OldUpdRootD";
 const KEY_PROFILE_DIR     = "ProfD";
 
 // The pref prefix below should have the hash of the install path appended to
 // ensure that this is a per-installation pref (i.e. to ensure that migration
 // happens for every install rather than once per profile)
 const PREF_PREFIX_UPDATE_DIR_MIGRATED  = "app.update.migrated.updateDir2.";
+const PREF_APP_UPDATE_ALTUPDATEDIRPATH = "app.update.altUpdateDirPath";
 const PREF_APP_UPDATE_LOG              = "app.update.log";
 const PREF_APP_UPDATE_FILE_LOGGING     = "app.update.log.file";
 
 XPCOMUtils.defineLazyGetter(this, "gLogEnabled", function aus_gLogEnabled() {
   return Services.prefs.getBoolPref(PREF_APP_UPDATE_LOG, false);
 });
 
+function getUpdateBaseDirNoCreate() {
+  if (Cu.isInAutomation) {
+    // This allows tests to use an alternate updates directory so they can test
+    // startup behavior.
+    const MAGIC_TEST_ROOT_PREFIX = "<test-root>";
+    const PREF_TEST_ROOT = "mochitest.testRoot";
+    let alternatePath =
+      Services.prefs.getCharPref(PREF_APP_UPDATE_ALTUPDATEDIRPATH, null);
+    if (alternatePath && alternatePath.startsWith(MAGIC_TEST_ROOT_PREFIX)) {
+      let testRoot = Services.prefs.getCharPref(PREF_TEST_ROOT);
+      let relativePath = alternatePath.substring(MAGIC_TEST_ROOT_PREFIX.length);
+      if (AppConstants.platform == "win") {
+        relativePath = relativePath.replace(/\//g, "\\");
+      }
+      alternatePath = testRoot + relativePath;
+      let updateDir = Cc["@mozilla.org/file/local;1"].createInstance(Ci.nsIFile);
+      updateDir.initWithPath(alternatePath);
+      LOG("getUpdateBaseDirNoCreate returning test directory, path: " +
+          updateDir.path);
+      return updateDir;
+    }
+  }
+
+  return FileUtils.getDir(KEY_UPDROOT, [], false);
+}
+
 function UpdateServiceStub() {
-  let updateDir = FileUtils.getDir(KEY_UPDROOT, [], false);
+  let updateDir = getUpdateBaseDirNoCreate();
   let prefUpdateDirMigrated = PREF_PREFIX_UPDATE_DIR_MIGRATED
                             + updateDir.leafName;
 
   let statusFile = updateDir;
   statusFile.append(DIR_UPDATES);
   statusFile.append("0");
   statusFile.append(FILE_UPDATE_STATUS);
   updateDir = null; // We don't need updateDir anymore, plus now its nsIFile