PageRenderTime 34ms CodeModel.GetById 10ms RepoModel.GetById 0ms app.codeStats 0ms

/core/modules/shortcut/src/Tests/ShortcutLinksTest.php

http://github.com/drupal/drupal
PHP | 407 lines | 251 code | 56 blank | 100 comment | 2 complexity | b50da73b7bc234f49d6c03bda0165500 MD5 | raw file
Possible License(s): GPL-2.0, LGPL-2.1
  1. <?php
  2. namespace Drupal\shortcut\Tests;
  3. use Drupal\Component\Utility\SafeMarkup;
  4. use Drupal\Core\Url;
  5. use Drupal\shortcut\Entity\Shortcut;
  6. use Drupal\shortcut\Entity\ShortcutSet;
  7. use Drupal\views\Entity\View;
  8. /**
  9. * Create, view, edit, delete, and change shortcut links.
  10. *
  11. * @group shortcut
  12. */
  13. class ShortcutLinksTest extends ShortcutTestBase {
  14. /**
  15. * Modules to enable.
  16. *
  17. * @var array
  18. */
  19. public static $modules = array('router_test', 'views', 'block');
  20. /**
  21. * {@inheritdoc}
  22. */
  23. protected function setUp() {
  24. parent::setUp();
  25. $this->drupalPlaceBlock('page_title_block');
  26. }
  27. /**
  28. * Tests that creating a shortcut works properly.
  29. */
  30. public function testShortcutLinkAdd() {
  31. $set = $this->set;
  32. // Create an alias for the node so we can test aliases.
  33. $path = array(
  34. 'source' => '/node/' . $this->node->id(),
  35. 'alias' => '/' . $this->randomMachineName(8),
  36. );
  37. $this->container->get('path.alias_storage')->save($path['source'], $path['alias']);
  38. // Create some paths to test.
  39. $test_cases = [
  40. '/',
  41. '/admin',
  42. '/admin/config/system/site-information',
  43. '/node/' . $this->node->id() . '/edit',
  44. $path['alias'],
  45. '/router_test/test2',
  46. '/router_test/test3/value',
  47. ];
  48. $test_cases_non_access = [
  49. '/admin',
  50. '/admin/config/system/site-information',
  51. ];
  52. // Check that each new shortcut links where it should.
  53. foreach ($test_cases as $test_path) {
  54. $title = $this->randomMachineName();
  55. $form_data = array(
  56. 'title[0][value]' => $title,
  57. 'link[0][uri]' => $test_path,
  58. );
  59. $this->drupalPostForm('admin/config/user-interface/shortcut/manage/' . $set->id() . '/add-link', $form_data, t('Save'));
  60. $this->assertResponse(200);
  61. $this->assertText(t('Added a shortcut for @title.', array('@title' => $title)));
  62. $saved_set = ShortcutSet::load($set->id());
  63. $paths = $this->getShortcutInformation($saved_set, 'link');
  64. $this->assertTrue(in_array('internal:' . $test_path, $paths), 'Shortcut created: ' . $test_path);
  65. if (in_array($test_path, $test_cases_non_access)) {
  66. $this->assertNoLink($title, SafeMarkup::format('Shortcut link %url not accessible on the page.', ['%url' => $test_path]));
  67. }
  68. else {
  69. $this->assertLink($title, 0, SafeMarkup::format('Shortcut link %url found on the page.', ['%url' => $test_path]));
  70. }
  71. }
  72. $saved_set = ShortcutSet::load($set->id());
  73. // Test that saving and re-loading a shortcut preserves its values.
  74. $shortcuts = $saved_set->getShortcuts();
  75. foreach ($shortcuts as $entity) {
  76. // Test the node routes with parameters.
  77. $entity->save();
  78. $loaded = Shortcut::load($entity->id());
  79. $this->assertEqual($entity->link->uri, $loaded->link->uri);
  80. $this->assertEqual($entity->link->options, $loaded->link->options);
  81. }
  82. // Log in as non admin user, to check that access is checked when creating
  83. // shortcuts.
  84. $this->drupalLogin($this->shortcutUser);
  85. $title = $this->randomMachineName();
  86. $form_data = [
  87. 'title[0][value]' => $title,
  88. 'link[0][uri]' => '/admin',
  89. ];
  90. $this->drupalPostForm('admin/config/user-interface/shortcut/manage/' . $set->id() . '/add-link', $form_data, t('Save'));
  91. $this->assertResponse(200);
  92. $this->assertRaw(t("The path '@link_path' is inaccessible.", ['@link_path' => '/admin']));
  93. $form_data = [
  94. 'title[0][value]' => $title,
  95. 'link[0][uri]' => '/node',
  96. ];
  97. $this->drupalPostForm('admin/config/user-interface/shortcut/manage/' . $set->id() . '/add-link', $form_data, t('Save'));
  98. $this->assertLink($title, 0, 'Shortcut link found on the page.');
  99. // Create a new shortcut set and add a link to it.
  100. $this->drupalLogin($this->adminUser);
  101. $edit = array(
  102. 'label' => $this->randomMachineName(),
  103. 'id' => strtolower($this->randomMachineName()),
  104. );
  105. $this->drupalPostForm('admin/config/user-interface/shortcut/add-set', $edit, t('Save'));
  106. $title = $this->randomMachineName();
  107. $form_data = [
  108. 'title[0][value]' => $title,
  109. 'link[0][uri]' => '/admin',
  110. ];
  111. $this->drupalPostForm('admin/config/user-interface/shortcut/manage/' . $edit['id'] . '/add-link', $form_data, t('Save'));
  112. $this->assertResponse(200);
  113. }
  114. /**
  115. * Tests that the "add to shortcut" and "remove from shortcut" links work.
  116. */
  117. public function testShortcutQuickLink() {
  118. \Drupal::service('theme_handler')->install(array('seven'));
  119. $this->config('system.theme')->set('admin', 'seven')->save();
  120. $this->config('node.settings')->set('use_admin_theme', '1')->save();
  121. $this->container->get('router.builder')->rebuild();
  122. $this->drupalLogin($this->rootUser);
  123. $this->drupalGet('admin/config/system/cron');
  124. // Test the "Add to shortcuts" link.
  125. $this->clickLink('Add to Default shortcuts');
  126. $this->assertText('Added a shortcut for Cron.');
  127. $this->assertLink('Cron', 0, 'Shortcut link found on page');
  128. $this->drupalGet('admin/structure');
  129. $this->assertLink('Cron', 0, 'Shortcut link found on different page');
  130. // Test the "Remove from shortcuts" link.
  131. $this->clickLink('Cron');
  132. $this->clickLink('Remove from Default shortcuts');
  133. $this->assertText('The shortcut Cron has been deleted.');
  134. $this->assertNoLink('Cron', 'Shortcut link removed from page');
  135. $this->drupalGet('admin/structure');
  136. $this->assertNoLink('Cron', 'Shortcut link removed from different page');
  137. $this->drupalGet('admin/people');
  138. // Test the "Add to shortcuts" link for a page generated by views.
  139. $this->clickLink('Add to Default shortcuts');
  140. $this->assertText('Added a shortcut for People.');
  141. // Due to the structure of the markup in the link ::assertLink() doesn't
  142. // works here.
  143. $link = $this->xpath('//a[normalize-space()=:label]', array(':label' => 'Remove from Default shortcuts'));
  144. $this->assertTrue(!empty($link), 'Link Remove from Default shortcuts found.');
  145. // Test the "Remove from shortcuts" link for a page generated by views.
  146. $this->clickLink('Remove from Default shortcuts');
  147. $this->assertText('The shortcut People has been deleted.');
  148. // Due to the structure of the markup in the link ::assertLink() doesn't
  149. // works here.
  150. $link = $this->xpath('//a[normalize-space()=:label]', array(':label' => 'Add to Default shortcuts'));
  151. $this->assertTrue(!empty($link), 'Link Add to Default shortcuts found.');
  152. // Test two pages which use same route name but different route parameters.
  153. $this->drupalGet('node/add/page');
  154. // Add Shortcut for Basic Page.
  155. $this->clickLink('Add to Default shortcuts');
  156. $this->assertText('Added a shortcut for Create Basic page.');
  157. // Assure that Article does not have its shortcut indicated as set.
  158. $this->drupalGet('node/add/article');
  159. $link = $this->xpath('//a[normalize-space()=:label]', array(':label' => 'Remove from Default shortcuts'));
  160. $this->assertTrue(empty($link), 'Link Remove to Default shortcuts not found for Create Article page.');
  161. // Add Shortcut for Article.
  162. $this->clickLink('Add to Default shortcuts');
  163. $this->assertText('Added a shortcut for Create Article.');
  164. }
  165. /**
  166. * Tests that shortcut links can be renamed.
  167. */
  168. public function testShortcutLinkRename() {
  169. $set = $this->set;
  170. // Attempt to rename shortcut link.
  171. $new_link_name = $this->randomMachineName();
  172. $shortcuts = $set->getShortcuts();
  173. $shortcut = reset($shortcuts);
  174. $this->drupalPostForm('admin/config/user-interface/shortcut/link/' . $shortcut->id(), array('title[0][value]' => $new_link_name), t('Save'));
  175. $saved_set = ShortcutSet::load($set->id());
  176. $titles = $this->getShortcutInformation($saved_set, 'title');
  177. $this->assertTrue(in_array($new_link_name, $titles), 'Shortcut renamed: ' . $new_link_name);
  178. $this->assertLink($new_link_name, 0, 'Renamed shortcut link appears on the page.');
  179. $this->assertText(t('The shortcut @link has been updated.', array('@link' => $new_link_name)));
  180. }
  181. /**
  182. * Tests that changing the path of a shortcut link works.
  183. */
  184. public function testShortcutLinkChangePath() {
  185. $set = $this->set;
  186. // Tests changing a shortcut path.
  187. $new_link_path = '/admin/config';
  188. $shortcuts = $set->getShortcuts();
  189. $shortcut = reset($shortcuts);
  190. $this->drupalPostForm('admin/config/user-interface/shortcut/link/' . $shortcut->id(), array('title[0][value]' => $shortcut->getTitle(), 'link[0][uri]' => $new_link_path), t('Save'));
  191. $saved_set = ShortcutSet::load($set->id());
  192. $paths = $this->getShortcutInformation($saved_set, 'link');
  193. $this->assertTrue(in_array('internal:' . $new_link_path, $paths), 'Shortcut path changed: ' . $new_link_path);
  194. $this->assertLinkByHref($new_link_path, 0, 'Shortcut with new path appears on the page.');
  195. $this->assertText(t('The shortcut @link has been updated.', array('@link' => $shortcut->getTitle())));
  196. }
  197. /**
  198. * Tests that changing the route of a shortcut link works.
  199. */
  200. public function testShortcutLinkChangeRoute() {
  201. $this->drupalLogin($this->rootUser);
  202. $this->drupalGet('admin/content');
  203. $this->assertResponse(200);
  204. // Disable the view.
  205. View::load('content')->disable()->save();
  206. /** @var \Drupal\Core\Routing\RouteBuilderInterface $router_builder */
  207. $router_builder = \Drupal::service('router.builder');
  208. $router_builder->rebuildIfNeeded();
  209. $this->drupalGet('admin/content');
  210. $this->assertResponse(200);
  211. }
  212. /**
  213. * Tests deleting a shortcut link.
  214. */
  215. public function testShortcutLinkDelete() {
  216. $set = $this->set;
  217. $shortcuts = $set->getShortcuts();
  218. $shortcut = reset($shortcuts);
  219. $this->drupalPostForm('admin/config/user-interface/shortcut/link/' . $shortcut->id() . '/delete', array(), 'Delete');
  220. $saved_set = ShortcutSet::load($set->id());
  221. $ids = $this->getShortcutInformation($saved_set, 'id');
  222. $this->assertFalse(in_array($shortcut->id(), $ids), 'Successfully deleted a shortcut.');
  223. // Delete all the remaining shortcut links.
  224. entity_delete_multiple('shortcut', array_filter($ids));
  225. // Get the front page to check that no exceptions occur.
  226. $this->drupalGet('');
  227. }
  228. /**
  229. * Tests that the add shortcut link is not displayed for 404/403 errors.
  230. *
  231. * Tests that the "Add to shortcuts" link is not displayed on a page not
  232. * found or a page the user does not have access to.
  233. */
  234. public function testNoShortcutLink() {
  235. // Change to a theme that displays shortcuts.
  236. \Drupal::service('theme_handler')->install(array('seven'));
  237. $this->config('system.theme')
  238. ->set('default', 'seven')
  239. ->save();
  240. $this->drupalGet('page-that-does-not-exist');
  241. $result = $this->xpath('//a[contains(@class, "shortcut-action--add")]');
  242. $this->assertTrue(empty($result), 'Add to shortcuts link was not shown on a page not found.');
  243. // The user does not have access to this path.
  244. $this->drupalGet('admin/modules');
  245. $result = $this->xpath('//a[contains(@class, "shortcut-action--add")]');
  246. $this->assertTrue(empty($result), 'Add to shortcuts link was not shown on a page the user does not have access to.');
  247. // Verify that the testing mechanism works by verifying the shortcut link
  248. // appears on admin/content.
  249. $this->drupalGet('admin/content');
  250. $result = $this->xpath('//a[contains(@class, "shortcut-action--remove")]');
  251. $this->assertTrue(!empty($result), 'Remove from shortcuts link was shown on a page the user does have access to.');
  252. // Verify that the shortcut link appears on routing only pages.
  253. $this->drupalGet('router_test/test2');
  254. $result = $this->xpath('//a[contains(@class, "shortcut-action--add")]');
  255. $this->assertTrue(!empty($result), 'Add to shortcuts link was shown on a page the user does have access to.');
  256. }
  257. /**
  258. * Tests that the 'access shortcuts' permissions works properly.
  259. */
  260. public function testAccessShortcutsPermission() {
  261. // Change to a theme that displays shortcuts.
  262. \Drupal::service('theme_handler')->install(array('seven'));
  263. $this->config('system.theme')
  264. ->set('default', 'seven')
  265. ->save();
  266. // Add cron to the default shortcut set.
  267. $this->drupalLogin($this->rootUser);
  268. $this->drupalGet('admin/config/system/cron');
  269. $this->clickLink('Add to Default shortcuts');
  270. // Verify that users without the 'access shortcuts' permission can't see the
  271. // shortcuts.
  272. $this->drupalLogin($this->drupalCreateUser(array('access toolbar')));
  273. $this->assertNoLink('Shortcuts', 'Shortcut link not found on page.');
  274. // Verify that users without the 'administer site configuration' permission
  275. // can't see the cron shortcuts.
  276. $this->drupalLogin($this->drupalCreateUser(array('access toolbar', 'access shortcuts')));
  277. $this->assertNoLink('Shortcuts', 'Shortcut link not found on page.');
  278. $this->assertNoLink('Cron', 'Cron shortcut link not found on page.');
  279. // Verify that users with the 'access shortcuts' permission can see the
  280. // shortcuts.
  281. $this->drupalLogin($this->drupalCreateUser(array(
  282. 'access toolbar', 'access shortcuts', 'administer site configuration',
  283. )));
  284. $this->clickLink('Shortcuts', 0, 'Shortcut link found on page.');
  285. $this->assertLink('Cron', 0, 'Cron shortcut link found on page.');
  286. $this->verifyAccessShortcutsPermissionForEditPages();
  287. }
  288. /**
  289. * Tests the shortcuts are correctly ordered by weight in the toolbar.
  290. */
  291. public function testShortcutLinkOrder() {
  292. // Ensure to give permissions to access the shortcuts.
  293. $this->drupalLogin($this->drupalCreateUser(array('access toolbar', 'access shortcuts', 'access content overview', 'administer content types')));
  294. $this->drupalGet(Url::fromRoute('<front>'));
  295. $shortcuts = $this->cssSelect('#toolbar-item-shortcuts-tray .toolbar-menu a');
  296. $this->assertEqual((string) $shortcuts[0], 'Add content');
  297. $this->assertEqual((string) $shortcuts[1], 'All content');
  298. foreach ($this->set->getShortcuts() as $shortcut) {
  299. $shortcut->setWeight($shortcut->getWeight() * -1)->save();
  300. }
  301. $this->drupalGet(Url::fromRoute('<front>'));
  302. $shortcuts = $this->cssSelect('#toolbar-item-shortcuts-tray .toolbar-menu a');
  303. $this->assertEqual((string) $shortcuts[0], 'All content');
  304. $this->assertEqual((string) $shortcuts[1], 'Add content');
  305. }
  306. /**
  307. * Tests that the 'access shortcuts' permission is required for shortcut set
  308. * administration page access.
  309. */
  310. private function verifyAccessShortcutsPermissionForEditPages() {
  311. // Create a user with customize links and switch sets permissions but
  312. // without the 'access shortcuts' permission.
  313. $test_permissions = array(
  314. 'customize shortcut links',
  315. 'switch shortcut sets',
  316. );
  317. $noaccess_user = $this->drupalCreateUser($test_permissions);
  318. $this->drupalLogin($noaccess_user);
  319. // Verify that set administration pages are inaccessible without the
  320. // 'access shortcuts' permission.
  321. $edit_paths = array(
  322. 'admin/config/user-interface/shortcut/manage/default/customize',
  323. 'admin/config/user-interface/shortcut/manage/default',
  324. 'user/' . $noaccess_user->id() . '/shortcuts',
  325. );
  326. foreach ($edit_paths as $path) {
  327. $this->drupalGet($path);
  328. $message = format_string('Access is denied on %s', array('%s' => $path));
  329. $this->assertResponse(403, $message);
  330. }
  331. }
  332. /**
  333. * Tests that the 'access shortcuts' permission is required to access the
  334. * shortcut block.
  335. */
  336. public function testShortcutBlockAccess() {
  337. // Creates a block instance and place in a region through api.
  338. $block = $this->drupalPlaceBlock('shortcuts');
  339. // Verify that users with the 'access shortcuts' permission can see the
  340. // shortcut block.
  341. $this->drupalLogin($this->shortcutUser);
  342. $this->drupalGet('');
  343. $this->assertBlockAppears($block);
  344. $this->drupalLogout();
  345. // Verify that users without the 'access shortcuts' permission can see the
  346. // shortcut block.
  347. $this->drupalLogin($this->drupalCreateUser(array()));
  348. $this->drupalGet('');
  349. $this->assertNoBlockAppears($block);
  350. }
  351. }