+++ /dev/null
-<?php
-
-namespace Drupal\system\Tests\Menu;
-
-use Drupal\Component\Utility\Html;
-use Drupal\Core\Url;
-use Drupal\simpletest\WebTestBase;
-
-/**
- * Tests local tasks derived from router and added/altered via hooks.
- *
- * @group Menu
- */
-class LocalTasksTest extends WebTestBase {
-
- /**
- * Modules to enable.
- *
- * @var string[]
- */
- public static $modules = ['block', 'menu_test', 'entity_test'];
-
- /**
- * The local tasks block under testing.
- *
- * @var \Drupal\block\Entity\Block
- */
- protected $sut;
-
- /**
- * {@inheritdoc}
- */
- protected function setUp() {
- parent::setUp();
-
- $this->sut = $this->drupalPlaceBlock('local_tasks_block', ['id' => 'tabs_block']);
- }
-
- /**
- * Asserts local tasks in the page output.
- *
- * @param array $routes
- * A list of expected local tasks, prepared as an array of route names and
- * their associated route parameters, to assert on the page (in the given
- * order).
- * @param int $level
- * (optional) The local tasks level to assert; 0 for primary, 1 for
- * secondary. Defaults to 0.
- */
- protected function assertLocalTasks(array $routes, $level = 0) {
- $elements = $this->xpath('//*[contains(@class, :class)]//a', [
- ':class' => $level == 0 ? 'tabs primary' : 'tabs secondary',
- ]);
- $this->assertTrue(count($elements), 'Local tasks found.');
- foreach ($routes as $index => $route_info) {
- list($route_name, $route_parameters) = $route_info;
- $expected = Url::fromRoute($route_name, $route_parameters)->toString();
- $method = ($elements[$index]['href'] == $expected ? 'pass' : 'fail');
- $this->{$method}(format_string('Task @number href @value equals @expected.', [
- '@number' => $index + 1,
- '@value' => (string) $elements[$index]['href'],
- '@expected' => $expected,
- ]));
- }
- }
-
- /**
- * Ensures that some local task appears.
- *
- * @param string $title
- * The expected title.
- *
- * @return bool
- * TRUE if the local task exists on the page.
- */
- protected function assertLocalTaskAppers($title) {
- // SimpleXML gives us the unescaped text, not the actual escaped markup,
- // so use a pattern instead to check the raw content.
- // This behaviour is a bug in libxml, see
- // https://bugs.php.net/bug.php?id=49437.
- return $this->assertPattern('@<a [^>]*>' . preg_quote($title, '@') . '</a>@');
- }
-
- /**
- * Asserts that the local tasks on the specified level are not being printed.
- *
- * @param int $level
- * (optional) The local tasks level to assert; 0 for primary, 1 for
- * secondary. Defaults to 0.
- */
- protected function assertNoLocalTasks($level = 0) {
- $elements = $this->xpath('//*[contains(@class, :class)]//a', [
- ':class' => $level == 0 ? 'tabs primary' : 'tabs secondary',
- ]);
- $this->assertFalse(count($elements), 'Local tasks not found.');
- }
-
- /**
- * Tests the plugin based local tasks.
- */
- public function testPluginLocalTask() {
- // Verify local tasks defined in the hook.
- $this->drupalGet(Url::fromRoute('menu_test.tasks_default'));
- $this->assertLocalTasks([
- ['menu_test.tasks_default', []],
- ['menu_test.router_test1', ['bar' => 'unsafe']],
- ['menu_test.router_test1', ['bar' => '1']],
- ['menu_test.router_test2', ['bar' => '2']],
- ]);
-
- // Verify that script tags are escaped on output.
- $title = Html::escape("Task 1 <script>alert('Welcome to the jungle!')</script>");
- $this->assertLocalTaskAppers($title);
- $title = Html::escape("<script>alert('Welcome to the derived jungle!')</script>");
- $this->assertLocalTaskAppers($title);
-
- // Verify that local tasks appear as defined in the router.
- $this->drupalGet(Url::fromRoute('menu_test.local_task_test_tasks_view'));
- $this->assertLocalTasks([
- ['menu_test.local_task_test_tasks_view', []],
- ['menu_test.local_task_test_tasks_edit', []],
- ['menu_test.local_task_test_tasks_settings', []],
- ['menu_test.local_task_test_tasks_settings_dynamic', []],
- ]);
-
- $title = Html::escape("<script>alert('Welcome to the jungle!')</script>");
- $this->assertLocalTaskAppers($title);
-
- // Ensure the view tab is active.
- $result = $this->xpath('//ul[contains(@class, "tabs")]//li[contains(@class, "active")]/a');
- $this->assertEqual(1, count($result), 'There is just a single active tab.');
- $this->assertEqual('View', (string) $result[0], 'The view tab is active.');
-
- // Verify that local tasks in the second level appear.
- $sub_tasks = [
- ['menu_test.local_task_test_tasks_settings_sub1', []],
- ['menu_test.local_task_test_tasks_settings_sub2', []],
- ['menu_test.local_task_test_tasks_settings_sub3', []],
- ['menu_test.local_task_test_tasks_settings_derived', ['placeholder' => 'derive1']],
- ['menu_test.local_task_test_tasks_settings_derived', ['placeholder' => 'derive2']],
- ];
- $this->drupalGet(Url::fromRoute('menu_test.local_task_test_tasks_settings'));
- $this->assertLocalTasks($sub_tasks, 1);
-
- $result = $this->xpath('//ul[contains(@class, "tabs")]//li[contains(@class, "active")]/a');
- $this->assertEqual(1, count($result), 'There is just a single active tab.');
- $this->assertEqual('Settings', (string) $result[0], 'The settings tab is active.');
-
- $this->drupalGet(Url::fromRoute('menu_test.local_task_test_tasks_settings_sub1'));
- $this->assertLocalTasks($sub_tasks, 1);
-
- $result = $this->xpath('//ul[contains(@class, "tabs")]//a[contains(@class, "active")]');
- $this->assertEqual(2, count($result), 'There are tabs active on both levels.');
- $this->assertEqual('Settings', (string) $result[0], 'The settings tab is active.');
- $this->assertEqual('Dynamic title for TestTasksSettingsSub1', (string) $result[1], 'The sub1 tab is active.');
-
- $this->assertCacheTag('kittens:ragdoll');
- $this->assertCacheTag('kittens:dwarf-cat');
-
- $this->drupalGet(Url::fromRoute('menu_test.local_task_test_tasks_settings_derived', ['placeholder' => 'derive1']));
- $this->assertLocalTasks($sub_tasks, 1);
-
- $result = $this->xpath('//ul[contains(@class, "tabs")]//li[contains(@class, "active")]');
- $this->assertEqual(2, count($result), 'There are tabs active on both levels.');
- $this->assertEqual('Settings', (string) $result[0]->a, 'The settings tab is active.');
- $this->assertEqual('Derive 1', (string) $result[1]->a, 'The derive1 tab is active.');
-
- // Ensures that the local tasks contains the proper 'provider key'
- $definitions = $this->container->get('plugin.manager.menu.local_task')->getDefinitions();
- $this->assertEqual($definitions['menu_test.local_task_test_tasks_view']['provider'], 'menu_test');
- $this->assertEqual($definitions['menu_test.local_task_test_tasks_edit']['provider'], 'menu_test');
- $this->assertEqual($definitions['menu_test.local_task_test_tasks_settings']['provider'], 'menu_test');
- $this->assertEqual($definitions['menu_test.local_task_test_tasks_settings_sub1']['provider'], 'menu_test');
- $this->assertEqual($definitions['menu_test.local_task_test_tasks_settings_sub2']['provider'], 'menu_test');
- $this->assertEqual($definitions['menu_test.local_task_test_tasks_settings_sub3']['provider'], 'menu_test');
-
- // Test that we we correctly apply the active class to tabs where one of the
- // request attributes is upcast to an entity object.
- $entity = \Drupal::entityManager()->getStorage('entity_test')->create(['bundle' => 'test']);
- $entity->save();
-
- $this->drupalGet(Url::fromRoute('menu_test.local_task_test_upcasting_sub1', ['entity_test' => '1']));
-
- $tasks = [
- ['menu_test.local_task_test_upcasting_sub1', ['entity_test' => '1']],
- ['menu_test.local_task_test_upcasting_sub2', ['entity_test' => '1']],
- ];
-
- $this->assertLocalTasks($tasks, 0);
-
- $result = $this->xpath('//ul[contains(@class, "tabs")]//li[contains(@class, "active")]');
- $this->assertEqual(1, count($result), 'There is one active tab.');
- $this->assertEqual('upcasting sub1', (string) $result[0]->a, 'The "upcasting sub1" tab is active.');
-
- $this->drupalGet(Url::fromRoute('menu_test.local_task_test_upcasting_sub2', ['entity_test' => '1']));
-
- $tasks = [
- ['menu_test.local_task_test_upcasting_sub1', ['entity_test' => '1']],
- ['menu_test.local_task_test_upcasting_sub2', ['entity_test' => '1']],
- ];
- $this->assertLocalTasks($tasks, 0);
-
- $result = $this->xpath('//ul[contains(@class, "tabs")]//li[contains(@class, "active")]');
- $this->assertEqual(1, count($result), 'There is one active tab.');
- $this->assertEqual('upcasting sub2', (string) $result[0]->a, 'The "upcasting sub2" tab is active.');
- }
-
- /**
- * Tests that local task blocks are configurable to show a specific level.
- */
- public function testLocalTaskBlock() {
- // Remove the default block and create a new one.
- $this->sut->delete();
-
- $this->sut = $this->drupalPlaceBlock('local_tasks_block', [
- 'id' => 'tabs_block',
- 'primary' => TRUE,
- 'secondary' => FALSE,
- ]);
-
- $this->drupalGet(Url::fromRoute('menu_test.local_task_test_tasks_settings'));
-
- // Verify that local tasks in the first level appear.
- $this->assertLocalTasks([
- ['menu_test.local_task_test_tasks_view', []],
- ['menu_test.local_task_test_tasks_edit', []],
- ['menu_test.local_task_test_tasks_settings', []],
- ]);
-
- // Verify that local tasks in the second level doesn't appear.
- $this->assertNoLocalTasks(1);
-
- $this->sut->delete();
- $this->sut = $this->drupalPlaceBlock('local_tasks_block', [
- 'id' => 'tabs_block',
- 'primary' => FALSE,
- 'secondary' => TRUE,
- ]);
-
- $this->drupalGet(Url::fromRoute('menu_test.local_task_test_tasks_settings'));
-
- // Verify that local tasks in the first level doesn't appear.
- $this->assertNoLocalTasks(0);
-
- // Verify that local tasks in the second level appear.
- $sub_tasks = [
- ['menu_test.local_task_test_tasks_settings_sub1', []],
- ['menu_test.local_task_test_tasks_settings_sub2', []],
- ['menu_test.local_task_test_tasks_settings_sub3', []],
- ['menu_test.local_task_test_tasks_settings_derived', ['placeholder' => 'derive1']],
- ['menu_test.local_task_test_tasks_settings_derived', ['placeholder' => 'derive2']],
- ];
- $this->assertLocalTasks($sub_tasks, 1);
- }
-
-}