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