Mercurial > hg > cmmr2012-drupal-site
comparison core/modules/views/tests/src/Kernel/FieldApiDataTest.php @ 5:12f9dff5fda9 tip
Update to Drupal core 8.7.1
author | Chris Cannam |
---|---|
date | Thu, 09 May 2019 15:34:47 +0100 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
4:a9cd425dd02b | 5:12f9dff5fda9 |
---|---|
1 <?php | |
2 | |
3 namespace Drupal\Tests\views\Kernel; | |
4 | |
5 use Drupal\Component\Render\MarkupInterface; | |
6 use Drupal\field\Entity\FieldConfig; | |
7 use Drupal\field\Entity\FieldStorageConfig; | |
8 use Drupal\language\Entity\ConfigurableLanguage; | |
9 use Drupal\language\Entity\ContentLanguageSettings; | |
10 use Drupal\node\Entity\Node; | |
11 use Drupal\node\Entity\NodeType; | |
12 use Drupal\views\Views; | |
13 | |
14 /** | |
15 * Tests the Field Views data. | |
16 * | |
17 * @group views | |
18 */ | |
19 class FieldApiDataTest extends ViewsKernelTestBase { | |
20 | |
21 /** | |
22 * {@inheritdoc} | |
23 */ | |
24 public static $modules = [ | |
25 'field', | |
26 'filter', | |
27 'language', | |
28 'node', | |
29 'user', | |
30 ]; | |
31 | |
32 /** | |
33 * {@inheritdoc} | |
34 */ | |
35 public static $testViews = ['test_field_config_translation_filter']; | |
36 | |
37 /** | |
38 * {@inheritdoc} | |
39 */ | |
40 protected function setUp($import_test_views = TRUE) { | |
41 parent::setUp($import_test_views); | |
42 $this->installEntitySchema('user'); | |
43 $this->installEntitySchema('node'); | |
44 $this->installSchema('node', ['node_access']); | |
45 } | |
46 | |
47 /** | |
48 * Unit testing the views data structure. | |
49 * | |
50 * We check data structure for both node and node revision tables. | |
51 */ | |
52 public function testViewsData() { | |
53 $field_storage_string = FieldStorageConfig::create([ | |
54 'field_name' => 'field_string', | |
55 'entity_type' => 'node', | |
56 'type' => 'string', | |
57 ]); | |
58 $field_storage_string->save(); | |
59 | |
60 $field_storage_string_long = FieldStorageConfig::create([ | |
61 'field_name' => 'field_string_long', | |
62 'entity_type' => 'node', | |
63 'type' => 'string_long', | |
64 ]); | |
65 $field_storage_string_long->save(); | |
66 | |
67 NodeType::create(['type' => 'page'])->save(); | |
68 NodeType::create(['type' => 'article'])->save(); | |
69 | |
70 // Attach the field to nodes. | |
71 FieldConfig::create([ | |
72 'field_name' => 'field_string', | |
73 'entity_type' => 'node', | |
74 'bundle' => 'page', | |
75 'label' => 'GiraffeA" label', | |
76 ])->save(); | |
77 | |
78 // Attach the string_long field to the page node type. | |
79 FieldConfig::create([ | |
80 'field_name' => 'field_string_long', | |
81 'entity_type' => 'node', | |
82 'bundle' => 'page', | |
83 'label' => 'string_long label', | |
84 ])->save(); | |
85 | |
86 // Attach the same field to a different bundle with a different label. | |
87 FieldConfig::create([ | |
88 'field_name' => 'field_string', | |
89 'entity_type' => 'node', | |
90 'bundle' => 'article', | |
91 'label' => 'GiraffeB" label', | |
92 ])->save(); | |
93 | |
94 // Now create some example nodes/users for the view result. | |
95 for ($i = 0; $i < 5; $i++) { | |
96 $edit = [ | |
97 'field_string' => [(['value' => $this->randomMachineName()])], | |
98 ]; | |
99 $nodes[] = Node::create(['type' => 'page'] + $edit); | |
100 } | |
101 | |
102 /** @var \Drupal\Core\Entity\Sql\DefaultTableMapping $table_mapping */ | |
103 $table_mapping = $this->container->get('entity_type.manager') | |
104 ->getStorage('node') | |
105 ->getTableMapping(); | |
106 | |
107 $current_table = $table_mapping->getDedicatedDataTableName($field_storage_string); | |
108 $revision_table = $table_mapping->getDedicatedRevisionTableName($field_storage_string); | |
109 $data = $this->getViewsData(); | |
110 | |
111 $this->assertArrayHasKey($current_table, $data); | |
112 $this->assertArrayHasKey($revision_table, $data); | |
113 | |
114 // The node field should join against node_field_data. | |
115 $this->assertArrayHasKey('node_field_data', $data[$current_table]['table']['join']); | |
116 $this->assertArrayHasKey('node_field_revision', $data[$revision_table]['table']['join']); | |
117 | |
118 $expected_join = [ | |
119 'table' => $current_table, | |
120 'left_field' => 'nid', | |
121 'field' => 'entity_id', | |
122 'extra' => [ | |
123 ['field' => 'deleted', 'value' => 0, 'numeric' => TRUE], | |
124 ['left_field' => 'langcode', 'field' => 'langcode'], | |
125 ], | |
126 ]; | |
127 $this->assertSame($expected_join, $data[$current_table]['table']['join']['node_field_data']); | |
128 $expected_join = [ | |
129 'table' => $revision_table, | |
130 'left_field' => 'vid', | |
131 'field' => 'revision_id', | |
132 'extra' => [ | |
133 ['field' => 'deleted', 'value' => 0, 'numeric' => TRUE], | |
134 ['left_field' => 'langcode', 'field' => 'langcode'], | |
135 ], | |
136 ]; | |
137 $this->assertSame($expected_join, $data[$revision_table]['table']['join']['node_field_revision']); | |
138 | |
139 // Test click sortable for string field. | |
140 $this->assertTrue($data[$current_table][$field_storage_string->getName()]['field']['click sortable']); | |
141 // Click sort should only be on the primary field. | |
142 $this->assertTrue(empty($data[$revision_table][$field_storage_string->getName()]['field']['click sortable'])); | |
143 // Test click sortable for long text field. | |
144 $data_long = $this->getViewsData('field_string_long'); | |
145 $current_table_long = $table_mapping->getDedicatedDataTableName($field_storage_string_long); | |
146 $this->assertTrue($data_long[$current_table_long][$field_storage_string_long->getName()]['field']['click sortable']); | |
147 | |
148 $this->assertInstanceOf(MarkupInterface::class, $data[$current_table][$field_storage_string->getName()]['help']); | |
149 $this->assertEquals('Appears in: page, article. Also known as: Content: GiraffeB" label', $data[$current_table][$field_storage_string->getName()]['help']); | |
150 | |
151 $this->assertInstanceOf(MarkupInterface::class, $data[$current_table][$field_storage_string->getName() . '_value']['help']); | |
152 $this->assertEquals('Appears in: page, article. Also known as: Content: GiraffeA" label (field_string)', $data[$current_table][$field_storage_string->getName() . '_value']['help']); | |
153 | |
154 // Since each label is only used once, views_entity_field_label() will | |
155 // return a label using alphabetical sorting. | |
156 $this->assertEquals('GiraffeA" label (field_string)', $data[$current_table][$field_storage_string->getName() . '_value']['title']); | |
157 | |
158 // Attach the same field to a different bundle with a different label. | |
159 NodeType::create(['type' => 'news'])->save(); | |
160 FieldConfig::create([ | |
161 'field_name' => $field_storage_string->getName(), | |
162 'entity_type' => 'node', | |
163 'bundle' => 'news', | |
164 'label' => 'GiraffeB" label', | |
165 ])->save(); | |
166 $this->container->get('views.views_data')->clear(); | |
167 $data = $this->getViewsData(); | |
168 | |
169 // Now the 'GiraffeB" label' is used twice and therefore will be | |
170 // selected by views_entity_field_label(). | |
171 $this->assertEquals('GiraffeB" label (field_string)', $data[$current_table][$field_storage_string->getName() . '_value']['title']); | |
172 $this->assertInstanceOf(MarkupInterface::class, $data[$current_table][$field_storage_string->getName()]['help']); | |
173 $this->assertEquals('Appears in: page, article, news. Also known as: Content: GiraffeA" label', $data[$current_table][$field_storage_string->getName()]['help']); | |
174 } | |
175 | |
176 /** | |
177 * Gets the views data for the field created in setUp(). | |
178 * | |
179 * @param string $field_storage_key | |
180 * (optional) The optional field name. | |
181 * | |
182 * @return array | |
183 * Views data. | |
184 */ | |
185 protected function getViewsData($field_storage_key = 'field_string') { | |
186 $views_data = $this->container->get('views.views_data'); | |
187 $data = []; | |
188 | |
189 // Check the table and the joins of the first field. Attached to node only. | |
190 /** @var \Drupal\Core\Entity\Sql\DefaultTableMapping $table_mapping */ | |
191 $table_mapping = $this->container->get('entity_type.manager')->getStorage('node')->getTableMapping(); | |
192 $field_storage = FieldStorageConfig::loadByName('node', $field_storage_key); | |
193 $current_table = $table_mapping->getDedicatedDataTableName($field_storage); | |
194 $revision_table = $table_mapping->getDedicatedRevisionTableName($field_storage); | |
195 $data[$current_table] = $views_data->get($current_table); | |
196 $data[$revision_table] = $views_data->get($revision_table); | |
197 return $data; | |
198 } | |
199 | |
200 /** | |
201 * Tests filtering entries with different translatability. | |
202 */ | |
203 public function testEntityFieldFilter() { | |
204 NodeType::create(['type' => 'bundle1'])->save(); | |
205 NodeType::create(['type' => 'bundle2'])->save(); | |
206 | |
207 // Create some example content. | |
208 ConfigurableLanguage::create(['id' => 'es'])->save(); | |
209 ConfigurableLanguage::create(['id' => 'fr'])->save(); | |
210 | |
211 ContentLanguageSettings::loadByEntityTypeBundle('node', 'bundle1') | |
212 ->setDefaultLangcode('es') | |
213 ->setLanguageAlterable(TRUE) | |
214 ->save(); | |
215 ContentLanguageSettings::loadByEntityTypeBundle('node', 'bundle2') | |
216 ->setDefaultLangcode('es') | |
217 ->setLanguageAlterable(TRUE) | |
218 ->save(); | |
219 | |
220 $field_translation_map = [ | |
221 1 => ['bundle1' => TRUE, 'bundle2' => TRUE], | |
222 2 => ['bundle1' => FALSE, 'bundle2' => FALSE], | |
223 3 => ['bundle1' => TRUE, 'bundle2' => FALSE], | |
224 ]; | |
225 | |
226 for ($i = 1; $i < 4; $i++) { | |
227 $field_name = "field_name_$i"; | |
228 FieldStorageConfig::create([ | |
229 'field_name' => $field_name, | |
230 'entity_type' => 'node', | |
231 'type' => 'string', | |
232 ])->save(); | |
233 | |
234 foreach (['bundle1', 'bundle2'] as $bundle) { | |
235 FieldConfig::create([ | |
236 'field_name' => $field_name, | |
237 'entity_type' => 'node', | |
238 'bundle' => $bundle, | |
239 'translatable' => $field_translation_map[$i][$bundle], | |
240 ])->save(); | |
241 } | |
242 } | |
243 | |
244 $node1 = Node::create([ | |
245 'title' => 'Test title bundle1', | |
246 'type' => 'bundle1', | |
247 'langcode' => 'es', | |
248 'field_name_1' => 'field name 1: es', | |
249 'field_name_2' => 'field name 2: es', | |
250 'field_name_3' => 'field name 3: es', | |
251 ]); | |
252 $node1->save(); | |
253 /** @var \Drupal\node\NodeInterface $translation */ | |
254 $node1->addTranslation('fr', [ | |
255 'title' => $node1->title->value, | |
256 'field_name_1' => 'field name 1: fr', | |
257 'field_name_3' => 'field name 3: fr', | |
258 ])->save(); | |
259 | |
260 $node2 = Node::create([ | |
261 'title' => 'Test title bundle2', | |
262 'type' => 'bundle2', | |
263 'langcode' => 'es', | |
264 'field_name_1' => 'field name 1: es', | |
265 'field_name_2' => 'field name 2: es', | |
266 'field_name_3' => 'field name 3: es', | |
267 ]); | |
268 $node2->save(); | |
269 | |
270 $node2->addTranslation('fr', [ | |
271 'title' => $node2->title->value, | |
272 'field_name_1' => 'field name 1: fr', | |
273 ])->save(); | |
274 | |
275 $map = [ | |
276 'nid' => 'nid', | |
277 'langcode' => 'langcode', | |
278 ]; | |
279 | |
280 $view = Views::getView('test_field_config_translation_filter'); | |
281 | |
282 // Filter by 'field name 1: es'. | |
283 $view->setDisplay('embed_1'); | |
284 $this->executeView($view); | |
285 $expected = [ | |
286 [ | |
287 'nid' => $node1->id(), | |
288 'langcode' => 'es', | |
289 ], | |
290 [ | |
291 'nid' => $node2->id(), | |
292 'langcode' => 'es', | |
293 ], | |
294 ]; | |
295 | |
296 $this->assertIdenticalResultset($view, $expected, $map); | |
297 $view->destroy(); | |
298 | |
299 // Filter by 'field name 1: fr'. | |
300 $view->setDisplay('embed_2'); | |
301 $this->executeView($view); | |
302 $expected = [ | |
303 [ | |
304 'nid' => $node1->id(), | |
305 'langcode' => 'fr', | |
306 ], | |
307 [ | |
308 'nid' => $node2->id(), | |
309 'langcode' => 'fr', | |
310 ], | |
311 ]; | |
312 | |
313 $this->assertIdenticalResultset($view, $expected, $map); | |
314 $view->destroy(); | |
315 | |
316 // Filter by 'field name 2: es'. | |
317 $view->setDisplay('embed_3'); | |
318 $this->executeView($view); | |
319 $expected = [ | |
320 [ | |
321 'nid' => $node1->id(), | |
322 'langcode' => 'es', | |
323 ], | |
324 [ | |
325 'nid' => $node1->id(), | |
326 'langcode' => 'fr', | |
327 ], | |
328 [ | |
329 'nid' => $node2->id(), | |
330 'langcode' => 'es', | |
331 ], | |
332 [ | |
333 'nid' => $node2->id(), | |
334 'langcode' => 'fr', | |
335 ], | |
336 ]; | |
337 | |
338 $this->assertIdenticalResultset($view, $expected, $map); | |
339 $view->destroy(); | |
340 | |
341 // Filter by 'field name 2: fr', which doesn't exist. | |
342 $view->setDisplay('embed_4'); | |
343 $this->executeView($view); | |
344 $expected = []; | |
345 | |
346 $this->assertIdenticalResultset($view, $expected, $map); | |
347 $view->destroy(); | |
348 | |
349 // Filter by 'field name 3: es'. | |
350 $view->setDisplay('embed_5'); | |
351 $this->executeView($view); | |
352 $expected = [ | |
353 [ | |
354 'nid' => $node1->id(), | |
355 'langcode' => 'es', | |
356 ], | |
357 [ | |
358 'nid' => $node2->id(), | |
359 'langcode' => 'es', | |
360 ], | |
361 // Why is this one returned? | |
362 [ | |
363 'nid' => $node2->id(), | |
364 'langcode' => 'fr', | |
365 ], | |
366 ]; | |
367 | |
368 $this->assertIdenticalResultset($view, $expected, $map); | |
369 $view->destroy(); | |
370 | |
371 // Filter by 'field name 3: fr'. | |
372 $view->setDisplay('embed_6'); | |
373 $this->executeView($view); | |
374 $expected = [ | |
375 [ | |
376 'nid' => $node1->id(), | |
377 'langcode' => 'fr', | |
378 ], | |
379 ]; | |
380 | |
381 $this->assertIdenticalResultset($view, $expected, $map); | |
382 $view->destroy(); | |
383 } | |
384 | |
385 } |