comparison core/modules/field/src/Tests/Views/HandlerFieldFieldTest.php @ 0:4c8ae668cc8c

Initial import (non-working)
author Chris Cannam
date Wed, 29 Nov 2017 16:09:58 +0000
parents
children 1fec387a4317
comparison
equal deleted inserted replaced
-1:000000000000 0:4c8ae668cc8c
1 <?php
2
3 namespace Drupal\field\Tests\Views;
4
5 use Drupal\Core\Field\FieldStorageDefinitionInterface;
6 use Drupal\views\ViewExecutable;
7 use Drupal\views\Views;
8 use Drupal\field\Entity\FieldStorageConfig;
9
10 /**
11 * Tests the field itself of the Field integration.
12 *
13 * @group field
14 * @TODO
15 * Check a entity-type with bundles
16 * Check a entity-type without bundles
17 * Check locale:disabled, locale:enabled and locale:enabled with another language
18 * Check revisions
19 */
20 class HandlerFieldFieldTest extends FieldTestBase {
21
22 /**
23 * {@inheritdoc}
24 */
25 public static $modules = ['node', 'field_test'];
26
27 /**
28 * Views used by this test.
29 *
30 * @var array
31 */
32 public static $testViews = ['test_view_fieldapi'];
33
34 /**
35 * Test nodes.
36 *
37 * @var \Drupal\node\NodeInterface[]
38 */
39 public $nodes;
40
41 /**
42 * {@inheritdoc}
43 */
44 protected function setUp() {
45 parent::setUp();
46
47 // Setup basic fields.
48 $this->setUpFieldStorages(3);
49
50 // Setup a field with cardinality > 1.
51 $this->fieldStorages[3] = FieldStorageConfig::create([
52 'field_name' => 'field_name_3',
53 'entity_type' => 'node',
54 'type' => 'string',
55 'cardinality' => FieldStorageDefinitionInterface::CARDINALITY_UNLIMITED,
56 ]);
57 $this->fieldStorages[3]->save();
58 // Setup a field that will have no value.
59 $this->fieldStorages[4] = FieldStorageConfig::create([
60 'field_name' => 'field_name_4',
61 'entity_type' => 'node',
62 'type' => 'string',
63 'cardinality' => FieldStorageDefinitionInterface::CARDINALITY_UNLIMITED,
64 ]);
65 $this->fieldStorages[4]->save();
66
67 // Setup a text field.
68 $this->fieldStorages[5] = FieldStorageConfig::create([
69 'field_name' => 'field_name_5',
70 'entity_type' => 'node',
71 'type' => 'text',
72 ]);
73 $this->fieldStorages[5]->save();
74
75 // Setup a text field with access control.
76 // @see field_test_entity_field_access()
77 $this->fieldStorages[6] = FieldStorageConfig::create([
78 'field_name' => 'field_no_view_access',
79 'entity_type' => 'node',
80 'type' => 'text',
81 ]);
82 $this->fieldStorages[6]->save();
83
84 $this->setUpFields();
85
86 // Create some nodes.
87 $this->nodes = [];
88 for ($i = 0; $i < 3; $i++) {
89 $edit = ['type' => 'page'];
90
91 foreach ([0, 1, 2, 5] as $key) {
92 $field_storage = $this->fieldStorages[$key];
93 $edit[$field_storage->getName()][0]['value'] = $this->randomMachineName(8);
94 }
95 // Add a hidden value for the no-view field.
96 $edit[$this->fieldStorages[6]->getName()][0]['value'] = 'ssh secret squirrel';
97 for ($j = 0; $j < 5; $j++) {
98 $edit[$this->fieldStorages[3]->getName()][$j]['value'] = $this->randomMachineName(8);
99 }
100 // Set this field to be empty.
101 $edit[$this->fieldStorages[4]->getName()] = [['value' => NULL]];
102
103 $this->nodes[$i] = $this->drupalCreateNode($edit);
104 }
105
106 $this->container->get('views.views_data')->clear();
107 }
108
109 /**
110 * Sets up the testing view with random field data.
111 *
112 * @param \Drupal\views\ViewExecutable $view
113 * The view to add field data to.
114 */
115 protected function prepareView(ViewExecutable $view) {
116 $view->storage->invalidateCaches();
117 $view->initDisplay();
118 foreach ($this->fieldStorages as $field_storage) {
119 $field_name = $field_storage->getName();
120 $view->display_handler->options['fields'][$field_name]['id'] = $field_name;
121 $view->display_handler->options['fields'][$field_name]['table'] = 'node__' . $field_name;
122 $view->display_handler->options['fields'][$field_name]['field'] = $field_name;
123 }
124 }
125
126 public function testFieldRender() {
127 $this->_testSimpleFieldRender();
128 $this->_testInaccessibleFieldRender();
129 $this->_testFormatterSimpleFieldRender();
130 $this->_testMultipleFieldRender();
131 }
132
133 public function _testSimpleFieldRender() {
134 $view = Views::getView('test_view_fieldapi');
135 $this->prepareView($view);
136 $this->executeView($view);
137
138 // Tests that the rendered fields match the actual value of the fields.
139 for ($i = 0; $i < 3; $i++) {
140 for ($key = 0; $key < 2; $key++) {
141 $field_name = $this->fieldStorages[$key]->getName();
142 $rendered_field = $view->style_plugin->getField($i, $field_name);
143 $expected_field = $this->nodes[$i]->$field_name->value;
144 $this->assertEqual($rendered_field, $expected_field);
145 }
146 }
147 }
148
149 public function _testInaccessibleFieldRender() {
150 $view = Views::getView('test_view_fieldapi');
151 $this->prepareView($view);
152 $this->executeView($view);
153
154 // Check that the field handler for the hidden field is correctly removed
155 // from the display.
156 // @see https://www.drupal.org/node/2382931
157 $this->assertFalse(array_key_exists('field_no_view_access', $view->field));
158
159 // Check that the access-denied field is not visible.
160 for ($i = 0; $i < 3; $i++) {
161 $field_name = $this->fieldStorages[6]->getName();
162 $rendered_field = $view->style_plugin->getField($i, $field_name);
163 $this->assertFalse($rendered_field, 'Hidden field not rendered');
164 }
165 }
166
167 /**
168 * Tests that fields with formatters runs as expected.
169 */
170 public function _testFormatterSimpleFieldRender() {
171 $view = Views::getView('test_view_fieldapi');
172 $this->prepareView($view);
173 $view->displayHandlers->get('default')->options['fields'][$this->fieldStorages[5]->getName()]['type'] = 'text_trimmed';
174 $view->displayHandlers->get('default')->options['fields'][$this->fieldStorages[5]->getName()]['settings'] = [
175 'trim_length' => 3,
176 ];
177 $this->executeView($view);
178
179 // Make sure that the formatter works as expected.
180 // @TODO: actually there should be a specific formatter.
181 for ($i = 0; $i < 2; $i++) {
182 $rendered_field = $view->style_plugin->getField($i, $this->fieldStorages[5]->getName());
183 $this->assertEqual(strlen(html_entity_decode($rendered_field)), 3);
184 }
185 }
186
187 public function _testMultipleFieldRender() {
188 $view = Views::getView('test_view_fieldapi');
189 $field_name = $this->fieldStorages[3]->getName();
190
191 // Test delta limit.
192 $this->prepareView($view);
193 $view->displayHandlers->get('default')->options['fields'][$field_name]['group_rows'] = TRUE;
194 $view->displayHandlers->get('default')->options['fields'][$field_name]['delta_limit'] = 3;
195 $this->executeView($view);
196
197 for ($i = 0; $i < 3; $i++) {
198 $rendered_field = $view->style_plugin->getField($i, $field_name);
199 $items = [];
200 $pure_items = $this->nodes[$i]->{$field_name}->getValue();
201 $pure_items = array_splice($pure_items, 0, 3);
202 foreach ($pure_items as $j => $item) {
203 $items[] = $pure_items[$j]['value'];
204 }
205 $this->assertEqual($rendered_field, implode(', ', $items), 'The amount of items is limited.');
206 }
207
208 // Test that an empty field is rendered without error.
209 $view->style_plugin->getField(4, $this->fieldStorages[4]->getName());
210 $view->destroy();
211
212 // Test delta limit + offset
213 $this->prepareView($view);
214 $view->displayHandlers->get('default')->options['fields'][$field_name]['group_rows'] = TRUE;
215 $view->displayHandlers->get('default')->options['fields'][$field_name]['delta_limit'] = 3;
216 $view->displayHandlers->get('default')->options['fields'][$field_name]['delta_offset'] = 1;
217 $this->executeView($view);
218
219 for ($i = 0; $i < 3; $i++) {
220 $rendered_field = $view->style_plugin->getField($i, $field_name);
221 $items = [];
222 $pure_items = $this->nodes[$i]->{$field_name}->getValue();
223 $pure_items = array_splice($pure_items, 1, 3);
224 foreach ($pure_items as $j => $item) {
225 $items[] = $pure_items[$j]['value'];
226 }
227 $this->assertEqual($rendered_field, implode(', ', $items), 'The amount of items is limited and the offset is correct.');
228 }
229 $view->destroy();
230
231 // Test delta limit + reverse.
232 $this->prepareView($view);
233 $view->displayHandlers->get('default')->options['fields'][$field_name]['delta_offset'] = 0;
234 $view->displayHandlers->get('default')->options['fields'][$field_name]['group_rows'] = TRUE;
235 $view->displayHandlers->get('default')->options['fields'][$field_name]['delta_limit'] = 3;
236 $view->displayHandlers->get('default')->options['fields'][$field_name]['delta_reversed'] = TRUE;
237 $this->executeView($view);
238
239 for ($i = 0; $i < 3; $i++) {
240 $rendered_field = $view->style_plugin->getField($i, $field_name);
241 $items = [];
242 $pure_items = $this->nodes[$i]->{$field_name}->getValue();
243 array_splice($pure_items, 0, -3);
244 $pure_items = array_reverse($pure_items);
245 foreach ($pure_items as $j => $item) {
246 $items[] = $pure_items[$j]['value'];
247 }
248 $this->assertEqual($rendered_field, implode(', ', $items), 'The amount of items is limited and they are reversed.');
249 }
250 $view->destroy();
251
252 // Test delta first last.
253 $this->prepareView($view);
254 $view->displayHandlers->get('default')->options['fields'][$field_name]['group_rows'] = TRUE;
255 $view->displayHandlers->get('default')->options['fields'][$field_name]['delta_limit'] = 0;
256 $view->displayHandlers->get('default')->options['fields'][$field_name]['delta_first_last'] = TRUE;
257 $view->displayHandlers->get('default')->options['fields'][$field_name]['delta_reversed'] = FALSE;
258 $this->executeView($view);
259
260 for ($i = 0; $i < 3; $i++) {
261 $rendered_field = $view->style_plugin->getField($i, $field_name);
262 $items = [];
263 $pure_items = $this->nodes[$i]->{$field_name}->getValue();
264 $items[] = $pure_items[0]['value'];
265 $items[] = $pure_items[4]['value'];
266 $this->assertEqual($rendered_field, implode(', ', $items), 'Items are limited to first and last.');
267 }
268 $view->destroy();
269
270 // Test delta limit + custom separator.
271 $this->prepareView($view);
272 $view->displayHandlers->get('default')->options['fields'][$field_name]['delta_first_last'] = FALSE;
273 $view->displayHandlers->get('default')->options['fields'][$field_name]['delta_limit'] = 3;
274 $view->displayHandlers->get('default')->options['fields'][$field_name]['group_rows'] = TRUE;
275 $view->displayHandlers->get('default')->options['fields'][$field_name]['separator'] = ':';
276 $this->executeView($view);
277
278 for ($i = 0; $i < 3; $i++) {
279 $rendered_field = $view->style_plugin->getField($i, $field_name);
280 $items = [];
281 $pure_items = $this->nodes[$i]->{$field_name}->getValue();
282 $pure_items = array_splice($pure_items, 0, 3);
283 foreach ($pure_items as $j => $item) {
284 $items[] = $pure_items[$j]['value'];
285 }
286 $this->assertEqual($rendered_field, implode(':', $items), 'The amount of items is limited and the custom separator is correct.');
287 }
288 $view->destroy();
289
290 // Test separator with HTML, ensure it is escaped.
291 $this->prepareView($view);
292 $view->displayHandlers->get('default')->options['fields'][$field_name]['group_rows'] = TRUE;
293 $view->displayHandlers->get('default')->options['fields'][$field_name]['delta_limit'] = 3;
294 $view->displayHandlers->get('default')->options['fields'][$field_name]['separator'] = '<h2>test</h2>';
295 $this->executeView($view);
296
297 for ($i = 0; $i < 3; $i++) {
298 $rendered_field = $view->style_plugin->getField($i, $field_name);
299 $items = [];
300 $pure_items = $this->nodes[$i]->{$field_name}->getValue();
301 $pure_items = array_splice($pure_items, 0, 3);
302 foreach ($pure_items as $j => $item) {
303 $items[] = $pure_items[$j]['value'];
304 }
305 $this->assertEqual($rendered_field, implode('<h2>test</h2>', $items), 'The custom separator is correctly escaped.');
306 }
307 $view->destroy();
308 }
309
310 }