1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 // Mac and Windows go to native certificate manager, and certificate manager 6 // isn't implemented if OpenSSL is used. 7 GEN('#if defined(USE_NSS)'); 8 9 /** 10 * TestFixture for certificate manager WebUI testing. 11 * @extends {testing.Test} 12 * @constructor 13 */ 14 function CertificateManagerWebUIBaseTest() {} 15 16 CertificateManagerWebUIBaseTest.prototype = { 17 __proto__: testing.Test.prototype, 18 19 /** 20 * Browse to the certificate manager. 21 */ 22 browsePreload: 'chrome://settings-frame/certificates', 23 24 /** @override */ 25 preLoad: function() { 26 // We can't check cr.isChromeOS in the preLoad since "cr" doesn't exist yet. 27 // This is copied from ui/webui/resources/js/cr.js, maybe 28 // there's a better way to do this. 29 this.isChromeOS = /CrOS/.test(navigator.userAgent); 30 31 this.makeAndRegisterMockHandler( 32 [ 33 'editCaCertificateTrust', 34 'exportPersonalCertificate', 35 'importPersonalCertificate', 36 'importCaCertificate', 37 'exportCertificate', 38 'deleteCertificate', 39 'populateCertificateManager', 40 'viewCertificate', 41 ]); 42 }, 43 }; 44 45 /** 46 * TestFixture for certificate manager WebUI testing. 47 * @extends {CertificateManagerWebUIBaseTest} 48 * @constructor 49 */ 50 function CertificateManagerWebUIUnpopulatedTest() {} 51 52 CertificateManagerWebUIUnpopulatedTest.prototype = { 53 __proto__: CertificateManagerWebUIBaseTest.prototype, 54 55 /** @override */ 56 preLoad: function() { 57 CertificateManagerWebUIBaseTest.prototype.preLoad.call(this); 58 59 // We expect the populateCertificateManager callback, but do not reply to 60 // it. This simulates what will be displayed if retrieving the cert list 61 // from NSS is slow. 62 this.mockHandler.expects(once()).populateCertificateManager(); 63 }, 64 }; 65 66 // Test opening the certificate manager has correct location and buttons have 67 // correct initial states when onPopulateTree has not been called. 68 TEST_F('CertificateManagerWebUIUnpopulatedTest', 69 'testUnpopulatedCertificateManager', function() { 70 assertEquals(this.browsePreload, document.location.href); 71 72 // All buttons should be disabled to start. 73 expectTrue($('personalCertsTab-view').disabled); 74 expectTrue($('personalCertsTab-backup').disabled); 75 expectTrue($('personalCertsTab-delete').disabled); 76 expectTrue($('personalCertsTab-import').disabled); 77 if (this.isChromeOS) 78 expectTrue($('personalCertsTab-import-and-bind').disabled); 79 80 expectTrue($('serverCertsTab-view').disabled); 81 expectTrue($('serverCertsTab-export').disabled); 82 expectTrue($('serverCertsTab-delete').disabled); 83 expectTrue($('serverCertsTab-import').disabled); 84 85 expectTrue($('caCertsTab-view').disabled); 86 expectTrue($('caCertsTab-edit').disabled); 87 expectTrue($('caCertsTab-export').disabled); 88 expectTrue($('caCertsTab-delete').disabled); 89 expectTrue($('caCertsTab-import').disabled); 90 91 expectTrue($('otherCertsTab-view').disabled); 92 expectTrue($('otherCertsTab-export').disabled); 93 expectTrue($('otherCertsTab-delete').disabled); 94 95 Mock4JS.verifyAllMocks(); 96 97 // If user database is not available, import buttons should be disabled. 98 CertificateManager.onModelReady(false /* userDbAvailable*/, 99 false /* tpmAvailable */); 100 101 expectTrue($('personalCertsTab-import').disabled); 102 expectTrue($('serverCertsTab-import').disabled); 103 expectTrue($('caCertsTab-import').disabled); 104 105 // Once we get the onModelReady call, the import buttons should be enabled, 106 // others should still be disabled. 107 CertificateManager.onModelReady(true /* userDbAvailable*/, 108 false /* tpmAvailable */); 109 110 expectTrue($('personalCertsTab-view').disabled); 111 expectTrue($('personalCertsTab-backup').disabled); 112 expectTrue($('personalCertsTab-delete').disabled); 113 expectFalse($('personalCertsTab-import').disabled); 114 115 expectTrue($('serverCertsTab-view').disabled); 116 expectTrue($('serverCertsTab-export').disabled); 117 expectTrue($('serverCertsTab-delete').disabled); 118 expectFalse($('serverCertsTab-import').disabled); 119 120 expectTrue($('caCertsTab-view').disabled); 121 expectTrue($('caCertsTab-edit').disabled); 122 expectTrue($('caCertsTab-export').disabled); 123 expectTrue($('caCertsTab-delete').disabled); 124 expectFalse($('caCertsTab-import').disabled); 125 126 expectTrue($('otherCertsTab-view').disabled); 127 expectTrue($('otherCertsTab-export').disabled); 128 expectTrue($('otherCertsTab-delete').disabled); 129 130 // On ChromeOS, the import and bind button should only be enabled if TPM is 131 // present. 132 if (this.isChromeOS) { 133 expectTrue($('personalCertsTab-import-and-bind').disabled); 134 CertificateManager.onModelReady(true /* userDbAvailable*/, 135 true /* tpmAvailable */); 136 expectFalse($('personalCertsTab-import-and-bind').disabled); 137 } 138 }); 139 140 /** 141 * TestFixture for certificate manager WebUI testing. 142 * @extends {CertificateManagerWebUIBaseTest} 143 * @constructor 144 */ 145 function CertificateManagerWebUITest() {} 146 147 CertificateManagerWebUITest.prototype = { 148 __proto__: CertificateManagerWebUIBaseTest.prototype, 149 150 /** @override */ 151 preLoad: function() { 152 CertificateManagerWebUIBaseTest.prototype.preLoad.call(this); 153 154 var tpmAvailable = this.isChromeOS; 155 var userDbAvailable = true; 156 this.mockHandler.expects(once()).populateCertificateManager().will( 157 callFunction(function() { 158 CertificateManager.onModelReady(userDbAvailable, tpmAvailable); 159 160 [['personalCertsTab-tree', 161 [{'id': 'o1', 162 'name': 'org1', 163 'subnodes': [{ 'id': 'c1', 164 'name': 'cert1', 165 'readonly': false, 166 'untrusted': false, 167 'extractable': true }], 168 }], 169 ], 170 ['caCertsTab-tree', 171 [{'id': 'o2', 172 'name': 'org2', 173 'subnodes': [{ 'id': 'ca_cert0', 174 'name': 'ca_cert0', 175 'readonly': false, 176 'untrusted': false, 177 'extractable': true, 178 'policy': false }, 179 { 'id': 'ca_cert1', 180 'name': 'ca_cert1', 181 'readonly': false, 182 'untrusted': false, 183 'extractable': true, 184 'policy': true }], 185 }], 186 ] 187 ].forEach(CertificateManager.onPopulateTree)})); 188 }, 189 }; 190 191 TEST_F('CertificateManagerWebUITest', 192 'testViewAndDeleteCert', function() { 193 assertEquals(this.browsePreload, document.location.href); 194 195 this.mockHandler.expects(once()).viewCertificate(['c1']); 196 197 expectTrue($('personalCertsTab-view').disabled); 198 expectTrue($('personalCertsTab-backup').disabled); 199 expectTrue($('personalCertsTab-delete').disabled); 200 expectFalse($('personalCertsTab-import').disabled); 201 if (this.isChromeOS) 202 expectFalse($('personalCertsTab-import-and-bind').disabled); 203 204 var personalCerts = $('personalCertsTab'); 205 206 // Click on the first folder. 207 personalCerts.querySelector('div.tree-item').click(); 208 // Buttons should still be in same state. 209 expectTrue($('personalCertsTab-view').disabled); 210 expectTrue($('personalCertsTab-backup').disabled); 211 expectTrue($('personalCertsTab-delete').disabled); 212 expectFalse($('personalCertsTab-import').disabled); 213 if (this.isChromeOS) 214 expectFalse($('personalCertsTab-import-and-bind').disabled); 215 216 // Click on the first cert. 217 personalCerts.querySelector('div.tree-item div.tree-item').click(); 218 // Buttons should now allow you to act on the cert. 219 expectFalse($('personalCertsTab-view').disabled); 220 expectFalse($('personalCertsTab-backup').disabled); 221 expectFalse($('personalCertsTab-delete').disabled); 222 expectFalse($('personalCertsTab-import').disabled); 223 if (this.isChromeOS) 224 expectFalse($('personalCertsTab-import-and-bind').disabled); 225 226 // Click on the view button. 227 $('personalCertsTab-view').click(); 228 229 Mock4JS.verifyAllMocks(); 230 231 this.mockHandler.expects(once()).deleteCertificate(['c1']).will(callFunction( 232 function() { 233 CertificateManager.onPopulateTree(['personalCertsTab-tree', []]); 234 })); 235 236 // Click on the delete button. 237 $('personalCertsTab-delete').click(); 238 // Click on the ok button in the confirmation overlay. 239 $('alertOverlayOk').click(); 240 241 // Context sensitive buttons should be disabled. 242 expectTrue($('personalCertsTab-view').disabled); 243 expectTrue($('personalCertsTab-backup').disabled); 244 expectTrue($('personalCertsTab-delete').disabled); 245 expectFalse($('personalCertsTab-import').disabled); 246 if (this.isChromeOS) 247 expectFalse($('personalCertsTab-import-and-bind').disabled); 248 // Tree should be empty. 249 expectTrue(personalCerts.querySelector('div.tree-item') === null); 250 }); 251 252 // Ensure certificate objects with the 'policy' property set have 253 // the cert-policy CSS class appended. 254 TEST_F('CertificateManagerWebUITest', 255 'testPolicyInstalledCertificate', function() { 256 // Click on the first folder and get the certificates. 257 var caCertsTab = $('caCertsTab'); 258 caCertsTab.querySelector('div.tree-item').click(); 259 var certs = caCertsTab.querySelectorAll('div.tree-item div.tree-item'); 260 261 // First cert shouldn't show the controlled setting badge, and the 262 // edit and delete buttons should be enabled. 263 var cert0 = certs[0]; 264 expectEquals('ca_cert0', cert0.data.name); 265 expectEquals(null, cert0.querySelector('.cert-policy')); 266 cert0.click(); 267 expectFalse($('caCertsTab-edit').disabled); 268 expectFalse($('caCertsTab-delete').disabled); 269 270 // But the second should show the controlled setting badge, and the 271 // edit and delete buttons should be disabled. 272 var cert1 = certs[1]; 273 expectEquals('ca_cert1', cert1.data.name); 274 expectNotEquals(null, cert1.querySelector('.cert-policy')); 275 cert1.click(); 276 expectTrue($('caCertsTab-edit').disabled); 277 expectTrue($('caCertsTab-delete').disabled); 278 }); 279 280 GEN('#endif // defined(USE_NSS)'); 281