View source
<?php
namespace Drupal\Tests\system\Functional\Menu;
use Drupal\Component\Utility\Html;
use Drupal\Core\Url;
use Drupal\Tests\BrowserTestBase;
class LocalTasksTest extends BrowserTestBase {
public static $modules = [
'block',
'menu_test',
'entity_test',
'node',
];
protected $defaultTheme = 'classy';
protected $sut;
protected function setUp() {
parent::setUp();
$this->sut = $this
->drupalPlaceBlock('local_tasks_block', [
'id' => 'tabs_block',
]);
}
protected function assertLocalTasks(array $routes, $level = 0) {
$elements = $this
->xpath('//*[contains(@class, :class)]//a', [
':class' => $level == 0 ? 'tabs primary' : 'tabs secondary',
]);
$this
->assertGreaterThan(0, 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();
$this
->assertEquals($expected, $elements[$index]
->getAttribute('href'), "Task " . ($index + 1) . "number href " . $elements[$index]
->getAttribute('href') . " equals {$expected}.");
}
}
protected function assertLocalTaskAppears($title) {
return $this
->assertPattern('@<a [^>]*>' . preg_quote($title, '@') . '</a>@');
}
protected function assertNoLocalTasks($level = 0) {
$elements = $this
->xpath('//*[contains(@class, :class)]//a', [
':class' => $level == 0 ? 'tabs primary' : 'tabs secondary',
]);
$this
->assertEmpty($elements, 'Local tasks not found.');
}
public function testPluginLocalTask() {
$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',
],
],
]);
$title = Html::escape("Task 1 <script>alert('Welcome to the jungle!')</script>");
$this
->assertLocalTaskAppears($title);
$title = Html::escape("<script>alert('Welcome to the derived jungle!')</script>");
$this
->assertLocalTaskAppears($title);
$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
->assertLocalTaskAppears($title);
$result = $this
->xpath('//ul[contains(@class, "tabs")]//li[contains(@class, "active")]/a');
$this
->assertCount(1, $result, 'There is just a single active tab.');
$this
->assertEqual('View(active tab)', $result[0]
->getText(), 'The view tab is active.');
$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
->assertCount(1, $result, 'There is just a single active tab.');
$this
->assertEqual('Settings(active tab)', $result[0]
->getText(), '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
->assertCount(2, $result, 'There are tabs active on both levels.');
$this
->assertEqual('Settings(active tab)', $result[0]
->getText(), 'The settings tab is active.');
$this
->assertEqual('Dynamic title for TestTasksSettingsSub1(active tab)', $result[1]
->getText(), '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
->assertCount(2, $result, 'There are tabs active on both levels.');
$this
->assertEqual('Settings(active tab)', $result[0]
->getText(), 'The settings tab is active.');
$this
->assertEqual('Derive 1(active tab)', $result[1]
->getText(), 'The derive1 tab is active.');
$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');
$entity = \Drupal::entityTypeManager()
->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
->assertCount(1, $result, 'There is one active tab.');
$this
->assertEqual('upcasting sub1(active tab)', $result[0]
->getText(), '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
->assertCount(1, $result, 'There is one active tab.');
$this
->assertEqual('upcasting sub2(active tab)', $result[0]
->getText(), 'The "upcasting sub2" tab is active.');
}
public function testLocalTaskBlock() {
$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'));
$this
->assertLocalTasks([
[
'menu_test.local_task_test_tasks_view',
[],
],
[
'menu_test.local_task_test_tasks_edit',
[],
],
[
'menu_test.local_task_test_tasks_settings',
[],
],
]);
$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'));
$this
->assertNoLocalTasks(0);
$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);
}
public function testLocalTaskBlockCache() {
$this
->drupalLogin($this->rootUser);
$this
->drupalCreateContentType([
'type' => 'page',
]);
$this
->drupalGet('/admin/structure/types/manage/page');
$this
->assertNoLocalTasks();
\Drupal::service('module_installer')
->install([
'field_ui',
]);
$this
->drupalGet('/admin/structure/types/manage/page');
$this
->assertLocalTasks([
[
'entity.node_type.edit_form',
[
'node_type' => 'page',
],
],
[
'entity.node.field_ui_fields',
[
'node_type' => 'page',
],
],
[
'entity.entity_form_display.node.default',
[
'node_type' => 'page',
],
],
[
'entity.entity_view_display.node.default',
[
'node_type' => 'page',
],
],
]);
}
}