1// Copyright 2013 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 5GEN('#include "chrome/browser/ui/webui/identity_internals_ui_browsertest.h"'); 6 7/** 8 * Test C++ fixture for downloads WebUI testing. 9 * @constructor 10 * @extends {testing.Test} 11 */ 12function IdentityInternalsUIBrowserTest() {} 13 14/** 15 * Base fixture for Downloads WebUI testing. 16 * @extends {testing.Test} 17 * @constructor 18 */ 19function BaseIdentityInternalsWebUITest() {} 20 21BaseIdentityInternalsWebUITest.prototype = { 22 __proto__: testing.Test.prototype, 23 24 /** 25 * Browse to the downloads page & call our preLoad(). 26 */ 27 browsePreload: 'chrome://identity-internals', 28 29 /** @override */ 30 typedefCppFixture: 'IdentityInternalsUIBrowserTest', 31 32 /** 33 * Gets all of the token entries on the page. 34 * @return {!NodeList} Elements displaying token information. 35 */ 36 getTokens: function() { 37 return document.querySelectorAll('#token-list > div'); 38 }, 39 40 /** 41 * Gets the expiration time displayed on the page for a given entry. 42 * @param {Element} tokenEntry Display element holding token information. 43 * @return {Date} Expiration date of the token. 44 */ 45 getExpirationTime: function(tokenEntry) { 46 // Full-date format has 'at' between date and time in en-US, but 47 // ECMAScript's Date.parse cannot grok it. 48 return Date.parse(tokenEntry.querySelector('.expiration-time') 49 .innerText.replace(' at ', ' ')); 50 }, 51 52 /** 53 * Gets the extension id displayed on the page for a given entry. 54 * @param {Element} tokenEntry Display element holding token information. 55 * @return {string} Extension Id of the token. 56 */ 57 getExtensionId: function(tokenEntry) { 58 return tokenEntry.querySelector('.extension-id').innerText; 59 }, 60 61 /** 62 * Gets the extension name displayed on the page for a given entry. 63 * @param {Element} tokenEntry Display element holding token information. 64 * @return {string} Extension Name of the token. 65 */ 66 getExtensionName: function(tokenEntry) { 67 return tokenEntry.querySelector('.extension-name').innerText; 68 }, 69 70 /** 71 * Gets the revoke button of the token entry. 72 * @param {Element} tokenEntry Diplsy element holding token information. 73 * @return {HTMLButtonElement} Revoke button belonging related to the token. 74 */ 75 getRevokeButton: function(tokenEntry) { 76 return tokenEntry.querySelector('.revoke-button'); 77 }, 78 79 /** 80 * Gets the token ID displayed on the page for a given entry. 81 * @param {Element} tokenEntry Display element holding token information. 82 * @return {string} Token ID of the token. 83 */ 84 getAccessToken: function(tokenEntry) { 85 return tokenEntry.querySelector('.access-token').innerText; 86 }, 87 88 /** 89 * Gets the token status displayed on the page for a given entry. 90 * @param {Element} tokenEntry Display element holding token information. 91 * @return {string} Token status of the token. 92 */ 93 getTokenStatus: function(tokenEntry) { 94 return tokenEntry.querySelector('.token-status').innerText; 95 }, 96 97 /** 98 * Gets the token scopes displayed on the page for a given entry. 99 * @param {Element} tokenEntry Display element holding token information. 100 * @return {string[]} Token scopes of the token. 101 */ 102 getScopes: function(tokenEntry) { 103 return tokenEntry.querySelector('.scope-list') 104 .innerHTML.split('<br>'); 105 }, 106}; 107 108// Test verifying chrome://identity-internals Web UI when the token cache is 109// empty. 110TEST_F('BaseIdentityInternalsWebUITest', 'emptyTokenCache', function() { 111 var tokenListEntries = this.getTokens(); 112 expectEquals(0, tokenListEntries.length); 113}); 114 115/** 116 * Fixture for Identity Internals Web UI testing with a single token in the 117 * Identity API token cache. 118 * @extends {BaseIdentityInternalsWebUITest} 119 * @constructor 120 */ 121function IdentityInternalsSingleTokenWebUITest() {} 122 123IdentityInternalsSingleTokenWebUITest.prototype = { 124 __proto__: BaseIdentityInternalsWebUITest.prototype, 125 126 /** @override */ 127 testGenPreamble: function() { 128 GEN(' SetupTokenCacheWithStoreApp();'); 129 }, 130}; 131 132// Test for listing a token cache with a single token. It uses a known extension 133// - the Chrome Web Store, in order to check the extension name. 134TEST_F('IdentityInternalsSingleTokenWebUITest', 'getAllTokens', function() { 135 var tokenListEntries = this.getTokens(); 136 expectEquals(1, tokenListEntries.length); 137 expectEquals('Web Store', this.getExtensionName(tokenListEntries[0])); 138 expectEquals('ahfgeienlihckogmohjhadlkjgocpleb', 139 this.getExtensionId(tokenListEntries[0])); 140 expectEquals('store_token', this.getAccessToken(tokenListEntries[0])); 141 expectEquals('Token Present', this.getTokenStatus(tokenListEntries[0])); 142 expectLT(this.getExpirationTime(tokenListEntries[0]) - new Date(), 143 3600 * 1000); 144 var scopes = this.getScopes(tokenListEntries[0]); 145 expectEquals(3, scopes.length); 146 expectEquals('store_scope1', scopes[0]); 147 expectEquals('store_scope2', scopes[1]); 148 expectEquals('', scopes[2]); 149}); 150 151// Test ensuring the getters on the BaseIdentityInternalsWebUITest work 152// correctly. They are implemented on the child class, because the parent does 153// not have any tokens to display. 154TEST_F('IdentityInternalsSingleTokenWebUITest', 'verifyGetters', function() { 155 var tokenListEntries = document.querySelectorAll('#token-list > div'); 156 var actualTokens = this.getTokens(); 157 expectEquals(tokenListEntries.length, actualTokens.length); 158 expectEquals(tokenListEntries[0], actualTokens[0]); 159 expectEquals(this.getExtensionName(tokenListEntries[0]), 160 tokenListEntries[0].querySelector('.extension-name').innerText); 161 expectEquals(this.getExtensionId(tokenListEntries[0]), 162 tokenListEntries[0].querySelector('.extension-id').innerText); 163 expectEquals(this.getAccessToken(tokenListEntries[0]), 164 tokenListEntries[0].querySelector('.access-token').innerText); 165 expectEquals(this.getTokenStatus(tokenListEntries[0]), 166 tokenListEntries[0].querySelector('.token-status').innerText); 167 // Full-date format has 'at' between date and time in en-US, but 168 // ECMAScript's Date.parse cannot grok it. 169 expectEquals(this.getExpirationTime(tokenListEntries[0]), 170 Date.parse(tokenListEntries[0].querySelector('.expiration-time') 171 .innerText.replace(' at ', ' '))); 172 var scopes = tokenListEntries[0].querySelector('.scope-list') 173 .innerHTML.split('<br>'); 174 var actualScopes = this.getScopes(tokenListEntries[0]); 175 expectEquals(scopes.length, actualScopes.length); 176 for (var i = 0; i < scopes.length; i++) { 177 expectEquals(scopes[i], actualScopes[i]); 178 } 179}); 180 181/** 182 * Fixture for Identity Internals Web UI testing with multiple tokens in the 183 * Identity API token cache. 184 * @extends {BaseIdentityInternalsWebUITest} 185 * @constructor 186 */ 187function IdentityInternalsMultipleTokensWebUITest() {} 188 189IdentityInternalsMultipleTokensWebUITest.prototype = { 190 __proto__: BaseIdentityInternalsWebUITest.prototype, 191 192 /** @override */ 193 testGenPreamble: function() { 194 GEN(' SetupTokenCache(2);'); 195 }, 196}; 197 198// Test for listing a token cache with multiple tokens. Names of the extensions 199// are empty, because extensions are faked, and not present in the extension 200// service. 201TEST_F('IdentityInternalsMultipleTokensWebUITest', 'getAllTokens', function() { 202 var tokenListEntries = this.getTokens(); 203 expectEquals(2, tokenListEntries.length); 204 expectEquals('', this.getExtensionName(tokenListEntries[0])); 205 expectEquals('extension0', 206 this.getExtensionId(tokenListEntries[0])); 207 expectEquals('token0', this.getAccessToken(tokenListEntries[0])); 208 expectEquals('Token Present', this.getTokenStatus(tokenListEntries[0])); 209 expectLT(this.getExpirationTime(tokenListEntries[0]) - new Date(), 210 3600 * 1000); 211 var scopes = this.getScopes(tokenListEntries[0]); 212 expectEquals(3, scopes.length); 213 expectEquals('scope_1_0', scopes[0]); 214 expectEquals('scope_2_0', scopes[1]); 215 expectEquals('', scopes[2]); 216 expectEquals('', this.getExtensionName(tokenListEntries[1])); 217 expectEquals('extension1', 218 this.getExtensionId(tokenListEntries[1])); 219 expectEquals('token1', this.getAccessToken(tokenListEntries[1])); 220 expectEquals('Token Present', this.getTokenStatus(tokenListEntries[1])); 221 expectLT(this.getExpirationTime(tokenListEntries[1]) - new Date(), 222 3600 * 1000); 223 var scopes = this.getScopes(tokenListEntries[1]); 224 expectEquals(3, scopes.length); 225 expectEquals('scope_1_1', scopes[0]); 226 expectEquals('scope_2_1', scopes[1]); 227 expectEquals('', scopes[2]); 228}); 229 230/** 231 * Fixture for asynchronous testing of Identity Internals Web UI with multiple 232 * tokens in Identity API token cache. 233 * @extends {IdentityInternalsMultipleTokensWebUITest} 234 * @constructor 235 */ 236function IdentityInternalsWebUITestAsync() {} 237 238IdentityInternalsWebUITestAsync.prototype = { 239 __proto__: IdentityInternalsMultipleTokensWebUITest.prototype, 240 241 /** @override */ 242 isAsync: true, 243}; 244 245TEST_F('IdentityInternalsWebUITestAsync', 'revokeToken', function() { 246 var tokenListBefore = this.getTokens(); 247 expectEquals(2, tokenListBefore.length); 248 var tokenRevokeDone = identity_internals.tokenRevokeDone; 249 identity_internals.tokenRevokeDone = this.continueTest( 250 WhenTestDone.ALWAYS, function(accessTokens) { 251 tokenRevokeDone.call(identity_internals, accessTokens); 252 identity_internals.tokenRevokeDone = tokenRevokeDone; 253 var tokenListAfter = this.getTokens(); 254 expectEquals(1, tokenListAfter.length); 255 expectEquals(this.getAccessToken(tokenListBefore[0]), 256 this.getAccessToken(tokenListAfter[0])); 257 }.bind(this)); 258 this.getRevokeButton(tokenListBefore[1]).click(); 259}); 260 261