diff --git a/core/.DS_Store b/core/.DS_Store new file mode 100644 index 0000000..907f242 Binary files /dev/null and b/core/.DS_Store differ diff --git a/core/modules/aggregator/src/Tests/AddFeedTest.php b/core/modules/aggregator/tests/src/Functional/AddFeedTest.php similarity index 98% rename from core/modules/aggregator/src/Tests/AddFeedTest.php rename to core/modules/aggregator/tests/src/Functional/AddFeedTest.php index b7ffe5f..90fff77 100644 --- a/core/modules/aggregator/src/Tests/AddFeedTest.php +++ b/core/modules/aggregator/tests/src/Functional/AddFeedTest.php @@ -1,6 +1,6 @@ getRawContent(). - */ - protected function basicAuthGet($path, $username, $password, array $options = []) { - return $this->drupalGet($path, $options, $this->getBasicAuthHeaders($username, $password)); - } - - /** - * Executes a form submission using basic authentication. - * - * @param string $path - * Location of the post form. - * @param array $edit - * Field data in an associative array. - * @param string $submit - * Value of the submit button whose click is to be emulated. - * @param string $username - * The username to use for basic authentication. - * @param string $password - * The password to use for basic authentication. - * @param array $options - * Options to be forwarded to the url generator. - * @param string $form_html_id - * (optional) HTML ID of the form to be submitted. - * @param string $extra_post - * (optional) A string of additional data to append to the POST submission. - * - * @return string - * The retrieved HTML string. - * - * @see \Drupal\simpletest\WebTestBase::drupalPostForm() - */ - protected function basicAuthPostForm($path, $edit, $submit, $username, $password, array $options = array(), $form_html_id = NULL, $extra_post = NULL) { - return $this->drupalPostForm($path, $edit, $submit, $options, $this->getBasicAuthHeaders($username, $password), $form_html_id, $extra_post); - } - - /** - * Returns HTTP headers that can be used for basic authentication in Curl. - * - * @param string $username - * The username to use for basic authentication. - * @param string $password - * The password to use for basic authentication. - * - * @return array - * An array of raw request headers as used by curl_setopt(). - */ - protected function getBasicAuthHeaders($username, $password) { - // Set up Curl to use basic authentication with the test user's credentials. - return ['Authorization: Basic ' . base64_encode("$username:$password")]; - } - -} diff --git a/core/modules/big_pipe/src/Tests/BigPipePlaceholderTestCases.php b/core/modules/big_pipe/tests/src/Functional/BigPipePlaceholderTestCases.php similarity index 99% rename from core/modules/big_pipe/src/Tests/BigPipePlaceholderTestCases.php rename to core/modules/big_pipe/tests/src/Functional/BigPipePlaceholderTestCases.php index 49719ec..76602fc 100644 --- a/core/modules/big_pipe/src/Tests/BigPipePlaceholderTestCases.php +++ b/core/modules/big_pipe/tests/src/Functional/BigPipePlaceholderTestCases.php @@ -5,7 +5,7 @@ * Contains \Drupal\Tests\big_pipe\Unit\Render\Placeholder\BigPipePlaceholderTestCases. */ -namespace Drupal\big_pipe\Tests; +namespace Drupal\Tests\big_pipe\Functional; use Drupal\big_pipe\Render\BigPipeMarkup; use Drupal\Core\Session\AccountInterface; diff --git a/core/modules/big_pipe/src/Tests/BigPipeTest.php b/core/modules/big_pipe/tests/src/Functional/BigPipeTest.php similarity index 99% rename from core/modules/big_pipe/src/Tests/BigPipeTest.php rename to core/modules/big_pipe/tests/src/Functional/BigPipeTest.php index 1a1bc3d..6eeb74b 100644 --- a/core/modules/big_pipe/src/Tests/BigPipeTest.php +++ b/core/modules/big_pipe/tests/src/Functional/BigPipeTest.php @@ -1,6 +1,6 @@ install(array('bartik')); - - // Create user. - $this->adminUser = $this->drupalCreateUser(array('administer themes')); - $this->drupalLogin($this->adminUser); - } - - /** - * Tests whether the color config schema is valid. - */ - function testValidColorConfigSchema() { - $settings_path = 'admin/appearance/settings/bartik'; - $edit['scheme'] = ''; - $edit['palette[bg]'] = '#123456'; - $this->drupalPostForm($settings_path, $edit, t('Save configuration')); - } - -} diff --git a/core/modules/color/src/Tests/ColorSafePreviewTest.php b/core/modules/color/src/Tests/ColorSafePreviewTest.php deleted file mode 100644 index 813a92e..0000000 --- a/core/modules/color/src/Tests/ColorSafePreviewTest.php +++ /dev/null @@ -1,57 +0,0 @@ -bigUser = $this->drupalCreateUser(['administer themes']); - } - - /** - * Ensures color preview.html is sanitized. - */ - function testColorPreview() { - // Install the color test theme. - \Drupal::service('theme_handler')->install(['color_test_theme']); - $this->drupalLogin($this->bigUser); - - // Markup is being printed from a HTML file located in: - // core/modules/color/tests/modules/color_test/themes/color_test_theme/color/preview.html - $url = Url::fromRoute('system.theme_settings_theme', ['theme' => 'color_test_theme']); - $this->drupalGet($url); - $this->assertText('TEST COLOR PREVIEW'); - - $this->assertNoRaw(''); - $this->assertRaw('

TEST COLOR PREVIEW

'); - } - -} diff --git a/core/modules/color/src/Tests/ColorTest.php b/core/modules/color/src/Tests/ColorTest.php deleted file mode 100644 index 578f7fb..0000000 --- a/core/modules/color/src/Tests/ColorTest.php +++ /dev/null @@ -1,231 +0,0 @@ -bigUser = $this->drupalCreateUser(array('administer themes')); - - // This tests the color module in Bartik. - $this->themes = array( - 'bartik' => array( - 'palette_input' => 'palette[bg]', - 'scheme' => 'slate', - 'scheme_color' => '#3b3b3b', - ), - 'color_test_theme' => array( - 'palette_input' => 'palette[bg]', - 'scheme' => 'custom', - 'scheme_color' => '#3b3b3b', - ), - ); - \Drupal::service('theme_handler')->install(array_keys($this->themes)); - - // Array filled with valid and not valid color values. - $this->colorTests = array( - '#000' => TRUE, - '#123456' => TRUE, - '#abcdef' => TRUE, - '#0' => FALSE, - '#00' => FALSE, - '#0000' => FALSE, - '#00000' => FALSE, - '123456' => FALSE, - '#00000g' => FALSE, - ); - } - - /** - * Tests the Color module functionality. - */ - function testColor() { - foreach ($this->themes as $theme => $test_values) { - $this->_testColor($theme, $test_values); - } - } - - /** - * Tests the Color module functionality using the given theme. - * - * @param string $theme - * The machine name of the theme being tested. - * @param array $test_values - * An associative array of test settings (i.e. 'Main background', 'Text - * color', 'Color set', etc) for the theme which being tested. - */ - function _testColor($theme, $test_values) { - $this->config('system.theme') - ->set('default', $theme) - ->save(); - $settings_path = 'admin/appearance/settings/' . $theme; - - $this->drupalLogin($this->bigUser); - $this->drupalGet($settings_path); - $this->assertResponse(200); - $this->assertUniqueText('Color set'); - $edit['scheme'] = ''; - $edit[$test_values['palette_input']] = '#123456'; - $this->drupalPostForm($settings_path, $edit, t('Save configuration')); - - $this->drupalGet(''); - $stylesheets = $this->config('color.theme.' . $theme)->get('stylesheets'); - foreach ($stylesheets as $stylesheet) { - $this->assertPattern('|' . file_url_transform_relative(file_create_url($stylesheet)) . '|', 'Make sure the color stylesheet is included in the content. (' . $theme . ')'); - $stylesheet_content = join("\n", file($stylesheet)); - $this->assertTrue(strpos($stylesheet_content, 'color: #123456') !== FALSE, 'Make sure the color we changed is in the color stylesheet. (' . $theme . ')'); - } - - $this->drupalGet($settings_path); - $this->assertResponse(200); - $edit['scheme'] = $test_values['scheme']; - $this->drupalPostForm($settings_path, $edit, t('Save configuration')); - - $this->drupalGet(''); - $stylesheets = $this->config('color.theme.' . $theme)->get('stylesheets'); - foreach ($stylesheets as $stylesheet) { - $stylesheet_content = join("\n", file($stylesheet)); - $this->assertTrue(strpos($stylesheet_content, 'color: ' . $test_values['scheme_color']) !== FALSE, 'Make sure the color we changed is in the color stylesheet. (' . $theme . ')'); - } - - // Test with aggregated CSS turned on. - $config = $this->config('system.performance'); - $config->set('css.preprocess', 1); - $config->save(); - $this->drupalGet(''); - $stylesheets = \Drupal::state()->get('drupal_css_cache_files') ?: array(); - $stylesheet_content = ''; - foreach ($stylesheets as $uri) { - $stylesheet_content .= join("\n", file(drupal_realpath($uri))); - } - $this->assertTrue(strpos($stylesheet_content, 'public://') === FALSE, 'Make sure the color paths have been translated to local paths. (' . $theme . ')'); - $config->set('css.preprocess', 0); - $config->save(); - } - - /** - * Tests whether the provided color is valid. - */ - function testValidColor() { - $this->config('system.theme') - ->set('default', 'bartik') - ->save(); - $settings_path = 'admin/appearance/settings/bartik'; - - $this->drupalLogin($this->bigUser); - $edit['scheme'] = ''; - - foreach ($this->colorTests as $color => $is_valid) { - $edit['palette[bg]'] = $color; - $this->drupalPostForm($settings_path, $edit, t('Save configuration')); - - if ($is_valid) { - $this->assertText('The configuration options have been saved.'); - } - else { - $this->assertText('You must enter a valid hexadecimal color value for Main background.'); - } - } - } - - /** - * Test whether the custom logo is used in the color preview. - */ - function testLogoSettingOverride() { - $this->drupalLogin($this->bigUser); - $edit = array( - 'default_logo' => FALSE, - 'logo_path' => 'core/misc/druplicon.png', - ); - $this->drupalPostForm('admin/appearance/settings', $edit, t('Save configuration')); - - // Ensure that the overridden logo is present in Bartik, which is colorable. - $this->drupalGet('admin/appearance/settings/bartik'); - $this->assertIdentical($GLOBALS['base_path'] . 'core/misc/druplicon.png', $this->getDrupalSettings()['color']['logo']); - } - - /** - * Test whether the scheme can be set, viewed anonymously and reset. - */ - function testOverrideAndResetScheme() { - $settings_path = 'admin/appearance/settings/bartik'; - $this->config('system.theme') - ->set('default', 'bartik') - ->save(); - - // Place branding block with site name and slogan into header region. - $this->drupalPlaceBlock('system_branding_block', ['region' => 'header']); - - $this->drupalGet(''); - $this->assertNoRaw('files/color/bartik-', 'Make sure the color logo is not being used.'); - $this->assertRaw('bartik/logo.svg', 'Make sure the original bartik logo exists.'); - - // Log in and set the color scheme to 'slate'. - $this->drupalLogin($this->bigUser); - $edit['scheme'] = 'slate'; - $this->drupalPostForm($settings_path, $edit, t('Save configuration')); - - // Visit the homepage and ensure color changes. - $this->drupalLogout(); - $this->drupalGet(''); - $this->assertRaw('files/color/bartik-', 'Make sure the color logo is being used.'); - $this->assertNoRaw('bartik/logo.svg', 'Make sure the original bartik logo does not exist.'); - - // Log in and set the color scheme back to default (delete config). - $this->drupalLogin($this->bigUser); - $edit['scheme'] = 'default'; - $this->drupalPostForm($settings_path, $edit, t('Save configuration')); - - // Log out and ensure there is no color and we have the original logo. - $this->drupalLogout(); - $this->drupalGet(''); - $this->assertNoRaw('files/color/bartik-', 'Make sure the color logo is not being used.'); - $this->assertRaw('bartik/logo.svg', 'Make sure the original bartik logo exists.'); - } - -} diff --git a/core/modules/comment/src/Tests/CommentActionsTest.php b/core/modules/comment/tests/src/Functional/CommentActionsTest.php similarity index 97% rename from core/modules/comment/src/Tests/CommentActionsTest.php rename to core/modules/comment/tests/src/Functional/CommentActionsTest.php index 220be20..4c32426 100644 --- a/core/modules/comment/src/Tests/CommentActionsTest.php +++ b/core/modules/comment/tests/src/Functional/CommentActionsTest.php @@ -1,6 +1,6 @@ uninstall(['page_cache']); - } - - /** - * Tests that Dynamic Page Cache works correctly, and verifies the edge cases. - */ - public function testDynamicPageCache() { - // Controllers returning plain response objects are ignored by Dynamic Page - // Cache. - $url = Url::fromUri('route:dynamic_page_cache_test.response'); - $this->drupalGet($url); - $this->assertFalse($this->drupalGetHeader(DynamicPageCacheSubscriber::HEADER), 'Response object returned: Dynamic Page Cache is ignoring.'); - - // Controllers returning CacheableResponseInterface (cacheable response) - // objects are handled by Dynamic Page Cache. - $url = Url::fromUri('route:dynamic_page_cache_test.cacheable_response'); - $this->drupalGet($url); - $this->assertEqual('MISS', $this->drupalGetHeader(DynamicPageCacheSubscriber::HEADER), 'Cacheable response object returned: Dynamic Page Cache is active, Dynamic Page Cache MISS.'); - $this->drupalGet($url); - $this->assertEqual('HIT', $this->drupalGetHeader(DynamicPageCacheSubscriber::HEADER), 'Cacheable response object returned: Dynamic Page Cache is active, Dynamic Page Cache HIT.'); - - // Controllers returning render arrays, rendered as HTML responses, are - // handled by Dynamic Page Cache. - $url = Url::fromUri('route:dynamic_page_cache_test.html'); - $this->drupalGet($url); - $this->assertEqual('MISS', $this->drupalGetHeader(DynamicPageCacheSubscriber::HEADER), 'Render array returned, rendered as HTML response: Dynamic Page Cache is active, Dynamic Page Cache MISS.'); - $this->drupalGet($url); - $this->assertEqual('HIT', $this->drupalGetHeader(DynamicPageCacheSubscriber::HEADER), 'Render array returned, rendered as HTML response: Dynamic Page Cache is active, Dynamic Page Cache HIT.'); - - // The above is the simple case, where the render array returned by the - // response contains no cache contexts. So let's now test a route/controller - // that *does* vary by a cache context whose value we can easily control: it - // varies by the 'animal' query argument. - foreach (['llama', 'piggy', 'unicorn', 'kitten'] as $animal) { - $url = Url::fromUri('route:dynamic_page_cache_test.html.with_cache_contexts', ['query' => ['animal' => $animal]]); - $this->drupalGet($url); - $this->assertRaw($animal); - $this->assertEqual('MISS', $this->drupalGetHeader(DynamicPageCacheSubscriber::HEADER), 'Render array returned, rendered as HTML response: Dynamic Page Cache is active, Dynamic Page Cache MISS.'); - $this->drupalGet($url); - $this->assertRaw($animal); - $this->assertEqual('HIT', $this->drupalGetHeader(DynamicPageCacheSubscriber::HEADER), 'Render array returned, rendered as HTML response: Dynamic Page Cache is active, Dynamic Page Cache HIT.'); - - // Finally, let's also verify that the 'dynamic_page_cache_test.html' - // route continued to see cache hits if we specify a query argument, - // because it *should* ignore it and continue to provide Dynamic Page - // Cache hits. - $url = Url::fromUri('route:dynamic_page_cache_test.html', ['query' => ['animal' => 'piglet']]); - $this->drupalGet($url); - $this->assertEqual('HIT', $this->drupalGetHeader(DynamicPageCacheSubscriber::HEADER), 'Render array returned, rendered as HTML response: Dynamic Page Cache is active, Dynamic Page Cache HIT.'); - } - - // Controllers returning render arrays, rendered as anything except a HTML - // response, are ignored by Dynamic Page Cache (but only because those - // wrapper formats' responses do not implement CacheableResponseInterface). - $this->drupalGet('dynamic-page-cache-test/html', array('query' => array(MainContentViewSubscriber::WRAPPER_FORMAT => 'drupal_ajax'))); - $this->assertFalse($this->drupalGetHeader(DynamicPageCacheSubscriber::HEADER), 'Render array returned, rendered as AJAX response: Dynamic Page Cache is ignoring.'); - $this->drupalGet('dynamic-page-cache-test/html', array('query' => array(MainContentViewSubscriber::WRAPPER_FORMAT => 'drupal_dialog'))); - $this->assertFalse($this->drupalGetHeader(DynamicPageCacheSubscriber::HEADER), 'Render array returned, rendered as dialog response: Dynamic Page Cache is ignoring.'); - $this->drupalGet('dynamic-page-cache-test/html', array('query' => array(MainContentViewSubscriber::WRAPPER_FORMAT => 'drupal_modal'))); - $this->assertFalse($this->drupalGetHeader(DynamicPageCacheSubscriber::HEADER), 'Render array returned, rendered as modal response: Dynamic Page Cache is ignoring.'); - - // Admin routes are ignored by Dynamic Page Cache. - $this->drupalGet('dynamic-page-cache-test/html/admin'); - $this->assertFalse($this->drupalGetHeader(DynamicPageCacheSubscriber::HEADER), 'Response returned, rendered as HTML response, admin route: Dynamic Page Cache is ignoring'); - $this->drupalGet('dynamic-page-cache-test/response/admin'); - $this->assertFalse($this->drupalGetHeader(DynamicPageCacheSubscriber::HEADER), 'Response returned, plain response, admin route: Dynamic Page Cache is ignoring'); - $this->drupalGet('dynamic-page-cache-test/cacheable-response/admin'); - $this->assertFalse($this->drupalGetHeader(DynamicPageCacheSubscriber::HEADER), 'Response returned, cacheable response, admin route: Dynamic Page Cache is ignoring'); - - // Max-age = 0 responses are ignored by Dynamic Page Cache. - $this->drupalGet('dynamic-page-cache-test/html/uncacheable/max-age'); - $this->assertEqual('UNCACHEABLE', $this->drupalGetHeader(DynamicPageCacheSubscriber::HEADER), 'Render array returned, rendered as HTML response, but uncacheable: Dynamic Page Cache is running, but not caching.'); - - // 'user' cache context responses are ignored by Dynamic Page Cache. - $this->drupalGet('dynamic-page-cache-test/html/uncacheable/contexts'); - $this->assertEqual('UNCACHEABLE', $this->drupalGetHeader(DynamicPageCacheSubscriber::HEADER), 'Render array returned, rendered as HTML response, but uncacheable: Dynamic Page Cache is running, but not caching.'); - - // 'current-temperature' cache tag responses are ignored by Dynamic Page - // Cache. - $this->drupalGet('dynamic-page-cache-test/html/uncacheable/tags'); - $this->assertEqual('MISS', $this->drupalGetHeader(DynamicPageCacheSubscriber::HEADER), 'By default, Drupal has no auto-placeholdering cache tags.'); - } - -} diff --git a/core/modules/editor/src/Tests/EditorAdminTest.php b/core/modules/editor/tests/src/Functional/EditorAdminTest.php similarity index 98% rename from core/modules/editor/src/Tests/EditorAdminTest.php rename to core/modules/editor/tests/src/Functional/EditorAdminTest.php index 97d47b1..8ac2459 100644 --- a/core/modules/editor/src/Tests/EditorAdminTest.php +++ b/core/modules/editor/tests/src/Functional/EditorAdminTest.php @@ -1,19 +1,19 @@ drupalCreateContentType(array('type' => 'page', 'name' => 'Basic page')); - - $this->user = $this->drupalCreateUser(array('create page content', 'access content')); - $this->drupalLogin($this->user); - $this->testNode = $this->drupalCreateNode(array('type' => 'page', 'uid' => $this->user->id())); - } - - /** - * Get node read timestamps from the server for the current user. - * - * @param array $node_ids - * An array of node IDs. - * - * @return string - * The response body. - */ - protected function getNodeReadTimestamps(array $node_ids) { - // Build POST values. - $post = array(); - for ($i = 0; $i < count($node_ids); $i++) { - $post['node_ids[' . $i . ']'] = $node_ids[$i]; - } - - // Serialize POST values. - foreach ($post as $key => $value) { - // Encode according to application/x-www-form-urlencoded - // Both names and values needs to be urlencoded, according to - // http://www.w3.org/TR/html4/interact/forms.html#h-17.13.4.1 - $post[$key] = urlencode($key) . '=' . urlencode($value); - } - $post = implode('&', $post); - - // Perform HTTP request. - return $this->curlExec(array( - CURLOPT_URL => \Drupal::url('history.get_last_node_view', array(), array('absolute' => TRUE)), - CURLOPT_POST => TRUE, - CURLOPT_POSTFIELDS => $post, - CURLOPT_HTTPHEADER => array( - 'Accept: application/json', - 'Content-Type: application/x-www-form-urlencoded', - ), - )); - } - - /** - * Mark a node as read for the current user. - * - * @param int $node_id - * A node ID. - * - * @return string - * The response body. - */ - protected function markNodeAsRead($node_id) { - return $this->curlExec(array( - CURLOPT_URL => \Drupal::url('history.read_node', array('node' => $node_id), array('absolute' => TRUE)), - CURLOPT_HTTPHEADER => array( - 'Accept: application/json', - ), - )); - } - - /** - * Verifies that the history endpoints work. - */ - function testHistory() { - $nid = $this->testNode->id(); - - // Retrieve "last read" timestamp for test node, for the current user. - $response = $this->getNodeReadTimestamps(array($nid)); - $this->assertResponse(200); - $json = Json::decode($response); - $this->assertIdentical(array(1 => 0), $json, 'The node has not yet been read.'); - - // View the node. - $this->drupalGet('node/' . $nid); - $this->assertCacheContext('user.roles:authenticated'); - // JavaScript present to record the node read. - $settings = $this->getDrupalSettings(); - $libraries = explode(',', $settings['ajaxPageState']['libraries']); - $this->assertTrue(in_array('history/mark-as-read', $libraries), 'history/mark-as-read library is present.'); - $this->assertEqual([$nid => TRUE], $settings['history']['nodesToMarkAsRead'], 'drupalSettings to mark node as read are present.'); - - // Simulate JavaScript: perform HTTP request to mark node as read. - $response = $this->markNodeAsRead($nid); - $this->assertResponse(200); - $timestamp = Json::decode($response); - $this->assertTrue(is_numeric($timestamp), 'Node has been marked as read. Timestamp received.'); - - // Retrieve "last read" timestamp for test node, for the current user. - $response = $this->getNodeReadTimestamps(array($nid)); - $this->assertResponse(200); - $json = Json::decode($response); - $this->assertIdentical(array(1 => $timestamp), $json, 'The node has been read.'); - - // Failing to specify node IDs for the first endpoint should return a 404. - $this->getNodeReadTimestamps(array()); - $this->assertResponse(404); - - // Accessing either endpoint as the anonymous user should return a 403. - $this->drupalLogout(); - $this->getNodeReadTimestamps(array($nid)); - $this->assertResponse(403); - $this->getNodeReadTimestamps(array()); - $this->assertResponse(403); - $this->markNodeAsRead($nid); - $this->assertResponse(403); - } - -} diff --git a/core/modules/image/src/Tests/FileMoveTest.php b/core/modules/image/tests/src/Functional/FileMoveTest.php similarity index 92% rename from core/modules/image/src/Tests/FileMoveTest.php rename to core/modules/image/tests/src/Functional/FileMoveTest.php index 1957994..3ac543e 100644 --- a/core/modules/image/src/Tests/FileMoveTest.php +++ b/core/modules/image/tests/src/Functional/FileMoveTest.php @@ -1,9 +1,9 @@ " - */ - public function testMenuBlock() { - $url = Url::fromRoute('test_page_test.test_page'); - - // Create a Llama menu, add a link to it and place the corresponding block. - $menu = Menu::create(array( - 'id' => 'llama', - 'label' => 'Llama', - 'description' => 'Description text', - )); - $menu->save(); - /** @var \Drupal\Core\Menu\MenuLinkManagerInterface $menu_link_manager */ - $menu_link_manager = \Drupal::service('plugin.manager.menu.link'); - // Move a link into the new menu. - $menu_link = $menu_link_manager->updateDefinition('test_page_test.test_page', array('menu_name' => 'llama', 'parent' => '')); - $block = $this->drupalPlaceBlock('system_menu_block:llama', array('label' => 'Llama', 'provider' => 'system', 'region' => 'footer')); - - // Prime the page cache. - $this->verifyPageCache($url, 'MISS'); - - // Verify a cache hit, but also the presence of the correct cache tags. - $expected_tags = array( - 'rendered', - 'block_view', - 'config:block_list', - 'config:block.block.' . $block->id(), - 'config:system.menu.llama', - // The cache contexts associated with the (in)accessible menu links are - // bubbled. - 'config:user.role.anonymous', - ); - $this->verifyPageCache($url, 'HIT', $expected_tags); - - // Verify that after modifying the menu, there is a cache miss. - $this->pass('Test modification of menu.', 'Debug'); - $menu->set('label', 'Awesome llama'); - $menu->save(); - $this->verifyPageCache($url, 'MISS'); - - // Verify a cache hit. - $this->verifyPageCache($url, 'HIT'); - - // Verify that after modifying the menu link weight, there is a cache miss. - $menu_link_manager->updateDefinition('test_page_test.test_page', array('weight' => -10)); - $this->pass('Test modification of menu link.', 'Debug'); - $this->verifyPageCache($url, 'MISS'); - - // Verify a cache hit. - $this->verifyPageCache($url, 'HIT'); - - // Verify that after adding a menu link, there is a cache miss. - $this->pass('Test addition of menu link.', 'Debug'); - $menu_link_2 = MenuLinkContent::create(array( - 'id' => '', - 'parent' => '', - 'title' => 'Alpaca', - 'menu_name' => 'llama', - 'link' => [[ - 'uri' => 'internal:/', - ]], - 'bundle' => 'menu_name', - )); - $menu_link_2->save(); - $this->verifyPageCache($url, 'MISS'); - - // Verify a cache hit. - $this->verifyPageCache($url, 'HIT'); - - // Verify that after resetting the first menu link, there is a cache miss. - $this->pass('Test reset of menu link.', 'Debug'); - $this->assertTrue($menu_link->isResettable(), 'First link can be reset'); - $menu_link = $menu_link_manager->resetLink($menu_link->getPluginId()); - $this->verifyPageCache($url, 'MISS'); - - // Verify a cache hit. - $this->verifyPageCache($url, 'HIT', $expected_tags); - - // Verify that after deleting the menu, there is a cache miss. - $this->pass('Test deletion of menu.', 'Debug'); - $menu->delete(); - $this->verifyPageCache($url, 'MISS'); - - // Verify a cache hit. - $this->verifyPageCache($url, 'HIT', ['config:block_list', 'config:user.role.anonymous', 'rendered']); - } - -} diff --git a/core/modules/menu_ui/src/Tests/MenuLanguageTest.php b/core/modules/menu_ui/src/Tests/MenuLanguageTest.php deleted file mode 100644 index 72865ea..0000000 --- a/core/modules/menu_ui/src/Tests/MenuLanguageTest.php +++ /dev/null @@ -1,133 +0,0 @@ -drupalLogin($this->drupalCreateUser(array('access administration pages', 'administer menu'))); - - // Add some custom languages. - foreach (array('aa', 'bb', 'cc', 'cs') as $language_code) { - ConfigurableLanguage::create(array( - 'id' => $language_code, - 'label' => $this->randomMachineName(), - ))->save(); - } - } - - /** - * Tests menu language settings and the defaults for menu link items. - */ - function testMenuLanguage() { - // Create a test menu to test the various language-related settings. - // Machine name has to be lowercase. - $menu_name = Unicode::strtolower($this->randomMachineName(16)); - $label = $this->randomString(); - $edit = array( - 'id' => $menu_name, - 'description' => '', - 'label' => $label, - 'langcode' => 'aa', - ); - $this->drupalPostForm('admin/structure/menu/add', $edit, t('Save')); - ContentLanguageSettings::loadByEntityTypeBundle('menu_link_content', 'menu_link_content') - ->setDefaultLangcode('bb') - ->setLanguageAlterable(TRUE) - ->save(); - - // Check menu language. - $this->assertOptionSelected('edit-langcode', $edit['langcode'], 'The menu language was correctly selected.'); - - // Test menu link language. - $link_path = '/'; - - // Add a menu link. - $link_title = $this->randomString(); - $edit = array( - 'title[0][value]' => $link_title, - 'link[0][uri]' => $link_path, - ); - $this->drupalPostForm("admin/structure/menu/manage/$menu_name/add", $edit, t('Save')); - // Check the link was added with the correct menu link default language. - $menu_links = entity_load_multiple_by_properties('menu_link_content', array('title' => $link_title)); - $menu_link = reset($menu_links); - $this->assertMenuLink($menu_link->getPluginId(), array( - 'menu_name' => $menu_name, - 'route_name' => '', - 'langcode' => 'bb', - )); - - // Edit menu link default, changing it to cc. - ContentLanguageSettings::loadByEntityTypeBundle('menu_link_content', 'menu_link_content') - ->setDefaultLangcode('cc') - ->setLanguageAlterable(TRUE) - ->save(); - - // Add a menu link. - $link_title = $this->randomString(); - $edit = array( - 'title[0][value]' => $link_title, - 'link[0][uri]' => $link_path, - ); - $this->drupalPostForm("admin/structure/menu/manage/$menu_name/add", $edit, t('Save')); - // Check the link was added with the correct new menu link default language. - $menu_links = entity_load_multiple_by_properties('menu_link_content', array('title' => $link_title)); - $menu_link = reset($menu_links); - $this->assertMenuLink($menu_link->getPluginId(), array( - 'menu_name' => $menu_name, - 'route_name' => '', - 'langcode' => 'cc', - )); - - // Now change the language of the new link to 'bb'. - $edit = array( - 'langcode[0][value]' => 'bb', - ); - $this->drupalPostForm('admin/structure/menu/item/' . $menu_link->id() . '/edit', $edit, t('Save')); - $this->assertMenuLink($menu_link->getPluginId(), array( - 'menu_name' => $menu_name, - 'route_name' => '', - 'langcode' => 'bb', - )); - - // Saving menu link items ends up on the edit menu page. To check the menu - // link has the correct language default on edit, go to the menu link edit - // page first. - $this->drupalGet('admin/structure/menu/item/' . $menu_link->id() . '/edit'); - // Check that the language selector has the correct default value. - $this->assertOptionSelected('edit-langcode-0-value', 'bb', 'The menu link language was correctly selected.'); - - // Edit menu to hide the language select on menu link item add. - ContentLanguageSettings::loadByEntityTypeBundle('menu_link_content', 'menu_link_content') - ->setDefaultLangcode('cc') - ->setLanguageAlterable(FALSE) - ->save(); - - // Check that the language selector is not available on menu link add page. - $this->drupalGet("admin/structure/menu/manage/$menu_name/add"); - $this->assertNoField('edit-langcode-0-value', 'The language selector field was hidden the page'); - } - -} diff --git a/core/modules/menu_ui/src/Tests/MenuLinkReorderTest.php b/core/modules/menu_ui/src/Tests/MenuLinkReorderTest.php deleted file mode 100644 index 0396f17..0000000 --- a/core/modules/menu_ui/src/Tests/MenuLinkReorderTest.php +++ /dev/null @@ -1,67 +0,0 @@ -drupalPlaceBlock('system_menu_block:main'); - - // Assert that the Home link is available. - $this->drupalGet('test-page'); - $this->assertLink('Home'); - - // The administrator user that can re-order menu links. - $this->administrator = $this->drupalCreateUser(array( - 'administer site configuration', - 'access administration pages', - 'administer menu', - )); - $this->drupalLogin($this->administrator); - - // Change the weight of the link to a non default value. - $edit = array( - 'links[menu_plugin_id:test_page_test.front_page][weight]' => -10, - ); - $this->drupalPostForm('admin/structure/menu/manage/main', $edit, t('Save')); - - // The link is still there. - $this->drupalGet('test-page'); - $this->assertLink('Home'); - - // Clear all caches. - $this->drupalPostForm('admin/config/development/performance', [], t('Clear all caches')); - - // Clearing all caches should not affect the state of the menu link. - $this->drupalGet('test-page'); - $this->assertLink('Home'); - - } - -} diff --git a/core/modules/menu_ui/src/Tests/MenuNodeTest.php b/core/modules/menu_ui/src/Tests/MenuNodeTest.php deleted file mode 100644 index 3fc8423..0000000 --- a/core/modules/menu_ui/src/Tests/MenuNodeTest.php +++ /dev/null @@ -1,341 +0,0 @@ -drupalPlaceBlock('system_menu_block:main'); - $this->drupalPlaceBlock('page_title_block'); - - $this->drupalCreateContentType(array('type' => 'page', 'name' => 'Basic page')); - - $this->editor = $this->drupalCreateUser(array( - 'access administration pages', - 'administer content types', - 'administer menu', - 'create page content', - 'edit any page content', - 'delete any page content', - 'create content translations', - 'update content translations', - 'delete content translations', - 'translate any entity', - )); - $this->drupalLogin($this->editor); - } - - /** - * Test creating, editing, deleting menu links via node form widget. - */ - function testMenuNodeFormWidget() { - // Verify that cacheability metadata is bubbled from the menu link tree - // access checking that is performed when determining the "default parent - // item" options in menu_ui_form_node_type_form_alter(). The "log out" link - // adds the "user.roles:authenticated" cache context. - $this->drupalGet('admin/structure/types/manage/page'); - $this->assertCacheContext('user.roles:authenticated'); - - // Verify that the menu link title has the correct maxlength. - $max_length = \Drupal::entityManager()->getBaseFieldDefinitions('menu_link_content')['title']->getSetting('max_length'); - $this->drupalGet('node/add/page'); - $this->assertPattern('//', 'Menu link title field has correct maxlength in node add form.'); - - // Disable the default main menu, so that no menus are enabled. - $edit = array( - 'menu_options[main]' => FALSE, - ); - $this->drupalPostForm('admin/structure/types/manage/page', $edit, t('Save content type')); - - // Verify that no menu settings are displayed and nodes can be created. - $this->drupalGet('node/add/page'); - $this->assertText(t('Create Basic page')); - $this->assertNoText(t('Menu settings')); - $node_title = $this->randomMachineName(); - $edit = array( - 'title[0][value]' => $node_title, - 'body[0][value]' => $this->randomString(), - ); - $this->drupalPostForm(NULL, $edit, t('Save')); - $node = $this->drupalGetNodeByTitle($node_title); - $this->assertEqual($node->getTitle(), $edit['title[0][value]']); - - // Test that we cannot set a menu item from a menu that is not set as - // available. - $edit = array( - 'menu_options[tools]' => 1, - 'menu_parent' => 'main:', - ); - $this->drupalPostForm('admin/structure/types/manage/page', $edit, t('Save content type')); - $this->assertText(t('The selected menu item is not under one of the selected menus.')); - $this->assertNoRaw(t('The content type %name has been updated.', array('%name' => 'Basic page'))); - - // Enable Tools menu as available menu. - $edit = array( - 'menu_options[main]' => 1, - 'menu_options[tools]' => 1, - 'menu_parent' => 'main:', - ); - $this->drupalPostForm('admin/structure/types/manage/page', $edit, t('Save content type')); - $this->assertRaw(t('The content type %name has been updated.', array('%name' => 'Basic page'))); - - // Test that we can preview a node that will create a menu item. - $edit = array( - 'title[0][value]' => $node_title, - 'menu[enabled]' => 1, - 'menu[title]' => 'Test preview', - ); - $this->drupalPostForm('node/add/page', $edit, t('Preview')); - - // Create a node. - $node_title = $this->randomMachineName(); - $edit = array( - 'title[0][value]' => $node_title, - 'body[0][value]' => $this->randomString(), - ); - $this->drupalPostForm('node/add/page', $edit, t('Save')); - $node = $this->drupalGetNodeByTitle($node_title); - // Assert that there is no link for the node. - $this->drupalGet('test-page'); - $this->assertNoLink($node_title); - - // Edit the node, enable the menu link setting, but skip the link title. - $edit = array( - 'menu[enabled]' => 1, - ); - $this->drupalPostForm('node/' . $node->id() . '/edit', $edit, t('Save')); - // Assert that there is no link for the node. - $this->drupalGet('test-page'); - $this->assertNoLink($node_title); - - // Use not only the save button, but also the two special buttons: - // 'Save and publish' as well as 'Save and keep published'. - // These buttons just appear for 'administer nodes' users. - $admin_user = $this->drupalCreateUser([ - 'access administration pages', - 'administer content types', - 'administer nodes', - 'administer menu', - 'create page content', - 'edit any page content', - ]); - $this->drupalLogin($admin_user); - foreach (['Save and unpublish' => FALSE, 'Save and keep unpublished' => FALSE, 'Save and publish' => TRUE, 'Save and keep published' => TRUE] as $submit => $visible) { - $edit = [ - 'menu[enabled]' => 1, - 'menu[title]' => $node_title, - ]; - $this->drupalPostForm('node/' . $node->id() . '/edit', $edit, $submit); - // Assert that the link exists. - $this->drupalGet('test-page'); - if ($visible) { - $this->assertLink($node_title, 0, 'Found a menu link after submitted with ' . $submit); - } - else { - $this->assertNoLink($node_title, 'Found no menu link after submitted with ' . $submit); - } - } - - // Log back in as normal user. - $this->drupalLogin($this->editor); - // Edit the node and create a menu link. - $edit = array( - 'menu[enabled]' => 1, - 'menu[title]' => $node_title, - 'menu[weight]' => 17, - ); - $this->drupalPostForm('node/' . $node->id() . '/edit', $edit, t('Save')); - // Assert that the link exists. - $this->drupalGet('test-page'); - $this->assertLink($node_title); - - $this->drupalGet('node/' . $node->id() . '/edit'); - $this->assertFieldById('edit-menu-weight', 17, 'Menu weight correct in edit form'); - $this->assertPattern('//', 'Menu link title field has correct maxlength in node edit form.'); - - // Disable the menu link, then edit the node--the link should stay disabled. - $link_id = menu_ui_get_menu_link_defaults($node)['entity_id']; - /** @var \Drupal\menu_link_content\Entity\MenuLinkContent $link */ - $link = MenuLinkContent::load($link_id); - $link->set('enabled', FALSE); - $link->save(); - $this->drupalPostForm($node->urlInfo('edit-form'), $edit, t('Save')); - $link = MenuLinkContent::load($link_id); - $this->assertFalse($link->isEnabled(), 'Saving a node with a disabled menu link keeps the menu link disabled.'); - - // Edit the node and remove the menu link. - $edit = array( - 'menu[enabled]' => FALSE, - ); - $this->drupalPostForm('node/' . $node->id() . '/edit', $edit, t('Save')); - // Assert that there is no link for the node. - $this->drupalGet('test-page'); - $this->assertNoLink($node_title); - - // Add a menu link to the Administration menu. - $item = MenuLinkContent::create(array( - 'link' => [['uri' => 'entity:node/' . $node->id()]], - 'title' => $this->randomMachineName(16), - 'menu_name' => 'admin', - )); - $item->save(); - - // Assert that disabled Administration menu is not shown on the - // node/$nid/edit page. - $this->drupalGet('node/' . $node->id() . '/edit'); - $this->assertText('Provide a menu link', 'Link in not allowed menu not shown in node edit form'); - // Assert that the link is still in the Administration menu after save. - $this->drupalPostForm('node/' . $node->id() . '/edit', $edit, t('Save')); - $link = MenuLinkContent::load($item->id()); - $this->assertTrue($link, 'Link in not allowed menu still exists after saving node'); - - // Move the menu link back to the Tools menu. - $item->menu_name->value = 'tools'; - $item->save(); - // Create a second node. - $child_node = $this->drupalCreateNode(array('type' => 'article')); - // Assign a menu link to the second node, being a child of the first one. - $child_item = MenuLinkContent::create(array( - 'link' => [['uri' => 'entity:node/' . $child_node->id()]], - 'title' => $this->randomMachineName(16), - 'parent' => $item->getPluginId(), - 'menu_name' => $item->getMenuName(), - )); - $child_item->save(); - // Edit the first node. - $this->drupalGet('node/' . $node->id() . '/edit'); - // Assert that it is not possible to set the parent of the first node to itself or the second node. - $this->assertNoOption('edit-menu-menu-parent', 'tools:' . $item->getPluginId()); - $this->assertNoOption('edit-menu-menu-parent', 'tools:' . $child_item->getPluginId()); - // Assert that unallowed Administration menu is not available in options. - $this->assertNoOption('edit-menu-menu-parent', 'admin:'); - } - - /** - * Testing correct loading and saving of menu links via node form widget in a multilingual environment. - */ - function testMultilingualMenuNodeFormWidget() { - // Setup languages. - $langcodes = array('de'); - foreach ($langcodes as $langcode) { - ConfigurableLanguage::createFromLangcode($langcode)->save(); - } - array_unshift($langcodes, \Drupal::languageManager()->getDefaultLanguage()->getId()); - - $config = \Drupal::service('config.factory')->getEditable('language.negotiation'); - // Ensure path prefix is used to determine the language. - $config->set('url.source', 'path_prefix'); - // Ensure that there's a path prefix set for english as well. - $config->set('url.prefixes.' . $langcodes[0], $langcodes[0]); - $config->save(); - - $this->rebuildContainer(); - - $languages = array(); - foreach ($langcodes as $langcode) { - $languages[$langcode] = ConfigurableLanguage::load($langcode); - } - - // Use a UI form submission to make the node type and menu link content entity translatable. - $this->drupalLogout(); - $this->drupalLogin($this->rootUser); - $edit = array( - 'entity_types[node]' => TRUE, - 'entity_types[menu_link_content]' => TRUE, - 'settings[node][page][settings][language][language_alterable]' => TRUE, - 'settings[node][page][translatable]' => TRUE, - 'settings[node][page][fields][title]' => TRUE, - 'settings[menu_link_content][menu_link_content][translatable]' => TRUE, - ); - $this->drupalPostForm('admin/config/regional/content-language', $edit, t('Save configuration')); - - // Log out and back in as normal user. - $this->drupalLogout(); - $this->drupalLogin($this->editor); - - // Create a node. - $node_title = $this->randomMachineName(8); - $node = Node::create([ - 'type' => 'page', - 'title' => $node_title, - 'body' => $this->randomMachineName(16), - 'uid' => $this->editor->id(), - 'status' => 1, - 'langcode' => $langcodes[0], - ]); - $node->save(); - - // Create translation. - $translated_node_title = $this->randomMachineName(8); - $node->addTranslation($langcodes[1], ['title' => $translated_node_title, 'body' => $this->randomMachineName(16), 'status' => 1]); - $node->save(); - - // Edit the node and create a menu link. - $edit = array( - 'menu[enabled]' => 1, - 'menu[title]' => $node_title, - 'menu[weight]' => 17, - ); - $options = array('language' => $languages[$langcodes[0]]); - $url = $node->toUrl('edit-form', $options); - $this->drupalPostForm($url, $edit, t('Save') . ' ' . t('(this translation)')); - - // Edit the node in a different language and translate the menu link. - $edit = array( - 'menu[enabled]' => 1, - 'menu[title]' => $translated_node_title, - 'menu[weight]' => 17, - ); - $options = array('language' => $languages[$langcodes[1]]); - $url = $node->toUrl('edit-form', $options); - $this->drupalPostForm($url, $edit, t('Save') . ' ' . t('(this translation)')); - - // Assert that the original link exists in the frontend. - $this->drupalGet('node/' . $node->id(), array('language' => $languages[$langcodes[0]])); - $this->assertLink($node_title); - - // Assert that the translated link exists in the frontend. - $this->drupalGet('node/' . $node->id(), array('language' => $languages[$langcodes[1]])); - $this->assertLink($translated_node_title); - - // Revisit the edit page in original language, check the loaded menu item title and save. - $options = array('language' => $languages[$langcodes[0]]); - $url = $node->toUrl('edit-form', $options); - $this->drupalGet($url); - $this->assertFieldById('edit-menu-title', $node_title); - $this->drupalPostForm(NULL, [], t('Save') . ' ' . t('(this translation)')); - - // Revisit the edit page of the translation and check the loaded menu item title. - $options = array('language' => $languages[$langcodes[1]]); - $url = $node->toUrl('edit-form', $options); - $this->drupalGet($url); - $this->assertFieldById('edit-menu-title', $translated_node_title); - } - -} diff --git a/core/modules/menu_ui/src/Tests/MenuTest.php b/core/modules/menu_ui/src/Tests/MenuTest.php deleted file mode 100644 index f640cc7..0000000 --- a/core/modules/menu_ui/src/Tests/MenuTest.php +++ /dev/null @@ -1,961 +0,0 @@ -drupalPlaceBlock('page_title_block'); - - $this->drupalCreateContentType(array('type' => 'article', 'name' => 'Article')); - - // Create users. - $this->adminUser = $this->drupalCreateUser(array('access administration pages', 'administer blocks', 'administer menu', 'create article content')); - $this->authenticatedUser = $this->drupalCreateUser(array()); - } - - /** - * Tests menu functionality using the admin and user interfaces. - */ - function testMenu() { - // Log in the user. - $this->drupalLogin($this->adminUser); - $this->items = array(); - - $this->menu = $this->addCustomMenu(); - $this->doMenuTests(); - $this->doTestMenuBlock(); - $this->addInvalidMenuLink(); - $this->addCustomMenuCRUD(); - - // Verify that the menu links rebuild is idempotent and leaves the same - // number of links in the table. - /** @var \Drupal\Core\Menu\MenuLinkManagerInterface $menu_link_manager */ - $menu_link_manager = \Drupal::service('plugin.manager.menu.link'); - $before_count = $menu_link_manager->countMenuLinks(NULL); - $menu_link_manager->rebuild(); - $after_count = $menu_link_manager->countMenuLinks(NULL); - $this->assertIdentical($before_count, $after_count, 'MenuLinkManager::rebuild() does not add more links'); - // Do standard user tests. - // Log in the user. - $this->drupalLogin($this->authenticatedUser); - $this->verifyAccess(403); - - foreach ($this->items as $item) { - // Menu link URIs are stored as 'internal:/node/$nid'. - $node = Node::load(str_replace('internal:/node/', '', $item->link->uri)); - $this->verifyMenuLink($item, $node); - } - - // Log in the administrator. - $this->drupalLogin($this->adminUser); - - // Verify delete link exists and reset link does not exist. - $this->drupalGet('admin/structure/menu/manage/' . $this->menu->id()); - $this->assertLinkByHref(Url::fromRoute('entity.menu_link_content.delete_form', ['menu_link_content' => $this->items[0]->id()])->toString()); - $this->assertNoLinkByHref(Url::fromRoute('menu_ui.link_reset', ['menu_link_plugin' => $this->items[0]->getPluginId()])->toString()); - // Check delete and reset access. - $this->drupalGet('admin/structure/menu/item/' . $this->items[0]->id() . '/delete'); - $this->assertResponse(200); - $this->drupalGet('admin/structure/menu/link/' . $this->items[0]->getPluginId() . '/reset'); - $this->assertResponse(403); - - // Delete menu links. - foreach ($this->items as $item) { - $this->deleteMenuLink($item); - } - - // Delete custom menu. - $this->deleteCustomMenu(); - - // Modify and reset a standard menu link. - $instance = $this->getStandardMenuLink(); - $old_weight = $instance->getWeight(); - // Edit the static menu link. - $edit = array(); - $edit['weight'] = 10; - $id = $instance->getPluginId(); - $this->drupalPostForm("admin/structure/menu/link/$id/edit", $edit, t('Save')); - $this->assertResponse(200); - $this->assertText('The menu link has been saved.'); - $menu_link_manager->resetDefinitions(); - - $instance = $menu_link_manager->createInstance($instance->getPluginId()); - $this->assertEqual($edit['weight'], $instance->getWeight(), 'Saving an existing link updates the weight.'); - $this->resetMenuLink($instance, $old_weight); - } - - /** - * Adds a custom menu using CRUD functions. - */ - function addCustomMenuCRUD() { - // Add a new custom menu. - $menu_name = substr(hash('sha256', $this->randomMachineName(16)), 0, MENU_MAX_MENU_NAME_LENGTH_UI); - $label = $this->randomMachineName(16); - - $menu = Menu::create(array( - 'id' => $menu_name, - 'label' => $label, - 'description' => 'Description text', - )); - $menu->save(); - - // Assert the new menu. - $this->drupalGet('admin/structure/menu/manage/' . $menu_name); - $this->assertRaw($label, 'Custom menu was added.'); - - // Edit the menu. - $new_label = $this->randomMachineName(16); - $menu->set('label', $new_label); - $menu->save(); - $this->drupalGet('admin/structure/menu/manage/' . $menu_name); - $this->assertRaw($new_label, 'Custom menu was edited.'); - } - - /** - * Creates a custom menu. - * - * @return \Drupal\system\Entity\Menu - * The custom menu that has been created. - */ - function addCustomMenu() { - // Try adding a menu using a menu_name that is too long. - $this->drupalGet('admin/structure/menu/add'); - $menu_name = substr(hash('sha256', $this->randomMachineName(16)), 0, MENU_MAX_MENU_NAME_LENGTH_UI + 1); - $label = $this->randomMachineName(16); - $edit = array( - 'id' => $menu_name, - 'description' => '', - 'label' => $label, - ); - $this->drupalPostForm('admin/structure/menu/add', $edit, t('Save')); - - // Verify that using a menu_name that is too long results in a validation - // message. - $this->assertRaw(t('@name cannot be longer than %max characters but is currently %length characters long.', array( - '@name' => t('Menu name'), - '%max' => MENU_MAX_MENU_NAME_LENGTH_UI, - '%length' => Unicode::strlen($menu_name), - ))); - - // Change the menu_name so it no longer exceeds the maximum length. - $menu_name = substr(hash('sha256', $this->randomMachineName(16)), 0, MENU_MAX_MENU_NAME_LENGTH_UI); - $edit['id'] = $menu_name; - $this->drupalPostForm('admin/structure/menu/add', $edit, t('Save')); - - // Verify that no validation error is given for menu_name length. - $this->assertNoRaw(t('@name cannot be longer than %max characters but is currently %length characters long.', array( - '@name' => t('Menu name'), - '%max' => MENU_MAX_MENU_NAME_LENGTH_UI, - '%length' => Unicode::strlen($menu_name), - ))); - // Verify that the confirmation message is displayed. - $this->assertRaw(t('Menu %label has been added.', array('%label' => $label))); - $this->drupalGet('admin/structure/menu'); - $this->assertText($label, 'Menu created'); - - // Confirm that the custom menu block is available. - $this->drupalGet('admin/structure/block/list/' . $this->config('system.theme')->get('default')); - $this->clickLinkPartialName('Place block'); - $this->assertText($label); - - // Enable the block. - $block = $this->drupalPlaceBlock('system_menu_block:' . $menu_name); - $this->blockPlacements[$menu_name] = $block->id(); - return Menu::load($menu_name); - } - - /** - * Deletes the locally stored custom menu. - * - * This deletes the custom menu that is stored in $this->menu and performs - * tests on the menu delete user interface. - */ - function deleteCustomMenu() { - $menu_name = $this->menu->id(); - $label = $this->menu->label(); - - // Delete custom menu. - $this->drupalPostForm("admin/structure/menu/manage/$menu_name/delete", array(), t('Delete')); - $this->assertResponse(200); - $this->assertRaw(t('The menu %title has been deleted.', array('%title' => $label)), 'Custom menu was deleted'); - $this->assertNull(Menu::load($menu_name), 'Custom menu was deleted'); - // Test if all menu links associated with the menu were removed from - // database. - $result = entity_load_multiple_by_properties('menu_link_content', array('menu_name' => $menu_name)); - $this->assertFalse($result, 'All menu links associated with the custom menu were deleted.'); - - // Make sure there's no delete button on system menus. - $this->drupalGet('admin/structure/menu/manage/main'); - $this->assertNoRaw('edit-delete', 'The delete button was not found'); - - // Try to delete the main menu. - $this->drupalGet('admin/structure/menu/manage/main/delete'); - $this->assertText(t('You are not authorized to access this page.')); - } - - /** - * Tests menu functionality. - */ - function doMenuTests() { - $menu_name = $this->menu->id(); - - // Test the 'Add link' local action. - $this->drupalGet(Url::fromRoute('entity.menu.edit_form', ['menu' => $menu_name])); - - $this->clickLink(t('Add link')); - $link_title = $this->randomString(); - $this->drupalPostForm(NULL, array('link[0][uri]' => '/', 'title[0][value]' => $link_title), t('Save')); - $this->assertUrl(Url::fromRoute('entity.menu.edit_form', ['menu' => $menu_name])); - // Test the 'Edit' operation. - $this->clickLink(t('Edit')); - $this->assertFieldByName('title[0][value]', $link_title); - $link_title = $this->randomString(); - $this->drupalPostForm(NULL, array('title[0][value]' => $link_title), t('Save')); - $this->assertUrl(Url::fromRoute('entity.menu.edit_form', ['menu' => $menu_name])); - // Test the 'Delete' operation. - $this->clickLink(t('Delete')); - $this->assertRaw(t('Are you sure you want to delete the custom menu link %item?', array('%item' => $link_title))); - $this->drupalPostForm(NULL, array(), t('Delete')); - $this->assertUrl(Url::fromRoute('entity.menu.edit_form', ['menu' => $menu_name])); - - // Add nodes to use as links for menu links. - $node1 = $this->drupalCreateNode(array('type' => 'article')); - $node2 = $this->drupalCreateNode(array('type' => 'article')); - $node3 = $this->drupalCreateNode(array('type' => 'article')); - $node4 = $this->drupalCreateNode(array('type' => 'article')); - // Create a node with an alias. - $node5 = $this->drupalCreateNode(array( - 'type' => 'article', - 'path' => array( - 'alias' => '/node5', - ), - )); - - // Verify add link button. - $this->drupalGet('admin/structure/menu'); - $this->assertLinkByHref('admin/structure/menu/manage/' . $menu_name . '/add', 0, "The add menu link button URL is correct"); - - // Verify form defaults. - $this->doMenuLinkFormDefaultsTest(); - - // Add menu links. - $item1 = $this->addMenuLink('', '/node/' . $node1->id(), $menu_name, TRUE); - $item2 = $this->addMenuLink($item1->getPluginId(), '/node/' . $node2->id(), $menu_name, FALSE); - $item3 = $this->addMenuLink($item2->getPluginId(), '/node/' . $node3->id(), $menu_name); - - // Hierarchy - // <$menu_name> - // - item1 - // -- item2 - // --- item3 - - $this->assertMenuLink($item1->getPluginId(), array( - 'children' => array($item2->getPluginId(), $item3->getPluginId()), - 'parents' => array($item1->getPluginId()), - // We assert the language code here to make sure that the language - // selection element degrades gracefully without the Language module. - 'langcode' => 'en', - )); - $this->assertMenuLink($item2->getPluginId(), array( - 'children' => array($item3->getPluginId()), - 'parents' => array($item2->getPluginId(), $item1->getPluginId()), - // See above. - 'langcode' => 'en', - )); - $this->assertMenuLink($item3->getPluginId(), array( - 'children' => array(), - 'parents' => array($item3->getPluginId(), $item2->getPluginId(), $item1->getPluginId()), - // See above. - 'langcode' => 'en', - )); - - // Verify menu links. - $this->verifyMenuLink($item1, $node1); - $this->verifyMenuLink($item2, $node2, $item1, $node1); - $this->verifyMenuLink($item3, $node3, $item2, $node2); - - // Add more menu links. - $item4 = $this->addMenuLink('', '/node/' . $node4->id(), $menu_name); - $item5 = $this->addMenuLink($item4->getPluginId(), '/node/' . $node5->id(), $menu_name); - // Create a menu link pointing to an alias. - $item6 = $this->addMenuLink($item4->getPluginId(), '/node5', $menu_name, TRUE, '0'); - - // Hierarchy - // <$menu_name> - // - item1 - // -- item2 - // --- item3 - // - item4 - // -- item5 - // -- item6 - - $this->assertMenuLink($item4->getPluginId(), array( - 'children' => array($item5->getPluginId(), $item6->getPluginId()), - 'parents' => array($item4->getPluginId()), - // See above. - 'langcode' => 'en', - )); - $this->assertMenuLink($item5->getPluginId(), array( - 'children' => array(), - 'parents' => array($item5->getPluginId(), $item4->getPluginId()), - 'langcode' => 'en', - )); - $this->assertMenuLink($item6->getPluginId(), array( - 'children' => array(), - 'parents' => array($item6->getPluginId(), $item4->getPluginId()), - 'route_name' => 'entity.node.canonical', - 'route_parameters' => array('node' => $node5->id()), - 'url' => '', - // See above. - 'langcode' => 'en', - )); - - // Modify menu links. - $this->modifyMenuLink($item1); - $this->modifyMenuLink($item2); - - // Toggle menu links. - $this->toggleMenuLink($item1); - $this->toggleMenuLink($item2); - - // Move link and verify that descendants are updated. - $this->moveMenuLink($item2, $item5->getPluginId(), $menu_name); - // Hierarchy - // <$menu_name> - // - item1 - // - item4 - // -- item5 - // --- item2 - // ---- item3 - // -- item6 - - $this->assertMenuLink($item1->getPluginId(), array( - 'children' => array(), - 'parents' => array($item1->getPluginId()), - // See above. - 'langcode' => 'en', - )); - $this->assertMenuLink($item4->getPluginId(), array( - 'children' => array($item5->getPluginId(), $item6->getPluginId(), $item2->getPluginId(), $item3->getPluginId()), - 'parents' => array($item4->getPluginId()), - // See above. - 'langcode' => 'en', - )); - - $this->assertMenuLink($item5->getPluginId(), array( - 'children' => array($item2->getPluginId(), $item3->getPluginId()), - 'parents' => array($item5->getPluginId(), $item4->getPluginId()), - // See above. - 'langcode' => 'en', - )); - $this->assertMenuLink($item2->getPluginId(), array( - 'children' => array($item3->getPluginId()), - 'parents' => array($item2->getPluginId(), $item5->getPluginId(), $item4->getPluginId()), - // See above. - 'langcode' => 'en', - )); - $this->assertMenuLink($item3->getPluginId(), array( - 'children' => array(), - 'parents' => array($item3->getPluginId(), $item2->getPluginId(), $item5->getPluginId(), $item4->getPluginId()), - // See above. - 'langcode' => 'en', - )); - - // Add 102 menu links with increasing weights, then make sure the last-added - // item's weight doesn't get changed because of the old hardcoded delta=50. - $items = array(); - for ($i = -50; $i <= 51; $i++) { - $items[$i] = $this->addMenuLink('', '/node/' . $node1->id(), $menu_name, TRUE, strval($i)); - } - $this->assertMenuLink($items[51]->getPluginId(), array('weight' => '51')); - - // Disable a link and then re-enable the link via the overview form. - $this->disableMenuLink($item1); - $edit = array(); - $edit['links[menu_plugin_id:' . $item1->getPluginId() . '][enabled]'] = TRUE; - $this->drupalPostForm('admin/structure/menu/manage/' . $item1->getMenuName(), $edit, t('Save')); - - // Mark item2, item4 and item5 as expanded. - // This is done in order to show them on the frontpage. - $item2->expanded->value = 1; - $item2->save(); - $item4->expanded->value = 1; - $item4->save(); - $item5->expanded->value = 1; - $item5->save(); - - // Verify in the database. - $this->assertMenuLink($item1->getPluginId(), array('enabled' => 1)); - - // Add an external link. - $item7 = $this->addMenuLink('', 'https://www.drupal.org', $menu_name); - $this->assertMenuLink($item7->getPluginId(), array('url' => 'https://www.drupal.org')); - - // Add menu item. - $item8 = $this->addMenuLink('', '/', $menu_name); - $this->assertMenuLink($item8->getPluginId(), array('route_name' => '')); - $this->drupalGet(''); - $this->assertResponse(200); - // Make sure we get routed correctly. - $this->clickLink($item8->getTitle()); - $this->assertResponse(200); - - // Check invalid menu link parents. - $this->checkInvalidParentMenuLinks(); - - // Save menu links for later tests. - $this->items[] = $item1; - $this->items[] = $item2; - } - - /** - * Ensures that the proper default values are set when adding a menu link - */ - protected function doMenuLinkFormDefaultsTest() { - $this->drupalGet("admin/structure/menu/manage/tools/add"); - $this->assertResponse(200); - - $this->assertFieldByName('title[0][value]', ''); - $this->assertFieldByName('link[0][uri]', ''); - - $this->assertNoFieldChecked('edit-expanded-value'); - $this->assertFieldChecked('edit-enabled-value'); - - $this->assertFieldByName('description[0][value]', ''); - $this->assertFieldByName('weight[0][value]', 0); - } - - /** - * Adds and removes a menu link with a query string and fragment. - */ - function testMenuQueryAndFragment() { - $this->drupalLogin($this->adminUser); - - // Make a path with query and fragment on. - $path = '/test-page?arg1=value1&arg2=value2'; - $item = $this->addMenuLink('', $path); - - $this->drupalGet('admin/structure/menu/item/' . $item->id() . '/edit'); - $this->assertFieldByName('link[0][uri]', $path, 'Path is found with both query and fragment.'); - - // Now change the path to something without query and fragment. - $path = '/test-page'; - $this->drupalPostForm('admin/structure/menu/item/' . $item->id() . '/edit', array('link[0][uri]' => $path), t('Save')); - $this->drupalGet('admin/structure/menu/item/' . $item->id() . '/edit'); - $this->assertFieldByName('link[0][uri]', $path, 'Path no longer has query or fragment.'); - - // Use #fragment and ensure that saving it does not lose its content. - $path = '?arg1=value#fragment'; - $item = $this->addMenuLink('', $path); - - $this->drupalGet('admin/structure/menu/item/' . $item->id() . '/edit'); - $this->assertFieldByName('link[0][uri]', $path, 'Path is found with both query and fragment.'); - - $this->drupalPostForm('admin/structure/menu/item/' . $item->id() . '/edit', array(), t('Save')); - - $this->drupalGet('admin/structure/menu/item/' . $item->id() . '/edit'); - $this->assertFieldByName('link[0][uri]', $path, 'Path is found with both query and fragment.'); - } - - /** - * Tests renaming the built-in menu. - */ - function testSystemMenuRename() { - $this->drupalLogin($this->adminUser); - $edit = array( - 'label' => $this->randomMachineName(16), - ); - $this->drupalPostForm('admin/structure/menu/manage/main', $edit, t('Save')); - - // Make sure menu shows up with new name in block addition. - $default_theme = $this->config('system.theme')->get('default'); - $this->drupalget('admin/structure/block/list/' . $default_theme); - $this->clickLinkPartialName('Place block'); - $this->assertText($edit['label']); - } - - /** - * Tests that menu items pointing to unpublished nodes are editable. - */ - function testUnpublishedNodeMenuItem() { - $this->drupalLogin($this->drupalCreateUser(array('access administration pages', 'administer blocks', 'administer menu', 'create article content', 'bypass node access'))); - // Create an unpublished node. - $node = $this->drupalCreateNode(array( - 'type' => 'article', - 'status' => NODE_NOT_PUBLISHED, - )); - - $item = $this->addMenuLink('', '/node/' . $node->id()); - $this->modifyMenuLink($item); - - // Test that a user with 'administer menu' but without 'bypass node access' - // cannot see the menu item. - $this->drupalLogout(); - $this->drupalLogin($this->adminUser); - $this->drupalGet('admin/structure/menu/manage/' . $item->getMenuName()); - $this->assertNoText($item->getTitle(), "Menu link pointing to unpublished node is only visible to users with 'bypass node access' permission"); - // The cache contexts associated with the (in)accessible menu links are - // bubbled. See DefaultMenuLinkTreeManipulators::menuLinkCheckAccess(). - $this->assertCacheContext('user.permissions'); - } - - /** - * Tests the contextual links on a menu block. - */ - public function testBlockContextualLinks() { - $this->drupalLogin($this->drupalCreateUser(array('administer menu', 'access contextual links', 'administer blocks'))); - $custom_menu = $this->addCustomMenu(); - $this->addMenuLink('', '/', $custom_menu->id()); - $block = $this->drupalPlaceBlock('system_menu_block:' . $custom_menu->id(), array('label' => 'Custom menu', 'provider' => 'system')); - $this->drupalGet('test-page'); - - $id = 'block:block=' . $block->id() . ':langcode=en|menu:menu=' . $custom_menu->id() . ':langcode=en'; - // @see \Drupal\contextual\Tests\ContextualDynamicContextTest:assertContextualLinkPlaceHolder() - $this->assertRaw('
', format_string('Contextual link placeholder with id @id exists.', array('@id' => $id))); - - // Get server-rendered contextual links. - // @see \Drupal\contextual\Tests\ContextualDynamicContextTest:renderContextualLinks() - $post = array('ids[0]' => $id); - $response = $this->drupalPost('contextual/render', 'application/json', $post, array('query' => array('destination' => 'test-page'))); - $this->assertResponse(200); - $json = Json::decode($response); - $this->assertIdentical($json[$id], ''); - } - - /** - * Adds a menu link using the UI. - * - * @param string $parent - * Optional parent menu link id. - * @param string $path - * The path to enter on the form. Defaults to the front page. - * @param string $menu_name - * Menu name. Defaults to 'tools'. - * @param bool $expanded - * Whether or not this menu link is expanded. Setting this to TRUE should - * test whether it works when we do the authenticatedUser tests. Defaults - * to FALSE. - * @param string $weight - * Menu weight. Defaults to 0. - * - * @return \Drupal\menu_link_content\Entity\MenuLinkContent - * A menu link entity. - */ - function addMenuLink($parent = '', $path = '/', $menu_name = 'tools', $expanded = FALSE, $weight = '0') { - // View add menu link page. - $this->drupalGet("admin/structure/menu/manage/$menu_name/add"); - $this->assertResponse(200); - - $title = '!link_' . $this->randomMachineName(16); - $edit = array( - 'link[0][uri]' => $path, - 'title[0][value]' => $title, - 'description[0][value]' => '', - 'enabled[value]' => 1, - 'expanded[value]' => $expanded, - 'menu_parent' => $menu_name . ':' . $parent, - 'weight[0][value]' => $weight, - ); - - // Add menu link. - $this->drupalPostForm(NULL, $edit, t('Save')); - $this->assertResponse(200); - $this->assertText('The menu link has been saved.'); - - $menu_links = entity_load_multiple_by_properties('menu_link_content', array('title' => $title)); - - $menu_link = reset($menu_links); - $this->assertTrue($menu_link, 'Menu link was found in database.'); - $this->assertMenuLink($menu_link->getPluginId(), array('menu_name' => $menu_name, 'children' => array(), 'parent' => $parent)); - - return $menu_link; - } - - /** - * Attempts to add menu link with invalid path or no access permission. - */ - function addInvalidMenuLink() { - foreach (array('access' => '/admin/people/permissions') as $type => $link_path) { - $edit = array( - 'link[0][uri]' => $link_path, - 'title[0][value]' => 'title', - ); - $this->drupalPostForm("admin/structure/menu/manage/{$this->menu->id()}/add", $edit, t('Save')); - $this->assertRaw(t("The path '@link_path' is inaccessible.", array('@link_path' => $link_path)), 'Menu link was not created'); - } - } - - /** - * Tests that parent options are limited by depth when adding menu links. - */ - function checkInvalidParentMenuLinks() { - $last_link = NULL; - $created_links = array(); - - // Get the max depth of the tree. - $menu_link_tree = \Drupal::service('menu.link_tree'); - $max_depth = $menu_link_tree->maxDepth(); - - // Create a maximum number of menu links, each a child of the previous. - for ($i = 0; $i <= $max_depth - 1; $i++) { - $parent = $last_link ? 'tools:' . $last_link->getPluginId() : 'tools:'; - $title = 'title' . $i; - $edit = array( - 'link[0][uri]' => '/', - 'title[0][value]' => $title, - 'menu_parent' => $parent, - 'description[0][value]' => '', - 'enabled[value]' => 1, - 'expanded[value]' => FALSE, - 'weight[0][value]' => '0', - ); - $this->drupalPostForm("admin/structure/menu/manage/{$this->menu->id()}/add", $edit, t('Save')); - $menu_links = entity_load_multiple_by_properties('menu_link_content', array('title' => $title)); - $last_link = reset($menu_links); - $created_links[] = 'tools:' . $last_link->getPluginId(); - } - - // The last link cannot be a parent in the new menu link form. - $this->drupalGet('admin/structure/menu/manage/admin/add'); - $value = 'tools:' . $last_link->getPluginId(); - $this->assertNoOption('edit-menu-parent', $value, 'The invalid option is not there.'); - - // All but the last link can be parents in the new menu link form. - array_pop($created_links); - foreach ($created_links as $key => $link) { - $this->assertOption('edit-menu-parent', $link, 'The valid option number ' . ($key + 1) . ' is there.'); - } - } - - /** - * Verifies a menu link using the UI. - * - * @param \Drupal\menu_link_content\Entity\MenuLinkContent $item - * Menu link. - * @param object $item_node - * Menu link content node. - * @param \Drupal\menu_link_content\Entity\MenuLinkContent $parent - * Parent menu link. - * @param object $parent_node - * Parent menu link content node. - */ - function verifyMenuLink(MenuLinkContent $item, $item_node, MenuLinkContent $parent = NULL, $parent_node = NULL) { - // View home page. - $this->drupalGet(''); - $this->assertResponse(200); - - // Verify parent menu link. - if (isset($parent)) { - // Verify menu link. - $title = $parent->getTitle(); - $this->assertLink($title, 0, 'Parent menu link was displayed'); - - // Verify menu link link. - $this->clickLink($title); - $title = $parent_node->label(); - $this->assertTitle(t("@title | Drupal", array('@title' => $title)), 'Parent menu link link target was correct'); - } - - // Verify menu link. - $title = $item->getTitle(); - $this->assertLink($title, 0, 'Menu link was displayed'); - - // Verify menu link link. - $this->clickLink($title); - $title = $item_node->label(); - $this->assertTitle(t("@title | Drupal", array('@title' => $title)), 'Menu link link target was correct'); - } - - /** - * Changes the parent of a menu link using the UI. - * - * @param \Drupal\menu_link_content\MenuLinkContentInterface $item - * The menu link item to move. - * @param int $parent - * The id of the new parent. - * @param string $menu_name - * The menu the menu link will be moved to. - */ - function moveMenuLink(MenuLinkContent $item, $parent, $menu_name) { - $mlid = $item->id(); - - $edit = array( - 'menu_parent' => $menu_name . ':' . $parent, - ); - $this->drupalPostForm("admin/structure/menu/item/$mlid/edit", $edit, t('Save')); - $this->assertResponse(200); - } - - /** - * Modifies a menu link using the UI. - * - * @param \Drupal\menu_link_content\Entity\MenuLinkContent $item - * Menu link entity. - */ - function modifyMenuLink(MenuLinkContent $item) { - $item->title->value = $this->randomMachineName(16); - - $mlid = $item->id(); - $title = $item->getTitle(); - - // Edit menu link. - $edit = array(); - $edit['title[0][value]'] = $title; - $this->drupalPostForm("admin/structure/menu/item/$mlid/edit", $edit, t('Save')); - $this->assertResponse(200); - $this->assertText('The menu link has been saved.'); - // Verify menu link. - $this->drupalGet('admin/structure/menu/manage/' . $item->getMenuName()); - $this->assertText($title, 'Menu link was edited'); - } - - /** - * Resets a standard menu link using the UI. - * - * @param \Drupal\Core\Menu\MenuLinkInterface $menu_link - * The Menu link. - * @param int $old_weight - * Original title for menu link. - */ - function resetMenuLink(MenuLinkInterface $menu_link, $old_weight) { - // Reset menu link. - $this->drupalPostForm("admin/structure/menu/link/{$menu_link->getPluginId()}/reset", array(), t('Reset')); - $this->assertResponse(200); - $this->assertRaw(t('The menu link was reset to its default settings.'), 'Menu link was reset'); - - // Verify menu link. - $instance = \Drupal::service('plugin.manager.menu.link')->createInstance($menu_link->getPluginId()); - $this->assertEqual($old_weight, $instance->getWeight(), 'Resets to the old weight.'); - } - - /** - * Deletes a menu link using the UI. - * - * @param \Drupal\menu_link_content\Entity\MenuLinkContent $item - * Menu link. - */ - function deleteMenuLink(MenuLinkContent $item) { - $mlid = $item->id(); - $title = $item->getTitle(); - - // Delete menu link. - $this->drupalPostForm("admin/structure/menu/item/$mlid/delete", array(), t('Delete')); - $this->assertResponse(200); - $this->assertRaw(t('The menu link %title has been deleted.', array('%title' => $title)), 'Menu link was deleted'); - - // Verify deletion. - $this->drupalGet(''); - $this->assertNoText($title, 'Menu link was deleted'); - } - - /** - * Alternately disables and enables a menu link. - * - * @param \Drupal\menu_link_content\Entity\MenuLinkContent $item - * Menu link. - */ - function toggleMenuLink(MenuLinkContent $item) { - $this->disableMenuLink($item); - - // Verify menu link is absent. - $this->drupalGet(''); - $this->assertNoText($item->getTitle(), 'Menu link was not displayed'); - $this->enableMenuLink($item); - - // Verify menu link is displayed. - $this->drupalGet(''); - $this->assertText($item->getTitle(), 'Menu link was displayed'); - } - - /** - * Disables a menu link. - * - * @param \Drupal\menu_link_content\Entity\MenuLinkContent $item - * Menu link. - */ - function disableMenuLink(MenuLinkContent $item) { - $mlid = $item->id(); - $edit['enabled[value]'] = FALSE; - $this->drupalPostForm("admin/structure/menu/item/$mlid/edit", $edit, t('Save')); - - // Unlike most other modules, there is no confirmation message displayed. - // Verify in the database. - $this->assertMenuLink($item->getPluginId(), array('enabled' => 0)); - } - - /** - * Enables a menu link. - * - * @param \Drupal\menu_link_content\Entity\MenuLinkContent $item - * Menu link. - */ - function enableMenuLink(MenuLinkContent $item) { - $mlid = $item->id(); - $edit['enabled[value]'] = TRUE; - $this->drupalPostForm("admin/structure/menu/item/$mlid/edit", $edit, t('Save')); - - // Verify in the database. - $this->assertMenuLink($item->getPluginId(), array('enabled' => 1)); - } - - /** - * Tests if administrative users other than user 1 can access the menu parents - * AJAX callback. - */ - public function testMenuParentsJsAccess() { - $admin = $this->drupalCreateUser(array('administer menu')); - $this->drupalLogin($admin); - // Just check access to the callback overall, the POST data is irrelevant. - $this->drupalGetAjax('admin/structure/menu/parents'); - $this->assertResponse(200); - - // Do standard user tests. - // Log in the user. - $this->drupalLogin($this->authenticatedUser); - $this->drupalGetAjax('admin/structure/menu/parents'); - $this->assertResponse(403); - } - - /** - * Returns standard menu link. - * - * @return \Drupal\Core\Menu\MenuLinkInterface - * A menu link plugin. - */ - private function getStandardMenuLink() { - // Retrieve menu link id of the Log out menu link, which will always be on - // the front page. - /** @var \Drupal\Core\Menu\MenuLinkManagerInterface $menu_link_manager */ - $menu_link_manager = \Drupal::service('plugin.manager.menu.link'); - $instance = $menu_link_manager->getInstance(['id' => 'user.logout']); - - $this->assertTrue((bool) $instance, 'Standard menu link was loaded'); - return $instance; - } - - /** - * Verifies the logged in user has the desired access to various menu pages. - * - * @param int $response - * (optional) The expected HTTP response code. Defaults to 200. - */ - private function verifyAccess($response = 200) { - // View menu help page. - $this->drupalGet('admin/help/menu'); - $this->assertResponse($response); - if ($response == 200) { - $this->assertText(t('Menu'), 'Menu help was displayed'); - } - - // View menu build overview page. - $this->drupalGet('admin/structure/menu'); - $this->assertResponse($response); - if ($response == 200) { - $this->assertText(t('Menus'), 'Menu build overview page was displayed'); - } - - // View tools menu customization page. - $this->drupalGet('admin/structure/menu/manage/' . $this->menu->id()); - $this->assertResponse($response); - if ($response == 200) { - $this->assertText(t('Tools'), 'Tools menu page was displayed'); - } - - // View menu edit page for a static link. - $item = $this->getStandardMenuLink(); - $this->drupalGet('admin/structure/menu/link/' . $item->getPluginId() . '/edit'); - $this->assertResponse($response); - if ($response == 200) { - $this->assertText(t('Edit menu item'), 'Menu edit page was displayed'); - } - - // View add menu page. - $this->drupalGet('admin/structure/menu/add'); - $this->assertResponse($response); - if ($response == 200) { - $this->assertText(t('Menus'), 'Add menu page was displayed'); - } - } - - /** - * Tests menu block settings. - */ - protected function doTestMenuBlock() { - $menu_id = $this->menu->id(); - $block_id = $this->blockPlacements[$menu_id]; - $this->drupalGet('admin/structure/block/manage/' . $block_id); - $this->drupalPostForm(NULL, [ - 'settings[depth]' => 3, - 'settings[level]' => 2, - ], t('Save block')); - $block = Block::load($block_id); - $settings = $block->getPlugin()->getConfiguration(); - $this->assertEqual($settings['depth'], 3); - $this->assertEqual($settings['level'], 2); - // Reset settings. - $block->getPlugin()->setConfigurationValue('depth', 0); - $block->getPlugin()->setConfigurationValue('level', 1); - $block->save(); - } - -} diff --git a/core/modules/menu_ui/src/Tests/MenuUninstallTest.php b/core/modules/menu_ui/src/Tests/MenuUninstallTest.php deleted file mode 100644 index b1ea03c..0000000 --- a/core/modules/menu_ui/src/Tests/MenuUninstallTest.php +++ /dev/null @@ -1,33 +0,0 @@ -uninstall(array('menu_ui')); - - \Drupal::entityManager()->getStorage('menu')->resetCache(array('admin')); - - $this->assertTrue(Menu::load('admin'), 'The \'admin\' menu still exists after uninstalling Menu UI module.'); - } - -} diff --git a/core/modules/menu_ui/src/Tests/MenuWebTestBase.php b/core/modules/menu_ui/src/Tests/MenuWebTestBase.php deleted file mode 100644 index c08fc14..0000000 --- a/core/modules/menu_ui/src/Tests/MenuWebTestBase.php +++ /dev/null @@ -1,77 +0,0 @@ -resetDefinitions(); - // Reset the static load cache. - \Drupal::entityManager()->getStorage('menu_link_content')->resetCache(); - $definition = $menu_link_manager->getDefinition($menu_plugin_id); - - $entity = NULL; - - // Pull the path from the menu link content. - if (strpos($menu_plugin_id, 'menu_link_content') === 0) { - list(, $uuid) = explode(':', $menu_plugin_id, 2); - /** @var \Drupal\menu_link_content\Entity\MenuLinkContent $entity */ - $entity = \Drupal::entityManager()->loadEntityByUuid('menu_link_content', $uuid); - } - - if (isset($expected_item['children'])) { - $child_ids = array_values($menu_link_manager->getChildIds($menu_plugin_id)); - sort($expected_item['children']); - if ($child_ids) { - sort($child_ids); - } - $this->assertEqual($expected_item['children'], $child_ids); - unset($expected_item['children']); - } - - if (isset($expected_item['parents'])) { - $parent_ids = array_values($menu_link_manager->getParentIds($menu_plugin_id)); - $this->assertEqual($expected_item['parents'], $parent_ids); - unset($expected_item['parents']); - } - - if (isset($expected_item['langcode']) && $entity) { - $this->assertEqual($entity->langcode->value, $expected_item['langcode']); - unset($expected_item['langcode']); - } - - if (isset($expected_item['enabled']) && $entity) { - $this->assertEqual($entity->enabled->value, $expected_item['enabled']); - unset($expected_item['enabled']); - } - - foreach ($expected_item as $key => $value) { - $this->assertTrue(isset($definition[$key])); - $this->assertEqual($definition[$key], $value); - } - } - -} diff --git a/core/modules/migrate_drupal/src/Tests/StubTestTrait.php b/core/modules/migrate_drupal/tests/src/Functional/StubTestTrait.php similarity index 97% rename from core/modules/migrate_drupal/src/Tests/StubTestTrait.php rename to core/modules/migrate_drupal/tests/src/Functional/StubTestTrait.php index 3bf0028..661427f 100644 --- a/core/modules/migrate_drupal/src/Tests/StubTestTrait.php +++ b/core/modules/migrate_drupal/tests/src/Functional/StubTestTrait.php @@ -1,6 +1,6 @@ drupalLogin($this->rootUser); - $this->drupalGet('upgrade'); - $this->assertResponse(200); - $this->assertText(t('Upgrade')); - - $user = $this->createUser(['administer software updates']); - $this->drupalLogin($user); - $this->drupalGet('upgrade'); - $this->assertResponse(403); - $this->assertNoText(t('Upgrade')); - } - -} diff --git a/core/modules/migrate_drupal_ui/src/Tests/MigrateUpgradeTestBase.php b/core/modules/migrate_drupal_ui/src/Tests/MigrateUpgradeTestBase.php deleted file mode 100644 index c139291..0000000 --- a/core/modules/migrate_drupal_ui/src/Tests/MigrateUpgradeTestBase.php +++ /dev/null @@ -1,196 +0,0 @@ -createMigrationConnection(); - $this->sourceDatabase = Database::getConnection('default', 'migrate_drupal_ui'); - - // Log in as user 1. Migrations in the UI can only be performed as user 1. - $this->drupalLogin($this->rootUser); - } - - /** - * Loads a database fixture into the source database connection. - * - * @param string $path - * Path to the dump file. - */ - protected function loadFixture($path) { - $default_db = Database::getConnection()->getKey(); - Database::setActiveConnection($this->sourceDatabase->getKey()); - - if (substr($path, -3) == '.gz') { - $path = 'compress.zlib://' . $path; - } - require $path; - - Database::setActiveConnection($default_db); - } - - /** - * Changes the database connection to the prefixed one. - * - * @todo Remove when we don't use global. https://www.drupal.org/node/2552791 - */ - protected function createMigrationConnection() { - $connection_info = Database::getConnectionInfo('default')['default']; - if ($connection_info['driver'] === 'sqlite') { - // Create database file in the test site's public file directory so that - // \Drupal\simpletest\TestBase::restoreEnvironment() will delete this once - // the test is complete. - $file = $this->publicFilesDirectory . '/' . $this->testId . '-migrate.db.sqlite'; - touch($file); - $connection_info['database'] = $file; - $connection_info['prefix'] = ''; - } - else { - $prefix = is_array($connection_info['prefix']) ? $connection_info['prefix']['default'] : $connection_info['prefix']; - // Simpletest uses fixed length prefixes. Create a new prefix for the - // source database. Adding to the end of the prefix ensures that - // \Drupal\simpletest\TestBase::restoreEnvironment() will remove the - // additional tables. - $connection_info['prefix'] = $prefix . '0'; - } - - Database::addConnectionInfo('migrate_drupal_ui', 'default', $connection_info); - } - - /** - * {@inheritdoc} - */ - protected function tearDown() { - Database::removeConnection('migrate_drupal_ui'); - parent::tearDown(); - } - - /** - * Executes all steps of migrations upgrade. - */ - protected function testMigrateUpgrade() { - $connection_options = $this->sourceDatabase->getConnectionOptions(); - $this->drupalGet('/upgrade'); - $this->assertText('Upgrade a site by importing it into a clean and empty new install of Drupal 8. You will lose any existing configuration once you import your site into it. See the online documentation for Drupal site upgrades for more detailed information.'); - - $this->drupalPostForm(NULL, [], t('Continue')); - $this->assertText('Provide credentials for the database of the Drupal site you want to upgrade.'); - $this->assertFieldByName('mysql[host]'); - - $driver = $connection_options['driver']; - $connection_options['prefix'] = $connection_options['prefix']['default']; - - // Use the driver connection form to get the correct options out of the - // database settings. This supports all of the databases we test against. - $drivers = drupal_get_database_types(); - $form = $drivers[$driver]->getFormOptions($connection_options); - $connection_options = array_intersect_key($connection_options, $form + $form['advanced_options']); - $edit = [ - $driver => $connection_options, - 'source_base_path' => $this->getSourceBasePath(), - ]; - if (count($drivers) !== 1) { - $edit['driver'] = $driver; - } - $edits = $this->translatePostValues($edit); - - // Ensure submitting the form with invalid database credentials gives us a - // nice warning. - $this->drupalPostForm(NULL, [$driver . '[database]' => 'wrong'] + $edits, t('Review upgrade')); - $this->assertText('Resolve the issue below to continue the upgrade.'); - - $this->drupalPostForm(NULL, $edits, t('Review upgrade')); - $this->assertResponse(200); - $this->assertText('Are you sure?'); - $this->drupalPostForm(NULL, [], t('Perform upgrade')); - $this->assertText(t('Congratulations, you upgraded Drupal!')); - - // Have to reset all the statics after migration to ensure entities are - // loadable. - $this->resetAll(); - - $expected_counts = $this->getEntityCounts(); - foreach (array_keys(\Drupal::entityTypeManager()->getDefinitions()) as $entity_type) { - $real_count = count(\Drupal::entityTypeManager()->getStorage($entity_type)->loadMultiple()); - $expected_count = isset($expected_counts[$entity_type]) ? $expected_counts[$entity_type] : 0; - $this->assertEqual($expected_count, $real_count, "Found $real_count $entity_type entities, expected $expected_count."); - } - - $version_tag = 'Drupal ' . $this->getLegacyDrupalVersion($this->sourceDatabase); - $plugin_manager = \Drupal::service('plugin.manager.migration'); - /** @var \Drupal\migrate\Plugin\Migration[] $all_migrations */ - $all_migrations = $plugin_manager->createInstancesByTag($version_tag); - foreach ($all_migrations as $migration) { - $id_map = $migration->getIdMap(); - foreach ($id_map as $source_id => $map) { - // Convert $source_id into a keyless array so that - // \Drupal\migrate\Plugin\migrate\id_map\Sql::getSourceHash() works as - // expected. - $source_id_values = array_values(unserialize($source_id)); - $row = $id_map->getRowBySource($source_id_values); - $destination = serialize($id_map->currentDestination()); - $message = "Successful migration of $source_id to $destination as part of the {$migration->id()} migration. The source row status is " . $row['source_row_status']; - // A completed migration should have maps with - // MigrateIdMapInterface::STATUS_IGNORED or - // MigrateIdMapInterface::STATUS_IMPORTED. - if ($row['source_row_status'] == MigrateIdMapInterface::STATUS_FAILED || $row['source_row_status'] == MigrateIdMapInterface::STATUS_NEEDS_UPDATE) { - $this->fail($message); - } - else { - $this->pass($message); - } - } - } - \Drupal::service('module_installer')->install(['forum']); - } - - /** - * Gets the source base path for the concrete test. - * - * @return string - * The source base path. - */ - abstract protected function getSourceBasePath(); - - /** - * Gets the expected number of entities per entity type after migration. - * - * @return int[] - * An array of expected counts keyed by entity type ID. - */ - abstract protected function getEntityCounts(); - -} diff --git a/core/modules/node/src/Tests/AssertButtonsTrait.php b/core/modules/node/tests/src/Functional/AssertButtonsTrait.php similarity index 97% rename from core/modules/node/src/Tests/AssertButtonsTrait.php rename to core/modules/node/tests/src/Functional/AssertButtonsTrait.php index 58d484d..3f3c87f 100644 --- a/core/modules/node/src/Tests/AssertButtonsTrait.php +++ b/core/modules/node/tests/src/Functional/AssertButtonsTrait.php @@ -1,6 +1,6 @@ enablePageCaching(); - } - - /** - * Test that cache tags are properly bubbled up to the page level. - */ - function testPageCacheTags() { - // Create two nodes. - $author_1 = $this->drupalCreateUser(); - $node_1 = $this->drupalCreateNode(array( - 'uid' => $author_1->id(), - 'title' => 'Node 1', - 'body' => array( - 0 => array('value' => 'Body 1', 'format' => 'basic_html'), - ), - 'promote' => NODE_PROMOTED, - )); - $author_2 = $this->drupalCreateUser(); - $node_2 = $this->drupalCreateNode(array( - 'uid' => $author_2->id(), - 'title' => 'Node 2', - 'body' => array( - 0 => array('value' => 'Body 2', 'format' => 'full_html'), - ), - 'promote' => NODE_PROMOTED, - )); - - // Place a block, but only make it visible on full node page 2. - $block = $this->drupalPlaceBlock('views_block:comments_recent-block_1', array( - 'visibility' => array( - 'request_path' => array( - 'pages' => '/node/' . $node_2->id(), - ), - ), - )); - - $cache_contexts = [ - 'languages:' . LanguageInterface::TYPE_INTERFACE, - 'route', - 'theme', - 'timezone', - 'user', - // The placed block is only visible on certain URLs through a visibility - // condition. - 'url.path', - 'url.query_args:' . MainContentViewSubscriber::WRAPPER_FORMAT, - ]; - - // Full node page 1. - $this->assertPageCacheContextsAndTags($node_1->urlInfo(), $cache_contexts, array( - 'rendered', - 'block_view', - 'config:block_list', - 'config:block.block.bartik_branding', - 'config:block.block.bartik_breadcrumbs', - 'config:block.block.bartik_content', - 'config:block.block.bartik_tools', - 'config:block.block.bartik_footer', - 'config:block.block.bartik_help', - 'config:block.block.bartik_search', - 'config:block.block.' . $block->id(), - 'config:block.block.bartik_powered', - 'config:block.block.bartik_main_menu', - 'config:block.block.bartik_account_menu', - 'config:block.block.bartik_messages', - 'config:block.block.bartik_local_actions', - 'config:block.block.bartik_local_tasks', - 'config:block.block.bartik_page_title', - 'node_view', - 'node:' . $node_1->id(), - 'user:0', - 'user:' . $author_1->id(), - 'config:filter.format.basic_html', - 'config:color.theme.bartik', - 'config:search.settings', - 'config:system.menu.account', - 'config:system.menu.tools', - 'config:system.menu.footer', - 'config:system.menu.main', - 'config:system.site', - // FinishResponseSubscriber adds this cache tag to responses that have the - // 'user.permissions' cache context for anonymous users. - 'config:user.role.anonymous', - )); - - // Render the view block adds the languages cache context. - $cache_contexts[] = 'languages:' . LanguageInterface::TYPE_CONTENT; - - // Full node page 2. - $this->assertPageCacheContextsAndTags($node_2->urlInfo(), $cache_contexts, array( - 'rendered', - 'block_view', - 'config:block_list', - 'config:block.block.bartik_branding', - 'config:block.block.bartik_breadcrumbs', - 'config:block.block.bartik_content', - 'config:block.block.bartik_tools', - 'config:block.block.bartik_help', - 'config:block.block.bartik_search', - 'config:block.block.' . $block->id(), - 'config:block.block.bartik_footer', - 'config:block.block.bartik_powered', - 'config:block.block.bartik_main_menu', - 'config:block.block.bartik_account_menu', - 'config:block.block.bartik_messages', - 'config:block.block.bartik_local_actions', - 'config:block.block.bartik_local_tasks', - 'config:block.block.bartik_page_title', - 'node_view', - 'node:' . $node_2->id(), - 'user:' . $author_2->id(), - 'config:color.theme.bartik', - 'config:filter.format.full_html', - 'config:search.settings', - 'config:system.menu.account', - 'config:system.menu.tools', - 'config:system.menu.footer', - 'config:system.menu.main', - 'config:system.site', - 'comment_list', - 'node_list', - 'config:views.view.comments_recent', - // FinishResponseSubscriber adds this cache tag to responses that have the - // 'user.permissions' cache context for anonymous users. - 'config:user.role.anonymous', - 'user:0', - )); - } - -} diff --git a/core/modules/page_cache/src/Tests/PageCacheTest.php b/core/modules/page_cache/src/Tests/PageCacheTest.php deleted file mode 100644 index 64e4ee9..0000000 --- a/core/modules/page_cache/src/Tests/PageCacheTest.php +++ /dev/null @@ -1,518 +0,0 @@ -config('system.site') - ->set('name', 'Drupal') - ->set('page.front', '/test-page') - ->save(); - } - - /** - * Test that cache tags are properly persisted. - * - * Since tag based invalidation works, we know that our tag properly - * persisted. - */ - function testPageCacheTags() { - $config = $this->config('system.performance'); - $config->set('cache.page.max_age', 300); - $config->save(); - - $path = 'system-test/cache_tags_page'; - $tags = array('system_test_cache_tags_page'); - $this->drupalGet($path); - $this->assertEqual($this->drupalGetHeader('X-Drupal-Cache'), 'MISS'); - - // Verify a cache hit, but also the presence of the correct cache tags. - $this->drupalGet($path); - $this->assertEqual($this->drupalGetHeader('X-Drupal-Cache'), 'HIT'); - $cid_parts = array(\Drupal::url('system_test.cache_tags_page', array(), array('absolute' => TRUE)), 'html'); - $cid = implode(':', $cid_parts); - $cache_entry = \Drupal::cache('render')->get($cid); - sort($cache_entry->tags); - $expected_tags = array( - 'config:user.role.anonymous', - 'pre_render', - 'rendered', - 'system_test_cache_tags_page', - ); - $this->assertIdentical($cache_entry->tags, $expected_tags); - - Cache::invalidateTags($tags); - $this->drupalGet($path); - $this->assertEqual($this->drupalGetHeader('X-Drupal-Cache'), 'MISS'); - } - - /** - * Test that the page cache doesn't depend on cacheability headers. - */ - function testPageCacheTagsIndependentFromCacheabilityHeaders() { - $this->setHttpResponseDebugCacheabilityHeaders(FALSE); - - $path = 'system-test/cache_tags_page'; - $tags = array('system_test_cache_tags_page'); - $this->drupalGet($path); - $this->assertEqual($this->drupalGetHeader('X-Drupal-Cache'), 'MISS'); - - // Verify a cache hit, but also the presence of the correct cache tags. - $this->drupalGet($path); - $this->assertEqual($this->drupalGetHeader('X-Drupal-Cache'), 'HIT'); - $cid_parts = array(\Drupal::url('system_test.cache_tags_page', array(), array('absolute' => TRUE)), 'html'); - $cid = implode(':', $cid_parts); - $cache_entry = \Drupal::cache('render')->get($cid); - sort($cache_entry->tags); - $expected_tags = array( - 'config:user.role.anonymous', - 'pre_render', - 'rendered', - 'system_test_cache_tags_page', - ); - $this->assertIdentical($cache_entry->tags, $expected_tags); - - Cache::invalidateTags($tags); - $this->drupalGet($path); - $this->assertEqual($this->drupalGetHeader('X-Drupal-Cache'), 'MISS'); - } - - /** - * Tests support for different cache items with different request formats - * specified via a query parameter. - */ - function testQueryParameterFormatRequests() { - $config = $this->config('system.performance'); - $config->set('cache.page.max_age', 300); - $config->save(); - - $accept_header_cache_url = Url::fromRoute('system_test.page_cache_accept_header'); - $accept_header_cache_url_with_json = Url::fromRoute('system_test.page_cache_accept_header', ['_format' => 'json']); - - $this->drupalGet($accept_header_cache_url); - $this->assertEqual($this->drupalGetHeader('X-Drupal-Cache'), 'MISS', 'HTML page was not yet cached.'); - $this->drupalGet($accept_header_cache_url); - $this->assertEqual($this->drupalGetHeader('X-Drupal-Cache'), 'HIT', 'HTML page was cached.'); - $this->assertRaw('

