Patch 2 (tests only) - Bug 583408 - Notify user when the certificate attribute check fails. r=dtownsend, a=blocking2.0-beta6
authorRobert Strong <robert.bugzilla@gmail.com>
Wed, 01 Sep 2010 16:27:21 -0700
changeset 51864 3c3c95c37d204897dfef2e050368f2117ea9b097
parent 51863 c9ee9a98f2d4d4db468d593972e985b6e92634a6
child 51865 cbbccc115e555e4cc0b7aacd6c70b21131df87f7
push id15454
push userrstrong@mozilla.com
push dateWed, 01 Sep 2010 23:27:33 +0000
treeherdermozilla-central@3c3c95c37d20 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersdtownsend, blocking2
bugs583408
milestone2.0b6pre
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
Patch 2 (tests only) - Bug 583408 - Notify user when the certificate attribute check fails. r=dtownsend, a=blocking2.0-beta6
toolkit/mozapps/update/test/chrome/Makefile.in
toolkit/mozapps/update/test/chrome/test_0120_cert_valid_attributes_not_builtin.xul
toolkit/mozapps/update/test/chrome/test_0121_cert_invalid_attribute_name.xul
toolkit/mozapps/update/test/chrome/test_0121_check_requireBuiltinCert.xul
toolkit/mozapps/update/test/chrome/test_0122_check_allowNonBuiltinCert_validCertAttrs.xul
toolkit/mozapps/update/test/chrome/test_0123_check_allowNonBuiltinCert_noCertAttrsCheck.xul
toolkit/mozapps/update/test/chrome/test_0131_check_invalidCertAttrs_noUpdate.xul
toolkit/mozapps/update/test/chrome/test_0132_check_invalidCertAttrs_hasUpdate.xul
toolkit/mozapps/update/test/chrome/test_0141_notify_invalidCertAttrs_noUpdate.xul
toolkit/mozapps/update/test/chrome/test_0142_notify_invalidCertAttrs_hasUpdate.xul
toolkit/mozapps/update/test/chrome/utils.js
toolkit/mozapps/update/test/shared.js
--- a/toolkit/mozapps/update/test/chrome/Makefile.in
+++ b/toolkit/mozapps/update/test/chrome/Makefile.in
@@ -80,18 +80,23 @@ include $(DEPTH)/config/autoconf.mk
   test_0082_error_patchApplyFailure_complete_only.xul \
   test_0083_error_patchApplyFailure_partial_complete.xul \
   test_0084_error_patchApplyFailure_verify_failed.xul \
   test_0091_installed.xul \
   test_0092_finishedBackground.xul \
   test_0111_neverButton_basic.xul \
   test_0112_neverButton_billboard.xul \
   test_0113_showNeverForVersionRemovedWithPref.xul \
-  test_0120_cert_valid_attributes_not_builtin.xul \
-  test_0121_cert_invalid_attribute_name.xul \
+  test_0121_check_requireBuiltinCert.xul \
+  test_0122_check_allowNonBuiltinCert_validCertAttrs.xul \
+  test_0123_check_allowNonBuiltinCert_noCertAttrsCheck.xul \
+  test_0131_check_invalidCertAttrs_noUpdate.xul \
+  test_0132_check_invalidCertAttrs_hasUpdate.xul \
+  test_0141_notify_invalidCertAttrs_noUpdate.xul \
+  test_0142_notify_invalidCertAttrs_hasUpdate.xul \
   test_9999_cleanup.xul \
   $(NULL)
 
 include $(topsrcdir)/config/rules.mk
 
 libs:: $(_OTHER_FILES)
 	$(INSTALL) $(foreach f,$^,"$f") $(DEPTH)/_tests/testing/mochitest/chrome/$(relativesrcdir)
 
