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