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