Backup of db before drupal security update
[yaffs-website] / web / core / modules / views_ui / tests / src / Functional / DisplayPathTest.php
1 <?php
2
3 namespace Drupal\Tests\views_ui\Functional;
4
5 use Drupal\Core\Menu\MenuTreeParameters;
6 use Drupal\menu_link_content\Entity\MenuLinkContent;
7 use Drupal\system\Tests\Cache\AssertPageCacheContextsAndTagsTrait;
8
9 /**
10  * Tests the UI of generic display path plugin.
11  *
12  * @group views_ui
13  * @see \Drupal\views\Plugin\views\display\PathPluginBase
14  */
15 class DisplayPathTest extends UITestBase {
16   use AssertPageCacheContextsAndTagsTrait;
17
18   protected function setUp($import_test_views = TRUE) {
19     parent::setUp($import_test_views);
20
21     $this->placeBlock('page_title_block');
22   }
23
24   /**
25    * {@inheritdoc}
26    */
27   public static $modules = ['menu_ui'];
28
29   /**
30    * Views used by this test.
31    *
32    * @var array
33    */
34   public static $testViews = ['test_view', 'test_page_display_menu'];
35
36   /**
37    * Runs the tests.
38    */
39   public function testPathUI() {
40     $this->doBasicPathUITest();
41     $this->doAdvancedPathsValidationTest();
42     $this->doPathXssFilterTest();
43   }
44
45   /**
46    * Tests basic functionality in configuring a view.
47    */
48   protected function doBasicPathUITest() {
49     $this->drupalGet('admin/structure/views/view/test_view');
50
51     // Add a new page display and check the appearing text.
52     $this->drupalPostForm(NULL, [], 'Add Page');
53     $this->assertText(t('No path is set'), 'The right text appears if no path was set.');
54     $this->assertNoLink(t('View @display', ['@display' => 'page']), 'No view page link found on the page.');
55
56     // Save a path and make sure the summary appears as expected.
57     $random_path = $this->randomMachineName();
58     // @todo Once https://www.drupal.org/node/2351379 is resolved, Views will no
59     //   longer use Url::fromUri(), and this path will be able to contain ':'.
60     $random_path = str_replace(':', '', $random_path);
61
62     $this->drupalPostForm('admin/structure/views/nojs/display/test_view/page_1/path', ['path' => $random_path], t('Apply'));
63     $this->assertText('/' . $random_path, 'The custom path appears in the summary.');
64     $display_link_text = t('View @display', ['@display' => 'Page']);
65     $this->assertLink($display_link_text, 0, 'view page link found on the page.');
66     $this->clickLink($display_link_text);
67     $this->assertUrl($random_path);
68   }
69
70   /**
71    * Tests that View paths are properly filtered for XSS.
72    */
73   public function doPathXssFilterTest() {
74     $this->drupalGet('admin/structure/views/view/test_view');
75     $this->drupalPostForm(NULL, [], 'Add Page');
76     $this->drupalPostForm('admin/structure/views/nojs/display/test_view/page_2/path', ['path' => '<object>malformed_path</object>'], t('Apply'));
77     $this->drupalPostForm(NULL, [], 'Add Page');
78     $this->drupalPostForm('admin/structure/views/nojs/display/test_view/page_3/path', ['path' => '<script>alert("hello");</script>'], t('Apply'));
79     $this->drupalPostForm(NULL, [], 'Add Page');
80     $this->drupalPostForm('admin/structure/views/nojs/display/test_view/page_4/path', ['path' => '<script>alert("hello I have placeholders %");</script>'], t('Apply'));
81     $this->drupalPostForm('admin/structure/views/view/test_view', [], t('Save'));
82     $this->drupalGet('admin/structure/views');
83     // The anchor text should be escaped.
84     $this->assertEscaped('/<object>malformed_path</object>');
85     $this->assertEscaped('/<script>alert("hello");</script>');
86     $this->assertEscaped('/<script>alert("hello I have placeholders %");</script>');
87     // Links should be url-encoded.
88     $this->assertRaw('/%3Cobject%3Emalformed_path%3C/object%3E');
89     $this->assertRaw('/%3Cscript%3Ealert%28%22hello%22%29%3B%3C/script%3E');
90   }
91
92   /**
93    * Tests a couple of invalid path patterns.
94    */
95   protected function doAdvancedPathsValidationTest() {
96     $url = 'admin/structure/views/nojs/display/test_view/page_1/path';
97
98     $this->drupalPostForm($url, ['path' => '%/magrathea'], t('Apply'));
99     $this->assertUrl($url);
100     $this->assertText('"%" may not be used for the first segment of a path.');
101
102     $this->drupalPostForm($url, ['path' => 'user/%1/example'], t('Apply'));
103     $this->assertUrl($url);
104     $this->assertText("Numeric placeholders may not be used. Please use plain placeholders (%).");
105   }
106
107   /**
108    * Tests deleting a page display that has no path.
109    */
110   public function testDeleteWithNoPath() {
111     $this->drupalGet('admin/structure/views/view/test_view');
112     $this->drupalPostForm(NULL, [], t('Add Page'));
113     $this->drupalPostForm(NULL, [], t('Delete Page'));
114     $this->drupalPostForm(NULL, [], t('Save'));
115     $this->assertRaw(t('The view %view has been saved.', ['%view' => 'Test view']));
116   }
117
118   /**
119    * Tests the menu and tab option form.
120    */
121   public function testMenuOptions() {
122     $this->container->get('module_installer')->install(['menu_ui']);
123     $this->drupalGet('admin/structure/views/view/test_view');
124
125     // Add a new page display.
126     $this->drupalPostForm(NULL, [], 'Add Page');
127
128     // Add an invalid path (only fragment).
129     $this->drupalPostForm('admin/structure/views/nojs/display/test_view/page_1/path', ['path' => '#foo'], t('Apply'));
130     $this->assertText('Path is empty');
131
132     // Add an invalid path with a query.
133     $this->drupalPostForm('admin/structure/views/nojs/display/test_view/page_1/path', ['path' => 'foo?bar'], t('Apply'));
134     $this->assertText('No query allowed.');
135
136     // Add an invalid path with just a query.
137     $this->drupalPostForm('admin/structure/views/nojs/display/test_view/page_1/path', ['path' => '?bar'], t('Apply'));
138     $this->assertText('Path is empty');
139
140     // Provide a random, valid path string.
141     $random_string = $this->randomMachineName();
142
143     // Save a path.
144     $this->drupalPostForm('admin/structure/views/nojs/display/test_view/page_1/path', ['path' => $random_string], t('Apply'));
145     $this->drupalGet('admin/structure/views/view/test_view');
146
147     $this->drupalPostForm('admin/structure/views/nojs/display/test_view/page_1/menu', ['menu[type]' => 'default tab', 'menu[title]' => 'Test tab title'], t('Apply'));
148     $this->assertResponse(200);
149     $this->assertUrl('admin/structure/views/nojs/display/test_view/page_1/tab_options');
150
151     $this->drupalPostForm(NULL, ['tab_options[type]' => 'tab', 'tab_options[title]' => $this->randomString()], t('Apply'));
152     $this->assertResponse(200);
153     $this->assertUrl('admin/structure/views/view/test_view/edit/page_1');
154
155     $this->drupalGet('admin/structure/views/view/test_view');
156     $this->assertLink(t('Tab: @title', ['@title' => 'Test tab title']));
157     // If it's a default tab, it should also have an additional settings link.
158     $this->assertLinkByHref('admin/structure/views/nojs/display/test_view/page_1/tab_options');
159
160     // Ensure that you can select a parent in case the parent does not exist.
161     $this->drupalGet('admin/structure/views/nojs/display/test_page_display_menu/page_5/menu');
162     $this->assertResponse(200);
163     $menu_parent = $this->xpath('//select[@id="edit-menu-parent"]');
164     $menu_options = (array) $menu_parent[0]->findAll('css', 'option');
165     unset($menu_options['@attributes']);
166
167     // Convert array to make the next assertion possible.
168     $menu_options = array_map(function($element) {
169       return $element->getText();
170     }, $menu_options);
171
172     $this->assertEqual([
173       '<User account menu>',
174       '-- My account',
175       '-- Log out',
176       '<Administration>',
177       '<Footer>',
178       '<Main navigation>',
179       '<Tools>',
180       '-- Compose tips (disabled)',
181       '-- Test menu link',
182     ], $menu_options);
183
184     // The cache contexts associated with the (in)accessible menu links are
185     // bubbled.
186     $this->assertCacheContext('user.permissions');
187   }
188
189   /**
190    * Tests the regression in https://www.drupal.org/node/2532490.
191    */
192   public function testDefaultMenuTabRegression() {
193     $this->container->get('module_installer')->install(['menu_ui', 'menu_link_content', 'toolbar', 'system']);
194     $admin_user = $this->drupalCreateUser([
195       'administer views',
196       'administer blocks',
197       'bypass node access',
198       'access user profiles',
199       'view all revisions',
200       'administer permissions',
201       'administer menu',
202       'link to any page',
203       'access toolbar',
204     ]);
205     $this->drupalLogin($admin_user);
206
207     $edit = [
208       'title[0][value]' => 'Menu title',
209       'link[0][uri]' => '/admin/foo',
210       'menu_parent' => 'admin:system.admin'
211     ];
212     $this->drupalPostForm('admin/structure/menu/manage/admin/add', $edit, t('Save'));
213
214     $menu_items = \Drupal::entityManager()->getStorage('menu_link_content')->getQuery()
215       ->sort('id', 'DESC')
216       ->pager(1)
217       ->execute();
218     $menu_item = end($menu_items);
219     /** @var \Drupal\menu_link_content\MenuLinkContentInterface $menu_link_content */
220     $menu_link_content = MenuLinkContent::load($menu_item);
221
222     $edit = [];
223     $edit['label'] = $this->randomMachineName(16);
224     $view_id = $edit['id'] = strtolower($this->randomMachineName(16));
225     $edit['description'] = $this->randomMachineName(16);
226     $edit['page[create]'] = TRUE;
227     $edit['page[path]'] = 'admin/foo';
228
229     $this->drupalPostForm('admin/structure/views/add', $edit, t('Save and edit'));
230
231     $parameters = new MenuTreeParameters();
232     $parameters->addCondition('id', $menu_link_content->getPluginId());
233     $result = \Drupal::menuTree()->load('admin', $parameters);
234     $plugin_definition = end($result)->link->getPluginDefinition();
235     $this->assertEqual('view.' . $view_id . '.page_1', $plugin_definition['route_name']);
236
237     $this->clickLink(t('No menu'));
238
239     $this->drupalPostForm(NULL, [
240       'menu[type]' => 'default tab',
241       'menu[title]' => 'Menu title',
242     ], t('Apply'));
243
244     $this->assertText('Default tab options');
245
246     $this->drupalPostForm(NULL, [
247       'tab_options[type]' => 'normal',
248       'tab_options[title]' => 'Parent title',
249     ], t('Apply'));
250
251     $this->drupalPostForm(NULL, [], t('Save'));
252     // Assert that saving the view will not cause an exception.
253     $this->assertResponse(200);
254   }
255
256 }