X-Git-Url: http://www.aleph1.co.uk/gitweb/?p=yaffs-website;a=blobdiff_plain;f=web%2Fcore%2Fmodules%2Fsystem%2Ftests%2Fsrc%2FFunctional%2FMenu%2FLocalTasksTest.php;fp=web%2Fcore%2Fmodules%2Fsystem%2Ftests%2Fsrc%2FFunctional%2FMenu%2FLocalTasksTest.php;h=12a157d5879a2e0355f4f4c18964bd92eca67a0e;hp=0000000000000000000000000000000000000000;hb=9917807b03b64faf00f6a1f29dcb6eafc454efa5;hpb=aea91e65e895364e460983b890e295aa5d5540a5 diff --git a/web/core/modules/system/tests/src/Functional/Menu/LocalTasksTest.php b/web/core/modules/system/tests/src/Functional/Menu/LocalTasksTest.php new file mode 100644 index 000000000..12a157d58 --- /dev/null +++ b/web/core/modules/system/tests/src/Functional/Menu/LocalTasksTest.php @@ -0,0 +1,256 @@ +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]->getAttribute('href') == $expected ? 'pass' : 'fail'); + $this->{$method}(format_string('Task @number href @value equals @expected.', [ + '@number' => $index + 1, + '@value' => $elements[$index]->getAttribute('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('@]*>' . preg_quote($title, '@') . '@'); + } + + /** + * 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 "); + $this->assertLocalTaskAppers($title); + $title = Html::escape(""); + $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(""); + $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(active tab)', $result[0]->getText(), '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(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->assertEqual(2, count($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->assertEqual(2, count($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.'); + + // 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(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->assertEqual(1, count($result), 'There is one active tab.'); + $this->assertEqual('upcasting sub2(active tab)', $result[0]->getText(), '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); + } + +}