Bug 446527 - major update not offered when some language packs are installed. r=dtownsend, r=bsmedberg
authorRobert Strong <robert.bugzilla@gmail.com>
Sun, 17 Aug 2008 19:15:10 -0700
changeset 16978 2360ae300880817b4052cd1d2e2585cf9c2f09a9
parent 16977 c771615414feb1273ff4db0f197e7437b61df8df
child 16979 42a7ea1650c9b845ab6c95e650ef8c6a9be9113d
push id1312
push userrstrong@mozilla.com
push dateMon, 18 Aug 2008 02:16:07 +0000
treeherdermozilla-central@2360ae300880 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersdtownsend, bsmedberg
bugs446527
milestone1.9.1a2pre
Bug 446527 - major update not offered when some language packs are installed. r=dtownsend, r=bsmedberg
browser/locales/Makefile.in
browser/locales/updater_append.ini
toolkit/mozapps/update/src/nsUpdateService.js.in
toolkit/mozapps/update/test/Makefile.in
toolkit/mozapps/update/test/unit/head_update.js
toolkit/mozapps/update/test/unit/test_0040_general.js.in
--- a/browser/locales/Makefile.in
+++ b/browser/locales/Makefile.in
@@ -301,19 +301,21 @@ installers-%:
 ifeq (WINNT,$(OS_ARCH))
 	@$(MAKE) repackage-win32-installer-$*
 endif
 	@$(MAKE) repackage-zip-$*
 
 ifdef MOZ_UPDATER
 libs:: $(addprefix $(LOCALE_SRCDIR)/,updater/updater.ini)
 ifeq ($(OS_ARCH),WINNT)
-	cat $< $(srcdir)/../installer/windows/nsis/updater_append.ini | \
+	cat $< $(srcdir)/updater_append.ini $(srcdir)/../installer/windows/nsis/updater_append.ini | \
+	  sed -e "s/%AB_CD%/$(AB_CD)/" | \
 	  iconv -f UTF-8 -t $(WIN_INSTALLER_CHARSET) > $(FINAL_TARGET)/updater.ini
 else
-	$(SYSINSTALL) $(IFLAGS1) $^ $(FINAL_TARGET)
+	cat $< $(srcdir)/updater_append.ini | \
+	  sed -e "s/%AB_CD%/$(AB_CD)/" > $(FINAL_TARGET)/updater.ini
 endif
 endif
 
 ifdef MOZ_CRASHREPORTER
 libs:: $(addprefix $(LOCALE_SRCDIR)/,crashreporter/crashreporter-override.ini)
 	$(SYSINSTALL) $(IFLAGS1) $^ $(FINAL_TARGET)
 endif
new file mode 100644
--- /dev/null
+++ b/browser/locales/updater_append.ini
@@ -0,0 +1,5 @@
+
+; IMPORTANT: This file should always start with a newline in case a locale
+; provided updater.ini does not end with a newline.
+[Installation]
+Locale=%AB_CD%
--- a/toolkit/mozapps/update/src/nsUpdateService.js.in
+++ b/toolkit/mozapps/update/src/nsUpdateService.js.in
@@ -52,17 +52,16 @@ const PREF_APP_UPDATE_IDLETIME          
 const PREF_APP_UPDATE_PROMPTWAITTIME      = "app.update.promptWaitTime";
 const PREF_APP_UPDATE_LOG_BRANCH          = "app.update.log.";
 const PREF_APP_UPDATE_URL                 = "app.update.url";
 const PREF_APP_UPDATE_URL_OVERRIDE        = "app.update.url.override";
 const PREF_APP_UPDATE_URL_DETAILS         = "app.update.url.details";
 const PREF_APP_UPDATE_CHANNEL             = "app.update.channel";
 const PREF_APP_UPDATE_SHOW_INSTALLED_UI   = "app.update.showInstalledUI";
 const PREF_APP_UPDATE_LASTUPDATETIME_FMT  = "app.update.lastUpdateTime.%ID%";
-const PREF_GENERAL_USERAGENT_LOCALE       = "general.useragent.locale";
 const PREF_APP_UPDATE_INCOMPATIBLE_MODE   = "app.update.incompatible.mode";
 const PREF_UPDATE_NEVER_BRANCH            = "app.update.never.";
 const PREF_PARTNER_BRANCH                 = "app.partner.";
 const PREF_APP_DISTRIBUTION               = "distribution.id";
 const PREF_APP_DISTRIBUTION_VERSION       = "distribution.version";
 
 const URI_UPDATE_PROMPT_DIALOG  = "chrome://mozapps/content/update/updates.xul";
 const URI_UPDATE_HISTORY_DIALOG = "chrome://mozapps/content/update/history.xul";
