Further Drupal 8.6.4 changes. Some core files were not committed before a commit...
[yaffs-website] / web / core / modules / views / tests / src / Functional / Plugin / StyleTableTest.php
1 <?php
2
3 namespace Drupal\Tests\views\Functional\Plugin;
4
5 use Drupal\dynamic_page_cache\EventSubscriber\DynamicPageCacheSubscriber;
6 use Drupal\Tests\views\Functional\ViewTestBase;
7 use Drupal\views\Entity\View;
8
9 /**
10  * Tests the table style views plugin.
11  *
12  * @group views
13  */
14 class StyleTableTest extends ViewTestBase {
15
16   /**
17    * Views used by this test.
18    *
19    * @var array
20    */
21   public static $testViews = ['test_table'];
22
23   /**
24    * {@inheritdoc}
25    */
26   protected function setUp($import_test_views = TRUE) {
27     parent::setUp($import_test_views);
28
29     $this->enableViewsTestModule();
30   }
31
32   /**
33    * Test table caption/summary/description.
34    */
35   public function testAccessibilitySettings() {
36     $this->drupalGet('test-table');
37
38     $result = $this->xpath('//caption/child::text()');
39     $this->assertTrue(count($result), 'The caption appears on the table.');
40     $this->assertEqual(trim($result[0]->getText()), 'caption-text');
41
42     $result = $this->xpath('//summary/child::text()');
43     $this->assertTrue(count($result), 'The summary appears on the table.');
44     $this->assertEqual(trim($result[0]->getText()), 'summary-text');
45
46     $result = $this->xpath('//caption/details/child::text()');
47     $this->assertTrue(count($result), 'The table description appears on the table.');
48     $this->assertEqual(trim($result[0]->getText()), 'description-text');
49
50     // Remove the caption and ensure the caption is not displayed anymore.
51     $view = View::load('test_table');
52     $display = &$view->getDisplay('default');
53     $display['display_options']['style']['options']['caption'] = '';
54     $view->save();
55
56     $this->drupalGet('test-table');
57     $result = $this->xpath('//caption/child::text()');
58     $this->assertFalse(trim($result[0]->getText()), 'Ensure that the caption disappears.');
59
60     // Remove the table summary.
61     $display = &$view->getDisplay('default');
62     $display['display_options']['style']['options']['summary'] = '';
63     $view->save();
64
65     $this->drupalGet('test-table');
66     $result = $this->xpath('//summary/child::text()');
67     $this->assertFalse(count($result), 'Ensure that the summary disappears.');
68
69     // Remove the table description.
70     $display = &$view->getDisplay('default');
71     $display['display_options']['style']['options']['description'] = '';
72     $view->save();
73
74     $this->drupalGet('test-table');
75     $result = $this->xpath('//caption/details/child::text()');
76     $this->assertFalse(count($result), 'Ensure that the description disappears.');
77   }
78
79   /**
80    * Test table fields in columns.
81    */
82   public function testFieldInColumns() {
83     $this->drupalGet('test-table');
84
85     // Ensure that both columns are in separate tds.
86     // Check for class " views-field-job ", because just "views-field-job" won't
87     // do: "views-field-job-1" would also contain "views-field-job".
88     // @see Drupal\system\Tests\Form\ElementTest::testButtonClasses().
89     $result = $this->xpath('//tbody/tr/td[contains(concat(" ", @class, " "), " views-field-job ")]');
90     $this->assertTrue(count($result), 'Ensure there is a td with the class views-field-job');
91     $result = $this->xpath('//tbody/tr/td[contains(concat(" ", @class, " "), " views-field-job-1 ")]');
92     $this->assertTrue(count($result), 'Ensure there is a td with the class views-field-job-1');
93
94     // Combine the second job-column with the first one, with ', ' as separator.
95     $view = View::load('test_table');
96     $display = &$view->getDisplay('default');
97     $display['display_options']['style']['options']['columns']['job_1'] = 'job';
98     $display['display_options']['style']['options']['info']['job']['separator'] = ', ';
99     $view->save();
100
101     // Ensure that both columns are properly combined.
102     $this->drupalGet('test-table');
103
104     $result = $this->xpath('//tbody/tr/td[contains(concat(" ", @class, " "), " views-field-job views-field-job-1 ")]');
105     $this->assertTrue(count($result), 'Ensure that the job column class names are joined into a single column');
106
107     $result = $this->xpath('//tbody/tr/td[contains(., "Drummer, Drummer")]');
108     $this->assertTrue(count($result), 'Ensure the job column values are joined into a single column');
109   }
110
111   /**
112    * Test that a number with the value of "0" is displayed in the table.
113    */
114   public function testNumericFieldVisible() {
115     // Adds a new datapoint in the views_test_data table to have a person with
116     // an age of zero.
117     $data_set = $this->dataSet();
118     $query = db_insert('views_test_data')
119       ->fields(array_keys($data_set[0]));
120     $query->values([
121       'name' => 'James McCartney',
122       'age' => 0,
123       'job' => 'Baby',
124       'created' => gmmktime(6, 30, 10, 1, 1, 2000),
125       'status' => 1,
126     ]);
127     $query->execute();
128
129     $this->drupalGet('test-table');
130
131     $result = $this->xpath('//tbody/tr/td[contains(., "Baby")]');
132     $this->assertTrue(count($result), 'Ensure that the baby is found.');
133
134     $result = $this->xpath('//tbody/tr/td[text()=0]');
135     $this->assertTrue(count($result), 'Ensure that the baby\'s age is shown');
136   }
137
138   /**
139    * Test that empty columns are hidden when empty_column is set.
140    */
141   public function testEmptyColumn() {
142     // Empty the 'job' data.
143     \Drupal::database()->update('views_test_data')
144       ->fields(['job' => ''])
145       ->execute();
146
147     $this->drupalGet('test-table');
148
149     // Test that only one of the job columns still shows.
150     $result = $this->xpath('//thead/tr/th/a[text()="Job"]');
151     $this->assertEqual(count($result), 1, 'Ensure that empty column header is hidden.');
152
153     $result = $this->xpath('//tbody/tr/td[contains(concat(" ", @class, " "), " views-field-job-1 ")]');
154     $this->assertEqual(count($result), 0, 'Ensure the empty table cells are hidden.');
155   }
156
157   /**
158    * Tests grouping by a field.
159    */
160   public function testGrouping() {
161     /** @var \Drupal\views\ViewEntityInterface $view */
162     $view = \Drupal::entityTypeManager()->getStorage('view')->load('test_table');
163     // Get a reference to the display configuration so we can alter some
164     // specific style options.
165     $display = &$view->getDisplay('default');
166     // Set job as the grouping field.
167     $display['display_options']['style']['options']['grouping'][0] = [
168       'field' => 'job',
169       'rendered' => TRUE,
170       'rendered_strip' => FALSE,
171     ];
172     // Clear the caption text, the rendered job field will be used as a caption.
173     $display['display_options']['style']['options']['caption'] = '';
174     $display['display_options']['style']['options']['summary'] = '';
175     $display['display_options']['style']['options']['description'] = '';
176     $view->save();
177
178     // Add a record containing unsafe markup to be sure it's filtered out.
179     $unsafe_markup = '<script>alert("Rapper");</script>';
180     $unsafe_markup_data = [
181       'name' => 'Marshall',
182       'age' => 42,
183       'job' => $unsafe_markup,
184       'created' => gmmktime(0, 0, 0, 2, 15, 2001),
185       'status' => 1,
186     ];
187     $database = $this->container->get('database');
188     $database->insert('views_test_data')
189       ->fields(array_keys($unsafe_markup_data))
190       ->values($unsafe_markup_data)
191       ->execute();
192
193     $this->drupalGet('test-table');
194     $expected_captions = [
195       'Job: Speaker',
196       'Job: Songwriter',
197       'Job: Drummer',
198       'Job: Singer',
199       'Job: ' . $unsafe_markup,
200     ];
201
202     // Ensure that we don't find the caption containing unsafe markup.
203     $this->assertNoRaw($unsafe_markup, "Didn't find caption containing unsafe markup.");
204
205     // Ensure that all expected captions are found.
206     foreach ($expected_captions as $raw_caption) {
207       $this->assertEscaped($raw_caption);
208     }
209
210     $display = &$view->getDisplay('default');
211     // Remove the label from the grouping field.
212     $display['display_options']['fields']['job']['label'] = '';
213     $view->save();
214
215     $this->drupalGet('test-table');
216     $expected_captions = [
217       'Speaker',
218       'Songwriter',
219       'Drummer',
220       'Singer',
221       $unsafe_markup,
222     ];
223
224     // Ensure that we don't find the caption containing unsafe markup.
225     $this->assertNoRaw($unsafe_markup, "Didn't find caption containing unsafe markup.");
226
227     // Ensure that all expected captions are found.
228     foreach ($expected_captions as $raw_caption) {
229       $this->assertEscaped($raw_caption);
230     }
231   }
232
233   /**
234    * Tests the cacheability of the table display.
235    */
236   public function testTableCacheability() {
237     \Drupal::service('module_installer')->uninstall(['page_cache']);
238
239     $url = 'test-table';
240     $this->drupalGet($url);
241     $this->assertSession()->statusCodeEquals(200);
242     $this->assertEquals('MISS', $this->drupalGetHeader(DynamicPageCacheSubscriber::HEADER));
243     $this->drupalGet($url);
244     $this->assertEquals('HIT', $this->drupalGetHeader(DynamicPageCacheSubscriber::HEADER));
245   }
246
247 }