Updated Drupal to 8.6. This goes with the following updates because it's possible...
[yaffs-website] / web / core / modules / field / tests / src / Kernel / DisplayApiTest.php
1 <?php
2
3 namespace Drupal\Tests\field\Kernel;
4
5 use Drupal\Core\Entity\Entity\EntityViewMode;
6 use Drupal\entity_test\Entity\EntityTest;
7 use Drupal\field\Entity\FieldConfig;
8 use Drupal\field\Entity\FieldStorageConfig;
9
10 /**
11  * Tests the field display API.
12  *
13  * @group field
14  */
15 class DisplayApiTest extends FieldKernelTestBase {
16
17   /**
18    * The field name to use in this test.
19    *
20    * @var string
21    */
22   protected $fieldName;
23
24   /**
25    * The field label to use in this test.
26    *
27    * @var string
28    */
29   protected $label;
30
31   /**
32    * The field cardinality to use in this test.
33    *
34    * @var int
35    */
36   protected $cardinality;
37
38   /**
39    * The field display options to use in this test.
40    *
41    * @var array
42    */
43   protected $displayOptions;
44
45   /**
46    * The test entity.
47    *
48    * @var \Drupal\Core\Entity\EntityInterface
49    */
50   protected $entity;
51
52   /**
53    * An array of random values, in the format expected for field values.
54    *
55    * @var array
56    */
57   protected $values;
58
59   /**
60    * {@inheritdoc}
61    */
62   public static $modules = ['system'];
63
64   protected function setUp() {
65     parent::setUp();
66
67     // Create a field and its storage.
68     $this->fieldName = 'test_field';
69     $this->label = $this->randomMachineName();
70     $this->cardinality = 4;
71
72     $field_storage = [
73       'field_name' => $this->fieldName,
74       'entity_type' => 'entity_test',
75       'type' => 'test_field',
76       'cardinality' => $this->cardinality,
77     ];
78     $field = [
79       'field_name' => $this->fieldName,
80       'entity_type' => 'entity_test',
81       'bundle' => 'entity_test',
82       'label' => $this->label,
83     ];
84
85     $this->displayOptions = [
86       'default' => [
87         'type' => 'field_test_default',
88         'settings' => [
89           'test_formatter_setting' => $this->randomMachineName(),
90         ],
91       ],
92       'teaser' => [
93         'type' => 'field_test_default',
94         'settings' => [
95           'test_formatter_setting' => $this->randomMachineName(),
96         ],
97       ],
98     ];
99
100     FieldStorageConfig::create($field_storage)->save();
101     FieldConfig::create($field)->save();
102     // Create a display for the default view mode.
103     entity_get_display($field['entity_type'], $field['bundle'], 'default')
104       ->setComponent($this->fieldName, $this->displayOptions['default'])
105       ->save();
106     // Create a display for the teaser view mode.
107     EntityViewMode::create(['id' => 'entity_test.teaser', 'targetEntityType' => 'entity_test'])->save();
108     entity_get_display($field['entity_type'], $field['bundle'], 'teaser')
109       ->setComponent($this->fieldName, $this->displayOptions['teaser'])
110       ->save();
111
112     // Create an entity with values.
113     $this->values = $this->_generateTestFieldValues($this->cardinality);
114     $this->entity = EntityTest::create();
115     $this->entity->{$this->fieldName}->setValue($this->values);
116     $this->entity->save();
117   }
118
119   /**
120    * Tests the FieldItemListInterface::view() method.
121    */
122   public function testFieldItemListView() {
123     $items = $this->entity->get($this->fieldName);
124
125     \Drupal::service('theme_handler')->install(['classy']);
126     $this->config('system.theme')->set('default', 'classy')->save();
127
128     // No display settings: check that default display settings are used.
129     $build = $items->view();
130     $this->render($build);
131     $settings = \Drupal::service('plugin.manager.field.formatter')->getDefaultSettings('field_test_default');
132     $setting = $settings['test_formatter_setting'];
133     $this->assertText($this->label, 'Label was displayed.');
134     foreach ($this->values as $delta => $value) {
135       $this->assertText($setting . '|' . $value['value'], format_string('Value @delta was displayed with expected setting.', ['@delta' => $delta]));
136     }
137
138     // Display settings: Check hidden field.
139     $display = [
140       'label' => 'hidden',
141       'type' => 'field_test_multiple',
142       'settings' => [
143         'test_formatter_setting_multiple' => $this->randomMachineName(),
144         'alter' => TRUE,
145       ],
146     ];
147     $build = $items->view($display);
148     $this->render($build);
149     $setting = $display['settings']['test_formatter_setting_multiple'];
150     $this->assertNoText($this->label, 'Label was not displayed.');
151     $this->assertText('field_test_entity_display_build_alter', 'Alter fired, display passed.');
152     $this->assertText('entity language is en', 'Language is placed onto the context.');
153     $array = [];
154     foreach ($this->values as $delta => $value) {
155       $array[] = $delta . ':' . $value['value'];
156     }
157     $this->assertText($setting . '|' . implode('|', $array), 'Values were displayed with expected setting.');
158
159     // Display settings: Check visually_hidden field.
160     $display = [
161       'label' => 'visually_hidden',
162       'type' => 'field_test_multiple',
163       'settings' => [
164         'test_formatter_setting_multiple' => $this->randomMachineName(),
165         'alter' => TRUE,
166       ],
167     ];
168     $build = $items->view($display);
169     $this->render($build);
170     $setting = $display['settings']['test_formatter_setting_multiple'];
171     $this->assertRaw('visually-hidden', 'Label was visually hidden.');
172     $this->assertText('field_test_entity_display_build_alter', 'Alter fired, display passed.');
173     $this->assertText('entity language is en', 'Language is placed onto the context.');
174     $array = [];
175     foreach ($this->values as $delta => $value) {
176       $array[] = $delta . ':' . $value['value'];
177     }
178     $this->assertText($setting . '|' . implode('|', $array), 'Values were displayed with expected setting.');
179
180     // Check the prepare_view steps are invoked.
181     $display = [
182       'label' => 'hidden',
183       'type' => 'field_test_with_prepare_view',
184       'settings' => [
185         'test_formatter_setting_additional' => $this->randomMachineName(),
186       ],
187     ];
188     $build = $items->view($display);
189     $this->render($build);
190     $setting = $display['settings']['test_formatter_setting_additional'];
191     $this->assertNoText($this->label, 'Label was not displayed.');
192     $this->assertNoText('field_test_entity_display_build_alter', 'Alter not fired.');
193     foreach ($this->values as $delta => $value) {
194       $this->assertText($setting . '|' . $value['value'] . '|' . ($value['value'] + 1), format_string('Value @delta was displayed with expected setting.', ['@delta' => $delta]));
195     }
196
197     // View mode: check that display settings specified in the display object
198     // are used.
199     $build = $items->view('teaser');
200     $this->render($build);
201     $setting = $this->displayOptions['teaser']['settings']['test_formatter_setting'];
202     $this->assertText($this->label, 'Label was displayed.');
203     foreach ($this->values as $delta => $value) {
204       $this->assertText($setting . '|' . $value['value'], format_string('Value @delta was displayed with expected setting.', ['@delta' => $delta]));
205     }
206
207     // Unknown view mode: check that display settings for 'default' view mode
208     // are used.
209     $build = $items->view('unknown_view_mode');
210     $this->render($build);
211     $setting = $this->displayOptions['default']['settings']['test_formatter_setting'];
212     $this->assertText($this->label, 'Label was displayed.');
213     foreach ($this->values as $delta => $value) {
214       $this->assertText($setting . '|' . $value['value'], format_string('Value @delta was displayed with expected setting.', ['@delta' => $delta]));
215     }
216   }
217
218   /**
219    * Tests the FieldItemInterface::view() method.
220    */
221   public function testFieldItemView() {
222     // No display settings: check that default display settings are used.
223     $settings = \Drupal::service('plugin.manager.field.formatter')->getDefaultSettings('field_test_default');
224     $setting = $settings['test_formatter_setting'];
225     foreach ($this->values as $delta => $value) {
226       $item = $this->entity->{$this->fieldName}[$delta];
227       $build = $item->view();
228       $this->render($build);
229       $this->assertText($setting . '|' . $value['value'], format_string('Value @delta was displayed with expected setting.', ['@delta' => $delta]));
230     }
231
232     // Check that explicit display settings are used.
233     $display = [
234       'type' => 'field_test_multiple',
235       'settings' => [
236         'test_formatter_setting_multiple' => $this->randomMachineName(),
237       ],
238     ];
239     $setting = $display['settings']['test_formatter_setting_multiple'];
240     foreach ($this->values as $delta => $value) {
241       $item = $this->entity->{$this->fieldName}[$delta];
242       $build = $item->view($display);
243       $this->render($build);
244       $this->assertText($setting . '|0:' . $value['value'], format_string('Value @delta was displayed with expected setting.', ['@delta' => $delta]));
245     }
246
247     // Check that prepare_view steps are invoked.
248     $display = [
249       'type' => 'field_test_with_prepare_view',
250       'settings' => [
251         'test_formatter_setting_additional' => $this->randomMachineName(),
252       ],
253     ];
254     $setting = $display['settings']['test_formatter_setting_additional'];
255     foreach ($this->values as $delta => $value) {
256       $item = $this->entity->{$this->fieldName}[$delta];
257       $build = $item->view($display);
258       $this->render($build);
259       $this->assertText($setting . '|' . $value['value'] . '|' . ($value['value'] + 1), format_string('Value @delta was displayed with expected setting.', ['@delta' => $delta]));
260     }
261
262     // View mode: check that display settings specified in the field are used.
263     $setting = $this->displayOptions['teaser']['settings']['test_formatter_setting'];
264     foreach ($this->values as $delta => $value) {
265       $item = $this->entity->{$this->fieldName}[$delta];
266       $build = $item->view('teaser');
267       $this->render($build);
268       $this->assertText($setting . '|' . $value['value'], format_string('Value @delta was displayed with expected setting.', ['@delta' => $delta]));
269     }
270
271     // Unknown view mode: check that display settings for 'default' view mode
272     // are used.
273     $setting = $this->displayOptions['default']['settings']['test_formatter_setting'];
274     foreach ($this->values as $delta => $value) {
275       $item = $this->entity->{$this->fieldName}[$delta];
276       $build = $item->view('unknown_view_mode');
277       $this->render($build);
278       $this->assertText($setting . '|' . $value['value'], format_string('Value @delta was displayed with expected setting.', ['@delta' => $delta]));
279     }
280   }
281
282   /**
283    * Tests that the prepareView() formatter method still fires for empty values.
284    */
285   public function testFieldEmpty() {
286     // Uses \Drupal\field_test\Plugin\Field\FieldFormatter\TestFieldEmptyFormatter.
287     $display = [
288       'label' => 'hidden',
289       'type' => 'field_empty_test',
290       'settings' => [
291         'test_empty_string' => '**EMPTY FIELD**' . $this->randomMachineName(),
292       ],
293     ];
294     // $this->entity is set by the setUp() method and by default contains 4
295     // numeric values.  We only want to test the display of this one field.
296     $build = $this->entity->get($this->fieldName)->view($display);
297     $this->render($build);
298     // The test field by default contains values, so should not display the
299     // default "empty" text.
300     $this->assertNoText($display['settings']['test_empty_string']);
301
302     // Now remove the values from the test field and retest.
303     $this->entity->{$this->fieldName} = [];
304     $this->entity->save();
305     $build = $this->entity->get($this->fieldName)->view($display);
306     $this->render($build);
307     // This time, as the field values have been removed, we *should* show the
308     // default "empty" text.
309     $this->assertText($display['settings']['test_empty_string']);
310   }
311
312 }