@@ -79,16 +78,17 @@ const KEY_UAPPDATA        = "UAppData";
 const DIR_UPDATES         = "updates";
 const FILE_UPDATE_STATUS  = "update.status";
 const FILE_UPDATE_ARCHIVE = "update.mar";
 const FILE_UPDATE_LOG     = "update.log"
 const FILE_UPDATES_DB     = "updates.xml";
 const FILE_UPDATE_ACTIVE  = "active-update.xml";
 const FILE_PERMS_TEST     = "update.test";
 const FILE_LAST_LOG       = "last-update.log";
+const FILE_UPDATER_INI    = "updater.ini";
 
 const MODE_RDONLY   = 0x01;
 const MODE_WRONLY   = 0x02;
 const MODE_CREATE   = 0x08;
 const MODE_APPEND   = 0x10;
 const MODE_TRUNCATE = 0x20;
 
 const PERMS_FILE      = 0644;
@@ -117,23 +117,25 @@ const nsIExtensionManager     = Componen
 const nsILocalFile            = Components.interfaces.nsILocalFile;
 const nsIUpdateService        = Components.interfaces.nsIUpdateService;
 const nsIUpdateItem           = Components.interfaces.nsIUpdateItem;
 const nsIPrefLocalizedString  = Components.interfaces.nsIPrefLocalizedString;
 const nsIIncrementalDownload  = Components.interfaces.nsIIncrementalDownload;
 const nsIFileInputStream      = Components.interfaces.nsIFileInputStream;
 const nsIFileOutputStream     = Components.interfaces.nsIFileOutputStream;
 const nsICryptoHash           = Components.interfaces.nsICryptoHash;
+const nsIINIParserFactory     = Components.interfaces.nsIINIParserFactory;
 
 const Node = Components.interfaces.nsIDOMNode;
 
 var gApp        = null;
 var gPref       = null;
 var gABI        = null;
 var gOSVersion  = null;
