Mercurial > hg > cmmr2012-drupal-site
comparison core/modules/toolbar/tests/src/Functional/ToolbarAdminMenuTest.php @ 0:c75dbcec494b
Initial commit from drush-created site
author | Chris Cannam |
---|---|
date | Thu, 05 Jul 2018 14:24:15 +0000 |
parents | |
children | 12f9dff5fda9 |
comparison
equal
deleted
inserted
replaced
-1:000000000000 | 0:c75dbcec494b |
---|---|
1 <?php | |
2 | |
3 namespace Drupal\Tests\toolbar\Functional; | |
4 | |
5 use Drupal\Core\EventSubscriber\MainContentViewSubscriber; | |
6 use Drupal\Core\Language\LanguageInterface; | |
7 use Drupal\Core\Url; | |
8 use Drupal\language\Entity\ConfigurableLanguage; | |
9 use Drupal\Tests\BrowserTestBase; | |
10 use Drupal\user\RoleInterface; | |
11 | |
12 /** | |
13 * Tests the caching of the admin menu subtree items. | |
14 * | |
15 * The cache of the admin menu subtree items will be invalidated if the | |
16 * following hooks are invoked. | |
17 * | |
18 * toolbar_modules_enabled() | |
19 * toolbar_modules_disabled() | |
20 * toolbar_menu_link_update() | |
21 * toolbar_user_update() | |
22 * toolbar_user_role_update() | |
23 * | |
24 * Each hook invocation is simulated and then the previous hash of the admin | |
25 * menu subtrees is compared to the new hash. | |
26 * | |
27 * @group toolbar | |
28 */ | |
29 class ToolbarAdminMenuTest extends BrowserTestBase { | |
30 | |
31 /** | |
32 * A user with permission to access the administrative toolbar. | |
33 * | |
34 * @var \Drupal\user\UserInterface | |
35 */ | |
36 protected $adminUser; | |
37 | |
38 /** | |
39 * A second user with permission to access the administrative toolbar. | |
40 * | |
41 * @var \Drupal\user\UserInterface | |
42 */ | |
43 protected $adminUser2; | |
44 | |
45 /** | |
46 * The current admin menu subtrees hash for adminUser. | |
47 * | |
48 * @var string | |
49 */ | |
50 protected $hash; | |
51 | |
52 /** | |
53 * Modules to enable. | |
54 * | |
55 * @var array | |
56 */ | |
57 public static $modules = ['node', 'block', 'menu_ui', 'user', 'taxonomy', 'toolbar', 'language', 'test_page_test', 'locale']; | |
58 | |
59 protected function setUp() { | |
60 parent::setUp(); | |
61 | |
62 $perms = [ | |
63 'access toolbar', | |
64 'access administration pages', | |
65 'administer site configuration', | |
66 'bypass node access', | |
67 'administer themes', | |
68 'administer nodes', | |
69 'access content overview', | |
70 'administer blocks', | |
71 'administer menu', | |
72 'administer modules', | |
73 'administer permissions', | |
74 'administer users', | |
75 'access user profiles', | |
76 'administer taxonomy', | |
77 'administer languages', | |
78 'translate interface', | |
79 ]; | |
80 | |
81 // Create an administrative user and log it in. | |
82 $this->adminUser = $this->drupalCreateUser($perms); | |
83 $this->adminUser2 = $this->drupalCreateUser($perms); | |
84 | |
85 $this->drupalLogin($this->adminUser); | |
86 | |
87 $this->drupalGet('test-page'); | |
88 $this->assertResponse(200); | |
89 | |
90 // Assert that the toolbar is present in the HTML. | |
91 $this->assertRaw('id="toolbar-administration"'); | |
92 | |
93 // Store the adminUser admin menu subtrees hash for comparison later. | |
94 $this->hash = $this->getSubtreesHash(); | |
95 } | |
96 | |
97 /** | |
98 * Tests the toolbar_modules_installed() and toolbar_modules_uninstalled() hook | |
99 * implementations. | |
100 */ | |
101 public function testModuleStatusChangeSubtreesHashCacheClear() { | |
102 // Uninstall a module. | |
103 $edit = []; | |
104 $edit['uninstall[taxonomy]'] = TRUE; | |
105 $this->drupalPostForm('admin/modules/uninstall', $edit, t('Uninstall')); | |
106 // Confirm the uninstall form. | |
107 $this->drupalPostForm(NULL, [], t('Uninstall')); | |
108 $this->rebuildContainer(); | |
109 | |
110 // Assert that the subtrees hash has been altered because the subtrees | |
111 // structure changed. | |
112 $this->assertDifferentHash(); | |
113 | |
114 // Enable a module. | |
115 $edit = []; | |
116 $edit['modules[taxonomy][enable]'] = TRUE; | |
117 $this->drupalPostForm('admin/modules', $edit, t('Install')); | |
118 $this->rebuildContainer(); | |
119 | |
120 // Assert that the subtrees hash has been altered because the subtrees | |
121 // structure changed. | |
122 $this->assertDifferentHash(); | |
123 } | |
124 | |
125 /** | |
126 * Tests toolbar cache tags implementation. | |
127 */ | |
128 public function testMenuLinkUpdateSubtreesHashCacheClear() { | |
129 // The ID of a (any) admin menu link. | |
130 $admin_menu_link_id = 'system.admin_config_development'; | |
131 | |
132 // Disable the link. | |
133 $edit = []; | |
134 $edit['enabled'] = FALSE; | |
135 $this->drupalPostForm("admin/structure/menu/link/" . $admin_menu_link_id . "/edit", $edit, t('Save')); | |
136 $this->assertResponse(200); | |
137 $this->assertText('The menu link has been saved.'); | |
138 | |
139 // Assert that the subtrees hash has been altered because the subtrees | |
140 // structure changed. | |
141 $this->assertDifferentHash(); | |
142 } | |
143 | |
144 /** | |
145 * Exercises the toolbar_user_role_update() and toolbar_user_update() hook | |
146 * implementations. | |
147 */ | |
148 public function testUserRoleUpdateSubtreesHashCacheClear() { | |
149 // Find the new role ID. | |
150 $all_rids = $this->adminUser->getRoles(); | |
151 unset($all_rids[array_search(RoleInterface::AUTHENTICATED_ID, $all_rids)]); | |
152 $rid = reset($all_rids); | |
153 | |
154 $edit = []; | |
155 $edit[$rid . '[administer taxonomy]'] = FALSE; | |
156 $this->drupalPostForm('admin/people/permissions', $edit, t('Save permissions')); | |
157 | |
158 // Assert that the subtrees hash has been altered because the subtrees | |
159 // structure changed. | |
160 $this->assertDifferentHash(); | |
161 | |
162 // Test that assigning a user an extra role only affects that single user. | |
163 // Get the hash for a second user. | |
164 $this->drupalLogin($this->adminUser2); | |
165 $this->drupalGet('test-page'); | |
166 $this->assertResponse(200); | |
167 | |
168 // Assert that the toolbar is present in the HTML. | |
169 $this->assertRaw('id="toolbar-administration"'); | |
170 | |
171 $admin_user_2_hash = $this->getSubtreesHash(); | |
172 | |
173 // Log in the first admin user again. | |
174 $this->drupalLogin($this->adminUser); | |
175 $this->drupalGet('test-page'); | |
176 $this->assertResponse(200); | |
177 | |
178 // Assert that the toolbar is present in the HTML. | |
179 $this->assertRaw('id="toolbar-administration"'); | |
180 | |
181 $this->hash = $this->getSubtreesHash(); | |
182 | |
183 $rid = $this->drupalCreateRole(['administer content types']); | |
184 | |
185 // Assign the role to the user. | |
186 $this->drupalPostForm('user/' . $this->adminUser->id() . '/edit', ["roles[$rid]" => $rid], t('Save')); | |
187 $this->assertText(t('The changes have been saved.')); | |
188 | |
189 // Assert that the subtrees hash has been altered because the subtrees | |
190 // structure changed. | |
191 $this->assertDifferentHash(); | |
192 | |
193 // Log in the second user again and assert that their subtrees hash did not | |
194 // change. | |
195 $this->drupalLogin($this->adminUser2); | |
196 | |
197 // Request a new page to refresh the drupalSettings object. | |
198 $this->drupalGet('test-page'); | |
199 $this->assertResponse(200); | |
200 $new_subtree_hash = $this->getSubtreesHash(); | |
201 | |
202 // Assert that the old admin menu subtree hash and the new admin menu | |
203 // subtree hash are the same. | |
204 $this->assertTrue($new_subtree_hash, 'A valid hash value for the admin menu subtrees was created.'); | |
205 $this->assertEqual($admin_user_2_hash, $new_subtree_hash, 'The user-specific subtree menu hash has not been updated.'); | |
206 } | |
207 | |
208 /** | |
209 * Tests that changes to a user account by another user clears the changed | |
210 * account's toolbar cached, not the user's who took the action. | |
211 */ | |
212 public function testNonCurrentUserAccountUpdates() { | |
213 $admin_user_id = $this->adminUser->id(); | |
214 $this->hash = $this->getSubtreesHash(); | |
215 | |
216 // adminUser2 will add a role to adminUser. | |
217 $this->drupalLogin($this->adminUser2); | |
218 $rid = $this->drupalCreateRole(['administer content types']); | |
219 | |
220 // Get the subtree hash for adminUser2 to check later that it has not | |
221 // changed. Request a new page to refresh the drupalSettings object. | |
222 $this->drupalGet('test-page'); | |
223 $this->assertResponse(200); | |
224 $admin_user_2_hash = $this->getSubtreesHash(); | |
225 | |
226 // Assign the role to the user. | |
227 $this->drupalPostForm('user/' . $admin_user_id . '/edit', ["roles[$rid]" => $rid], t('Save')); | |
228 $this->assertText(t('The changes have been saved.')); | |
229 | |
230 // Log in adminUser and assert that the subtrees hash has changed. | |
231 $this->drupalLogin($this->adminUser); | |
232 $this->assertDifferentHash(); | |
233 | |
234 // Log in adminUser2 to check that its subtrees hash has not changed. | |
235 $this->drupalLogin($this->adminUser2); | |
236 $new_subtree_hash = $this->getSubtreesHash(); | |
237 | |
238 // Assert that the old adminUser subtree hash and the new adminUser | |
239 // subtree hash are the same. | |
240 $this->assertTrue($new_subtree_hash, 'A valid hash value for the admin menu subtrees was created.'); | |
241 $this->assertEqual($admin_user_2_hash, $new_subtree_hash, 'The user-specific subtree menu hash has not been updated.'); | |
242 } | |
243 | |
244 /** | |
245 * Tests that toolbar cache is cleared when string translations are made. | |
246 */ | |
247 public function testLocaleTranslationSubtreesHashCacheClear() { | |
248 $admin_user = $this->adminUser; | |
249 // User to translate and delete string. | |
250 $translate_user = $this->drupalCreateUser(['translate interface', 'access administration pages']); | |
251 | |
252 // Create a new language with the langcode 'xx'. | |
253 $langcode = 'xx'; | |
254 // The English name for the language. This will be translated. | |
255 $name = $this->randomMachineName(16); | |
256 // This will be the translation of $name. | |
257 $translation = $this->randomMachineName(16); | |
258 | |
259 // Add custom language. | |
260 $this->drupalLogin($admin_user); | |
261 $edit = [ | |
262 'predefined_langcode' => 'custom', | |
263 'langcode' => $langcode, | |
264 'label' => $name, | |
265 'direction' => LanguageInterface::DIRECTION_LTR, | |
266 ]; | |
267 $this->drupalPostForm('admin/config/regional/language/add', $edit, t('Add custom language')); | |
268 t($name, [], ['langcode' => $langcode]); | |
269 // Reset locale cache. | |
270 $this->container->get('string_translation')->reset(); | |
271 $this->assertRaw('"edit-languages-' . $langcode . '-weight"', 'Language code found.'); | |
272 $this->assertText(t($name), 'Test language added.'); | |
273 | |
274 // Have the adminUser request a page in the new language. | |
275 $this->drupalGet($langcode . '/test-page'); | |
276 $this->assertResponse(200); | |
277 | |
278 // Get a baseline hash for the admin menu subtrees before translating one | |
279 // of the menu link items. | |
280 $original_subtree_hash = $this->getSubtreesHash(); | |
281 $this->assertTrue($original_subtree_hash, 'A valid hash value for the admin menu subtrees was created.'); | |
282 $this->drupalLogout(); | |
283 | |
284 // Translate the string 'Search and metadata' in the xx language. This | |
285 // string appears in a link in the admin menu subtrees. Changing the string | |
286 // should create a new menu hash if the toolbar subtrees cache is correctly | |
287 // invalidated. | |
288 $this->drupalLogin($translate_user); | |
289 $search = [ | |
290 'string' => 'Search and metadata', | |
291 'langcode' => $langcode, | |
292 'translation' => 'untranslated', | |
293 ]; | |
294 $this->drupalPostForm('admin/config/regional/translate', $search, t('Filter')); | |
295 $this->assertNoText(t('No strings available')); | |
296 $this->assertText($name, 'Search found the string as untranslated.'); | |
297 | |
298 // Assume this is the only result. | |
299 // Translate the string to a random string. | |
300 $textarea = current($this->xpath('//textarea')); | |
301 $lid = (string) $textarea->getAttribute('name'); | |
302 $edit = [ | |
303 $lid => $translation, | |
304 ]; | |
305 $this->drupalPostForm('admin/config/regional/translate', $edit, t('Save translations')); | |
306 $this->assertText(t('The strings have been saved.'), 'The strings have been saved.'); | |
307 $this->assertUrl(\Drupal::url('locale.translate_page', [], ['absolute' => TRUE]), [], 'Correct page redirection.'); | |
308 $this->drupalLogout(); | |
309 | |
310 // Log in the adminUser. Check the admin menu subtrees hash now that one | |
311 // of the link items in the Structure tree (Menus) has had its text | |
312 // translated. | |
313 $this->drupalLogin($admin_user); | |
314 // Have the adminUser request a page in the new language. | |
315 $this->drupalGet($langcode . '/test-page'); | |
316 $this->assertResponse(200); | |
317 $new_subtree_hash = $this->getSubtreesHash(); | |
318 | |
319 // Assert that the old admin menu subtrees hash and the new admin menu | |
320 // subtrees hash are different. | |
321 $this->assertTrue($new_subtree_hash, 'A valid hash value for the admin menu subtrees was created.'); | |
322 $this->assertNotEqual($original_subtree_hash, $new_subtree_hash, 'The user-specific subtree menu hash has been updated.'); | |
323 } | |
324 | |
325 /** | |
326 * Tests that the 'toolbar/subtrees/{hash}' is reachable and correct. | |
327 */ | |
328 public function testSubtreesJsonRequest() { | |
329 $admin_user = $this->adminUser; | |
330 $this->drupalLogin($admin_user); | |
331 // Request a new page to refresh the drupalSettings object. | |
332 $subtrees_hash = $this->getSubtreesHash(); | |
333 | |
334 $this->drupalGet('toolbar/subtrees/' . $subtrees_hash, ['query' => [MainContentViewSubscriber::WRAPPER_FORMAT => 'drupal_ajax']], ['X-Requested-With: XMLHttpRequest']); | |
335 $ajax_result = json_decode($this->getSession()->getPage()->getContent(), TRUE); | |
336 $this->assertEqual($ajax_result[0]['command'], 'setToolbarSubtrees', 'Subtrees response uses the correct command.'); | |
337 $this->assertEqual(array_keys($ajax_result[0]['subtrees']), ['system-admin_content', 'system-admin_structure', 'system-themes_page', 'system-modules_list', 'system-admin_config', 'entity-user-collection', 'front'], 'Correct subtrees returned.'); | |
338 } | |
339 | |
340 /** | |
341 * Test that subtrees hashes vary by the language of the page. | |
342 */ | |
343 public function testLanguageSwitching() { | |
344 // Create a new language with the langcode 'xx'. | |
345 $langcode = 'xx'; | |
346 $language = ConfigurableLanguage::createFromLangcode($langcode); | |
347 $language->save(); | |
348 // The language path processor is just registered for more than one | |
349 // configured language, so rebuild the container now that we are | |
350 // multilingual. | |
351 $this->rebuildContainer(); | |
352 | |
353 // Get a page with the new language langcode in the URL. | |
354 $this->drupalGet('test-page', ['language' => $language]); | |
355 // Assert different hash. | |
356 $new_subtree_hash = $this->getSubtreesHash(); | |
357 | |
358 // Assert that the old admin menu subtree hash and the new admin menu | |
359 // subtree hash are different. | |
360 $this->assertTrue($new_subtree_hash, 'A valid hash value for the admin menu subtrees was created.'); | |
361 $this->assertNotEqual($this->hash, $new_subtree_hash, 'The user-specific subtree menu hash has been updated.'); | |
362 } | |
363 | |
364 /** | |
365 * Test that back to site link exists on admin pages, not on content pages. | |
366 */ | |
367 public function testBackToSiteLink() { | |
368 // Back to site link should exist in the markup. | |
369 $this->drupalGet('test-page'); | |
370 $back_link = $this->cssSelect('.home-toolbar-tab'); | |
371 $this->assertTrue($back_link); | |
372 } | |
373 | |
374 /** | |
375 * Tests that external links added to the menu appear in the toolbar. | |
376 */ | |
377 public function testExternalLink() { | |
378 $edit = [ | |
379 'title[0][value]' => 'External URL', | |
380 'link[0][uri]' => 'http://example.org', | |
381 'menu_parent' => 'admin:system.admin', | |
382 'description[0][value]' => 'External URL & escaped', | |
383 ]; | |
384 $this->drupalPostForm('admin/structure/menu/manage/admin/add', $edit, 'Save'); | |
385 | |
386 // Assert that the new menu link is shown on the menu link listing. | |
387 $this->drupalGet('admin/structure/menu/manage/admin'); | |
388 $this->assertText('External URL'); | |
389 | |
390 // Assert that the new menu link is shown in the toolbar on a regular page. | |
391 $this->drupalGet(Url::fromRoute('<front>')); | |
392 $this->assertText('External URL'); | |
393 // Ensure the description is escaped as expected. | |
394 $this->assertRaw('title="External URL & escaped"'); | |
395 } | |
396 | |
397 /** | |
398 * Get the hash value from the admin menu subtrees route path. | |
399 * | |
400 * @return string | |
401 * The hash value from the admin menu subtrees route path. | |
402 */ | |
403 private function getSubtreesHash() { | |
404 $settings = $this->getDrupalSettings(); | |
405 // The toolbar module defines a route '/toolbar/subtrees/{hash}' that | |
406 // returns JSON for the rendered subtrees. This hash is provided to the | |
407 // client in drupalSettings. | |
408 return $settings['toolbar']['subtreesHash']; | |
409 } | |
410 | |
411 /** | |
412 * Asserts the subtrees hash on a fresh page GET is different from the hash | |
413 * from the previous page GET. | |
414 */ | |
415 private function assertDifferentHash() { | |
416 // Request a new page to refresh the drupalSettings object. | |
417 $this->drupalGet('test-page'); | |
418 $this->assertResponse(200); | |
419 $new_subtree_hash = $this->getSubtreesHash(); | |
420 | |
421 // Assert that the old admin menu subtree hash and the new admin menu | |
422 // subtree hash are different. | |
423 $this->assertTrue($new_subtree_hash, 'A valid hash value for the admin menu subtrees was created.'); | |
424 $this->assertNotEqual($this->hash, $new_subtree_hash, 'The user-specific subtree menu hash has been updated.'); | |
425 | |
426 // Save the new subtree hash as the original. | |
427 $this->hash = $new_subtree_hash; | |
428 } | |
429 | |
430 } |