deleted file mode 100644
--- a/toolkit/mozapps/update/test/chrome/test_0120_cert_valid_attributes_not_builtin.xul
+++ /dev/null
@@ -1,113 +0,0 @@
-<?xml version="1.0"?>
-<!--
-/* Any copyright is dedicated to the Public Domain.
- * http://creativecommons.org/publicdomain/zero/1.0/
- */
--->
-
-<?xml-stylesheet href="chrome://global/skin" type="text/css"?>
-<?xml-stylesheet href="chrome://mochikit/content/tests/SimpleTest/test.css" type="text/css"?>
-
-<window title="Test update checking wizard with valid certificate attribute names and values and cert not built-in"
-        xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
-        onload="runTestDefault();">
-<script type="application/javascript" 
-        src="chrome://mochikit/content/MochiKit/packed.js"/>
-<script type="application/javascript"
-        src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"/>
-<script type="application/javascript"
-        src="chrome://mochikit/content/chrome/toolkit/mozapps/update/test/chrome/utils.js"/>
-
-<script type="application/javascript">
-<![CDATA[
-
-const TESTS = [ {
-  pageid: PAGEID_CHECKING
-}, {
-  pageid: PAGEID_ERRORS,
-  buttonClick: "finish"
-} ];
-
-Components.utils.import("resource://gre/modules/CertUtils.jsm");
-
-const CERT_ATTRS = ["nickname", "emailAddress", "subjectName", "commonName",
-                    "organization", "organizationalUnit", "sha1Fingerprint",
-                    "md5Fingerprint", "tokenName", "issuerName", "serialNumber",
-                    "issuerCommonName", "issuerOrganization",
-                    "issuerOrganizationUnit", "dbKey", "windowTitle"];
-var gDefaultAppUpdateURL;
-
-function runTest() {
-  debugDump("Entering runTest");
-
-  var request = AUS_Cc["@mozilla.org/xmlextras/xmlhttprequest;1"].
-                createInstance(AUS_Ci.nsIXMLHttpRequest);
-  request.open("GET", "https://example.com/", true);
-  request.channel.notificationCallbacks = new BadCertHandler(true);
-  request.onload = function(event) { testXHRLoad(event); };
-  request.onerror = function(event) { testXHRError(event); };
-  request.send(null);
-}
-
-function testXHRError(aEvent) {
-  debugDump("Entering testXHRError");
-
-  ok(true, "Entering testXHRError - something went wrong");
-
-  var request = aEvent.target;
-  var status = 0;
-  try {
-    status = request.status;
-  }
-  catch (e) {
-  }
-
-  if (status == 0)
-    status = request.channel.QueryInterface(AUS_Ci.nsIRequest).status;
-
-  ok(false, "XHR onerror called: " + status);
-
-  finishTestDefault();
-}
-
-function testXHRLoad(aEvent) {
-  debugDump("Entering testXHRLoad");
-
-  var channel = aEvent.target.channel;
-  var cert = channel.securityInfo.QueryInterface(AUS_Ci.nsISSLStatusProvider).
-             SSLStatus.QueryInterface(AUS_Ci.nsISSLStatus).serverCert;
-  CERT_ATTRS.forEach(function(aCertAttrName) {
-    Services.prefs.setCharPref(PREF_APP_UPDATE_CERTS_BRANCH + "1." +
-                               aCertAttrName, cert[aCertAttrName]);
-  });
-
-  var queryString = "?showDetails=1" + getVersionParams();
-  var url = "https://example.com/" + URL_PATH + "/update.sjs?showDetails=1" +
-            getVersionParams();
-  gDefaultAppUpdateURL = gDefaultPrefBranch.getCharPref(PREF_APP_UPDATE_URL);
-  gDefaultPrefBranch.setCharPref(PREF_APP_UPDATE_URL, url);
-  debugDump("Default Update URL: " + url);
-
-  gUP.checkForUpdates();
-}
-
-function finishTest() {
-  debugDump("Entering finishTest");
-
-  CERT_ATTRS.forEach(function(aCertAttrName) {
-    Services.prefs.clearUserPref(PREF_APP_UPDATE_CERTS_BRANCH + "1." +
-                                 aCertAttrName);
-  });
-  gDefaultPrefBranch.setCharPref(PREF_APP_UPDATE_URL, gDefaultAppUpdateURL);
-  finishTestDefault();
-}
-
-]]>
-</script>
-
-<body xmlns="http://www.w3.org/1999/xhtml">
-  <p id="display"></p>
-  <div id="content" style="display: none"></div>
-  <pre id="test"></pre>
-</body>
-</window>
deleted file mode 100644
--- a/toolkit/mozapps/update/test/chrome/test_0121_cert_invalid_attribute_name.xul
+++ /dev/null
@@ -1,67 +0,0 @@
-<?xml version="1.0"?>
-<!--
-/* Any copyright is dedicated to the Public Domain.
- * http://creativecommons.org/publicdomain/zero/1.0/
- */
--->
-
-<?xml-stylesheet href="chrome://global/skin" type="text/css"?>
-<?xml-stylesheet href="chrome://mochikit/content/tests/SimpleTest/test.css" type="text/css"?>
-
-<window title="Test update checking wizard with invalid certificate attribute name"
-        xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
-        onload="runTestDefault();">
-<script type="application/javascript" 
-        src="chrome://mochikit/content/MochiKit/packed.js"/>
-<script type="application/javascript"
-        src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"/>
-<script type="application/javascript"
-        src="chrome://mochikit/content/chrome/toolkit/mozapps/update/test/chrome/utils.js"/>
-
-<script type="application/javascript">
-<![CDATA[
-// This is treated as no updates found until Bug 583408 is fixed
-const TESTS = [ {
-  pageid: PAGEID_CHECKING
-}, {
-  pageid: PAGEID_NO_UPDATES_FOUND,
-  buttonClick: "finish"
-} ];
-
-const PREF_APP_UPDATE_CERT_INVALID_ATTR_NAME = PREF_APP_UPDATE_CERTS_BRANCH +
-                                               "1.invalidName";
-var gDefaultAppUpdateURL;
-
-function runTest() {
-  debugDump("Entering runTest");
-
-  Services.prefs.setCharPref(PREF_APP_UPDATE_CERT_INVALID_ATTR_NAME,
-                             "Invalid Attribute Name");
-
-  var queryString = "?showDetails=1" + getVersionParams();
-  var url = "https://example.com/" + URL_PATH + "/update.sjs?showDetails=1" +
-            getVersionParams();
-  gDefaultAppUpdateURL = gDefaultPrefBranch.getCharPref(PREF_APP_UPDATE_URL);
-  gDefaultPrefBranch.setCharPref(PREF_APP_UPDATE_URL, url);
-  debugDump("Default Update URL: " + url);
-
-  gUP.checkForUpdates();
-}
-
-function finishTest() {
-  debugDump("Entering finishTest - clearing user preference " +
-            PREF_APP_UPDATE_CERT_INVALID_ATTR_NAME);
-  Services.prefs.clearUserPref(PREF_APP_UPDATE_CERT_INVALID_ATTR_NAME);
-  gDefaultPrefBranch.setCharPref(PREF_APP_UPDATE_URL, gDefaultAppUpdateURL);
-  finishTestDefault();
-}
-
-]]>
-</script>
-
-<body xmlns="http://www.w3.org/1999/xhtml">
-  <p id="display"></p>
-  <div id="content" style="display: none"></div>
-  <pre id="test"></pre>
-</body>
-</window>
new file mode 100644
--- /dev/null
+++ b/toolkit/mozapps/update/test/chrome/test_0121_check_requireBuiltinCert.xul
@@ -0,0 +1,100 @@
+<?xml version="1.0"?>
+<!--
+/* Any copyright is dedicated to the Public Domain.
+ * http://creativecommons.org/publicdomain/zero/1.0/
+ */
+-->
+
+<?xml-stylesheet href="chrome://global/skin" type="text/css"?>
+<?xml-stylesheet href="chrome://mochikit/content/tests/SimpleTest/test.css" type="text/css"?>
+
+<window title="Test update check with certificate that is not built-in and valid certificate attribute names and values"
+        xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
+        onload="runTestDefault();">
+<script type="application/javascript" 
+        src="chrome://mochikit/content/MochiKit/packed.js"/>
+<script type="application/javascript"
+        src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"/>
+<script type="application/javascript"
+        src="chrome://mochikit/content/chrome/toolkit/mozapps/update/test/chrome/utils.js"/>
+
+<script type="application/javascript">
+<![CDATA[
+
+const TESTS = [ {
+  pageid: PAGEID_CHECKING
+}, {
+  pageid: PAGEID_ERRORS,
+  buttonClick: "finish"
+} ];
+
+Components.utils.import("resource://gre/modules/CertUtils.jsm");
+
+const CERT_ATTRS = ["nickname", "emailAddress", "subjectName", "commonName",
+                    "organization", "organizationalUnit", "sha1Fingerprint",
+                    "md5Fingerprint", "tokenName", "issuerName", "serialNumber",
+                    "issuerCommonName", "issuerOrganization",
+                    "issuerOrganizationUnit", "dbKey", "windowTitle"];
+
+function runTest() {
+  debugDump("Entering runTest");
+
+  var request = AUS_Cc["@mozilla.org/xmlextras/xmlhttprequest;1"].
+                createInstance(AUS_Ci.nsIXMLHttpRequest);
+  request.open("GET", "https://example.com/", true);
+  request.channel.notificationCallbacks = new BadCertHandler(true);
+  request.onload = function(event) { testXHRLoad(event); };
+  request.onerror = function(event) { testXHRError(event); };
+  request.send(null);
+}
+
+function testXHRError(aEvent) {
+  debugDump("Entering testXHRError");
+
+  ok(true, "Entering testXHRError - something went wrong");
+
+  var request = aEvent.target;
+  var status = 0;
+  try {
+    status = request.status;
+  }
+  catch (e) {
+  }
+
+  if (status == 0)
+    status = request.channel.QueryInterface(AUS_Ci.nsIRequest).status;
+
+  ok(false, "XHR onerror called: " + status);
+
+  finishTestDefault();
+}
+
+function testXHRLoad(aEvent) {
+  debugDump("Entering testXHRLoad");
+
+  var channel = aEvent.target.channel;
+  var cert = channel.securityInfo.QueryInterface(AUS_Ci.nsISSLStatusProvider).
+             SSLStatus.QueryInterface(AUS_Ci.nsISSLStatus).serverCert;
+  CERT_ATTRS.forEach(function(aCertAttrName) {
+    Services.prefs.setCharPref(PREF_APP_UPDATE_CERTS_BRANCH + "1." +
+                               aCertAttrName, cert[aCertAttrName]);
+  });
+
+  let url = "https://example.com/" + URL_PATH + "/update.sjs?showDetails=1" +
+            getVersionParams();
+  gAppUpdateURLDefault = gDefaultPrefBranch.getCharPref(PREF_APP_UPDATE_URL);
+  gDefaultPrefBranch.setCharPref(PREF_APP_UPDATE_URL, url);
+  debugDump("Default Update URL: " + url);
+
+  gUP.checkForUpdates();
+}
+
+]]>
+</script>
+
+<body xmlns="http://www.w3.org/1999/xhtml">
+  <p id="display"></p>
+  <div id="content" style="display: none"></div>
+  <pre id="test"></pre>
+</body>
+</window>
new file mode 100644
--- /dev/null
+++ b/toolkit/mozapps/update/test/chrome/test_0122_check_allowNonBuiltinCert_validCertAttrs.xul
@@ -0,0 +1,102 @@
+<?xml version="1.0"?>
+<!--
+/* Any copyright is dedicated to the Public Domain.
+ * http://creativecommons.org/publicdomain/zero/1.0/
+ */
+-->
+
+<?xml-stylesheet href="chrome://global/skin" type="text/css"?>
+<?xml-stylesheet href="chrome://mochikit/content/tests/SimpleTest/test.css" type="text/css"?>
+
+<window title="Test update check without requiring a certificate that is built-in and valid certificate attribute names and values"
+        xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
+        onload="runTestDefault();">
+<script type="application/javascript" 
+        src="chrome://mochikit/content/MochiKit/packed.js"/>
+<script type="application/javascript"
+        src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"/>
+<script type="application/javascript"
+        src="chrome://mochikit/content/chrome/toolkit/mozapps/update/test/chrome/utils.js"/>
+
+<script type="application/javascript">
+<![CDATA[
+
+const TESTS = [ {
+  pageid: PAGEID_CHECKING
+}, {
+  pageid: PAGEID_FOUND_BASIC,
+  buttonClick: "extra1"
+} ];
+
+Components.utils.import("resource://gre/modules/CertUtils.jsm");
+
+const CERT_ATTRS = ["nickname", "emailAddress", "subjectName", "commonName",
+                    "organization", "organizationalUnit", "sha1Fingerprint",
+                    "md5Fingerprint", "tokenName", "issuerName", "serialNumber",
+                    "issuerCommonName", "issuerOrganization",
+                    "issuerOrganizationUnit", "dbKey", "windowTitle"];
+
+function runTest() {
+  debugDump("Entering runTest");
+
+  var request = AUS_Cc["@mozilla.org/xmlextras/xmlhttprequest;1"].
+                createInstance(AUS_Ci.nsIXMLHttpRequest);
+  request.open("GET", "https://example.com/", true);
+  request.channel.notificationCallbacks = new BadCertHandler(true);
+  request.onload = function(event) { testXHRLoad(event); };
+  request.onerror = function(event) { testXHRError(event); };
+  request.send(null);
+}
+
+function testXHRError(aEvent) {
+  debugDump("Entering testXHRError");
+
+  ok(true, "Entering testXHRError - something went wrong");
+
+  var request = aEvent.target;
+  var status = 0;
+  try {
+    status = request.status;
+  }
+  catch (e) {
+  }
+
+  if (status == 0)
+    status = request.channel.QueryInterface(AUS_Ci.nsIRequest).status;
+
+  ok(false, "XHR onerror called: " + status);
+
+  finishTestDefault();
+}
+
+function testXHRLoad(aEvent) {
+  debugDump("Entering testXHRLoad");
+
+  var channel = aEvent.target.channel;
+  var cert = channel.securityInfo.QueryInterface(AUS_Ci.nsISSLStatusProvider).
+             SSLStatus.QueryInterface(AUS_Ci.nsISSLStatus).serverCert;
+  CERT_ATTRS.forEach(function(aCertAttrName) {
+    Services.prefs.setCharPref(PREF_APP_UPDATE_CERTS_BRANCH + "1." +
+                               aCertAttrName, cert[aCertAttrName]);
+  });
+
+  Services.prefs.setBoolPref(PREF_APP_UPDATE_CERT_REQUIREBUILTIN, false);
+
+  let url = "https://example.com/" + URL_PATH + "/update.sjs?showDetails=1" +
+            getVersionParams();
+  gAppUpdateURLDefault = gDefaultPrefBranch.getCharPref(PREF_APP_UPDATE_URL);
+  gDefaultPrefBranch.setCharPref(PREF_APP_UPDATE_URL, url);
+  debugDump("Default Update URL: " + url);
+
+  gUP.checkForUpdates();
+}
+
+]]>
+</script>
+
+<body xmlns="http://www.w3.org/1999/xhtml">
+  <p id="display"></p>
+  <div id="content" style="display: none"></div>
+  <pre id="test"></pre>
+</body>
+</window>
new file mode 100644
--- /dev/null
+++ b/toolkit/mozapps/update/test/chrome/test_0123_check_allowNonBuiltinCert_noCertAttrsCheck.xul
@@ -0,0 +1,60 @@
+<?xml version="1.0"?>
+<!--
+/* Any copyright is dedicated to the Public Domain.
+ * http://creativecommons.org/publicdomain/zero/1.0/
+ */
+-->
+
+<?xml-stylesheet href="chrome://global/skin" type="text/css"?>
+<?xml-stylesheet href="chrome://mochikit/content/tests/SimpleTest/test.css" type="text/css"?>
+
+<window title="Test update check without requiring a certificate that is built-in and without the certificate attribute check"
+        xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
+        onload="runTestDefault();">
+<script type="application/javascript" 
+        src="chrome://mochikit/content/MochiKit/packed.js"/>
+<script type="application/javascript"
+        src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"/>
+<script type="application/javascript"
+        src="chrome://mochikit/content/chrome/toolkit/mozapps/update/test/chrome/utils.js"/>
+
+<script type="application/javascript">
+<![CDATA[
+
+const TESTS = [ {
+  pageid: PAGEID_CHECKING
+}, {
+  pageid: PAGEID_FOUND_BASIC,
+  buttonClick: "extra1"
+} ];
+
+Components.utils.import("resource://gre/modules/CertUtils.jsm");
+
+function runTest() {
+  debugDump("Entering runTest");
+
+  Services.prefs.setCharPref(PREF_APP_UPDATE_CERT_INVALID_ATTR_NAME,
+                             "Invalid Attribute Name");
+  Services.prefs.setIntPref(PREF_APP_UPDATE_CERT_ERRORS, 1);
+  Services.prefs.setBoolPref(PREF_APP_UPDATE_CERT_REQUIREBUILTIN, false);
+  Services.prefs.setBoolPref(PREF_APP_UPDATE_CERT_CHECKATTRS, false);
+
+  let url = "https://example.com/" + URL_PATH + "/update.sjs?showDetails=1" +
+            getVersionParams();
+  gAppUpdateURLDefault = gDefaultPrefBranch.getCharPref(PREF_APP_UPDATE_URL);
+  gDefaultPrefBranch.setCharPref(PREF_APP_UPDATE_URL, url);
+  debugDump("Default Update URL: " + url);
+
+  gUP.checkForUpdates();
+}
+
+
+]]>
+</script>
+
+<body xmlns="http://www.w3.org/1999/xhtml">
+  <p id="display"></p>
+  <div id="content" style="display: none"></div>
+  <pre id="test"></pre>
+</body>
+</window>
new file mode 100644
--- /dev/null
+++ b/toolkit/mozapps/update/test/chrome/test_0131_check_invalidCertAttrs_noUpdate.xul
@@ -0,0 +1,56 @@
+<?xml version="1.0"?>
+<!--
+/* Any copyright is dedicated to the Public Domain.
+ * http://creativecommons.org/publicdomain/zero/1.0/
+ */
+-->
+
+<?xml-stylesheet href="chrome://global/skin" type="text/css"?>
+<?xml-stylesheet href="chrome://mochikit/content/tests/SimpleTest/test.css" type="text/css"?>
+
+<window title="Test update check with invalid certificate attribute name with no update"
+        xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
+        onload="runTestDefault();">
+<script type="application/javascript" 
+        src="chrome://mochikit/content/MochiKit/packed.js"/>
+<script type="application/javascript"
+        src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"/>
+<script type="application/javascript"
+        src="chrome://mochikit/content/chrome/toolkit/mozapps/update/test/chrome/utils.js"/>
+
+<script type="application/javascript">
+<![CDATA[
+
+const TESTS = [ {
+  pageid: PAGEID_CHECKING
+}, {
+  pageid: PAGEID_ERROR_CERT_CHECK,
+  extraDelayedCheckFunction: checkCertErrorPage,
+  shouldBeHidden: false,
+  buttonClick: "finish"
+} ];
+
+function runTest() {
+  debugDump("Entering runTest");
+
+  Services.prefs.setCharPref(PREF_APP_UPDATE_CERT_INVALID_ATTR_NAME,
+                             "Invalid Attribute Name");
+  Services.prefs.setIntPref(PREF_APP_UPDATE_CERT_ERRORS, 1);
+
+  let url = "https://example.com/" + URL_PATH + "/update.sjs?noUpdates=1";
+  gAppUpdateURLDefault = gDefaultPrefBranch.getCharPref(PREF_APP_UPDATE_URL);
+  gDefaultPrefBranch.setCharPref(PREF_APP_UPDATE_URL, url);
+  debugDump("Default Update URL: " + url);
+
+  gUP.checkForUpdates();
+}
+
+]]>
+</script>
+
+<body xmlns="http://www.w3.org/1999/xhtml">
+  <p id="display"></p>
+  <div id="content" style="display: none"></div>
+  <pre id="test"></pre>
+</body>
+</window>
new file mode 100644
--- /dev/null
+++ b/toolkit/mozapps/update/test/chrome/test_0132_check_invalidCertAttrs_hasUpdate.xul
@@ -0,0 +1,57 @@
+<?xml version="1.0"?>
+<!--
+/* Any copyright is dedicated to the Public Domain.
+ * http://creativecommons.org/publicdomain/zero/1.0/
+ */
+-->
+
+<?xml-stylesheet href="chrome://global/skin" type="text/css"?>
+<?xml-stylesheet href="chrome://mochikit/content/tests/SimpleTest/test.css" type="text/css"?>
+
+<window title="Test update check with invalid certificate attribute name with an update"
+        xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
+        onload="runTestDefault();">
+<script type="application/javascript" 
+        src="chrome://mochikit/content/MochiKit/packed.js"/>
+<script type="application/javascript"
+        src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"/>
+<script type="application/javascript"
+        src="chrome://mochikit/content/chrome/toolkit/mozapps/update/test/chrome/utils.js"/>
+
+<script type="application/javascript">
+<![CDATA[
+
+const TESTS = [ {
+  pageid: PAGEID_CHECKING
+}, {
+  pageid: PAGEID_ERROR_CERT_CHECK,
+  extraDelayedCheckFunction: checkCertErrorPage,
+  shouldBeHidden: true,
+  buttonClick: "finish"
+} ];
+
+function runTest() {
+  debugDump("Entering runTest");
+
+  Services.prefs.setCharPref(PREF_APP_UPDATE_CERT_INVALID_ATTR_NAME,
+                             "Invalid Attribute Name");
+  Services.prefs.setIntPref(PREF_APP_UPDATE_CERT_ERRORS, 1);
+
+  let url = "https://example.com/" + URL_PATH + "/update.sjs?showDetails=1" +
+            getVersionParams();
+  gAppUpdateURLDefault = gDefaultPrefBranch.getCharPref(PREF_APP_UPDATE_URL);
+  gDefaultPrefBranch.setCharPref(PREF_APP_UPDATE_URL, url);
+  debugDump("Default Update URL: " + url);
+
+  gUP.checkForUpdates();
+}
+
+]]>
+</script>
+
+<body xmlns="http://www.w3.org/1999/xhtml">
+  <p id="display"></p>
+  <div id="content" style="display: none"></div>
+  <pre id="test"></pre>
+</body>
+</window>
new file mode 100644
--- /dev/null
+++ b/toolkit/mozapps/update/test/chrome/test_0141_notify_invalidCertAttrs_noUpdate.xul
@@ -0,0 +1,55 @@
+<?xml version="1.0"?>
+<!--
+/* Any copyright is dedicated to the Public Domain.
+ * http://creativecommons.org/publicdomain/zero/1.0/
+ */
+-->
+
+<?xml-stylesheet href="chrome://global/skin" type="text/css"?>
+<?xml-stylesheet href="chrome://mochikit/content/tests/SimpleTest/test.css" type="text/css"?>
+
+<window title="Test notification with invalid certificate attribute name with no update"
+        xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
+        onload="runTestDefault();">
+<script type="application/javascript" 
+        src="chrome://mochikit/content/MochiKit/packed.js"/>
+<script type="application/javascript"
+        src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"/>
+<script type="application/javascript"
+        src="chrome://mochikit/content/chrome/toolkit/mozapps/update/test/chrome/utils.js"/>
+
+<script type="application/javascript">
+<![CDATA[
+
+const TESTS = [ {
+  pageid: PAGEID_ERROR_CERT_CHECK,
+  extraDelayedCheckFunction: checkCertErrorPage,
+  shouldBeHidden: false,
+  buttonClick: "finish"
+} ];
+
+function runTest() {
+  debugDump("Entering runTest");
+
+  Services.prefs.setCharPref(PREF_APP_UPDATE_CERT_INVALID_ATTR_NAME,
+                             "Invalid Attribute Name");
+
+  let url = "https://example.com/" + URL_PATH + "/update.sjs?noUpdates=1";
+  gAppUpdateURLDefault = gDefaultPrefBranch.getCharPref(PREF_APP_UPDATE_URL);
+  gDefaultPrefBranch.setCharPref(PREF_APP_UPDATE_URL, url);
+  debugDump("Default Update URL: " + url);
+
+  certErrorsPrefObserver.init();
+
+  gAUS.notify(null);
+}
+
+]]>
+</script>
+
+<body xmlns="http://www.w3.org/1999/xhtml">
+  <p id="display"></p>
+  <div id="content" style="display: none"></div>
+  <pre id="test"></pre>
+</body>
+</window>
new file mode 100644
--- /dev/null
+++ b/toolkit/mozapps/update/test/chrome/test_0142_notify_invalidCertAttrs_hasUpdate.xul
@@ -0,0 +1,56 @@
+<?xml version="1.0"?>
+<!--
+/* Any copyright is dedicated to the Public Domain.
+ * http://creativecommons.org/publicdomain/zero/1.0/
+ */
+-->
+
+<?xml-stylesheet href="chrome://global/skin" type="text/css"?>
+<?xml-stylesheet href="chrome://mochikit/content/tests/SimpleTest/test.css" type="text/css"?>
+
+<window title="Test notification with invalid certificate attribute name with no update"
+        xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
+        onload="runTestDefault();">
+<script type="application/javascript" 
+        src="chrome://mochikit/content/MochiKit/packed.js"/>
+<script type="application/javascript"
+        src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"/>
+<script type="application/javascript"
+        src="chrome://mochikit/content/chrome/toolkit/mozapps/update/test/chrome/utils.js"/>
+
+<script type="application/javascript">
+<![CDATA[
+
+const TESTS = [ {
+  pageid: PAGEID_ERROR_CERT_CHECK,
+  extraDelayedCheckFunction: checkCertErrorPage,
+  shouldBeHidden: true,
+  buttonClick: "finish"
+} ];
+
+function runTest() {
+  debugDump("Entering runTest");
+
+  Services.prefs.setCharPref(PREF_APP_UPDATE_CERT_INVALID_ATTR_NAME,
+                             "Invalid Attribute Name");
+
+  let url = "https://example.com/" + URL_PATH + "/update.sjs?showDetails=1" +
+            getVersionParams();
+  gAppUpdateURLDefault = gDefaultPrefBranch.getCharPref(PREF_APP_UPDATE_URL);
+  gDefaultPrefBranch.setCharPref(PREF_APP_UPDATE_URL, url);
+  debugDump("Default Update URL: " + url);
+
+  certErrorsPrefObserver.init();
+
+  gAUS.notify(null);
+}
+
+]]>
+</script>
+
+<body xmlns="http://www.w3.org/1999/xhtml">
+  <p id="display"></p>
+  <div id="content" style="display: none"></div>
+  <pre id="test"></pre>
+</body>
+</window>
--- a/toolkit/mozapps/update/test/chrome/utils.js
+++ b/toolkit/mozapps/update/test/chrome/utils.js
@@ -122,31 +122,35 @@ const PAGEID_NO_UPDATES_FOUND = "noupdat
 const PAGEID_MANUAL_UPDATE    = "manualUpdate"; // Tested on license load failure
 const PAGEID_INCOMPAT_CHECK   = "incompatibleCheck";     // Done
 const PAGEID_FOUND_BASIC      = "updatesfoundbasic";     // Done
 const PAGEID_FOUND_BILLBOARD  = "updatesfoundbillboard"; // Done
 const PAGEID_LICENSE          = "license";               // Done
 const PAGEID_INCOMPAT_LIST    = "incompatibleList";      // Done
 const PAGEID_DOWNLOADING      = "downloading";           // Done
 const PAGEID_ERRORS           = "errors";                // Done