+var gLocale     = null;
 var gConsole    = null;
 var gLogEnabled = { };
 
 // shared code for suppressing bad cert dialogs
 #include ../../shared/src/badCertHandler.js
 
 /**
  * Logs a string to the error console.
@@ -485,30 +487,29 @@ function getPref(func, preference, defau
     return gPref[func](preference);
   }
   catch (e) {
   }
   return defaultValue;
 }
 
 /**
- * Gets the current value of the locale.  It's possible for this preference to
- * be localized, so we have to do a little extra work here.  Similar code
- * exists in nsHttpHandler.cpp when building the UA string.
+ * Gets the locale specified by the 'Locale' key in the 'Installation' section
+ * of updater.ini.
  */
 function getLocale() {
-  try {
-      // Get the default branch
-      var prefs = Components.classes["@mozilla.org/preferences-service;1"]
-          .getService(Components.interfaces.nsIPrefService);
-      var defaultPrefs = prefs.getDefaultBranch(null);
-      return defaultPrefs.getCharPref(PREF_GENERAL_USERAGENT_LOCALE);
-  } catch (e) {}
-
-  return gPref.getCharPref(PREF_GENERAL_USERAGENT_LOCALE);
+  if (gLocale)
+    return gLocale;
+
+  var updaterIni = getFile(KEY_APPDIR, [FILE_UPDATER_INI]);
+  var iniParser = Components.classes["@mozilla.org/xpcom/ini-parser-factory;1"]
+                            .getService(nsIINIParserFactory).createINIParser(updaterIni);
+  gLocale = iniParser.getString("Installation", "Locale");
+  LOG("General", "Getting Locale from File: " + updaterIni.path + " Locale: " + gLocale);
+  return gLocale;
 }
 
 /**
  * Read the update channel from defaults only.  We do this to ensure that
  * the channel is tightly coupled with the application and does not apply
  * to other instances of the application that may use the same profile.
  */
 function getUpdateChannel() {
@@ -1971,17 +1972,17 @@ Checker.prototype = {
     url = url.replace(/%PLATFORM_VERSION%/g, gApp.platformVersion);
     url = url.replace(/%DISTRIBUTION%/g,
                       getDistributionPrefValue(PREF_APP_DISTRIBUTION));
     url = url.replace(/%DISTRIBUTION_VERSION%/g,
                       getDistributionPrefValue(PREF_APP_DISTRIBUTION_VERSION));
     url = url.replace(/\+/g, "%2B");
 
     if (force)
-	url += "?force=1"
+      url += "?force=1"
 
     LOG("Checker", "update url: " + url);
     return url;
   },
 
   /**
    * See nsIUpdateService.idl
    */
--- a/toolkit/mozapps/update/test/Makefile.in
+++ b/toolkit/mozapps/update/test/Makefile.in
@@ -43,9 +43,18 @@ VPATH = @srcdir@
 include $(DEPTH)/config/autoconf.mk
 
 MODULE = test_update
 
 XPCSHELL_TESTS = \
   unit \
   $(NULL)
 
+TESTROOT	= $(shell cd $(DEPTH) && pwd)/_tests/xpcshell-simple/$(MODULE)
+
+DEFINES += \
+	-DAB_CD=$(AB_CD) \
+	$(NULL)
+
 include $(topsrcdir)/config/rules.mk
+
+libs:: unit/test_0040_general.js.in
+	$(PYTHON) $(MOZILLA_DIR)/config/Preprocessor.py -Fsubstitution $(DEFINES) $^ > $(TESTROOT)/unit/test_0040_general.js
--- a/toolkit/mozapps/update/test/unit/head_update.js
+++ b/toolkit/mozapps/update/test/unit/head_update.js
@@ -31,16 +31,19 @@
  * decision by deleting the provisions above and replace them with the notice
  * and other provisions required by the GPL or the LGPL. If you do not delete
  * the provisions above, a recipient may use your version of this file under
  * the terms of any one of the MPL, the GPL or the LGPL.
  *
  * ***** END LICENSE BLOCK *****
  */
 
+const NS_APP_USER_PROFILE_50_DIR = "ProfD";
+const NS_APP_PROFILE_DIR_STARTUP = "ProfDS";
+
 // const Cc, Ci, and Cr are defined in netwerk/test/httpserver/httpd.js so we
 // need to define unique ones.
 const AUS_Cc = Components.classes;
 const AUS_Ci = Components.interfaces;
 const AUS_Cr = Components.results;
 
 var gAUS           = null;
 var gUpdateChecker = null;
@@ -85,16 +88,21 @@ function remove_dirs_and_files () {
                       .getService(AUS_Ci.nsIProperties);
   var dir = fileLocator.get("XCurProcD", AUS_Ci.nsIFile);
 
   var file = dir.clone();
   file.append("active-update.xml");
   if (file.exists())
     file.remove(false);
 
+  file = dir.clone();
+  file.append("updates.xml");
+  if (file.exists())
+    file.remove(false);
+
   dir.append("updates");
   if (dir.exists())
     dir.remove(true);
 }
 
 /**
  * Helper for starting the http server used by the tests
  * @param   aRelativeDirName
@@ -159,9 +167,44 @@ function createAppInfo(id, name, version
     }
   };
 
   var registrar = Components.manager.QueryInterface(AUS_Ci.nsIComponentRegistrar);
   registrar.registerFactory(XULAPPINFO_CID, "XULAppInfo",
                             XULAPPINFO_CONTRACTID, XULAppInfoFactory);
 }
 
+// Use a custom profile dir to keep the bin dir clean... not necessary but nice
+var gDirSvc = AUS_Cc["@mozilla.org/file/directory_service;1"].
+             getService(AUS_Ci.nsIProperties);
+var gTestRoot = gDirSvc.get("CurProcD", AUS_Ci.nsILocalFile);
+gTestRoot = gTestRoot.parent.parent;
+gTestRoot.append("_tests");
+gTestRoot.append("xpcshell-simple");
+gTestRoot.append("test_update");
+gTestRoot.normalize();
+
+// Create and register a profile directory.
+var gProfD = gTestRoot.clone();
+gProfD.append("profile");
+if (gProfD.exists())
+  gProfD.remove(true);
+gProfD.create(AUS_Ci.nsIFile.DIRECTORY_TYPE, 0755);
+
+var dirProvider = {
+  getFile: function(prop, persistent) {
+    persistent.value = true;
+    if (prop == NS_APP_USER_PROFILE_50_DIR ||
+        prop == NS_APP_PROFILE_DIR_STARTUP)
+      return gProfD.clone();
+    return null;
+  },
+  QueryInterface: function(iid) {
+    if (iid.equals(AUS_Ci.nsIDirectoryServiceProvider) ||
+        iid.equals(AUS_Ci.nsISupports)) {
+      return this;
+    }
+    throw AUS_Cr.NS_ERROR_NO_INTERFACE;
+  }
+};
+gDirSvc.QueryInterface(AUS_Ci.nsIDirectoryService).registerProvider(dirProvider);
+
 remove_dirs_and_files();
new file mode 100644
--- /dev/null
+++ b/toolkit/mozapps/update/test/unit/test_0040_general.js.in
@@ -0,0 +1,307 @@
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Application Update Service.
+ *
+ * The Initial Developer of the Original Code is
+ * Robert Strong <robert.bugzilla@gmail.com>.
+ *
+ * Portions created by the Initial Developer are Copyright (C) 2008
+ * the Mozilla Foundation <http://www.mozilla.org/>. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK *****
+ */
+
+/* General URL Construction Tests */
+
+const DIR_DATA   = "data"
+const URL_PREFIX = "http://localhost:4444/" + DIR_DATA + "/";
+
+const PREF_APP_UPDATE_CHANNEL        = "app.update.channel";
+const PREF_APP_UPDATE_URL_OVERRIDE   = "app.update.url.override";
+const PREF_PARTNER_BRANCH            = "app.partner.";
+const PREF_GEN_USERAGENT_LOCALE      = "general.useragent.locale";
+const PREF_APP_DISTRIBUTION          = "distribution.id";
+const PREF_APP_DISTRIBUTION_VERSION  = "distribution.version";
+
+var gAppInfo;
+var gCheckFunc;
+var gInstallationLocale = "@AB_CD@";
+
+function run_test() {
+  do_test_pending();
+  startAUS();
+  gAppInfo = AUS_Cc["@mozilla.org/xre/app-info;1"]
+               .getService(AUS_Ci.nsIXULAppInfo)
+               .QueryInterface(AUS_Ci.nsIXULRuntime);
+  start_httpserver(DIR_DATA);
+  do_timeout(0, "run_test_pt1()");
+}
+
+function end_test() {
+  do_test_finished();
+  stop_httpserver();
+}
+
+// Helper function for parsing the result from the contructed url
+function getResult(url) {
+  return url.substr(URL_PREFIX.length).split("/")[0];
+}
+
+// url constructed with %PRODUCT%
+function run_test_pt1() {
+  gCheckFunc = check_test_pt1;
+  var url = URL_PREFIX + "%PRODUCT%/";
+  dump("Testing: url constructed with %PRODUCT% - " + url + "\n");
+  gPrefs.setCharPref(PREF_APP_UPDATE_URL_OVERRIDE, url);
+  gUpdateChecker.checkForUpdates(updateCheckListener, true);
+}
+
+function check_test_pt1(aResult) {
+  do_check_eq(aResult, gAppInfo.name);
+  run_test_pt2();
+}
+
+// url constructed with %VERSION%
+function run_test_pt2() {
+  gCheckFunc = check_test_pt2;
+  var url = URL_PREFIX + "%VERSION%/";
+  dump("Testing: url constructed with %VERSION% - " + url + "\n");
+  gPrefs.setCharPref(PREF_APP_UPDATE_URL_OVERRIDE, url);
+  gUpdateChecker.checkForUpdates(updateCheckListener, true);
+}
+
+function check_test_pt2(aResult) {
+  do_check_eq(aResult, gAppInfo.version);
+  run_test_pt3();
+}
+
+// url constructed with %BUILD_ID%
+function run_test_pt3() {
+  gCheckFunc = check_test_pt3;
+  var url = URL_PREFIX + "%BUILD_ID%/";
+  dump("Testing: url constructed with %BUILD_ID% - " + url + "\n");
+  gPrefs.setCharPref(PREF_APP_UPDATE_URL_OVERRIDE, url);
+  gUpdateChecker.checkForUpdates(updateCheckListener, true);
+}
+
+function check_test_pt3(aResult) {
+  do_check_eq(aResult, gAppInfo.appBuildID);
+  run_test_pt4();
+}
+
+// url constructed with %BUILD_TARGET%
+// XXX TODO - it might be nice if we tested the actual ABI
+function run_test_pt4() {
+  gCheckFunc = check_test_pt4;
+  var url = URL_PREFIX + "%BUILD_TARGET%/";
+  dump("Testing: url constructed with %BUILD_TARGET% - " + url + "\n");
+  gPrefs.setCharPref(PREF_APP_UPDATE_URL_OVERRIDE, url);
+  gUpdateChecker.checkForUpdates(updateCheckListener, true);
+}
+
+function check_test_pt4(aResult) {
+  try {
+    abi = gAppInfo.XPCOMABI;
+  }
+  catch (e) {
+    do_throw("nsIXULAppInfo:XPCOMABI not defined\n");
+  }
+
+#ifdef XP_MACOSX
+  // Mac universal build should report a different ABI than either macppc
+  // or mactel. This is necessary since nsUpdateService.js will set the ABI to
+  // Universal-gcc3 for Mac universal builds.
+  var macutils = AUS_Cc["@mozilla.org/xpcom/mac-utils;1"]
+                   .getService(AUS_Ci.nsIMacUtils);
+
+  if (macutils.isUniversalBinary)
+    abi = "Universal-gcc3";
+#endif
+
+  do_check_eq(aResult, gAppInfo.OS + "_" + abi);
+  run_test_pt5();
+}
+
+// url constructed with %LOCALE%
+// Bug 446527 added the locale to the updater.ini
+function run_test_pt5() {
+  gCheckFunc = check_test_pt5;
+  var url = URL_PREFIX + "%LOCALE%/";
+  dump("Testing: url constructed with %LOCALE% - " + url + "\n");
+  gPrefs.setCharPref(PREF_APP_UPDATE_URL_OVERRIDE, url);
+  var defaults = gPrefs.QueryInterface(AUS_Ci.nsIPrefService)
+                   .getDefaultBranch(null);
+  defaults.setCharPref(PREF_GEN_USERAGENT_LOCALE, "bogus_locale");
+  gUpdateChecker.checkForUpdates(updateCheckListener, true);
+}
+
+function check_test_pt5(aResult) {
+  do_check_eq(aResult, gInstallationLocale);
+  run_test_pt6();
+}
+
+// url constructed with %CHANNEL%
+function run_test_pt6() {
+  gCheckFunc = check_test_pt6;
+  var url = URL_PREFIX + "%CHANNEL%/";
+  dump("Testing: url constructed with %CHANNEL% - " + url + "\n");
+  gPrefs.setCharPref(PREF_APP_UPDATE_URL_OVERRIDE, url);
+  var defaults = gPrefs.QueryInterface(AUS_Ci.nsIPrefService)
+                   .getDefaultBranch(null);
+  defaults.setCharPref(PREF_APP_UPDATE_CHANNEL, "bogus_channel");
+  gUpdateChecker.checkForUpdates(updateCheckListener, true);
+}
+
+function check_test_pt6(aResult) {
+  do_check_eq(aResult, "bogus_channel");
+  run_test_pt7();
+}
+
+// url constructed with %CHANNEL% with distribution partners
+function run_test_pt7() {
+  gCheckFunc = check_test_pt7;
+  var url = URL_PREFIX + "%CHANNEL%/";
+  dump("Testing: url constructed with %CHANNEL% - " + url + "\n");
+  gPrefs.setCharPref(PREF_APP_UPDATE_URL_OVERRIDE, url);
+  var defaults = gPrefs.QueryInterface(AUS_Ci.nsIPrefService)
+                   .getDefaultBranch(null);
+  defaults.setCharPref(PREF_PARTNER_BRANCH + "bogus_partner1", "bogus_partner1");
+  defaults.setCharPref(PREF_PARTNER_BRANCH + "bogus_partner2", "bogus_partner2");
+  gUpdateChecker.checkForUpdates(updateCheckListener, true);
+}
+
+function check_test_pt7(aResult) {
+  do_check_eq(aResult, "bogus_channel-cck-bogus_partner1-bogus_partner2");
+  run_test_pt8();
+}
+
+// url constructed with %PLATFORM_VERSION%
+function run_test_pt8() {
+  gCheckFunc = check_test_pt8;
+  var url = URL_PREFIX + "%PLATFORM_VERSION%/";
+  dump("Testing: url constructed with %PLATFORM_VERSION% - " + url + "\n");
+  gPrefs.setCharPref(PREF_APP_UPDATE_URL_OVERRIDE, url);
+  gUpdateChecker.checkForUpdates(updateCheckListener, true);
+}
+
+function check_test_pt8(aResult) {
+  do_check_eq(aResult, gAppInfo.platformVersion);
+  run_test_pt9();
+}
+
+// url constructed with %OS_VERSION%
+function run_test_pt9() {
+  gCheckFunc = check_test_pt9;
+  var url = URL_PREFIX + "%OS_VERSION%/";
+  dump("Testing: url constructed with %OS_VERSION% - " + url + "\n");
+  gPrefs.setCharPref(PREF_APP_UPDATE_URL_OVERRIDE, url);
+  gUpdateChecker.checkForUpdates(updateCheckListener, true);
+}
+
+function check_test_pt9(aResult) {
+  var osVersion;
+  var sysInfo = AUS_Cc["@mozilla.org/system-info;1"]
+                  .getService(AUS_Ci.nsIPropertyBag2);
+  osVersion = sysInfo.getProperty("name") + " " + sysInfo.getProperty("version");
+
+  if (osVersion) {
+    try {
+      osVersion += " (" + sysInfo.getProperty("secondaryLibrary") + ")";
+    }
+    catch (e) {
+      // Not all platforms have a secondary widget library, so an error is nothing to worry about.
+    }
+    osVersion = encodeURIComponent(osVersion);
+  }
+
+  do_check_eq(aResult, osVersion);
+  run_test_pt10();
+}
+
+// url constructed with %DISTRIBUTION%
+function run_test_pt10() {
+  gCheckFunc = check_test_pt10;
+  var url = URL_PREFIX + "%DISTRIBUTION%/";
+  dump("Testing: url constructed with %DISTRIBUTION% - " + url + "\n");
+  gPrefs.setCharPref(PREF_APP_UPDATE_URL_OVERRIDE, url);
+  var defaults = gPrefs.QueryInterface(AUS_Ci.nsIPrefService)
+                   .getDefaultBranch(null);
+  defaults.setCharPref(PREF_APP_DISTRIBUTION, "bogus_distro");
+  gUpdateChecker.checkForUpdates(updateCheckListener, true);
+}
+
+function check_test_pt10(aResult) {
+  do_check_eq(aResult, "bogus_distro");
+  run_test_pt11();
+}
+
+// url constructed with %DISTRIBUTION_VERSION%
+function run_test_pt11() {
+  gCheckFunc = check_test_pt11;
+  var url = URL_PREFIX + "%DISTRIBUTION_VERSION%/";
+  dump("Testing: url constructed with %DISTRIBUTION_VERSION% - " + url + "\n");
+  gPrefs.setCharPref(PREF_APP_UPDATE_URL_OVERRIDE, url);
+  var defaults = gPrefs.QueryInterface(AUS_Ci.nsIPrefService)
+                   .getDefaultBranch(null);
+  defaults.setCharPref(PREF_APP_DISTRIBUTION_VERSION, "bogus_distro_version");
+  gUpdateChecker.checkForUpdates(updateCheckListener, true);
+}
+
+function check_test_pt11(aResult) {
+  do_check_eq(aResult, "bogus_distro_version");
+  end_test();
+}
+
+// Update check listener
+const updateCheckListener = {
+  onProgress: function(request, position, totalSize) {
+  },
+
+  onCheckComplete: function(request, updates, updateCount) {
+    var url = request.channel.originalURI.spec;
+    dump("onCheckComplete url = " + url + "\n\n");
+    var result = getResult(url);
+    // Use a timeout to allow the XHR to complete
+    do_timeout(0, "gCheckFunc('" + result + "')");
+  },
+
+  onError: function(request, update) {
+    var url = request.channel.originalURI.spec;
+    dump("onError url = " + url + "\n\n");
+    var result = getResult(url);
+    // Use a timeout to allow the XHR to complete
+    do_timeout(0, "gCheckFunc('" + result + "')");
+  },
+
+  QueryInterface: function(aIID) {
+    if (!aIID.equals(AUS_Ci.nsIUpdateCheckListener) &&
+        !aIID.equals(AUS_Ci.nsISupports))
+      throw AUS_Cr.NS_ERROR_NO_INTERFACE;
+    return this;
+  }
+};