oh hai this is html.

', 'The correct HTML response was returned.'); - - $this->drupalGet($accept_header_cache_url_with_json); - $this->assertEqual($this->drupalGetHeader('X-Drupal-Cache'), 'MISS', 'Json response was not yet cached.'); - $this->drupalGet($accept_header_cache_url_with_json); - $this->assertEqual($this->drupalGetHeader('X-Drupal-Cache'), 'HIT', 'Json response was cached.'); - $this->assertRaw('{"content":"oh hai this is json"}', 'The correct Json response was returned.'); - - // Enable REST support for nodes and hal+json. - \Drupal::service('module_installer')->install(['node', 'rest', 'hal', 'basic_auth']); - $this->drupalCreateContentType(['type' => 'article']); - $node = $this->drupalCreateNode(['type' => 'article']); - $node_uri = $node->urlInfo(); - $node_url_with_hal_json_format = $node->urlInfo('canonical')->setRouteParameter('_format', 'hal_json'); - /** @var \Drupal\user\RoleInterface $role */ - $role = Role::load('anonymous'); - $role->grantPermission('restful get entity:node'); - $role->save(); - - $this->drupalGet($node_uri); - $this->assertEqual($this->drupalGetHeader('X-Drupal-Cache'), 'MISS'); - $this->assertEqual($this->drupalGetHeader('Content-Type'), 'text/html; charset=UTF-8'); - $this->drupalGet($node_uri); - $this->assertEqual($this->drupalGetHeader('X-Drupal-Cache'), 'HIT'); - $this->assertEqual($this->drupalGetHeader('Content-Type'), 'text/html; charset=UTF-8'); - - // Now request a HAL page, we expect that the first request is a cache miss - // and it serves HTML. - $this->drupalGet($node_url_with_hal_json_format); - $this->assertEqual($this->drupalGetHeader('X-Drupal-Cache'), 'MISS'); - $this->assertEqual($this->drupalGetHeader('Content-Type'), 'application/hal+json'); - $this->drupalGet($node_url_with_hal_json_format); - $this->assertEqual($this->drupalGetHeader('X-Drupal-Cache'), 'HIT'); - $this->assertEqual($this->drupalGetHeader('Content-Type'), 'application/hal+json'); - - // Clear the page cache. After that request a HAL request, followed by an - // ordinary HTML one. - \Drupal::cache('render')->deleteAll(); - $this->drupalGet($node_url_with_hal_json_format); - $this->assertEqual($this->drupalGetHeader('X-Drupal-Cache'), 'MISS'); - $this->assertEqual($this->drupalGetHeader('Content-Type'), 'application/hal+json'); - $this->drupalGet($node_url_with_hal_json_format); - $this->assertEqual($this->drupalGetHeader('X-Drupal-Cache'), 'HIT'); - $this->assertEqual($this->drupalGetHeader('Content-Type'), 'application/hal+json'); - - $this->drupalGet($node_uri); - $this->assertEqual($this->drupalGetHeader('X-Drupal-Cache'), 'MISS'); - $this->assertEqual($this->drupalGetHeader('Content-Type'), 'text/html; charset=UTF-8'); - $this->drupalGet($node_uri); - $this->assertEqual($this->drupalGetHeader('X-Drupal-Cache'), 'HIT'); - $this->assertEqual($this->drupalGetHeader('Content-Type'), 'text/html; charset=UTF-8'); - } - - /** - * Tests support of requests with If-Modified-Since and If-None-Match headers. - */ - function testConditionalRequests() { - $config = $this->config('system.performance'); - $config->set('cache.page.max_age', 300); - $config->save(); - - // Fill the cache. - $this->drupalGet(''); - // Verify the page is not printed twice when the cache is cold. - $this->assertNoPattern('#drupalHead(''); - $this->assertEqual($this->drupalGetHeader('X-Drupal-Cache'), 'HIT', 'Page was cached.'); - $etag = $this->drupalGetHeader('ETag'); - $last_modified = $this->drupalGetHeader('Last-Modified'); - - $this->drupalGet('', array(), array('If-Modified-Since: ' . $last_modified, 'If-None-Match: ' . $etag)); - $this->assertResponse(304, 'Conditional request returned 304 Not Modified.'); - - $this->drupalGet('', array(), array('If-Modified-Since: ' . gmdate(DATE_RFC822, strtotime($last_modified)), 'If-None-Match: ' . $etag)); - $this->assertResponse(304, 'Conditional request with obsolete If-Modified-Since date returned 304 Not Modified.'); - - $this->drupalGet('', array(), array('If-Modified-Since: ' . gmdate(DATE_RFC850, strtotime($last_modified)), 'If-None-Match: ' . $etag)); - $this->assertResponse(304, 'Conditional request with obsolete If-Modified-Since date returned 304 Not Modified.'); - - $this->drupalGet('', array(), array('If-Modified-Since: ' . $last_modified)); - // Verify the page is not printed twice when the cache is warm. - $this->assertNoPattern('#assertResponse(200, 'Conditional request without If-None-Match returned 200 OK.'); - $this->assertEqual($this->drupalGetHeader('X-Drupal-Cache'), 'HIT', 'Page was cached.'); - - $this->drupalGet('', array(), array('If-Modified-Since: ' . gmdate(DateTimePlus::RFC7231, strtotime($last_modified) + 1), 'If-None-Match: ' . $etag)); - $this->assertResponse(200, 'Conditional request with new a If-Modified-Since date newer than Last-Modified returned 200 OK.'); - $this->assertEqual($this->drupalGetHeader('X-Drupal-Cache'), 'HIT', 'Page was cached.'); - - $user = $this->drupalCreateUser(); - $this->drupalLogin($user); - $this->drupalGet('', array(), array('If-Modified-Since: ' . $last_modified, 'If-None-Match: ' . $etag)); - $this->assertResponse(200, 'Conditional request returned 200 OK for authenticated user.'); - $this->assertFalse($this->drupalGetHeader('X-Drupal-Cache'), 'Absence of Page was not cached.'); - } - - /** - * Tests cache headers. - */ - function testPageCache() { - $config = $this->config('system.performance'); - $config->set('cache.page.max_age', 300); - $config->set('response.gzip', 1); - $config->save(); - - // Fill the cache. - $this->drupalGet('system-test/set-header', array('query' => array('name' => 'Foo', 'value' => 'bar'))); - $this->assertEqual($this->drupalGetHeader('X-Drupal-Cache'), 'MISS', 'Page was not cached.'); - $this->assertEqual(strtolower($this->drupalGetHeader('Vary')), 'cookie,accept-encoding', 'Vary header was sent.'); - // Symfony's Response logic determines a specific order for the subvalues - // of the Cache-Control header, even if they are explicitly passed in to - // the response header bag in a different order. - $this->assertEqual($this->drupalGetHeader('Cache-Control'), 'max-age=300, public', 'Cache-Control header was sent.'); - $this->assertEqual($this->drupalGetHeader('Expires'), 'Sun, 19 Nov 1978 05:00:00 GMT', 'Expires header was sent.'); - $this->assertEqual($this->drupalGetHeader('Foo'), 'bar', 'Custom header was sent.'); - - // Check cache. - $this->drupalGet('system-test/set-header', array('query' => array('name' => 'Foo', 'value' => 'bar'))); - $this->assertEqual($this->drupalGetHeader('X-Drupal-Cache'), 'HIT', 'Page was cached.'); - $this->assertEqual(strtolower($this->drupalGetHeader('Vary')), 'cookie,accept-encoding', 'Vary: Cookie header was sent.'); - $this->assertEqual($this->drupalGetHeader('Cache-Control'), 'max-age=300, public', 'Cache-Control header was sent.'); - $this->assertEqual($this->drupalGetHeader('Expires'), 'Sun, 19 Nov 1978 05:00:00 GMT', 'Expires header was sent.'); - $this->assertEqual($this->drupalGetHeader('Foo'), 'bar', 'Custom header was sent.'); - - // Check replacing default headers. - $this->drupalGet('system-test/set-header', array('query' => array('name' => 'Expires', 'value' => 'Fri, 19 Nov 2008 05:00:00 GMT'))); - $this->assertEqual($this->drupalGetHeader('Expires'), 'Fri, 19 Nov 2008 05:00:00 GMT', 'Default header was replaced.'); - $this->drupalGet('system-test/set-header', array('query' => array('name' => 'Vary', 'value' => 'User-Agent'))); - $this->assertEqual(strtolower($this->drupalGetHeader('Vary')), 'user-agent,accept-encoding', 'Default header was replaced.'); - - // Check that authenticated users bypass the cache. - $user = $this->drupalCreateUser(); - $this->drupalLogin($user); - $this->drupalGet('system-test/set-header', array('query' => array('name' => 'Foo', 'value' => 'bar'))); - $this->assertFalse($this->drupalGetHeader('X-Drupal-Cache'), 'Caching was bypassed.'); - $this->assertTrue(strpos(strtolower($this->drupalGetHeader('Vary')), 'cookie') === FALSE, 'Vary: Cookie header was not sent.'); - $this->assertEqual($this->drupalGetHeader('Cache-Control'), 'must-revalidate, no-cache, private', 'Cache-Control header was sent.'); - $this->assertEqual($this->drupalGetHeader('Expires'), 'Sun, 19 Nov 1978 05:00:00 GMT', 'Expires header was sent.'); - $this->assertEqual($this->drupalGetHeader('Foo'), 'bar', 'Custom header was sent.'); - - // Until bubbling of max-age up to the response is supported, verify that - // a custom #cache max-age set on an element does not affect page max-age. - $this->drupalLogout(); - $this->drupalGet('system-test/cache_maxage_page'); - $this->assertEqual($this->drupalGetHeader('Cache-Control'), 'max-age=300, public'); - } - - /** - * Tests the automatic presence of the anonymous role's cache tag. - * - * The 'user.permissions' cache context ensures that if the permissions for a - * role are modified, users are not served stale render cache content. But, - * when entire responses are cached in reverse proxies, the value for the - * cache context is never calculated, causing the stale response to not be - * invalidated. Therefore, when varying by permissions and the current user is - * the anonymous user, the cache tag for the 'anonymous' role must be added. - * - * This test verifies that, and it verifies that it does not happen for other - * roles. - */ - public function testPageCacheAnonymousRolePermissions() { - $config = $this->config('system.performance'); - $config->set('cache.page.max_age', 300); - $config->save(); - - $content_url = Url::fromRoute('system_test.permission_dependent_content'); - $route_access_url = Url::fromRoute('system_test.permission_dependent_route_access'); - - // 1. anonymous user, without permission. - $this->drupalGet($content_url); - $this->assertText('Permission to pet llamas: no!'); - $this->assertCacheContext('user.permissions'); - $this->assertCacheTag('config:user.role.anonymous'); - $this->drupalGet($route_access_url); - $this->assertCacheContext('user.permissions'); - $this->assertCacheTag('config:user.role.anonymous'); - - // 2. anonymous user, with permission. - user_role_grant_permissions(RoleInterface::ANONYMOUS_ID, ['pet llamas']); - $this->drupalGet($content_url); - $this->assertText('Permission to pet llamas: yes!'); - $this->assertCacheContext('user.permissions'); - $this->assertCacheTag('config:user.role.anonymous'); - $this->drupalGet($route_access_url); - $this->assertCacheContext('user.permissions'); - $this->assertCacheTag('config:user.role.anonymous'); - - // 3. authenticated user, without permission. - $auth_user = $this->drupalCreateUser(); - $this->drupalLogin($auth_user); - $this->drupalGet($content_url); - $this->assertText('Permission to pet llamas: no!'); - $this->assertCacheContext('user.permissions'); - $this->assertNoCacheTag('config:user.role.authenticated'); - $this->drupalGet($route_access_url); - $this->assertCacheContext('user.permissions'); - $this->assertNoCacheTag('config:user.role.authenticated'); - - // 4. authenticated user, with permission. - user_role_grant_permissions(RoleInterface::AUTHENTICATED_ID, ['pet llamas']); - $this->drupalGet($content_url); - $this->assertText('Permission to pet llamas: yes!'); - $this->assertCacheContext('user.permissions'); - $this->assertNoCacheTag('config:user.role.authenticated'); - $this->drupalGet($route_access_url); - $this->assertCacheContext('user.permissions'); - $this->assertNoCacheTag('config:user.role.authenticated'); - } - - /** - * Tests the 4xx-response cache tag is added and invalidated. - */ - function testPageCacheAnonymous403404() { - $admin_url = Url::fromRoute('system.admin'); - $invalid_url = 'foo/does_not_exist'; - $tests = [ - 403 => $admin_url, - 404 => $invalid_url, - ]; - $cache_ttl_4xx = Settings::get('cache_ttl_4xx', 3600); - foreach ($tests as $code => $content_url) { - // Anonymous user, without permissions. - $this->drupalGet($content_url); - $this->assertResponse($code); - $this->assertEqual($this->drupalGetHeader('X-Drupal-Cache'), 'MISS'); - $this->assertCacheTag('4xx-response'); - $this->drupalGet($content_url); - $this->assertResponse($code); - $this->assertEqual($this->drupalGetHeader('X-Drupal-Cache'), 'HIT'); - $entity_values = array( - 'name' => $this->randomMachineName(), - 'user_id' => 1, - 'field_test_text' => array( - 0 => array( - 'value' => $this->randomString(), - 'format' => 'plain_text', - ) - ), - ); - $entity = EntityTest::create($entity_values); - $entity->save(); - // Saving an entity clears 4xx cache tag. - $this->drupalGet($content_url); - $this->assertResponse($code); - $this->assertEqual($this->drupalGetHeader('X-Drupal-Cache'), 'MISS'); - $this->drupalGet($content_url); - $this->assertResponse($code); - $this->assertEqual($this->drupalGetHeader('X-Drupal-Cache'), 'HIT'); - // Rebuilding the router should invalidate the 4xx cache tag. - $this->container->get('router.builder')->rebuild(); - $this->drupalGet($content_url); - $this->assertResponse($code); - $this->assertEqual($this->drupalGetHeader('X-Drupal-Cache'), 'MISS'); - - // Ensure the 'expire' field on the cache entry uses cache_ttl_4xx. - $cache_item = \Drupal::service('cache.render')->get($this->getUrl() . ':html'); - $difference = $cache_item->expire - (int) $cache_item->created; - // Given that a second might have passed we cannot be sure that - // $difference will exactly equal the default cache_ttl_4xx setting. - // Account for any timing difference or rounding errors by ensuring the - // value is within 5 seconds. - $this->assertTrue( - $difference > $cache_ttl_4xx - 5 && - $difference < $cache_ttl_4xx + 5, - 'The cache entry expiry time uses the cache_ttl_4xx setting.' - ); - } - - // Disable 403 and 404 caching. - $settings['settings']['cache_ttl_4xx'] = (object) array( - 'value' => 0, - 'required' => TRUE, - ); - $this->writeSettings($settings); - \Drupal::service('cache.render')->deleteAll(); - - foreach ($tests as $code => $content_url) { - // Getting the 404 page twice should still result in a cache miss. - $this->drupalGet($content_url); - $this->drupalGet($content_url); - $this->assertResponse($code); - $this->assertEqual($this->drupalGetHeader('X-Drupal-Cache'), 'MISS'); - } - } - - /** - * Tests the omit_vary_cookie setting. - */ - public function testPageCacheWithoutVaryCookie() { - $config = $this->config('system.performance'); - $config->set('cache.page.max_age', 300); - $config->save(); - - $settings['settings']['omit_vary_cookie'] = (object) array( - 'value' => TRUE, - 'required' => TRUE, - ); - $this->writeSettings($settings); - - // Fill the cache. - $this->drupalGet(''); - $this->assertEqual($this->drupalGetHeader('X-Drupal-Cache'), 'MISS', 'Page was not cached.'); - $this->assertTrue(strpos($this->drupalGetHeader('Vary'), 'Cookie') === FALSE, 'Vary: Cookie header was not sent.'); - $this->assertEqual($this->drupalGetHeader('Cache-Control'), 'max-age=300, public', 'Cache-Control header was sent.'); - - // Check cache. - $this->drupalGet(''); - $this->assertEqual($this->drupalGetHeader('X-Drupal-Cache'), 'HIT', 'Page was cached.'); - $this->assertTrue(strpos($this->drupalGetHeader('Vary'), 'Cookie') === FALSE, 'Vary: Cookie header was not sent.'); - $this->assertEqual($this->drupalGetHeader('Cache-Control'), 'max-age=300, public', 'Cache-Control header was sent.'); - } - - /** - * Test the setting of forms to be immutable. - */ - public function testFormImmutability() { - // Install the module that provides the test form. - $this->container->get('module_installer') - ->install(['page_cache_form_test']); - // Uninstall the page_cache module to verify that form is immutable - // regardless of the internal page cache module. - $this->container->get('module_installer')->uninstall(['page_cache']); - \Drupal::service('router.builder')->rebuild(); - - $this->drupalGet('page_cache_form_test_immutability'); - - $this->assertText("Immutable: TRUE", "Form is immutable."); - - // The immutable flag is set unconditionally by system_form_alter(), set - // a flag to tell page_cache_form_test_module_implements_alter() to disable - // that implementation. - \Drupal::state()->set('page_cache_bypass_form_immutability', TRUE); - \Drupal::moduleHandler()->resetImplementations(); - Cache::invalidateTags(['rendered']); - - $this->drupalGet('page_cache_form_test_immutability'); - - $this->assertText("Immutable: FALSE", "Form is not immutable,"); - } - - /** - * Tests cacheability of a CacheableResponse. - * - * Tests the difference between having a controller return a plain Symfony - * Response object versus returning a Response object that implements the - * CacheableResponseInterface. - */ - public function testCacheableResponseResponses() { - $config = $this->config('system.performance'); - $config->set('cache.page.max_age', 300); - $config->save(); - - // GET a URL, which would be marked as a cache miss if it were cacheable. - $this->drupalGet('/system-test/respond-reponse'); - $this->assertFalse($this->drupalGetHeader('X-Drupal-Cache'), 'Drupal page cache header not found.'); - $this->assertEqual($this->drupalGetHeader('Cache-Control'), 'must-revalidate, no-cache, private', 'Cache-Control header was sent'); - - // GET it again, verify it's still not cached. - $this->drupalGet('/system-test/respond-reponse'); - $this->assertFalse($this->drupalGetHeader('X-Drupal-Cache'), 'Drupal page cache header not found.'); - $this->assertEqual($this->drupalGetHeader('Cache-Control'), 'must-revalidate, no-cache, private', 'Cache-Control header was sent'); - - // GET a URL, which would be marked as a cache miss if it were cacheable. - $this->drupalGet('/system-test/respond-public-response'); - $this->assertFalse($this->drupalGetHeader('X-Drupal-Cache'), 'Drupal page cache header not found.'); - $this->assertEqual($this->drupalGetHeader('Cache-Control'), 'max-age=60, public', 'Cache-Control header was sent'); - - // GET it again, verify it's still not cached. - $this->drupalGet('/system-test/respond-public-response'); - $this->assertFalse($this->drupalGetHeader('X-Drupal-Cache'), 'Drupal page cache header not found.'); - $this->assertEqual($this->drupalGetHeader('Cache-Control'), 'max-age=60, public', 'Cache-Control header was sent'); - - // GET a URL, which should be marked as a cache miss. - $this->drupalGet('/system-test/respond-cacheable-reponse'); - $this->assertEqual($this->drupalGetHeader('X-Drupal-Cache'), 'MISS', 'Page was not cached.'); - $this->assertEqual($this->drupalGetHeader('Cache-Control'), 'max-age=300, public', 'Cache-Control header was sent.'); - - // GET it again, it should now be a cache hit. - $this->drupalGet('/system-test/respond-cacheable-reponse'); - $this->assertEqual($this->drupalGetHeader('X-Drupal-Cache'), 'HIT', 'Page was cached.'); - $this->assertEqual($this->drupalGetHeader('Cache-Control'), 'max-age=300, public', 'Cache-Control header was sent.'); - - // Uninstall page cache. This should flush all caches so the next call to a - // previously cached page should be a miss now. - $this->container->get('module_installer') - ->uninstall(['page_cache']); - - // GET a URL that was cached by Page Cache before, it should not be now. - $this->drupalGet('/respond-cacheable-reponse'); - $this->assertFalse($this->drupalGetHeader('X-Drupal-Cache'), 'Drupal page cache header not found.'); - } - -} diff --git a/core/modules/path/src/Tests/PathAdminTest.php b/core/modules/path/tests/src/Functional/PathAdminTest.php similarity index 98% rename from core/modules/path/src/Tests/PathAdminTest.php rename to core/modules/path/tests/src/Functional/PathAdminTest.php index 906ce64..a27840d 100644 --- a/core/modules/path/src/Tests/PathAdminTest.php +++ b/core/modules/path/tests/src/Functional/PathAdminTest.php @@ -1,6 +1,6 @@