+const PAGEID_ERROR_CERT_CHECK = "errorcertcheck";        // Done
 const PAGEID_ERROR_PATCHING   = "errorpatching";         // Done
 const PAGEID_FINISHED         = "finished";              // Done
 const PAGEID_FINISHED_BKGRD   = "finishedBackground";    // Done
 const PAGEID_INSTALLED        = "installed";             // Done
 
 const UPDATE_WINDOW_NAME = "Update:Wizard";
 
 const URL_HOST   = "http://example.com/";
 const URL_PATH   = "chrome/toolkit/mozapps/update/test/chrome";
 const URL_UPDATE = URL_HOST + URL_PATH + "/update.sjs";
 
 const URI_UPDATE_PROMPT_DIALOG  = "chrome://mozapps/content/update/updates.xul";
 
 const CRC_ERROR = 4;
 
+const PREF_APP_UPDATE_CERT_INVALID_ATTR_NAME = PREF_APP_UPDATE_CERTS_BRANCH +
+                                               "1.invalidName";
+
 const ADDON_ID_SUFFIX = "@appupdatetest.mozilla.org";
 const ADDON_PREP_DIR = "appupdateprep";
 // Preference for storing add-ons that are disabled by the tests to prevent them
 // from interefering with the tests.
 const PREF_DISABLEDADDONS = "app.update.test.disabledAddons";
 const TEST_ADDONS = [ "appdisabled_1", "appdisabled_2",
                       "compatible_1", "compatible_2",
                       "noupdate_1", "noupdate_2",
@@ -156,20 +160,21 @@ const TEST_ADDONS = [ "appdisabled_1", "
 
 const DEBUG_DUMP = false;
 
 const TEST_TIMEOUT = 30000; // 30 seconds
 var gTimeoutTimer;
 
 // The following vars are for restoring previous preference values (if present)
 // when the test finishes.
-var gAppUpdateChannel; // app.update.channel (default prefbranch)
-var gAppUpdateEnabled; // app.update.enabled
-var gAppUpdateURL;     // app.update.url.override
-var gExtUpdateURL;     // extensions.update.url
+var gAppUpdateChannel;    // app.update.channel (default prefbranch)
+var gAppUpdateEnabled;    // app.update.enabled
+var gAppUpdateURLDefault; // app.update.url (default prefbranch)
+var gAppUpdateURL;        // app.update.url.override
+var gExtUpdateURL;        // extensions.update.url
 
 var gTestCounter = -1;
 var gWin;
 var gDocElem;
 var gPrefToCheck;
 var gDisableNoUpdateAddon = false;
 
 #include ../shared.js
@@ -449,16 +454,17 @@ function getExpectedButtonStates() {
     case PAGEID_INCOMPAT_LIST:
       return { extra1: { disabled: false, hidden: false },
                next  : { disabled: false, hidden: false } };
     case PAGEID_DOWNLOADING:
       return { extra1: { disabled: false, hidden: false } };
     case PAGEID_NO_UPDATES_FOUND:
     case PAGEID_MANUAL_UPDATE:
     case PAGEID_ERRORS:
+    case PAGEID_ERROR_CERT_CHECK:
     case PAGEID_INSTALLED:
       return { finish: { disabled: false, hidden: false } };
     case PAGEID_ERROR_PATCHING:
       return { next  : { disabled: false, hidden: false } };
     case PAGEID_FINISHED:
     case PAGEID_FINISHED_BKGRD:
       return { extra1: { disabled: false, hidden: false },
                finish: { disabled: false, hidden: false } };
@@ -603,16 +609,39 @@ function checkPrefHasUserValue(aPrefHasV
   let prefHasUserValue = aPrefHasValue === undefined ? gTest.prefHasUserValue
                                                      : aPrefHasValue;
   is(Services.prefs.prefHasUserValue(gPrefToCheck), prefHasUserValue,
      "Checking prefHasUserValue for preference " + gPrefToCheck + " equals " +
      (prefHasUserValue ? "true" : "false"));
 }
 
 /**
+ * Checks whether the link is hidden (certificate attribute check error with an
+ * update) or not (certificate attribute check error without an update) on the
+ * errorcertcheck page and that the app.update.cert.errors preference does note
+ & have a user value.
+ *
+ * @param  aShouldBeHidden (optional)
+ *         The expected value for the label's hidden attribute for the link. If
+ *         aShouldBeHidden is undefined the value of the current test's
+ *         shouldBeHidden property will be used.
+ */
+function checkCertErrorPage(aShouldBeHidden) {
+  let shouldBeHidden = aShouldBeHidden === undefined ? gTest.shouldBeHidden
+                                                     : aShouldBeHidden;
+  is(gWin.document.getElementById("errorCertAttrLinkLabel").hidden, shouldBeHidden,
+     "Checking errorCertAttrLinkLabel hidden attribute equals " +
+     (shouldBeHidden ? "true" : "false"));
+
+  ok(!Services.prefs.prefHasUserValue(PREF_APP_UPDATE_CERT_ERRORS),
+     "Preference " + PREF_APP_UPDATE_CERT_ERRORS + " should not have a " +
+     "user value");
+}
+
+/**
  * Gets the update version info for the update url parameters to send to
  * update.sjs.
  *
  * @param  aAppVersion (optional)
  *         The application version for the update snippet. If not specified the
  *         current application version will be used.
  * @param  aPlatformVersion (optional)
  *         The platform version for the update snippet. If not specified the
@@ -679,16 +708,19 @@ function verifyTestsRan() {
  * Sets the most common preferences used by tests to values used by the tests
  * and saves some of the preference's original values if present so they can be
  * set back to the original values when each test has finished.
  */
 function setupPrefs() {
   gAppUpdateChannel = gDefaultPrefBranch.getCharPref(PREF_APP_UPDATE_CHANNEL);
   setUpdateChannel();
 
+  // Uncomment for debugging
+//  Services.prefs.setBoolPref(PREF_APP_UPDATE_LOG, true)
+
   if (Services.prefs.prefHasUserValue(PREF_APP_UPDATE_URL_OVERRIDE)) {
     gAppUpdateURL = Services.prefs.setIntPref(PREF_APP_UPDATE_URL_OVERRIDE);
   }
 
   if (Services.prefs.prefHasUserValue(PREF_APP_UPDATE_ENABLED)) {
     gAppUpdateEnabled = Services.prefs.getBoolPref(PREF_APP_UPDATE_ENABLED);
   }
   Services.prefs.setBoolPref(PREF_APP_UPDATE_ENABLED, true)
@@ -710,16 +742,20 @@ function setupPrefs() {
 function resetPrefs() {
   if (gAppUpdateURL !== undefined) {
     Services.prefs.setCharPref(PREF_APP_UPDATE_URL_OVERRIDE, gAppUpdateURL);
   }
   else if (Services.prefs.prefHasUserValue(PREF_APP_UPDATE_URL_OVERRIDE)) {
     Services.prefs.clearUserPref(PREF_APP_UPDATE_URL_OVERRIDE);
   }
 
+  if (gAppUpdateURLDefault) {
+    gDefaultPrefBranch.setCharPref(PREF_APP_UPDATE_URL, gAppUpdateURLDefault);
+  }
+
   if (gAppUpdateChannel !== undefined) {
     setUpdateChannel(gAppUpdateChannel);
   }
 
   if (gAppUpdateEnabled !== undefined) {
     Services.prefs.setBoolPref(PREF_APP_UPDATE_ENABLED, gAppUpdateEnabled);
   }
   else if (Services.prefs.prefHasUserValue(PREF_APP_UPDATE_ENABLED)) {
@@ -744,16 +780,41 @@ function resetPrefs() {
   if (Services.prefs.prefHasUserValue(PREF_APP_UPDATE_SHOW_INSTALLED_UI)) {
     Services.prefs.clearUserPref(PREF_APP_UPDATE_SHOW_INSTALLED_UI);
   }
 
   if (Services.prefs.prefHasUserValue(PREF_APP_UPDATE_LOG)) {
     Services.prefs.clearUserPref(PREF_APP_UPDATE_LOG);
   }
 
+  if (Services.prefs.prefHasUserValue(PREF_APP_UPDATE_CERT_MAXERRORS)) {
+    Services.prefs.clearUserPref(PREF_APP_UPDATE_CERT_MAXERRORS);
+  }
+
+  if (Services.prefs.prefHasUserValue(PREF_APP_UPDATE_CERT_INVALID_ATTR_NAME)) {
+    Services.prefs.clearUserPref(PREF_APP_UPDATE_CERT_INVALID_ATTR_NAME);
+  }
+
+  if (Services.prefs.prefHasUserValue(PREF_APP_UPDATE_CERT_REQUIREBUILTIN)) {
+    Services.prefs.clearUserPref(PREF_APP_UPDATE_CERT_REQUIREBUILTIN);
+  }
+
+  if (Services.prefs.prefHasUserValue(PREF_APP_UPDATE_CERT_CHECKATTRS)) {
+    Services.prefs.clearUserPref(PREF_APP_UPDATE_CERT_CHECKATTRS);
+  }
+
+  try {
+    CERT_ATTRS.forEach(function(aCertAttrName) {
+      Services.prefs.clearUserPref(PREF_APP_UPDATE_CERTS_BRANCH + "1." +
+                                   aCertAttrName);
+    });
+  }
+  catch (e) {
+  }
+
   try {
     Services.prefs.deleteBranch(PREF_APP_UPDATE_NEVER_BRANCH);
   }
   catch(e) {
   }
 }
 
 /**
@@ -1038,16 +1099,54 @@ function closeUpdateWindow() {
  * @return The nsIDOMWindowInternal for the Update Window if it is open and null
  *         if it isn't.
  */
 function getUpdateWindow() {
   return Services.wm.getMostRecentWindow(UPDATE_WINDOW_NAME);
 }
 
 /**
+ * Helper for certificate attribute check errors.
+ */
+var certErrorsPrefObserver = {
+  /**
+   * Sets up the app.update.cert.errors preference observer and sets the
+   * app.update.cert.maxErrors preference.
+   *
+   * @param  aMaxErrors
+   *         The value to set the app.update.cert.maxErrors preference to.
+   */
+  init: function(aMaxErrors) {
+    let maxErrors = aMaxErrors ? aMaxErrors : 5;
+    Services.prefs.setIntPref(PREF_APP_UPDATE_CERT_MAXERRORS, maxErrors);
+    Services.prefs.addObserver(PREF_APP_UPDATE_CERT_ERRORS, this, false);
+  },
+
+  /**
+   * Preference observer for the app.update.cert.errors preference.
+   */
+  observe: function XPI_observe(aSubject, aTopic, aData) {
+    if (aData == PREF_APP_UPDATE_CERT_ERRORS) {
+      let errCount = Services.prefs.getIntPref(PREF_APP_UPDATE_CERT_ERRORS);
+      let errMax = Services.prefs.getIntPref(PREF_APP_UPDATE_CERT_MAXERRORS);
+      if (errCount >= errMax) {
+        debugDump("prefObserver - removing pref observer");
+        Services.prefs.removeObserver(PREF_APP_UPDATE_CERT_ERRORS, this);
+      }
+      else {
+        debugDump("prefObserver - notifying AUS");
+        SimpleTest.executeSoon(function() {
+          gAUS.notify(null);
+        });
+      }
+    }
+  }
+};
+
+/**
  * nsIObserver for receiving window open and close notifications.
  */
 var gWindowObserver = {
   loaded: false,
 
   observe: function WO_observe(aSubject, aTopic, aData) {
     let win = aSubject.QueryInterface(AUS_Ci.nsIDOMEventTarget);
 
--- a/toolkit/mozapps/update/test/shared.js
+++ b/toolkit/mozapps/update/test/shared.js
@@ -39,33 +39,36 @@
 
 // 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;
 const AUS_Cu = Components.utils;
 
-const PREF_APP_UPDATE_CERTS_BRANCH      = "app.update.certs.";
-const PREF_APP_UPDATE_CHANNEL           = "app.update.channel";
-const PREF_APP_UPDATE_ENABLED           = "app.update.enabled";
-const PREF_APP_UPDATE_IDLETIME          = "app.update.idletime";
-const PREF_APP_UPDATE_LOG               = "app.update.log";
-const PREF_APP_UPDATE_SHOW_INSTALLED_UI = "app.update.showInstalledUI";
-const PREF_APP_UPDATE_URL               = "app.update.url";
-const PREF_APP_UPDATE_URL_DETAILS       = "app.update.url.details";
-const PREF_APP_UPDATE_URL_OVERRIDE      = "app.update.url.override";
+const PREF_APP_UPDATE_CERTS_BRANCH        = "app.update.certs.";
+const PREF_APP_UPDATE_CERT_CHECKATTRS     = "app.update.cert.checkAttributes";
+const PREF_APP_UPDATE_CERT_ERRORS         = "app.update.cert.errors";
+const PREF_APP_UPDATE_CERT_MAXERRORS      = "app.update.cert.maxErrors";
+const PREF_APP_UPDATE_CERT_REQUIREBUILTIN = "app.update.cert.requireBuiltIn";
+const PREF_APP_UPDATE_CHANNEL             = "app.update.channel";
+const PREF_APP_UPDATE_ENABLED             = "app.update.enabled";
+const PREF_APP_UPDATE_IDLETIME            = "app.update.idletime";
+const PREF_APP_UPDATE_LOG                 = "app.update.log";
+const PREF_APP_UPDATE_NEVER_BRANCH        = "app.update.never.";
+const PREF_APP_UPDATE_SHOW_INSTALLED_UI   = "app.update.showInstalledUI";
+const PREF_APP_UPDATE_URL                 = "app.update.url";
+const PREF_APP_UPDATE_URL_DETAILS         = "app.update.url.details";
+const PREF_APP_UPDATE_URL_OVERRIDE        = "app.update.url.override";
 
-const PREF_APP_UPDATE_NEVER_BRANCH      = "app.update.never.";
+const PREF_APP_PARTNER_BRANCH             = "app.partner.";
+const PREF_DISTRIBUTION_ID                = "distribution.id";
+const PREF_DISTRIBUTION_VERSION           = "distribution.version";
 
-const PREF_APP_PARTNER_BRANCH           = "app.partner.";
-const PREF_DISTRIBUTION_ID              = "distribution.id";
-const PREF_DISTRIBUTION_VERSION         = "distribution.version";
-
-const PREF_EXTENSIONS_UPDATE_URL         = "extensions.update.url";
+const PREF_EXTENSIONS_UPDATE_URL          = "extensions.update.url";
 
 const NS_APP_PROFILE_DIR_STARTUP   = "ProfDS";
 const NS_APP_USER_PROFILE_50_DIR   = "ProfD";
 const NS_GRE_DIR                   = "GreD";
 const NS_XPCOM_CURRENT_PROCESS_DIR = "XCurProcD";
 const XRE_UPDATE_ROOT_DIR          = "UpdRootD";
 
 const STATE_NONE            = "null";