Updated Drupal to 8.6. This goes with the following updates because it's possible...
[yaffs-website] / web / core / modules / field / tests / src / Kernel / TranslationTest.php
1 <?php
2
3 namespace Drupal\Tests\field\Kernel;
4
5 use Drupal\field\Entity\FieldConfig;
6 use Drupal\language\Entity\ConfigurableLanguage;
7 use Drupal\field\Entity\FieldStorageConfig;
8
9 /**
10  * Tests multilanguage fields logic.
11  *
12  * The following tests will check the multilanguage logic in field handling.
13  *
14  * @group field
15  */
16 class TranslationTest extends FieldKernelTestBase {
17
18   /**
19    * Modules to enable.
20    *
21    * The node module is required because the tests alter the node entity type.
22    *
23    * @var array
24    */
25   public static $modules = ['language', 'node'];
26
27   /**
28    * The name of the field to use in this test.
29    *
30    * @var string
31    */
32   protected $fieldName;
33
34   /**
35    * The name of the entity type to use in this test.
36    *
37    * @var string
38    */
39   protected $entityType = 'test_entity';
40
41   /**
42    * An array defining the field storage to use in this test.
43    *
44    * @var array
45    */
46   protected $fieldStorageDefinition;
47
48   /**
49    * An array defining the field to use in this test.
50    *
51    * @var array
52    */
53   protected $fieldDefinition;
54
55   /**
56    * The field storage to use in this test.
57    *
58    * @var \Drupal\field\Entity\FieldStorageConfig
59    */
60   protected $fieldStorage;
61
62   /**
63    * The field to use in this test.
64    *
65    * @var \Drupal\field\Entity\FieldConfig
66    */
67   protected $field;
68
69   /**
70    * {@inheritdoc}
71    */
72   protected function setUp() {
73     parent::setUp();
74
75     $this->installConfig(['language']);
76
77     $this->fieldName = mb_strtolower($this->randomMachineName());
78
79     $this->entityType = 'entity_test';
80
81     $this->fieldStorageDefinition = [
82       'field_name' => $this->fieldName,
83       'entity_type' => $this->entityType,
84       'type' => 'test_field',
85       'cardinality' => 4,
86     ];
87     $this->fieldStorage = FieldStorageConfig::create($this->fieldStorageDefinition);
88     $this->fieldStorage->save();
89
90     $this->fieldDefinition = [
91       'field_storage' => $this->fieldStorage,
92       'bundle' => 'entity_test',
93     ];
94     $this->field = FieldConfig::create($this->fieldDefinition);
95     $this->field->save();
96
97     for ($i = 0; $i < 3; ++$i) {
98       ConfigurableLanguage::create([
99         'id' => 'l' . $i,
100         'label' => $this->randomString(),
101       ])->save();
102     }
103   }
104
105   /**
106    * Test translatable fields storage/retrieval.
107    */
108   public function testTranslatableFieldSaveLoad() {
109     // Enable field translations for nodes.
110     field_test_entity_info_translatable('node', TRUE);
111     $entity_type = \Drupal::entityManager()->getDefinition('node');
112     $this->assertTrue($entity_type->isTranslatable(), 'Nodes are translatable.');
113
114     // Prepare the field translations.
115     $entity_type_id = 'entity_test';
116     field_test_entity_info_translatable($entity_type_id, TRUE);
117     $entity = $this->container->get('entity_type.manager')
118       ->getStorage($entity_type_id)
119       ->create(['type' => $this->field->getTargetBundle()]);
120     $field_translations = [];
121     $available_langcodes = array_keys($this->container->get('language_manager')->getLanguages());
122     $entity->langcode->value = reset($available_langcodes);
123     foreach ($available_langcodes as $langcode) {
124       $field_translations[$langcode] = $this->_generateTestFieldValues($this->fieldStorage->getCardinality());
125       $translation = $entity->hasTranslation($langcode) ? $entity->getTranslation($langcode) : $entity->addTranslation($langcode);
126       $translation->{$this->fieldName}->setValue($field_translations[$langcode]);
127     }
128
129     // Save and reload the field translations.
130     $entity = $this->entitySaveReload($entity);
131
132     // Check if the correct values were saved/loaded.
133     foreach ($field_translations as $langcode => $items) {
134       $result = TRUE;
135       foreach ($items as $delta => $item) {
136         $result = $result && $item['value'] == $entity->getTranslation($langcode)->{$this->fieldName}[$delta]->value;
137       }
138       $this->assertTrue($result, format_string('%language translation correctly handled.', ['%language' => $langcode]));
139     }
140
141     // Test default values.
142     $field_name_default = mb_strtolower($this->randomMachineName() . '_field_name');
143     $field_storage_definition = $this->fieldStorageDefinition;
144     $field_storage_definition['field_name'] = $field_name_default;
145     $field_storage = FieldStorageConfig::create($field_storage_definition);
146     $field_storage->save();
147
148     $field_definition = $this->fieldDefinition;
149     $field_definition['field_storage'] = $field_storage;
150     $field_definition['default_value'] = [['value' => rand(1, 127)]];
151     $field = FieldConfig::create($field_definition);
152     $field->save();
153
154     $translation_langcodes = array_slice($available_langcodes, 0, 2);
155     asort($translation_langcodes);
156     $translation_langcodes = array_values($translation_langcodes);
157
158     $values = ['type' => $field->getTargetBundle(), 'langcode' => $translation_langcodes[0]];
159     $entity = $this->container->get('entity_type.manager')
160       ->getStorage($entity_type_id)
161       ->create($values);
162     foreach ($translation_langcodes as $langcode) {
163       $values[$this->fieldName][$langcode] = $this->_generateTestFieldValues($this->fieldStorage->getCardinality());
164       $translation = $entity->hasTranslation($langcode) ? $entity->getTranslation($langcode) : $entity->addTranslation($langcode);
165       $translation->{$this->fieldName}->setValue($values[$this->fieldName][$langcode]);
166     }
167
168     $field_langcodes = array_keys($entity->getTranslationLanguages());
169     sort($field_langcodes);
170     $this->assertEqual($translation_langcodes, $field_langcodes, 'Missing translations did not get a default value.');
171
172     // @todo Test every translation once the Entity Translation API allows for
173     //   multilingual defaults.
174     $langcode = $entity->language()->getId();
175     $this->assertEqual($entity->getTranslation($langcode)->{$field_name_default}->getValue(), $field->getDefaultValueLiteral(), format_string('Default value correctly populated for language %language.', ['%language' => $langcode]));
176
177     // Check that explicit empty values are not overridden with default values.
178     foreach ([NULL, []] as $empty_items) {
179       $values = ['type' => $field->getTargetBundle(), 'langcode' => $translation_langcodes[0]];
180       $entity = entity_create($entity_type_id, $values);
181       foreach ($translation_langcodes as $langcode) {
182         $values[$this->fieldName][$langcode] = $this->_generateTestFieldValues($this->fieldStorage->getCardinality());
183         $translation = $entity->hasTranslation($langcode) ? $entity->getTranslation($langcode) : $entity->addTranslation($langcode);
184         $translation->{$this->fieldName}->setValue($values[$this->fieldName][$langcode]);
185         $translation->{$field_name_default}->setValue($empty_items);
186         $values[$field_name_default][$langcode] = $empty_items;
187       }
188
189       foreach ($entity->getTranslationLanguages() as $langcode => $language) {
190         $this->assertEquals([], $entity->getTranslation($langcode)->{$field_name_default}->getValue(), format_string('Empty value correctly populated for language %language.', ['%language' => $langcode]));
191       }
192     }
193   }
194
195   /**
196    * Tests field access.
197    *
198    * Regression test to verify that fieldAccess() can be called while only
199    * passing the required parameters.
200    *
201    * @see https://www.drupal.org/node/2404739
202    */
203   public function testFieldAccess() {
204     $access_control_handler = \Drupal::entityManager()->getAccessControlHandler($this->entityType);
205     $this->assertTrue($access_control_handler->fieldAccess('view', $this->field));
206   }
207
208 }