Upgraded drupal core with security updates
[yaffs-website] / web / core / modules / content_translation / tests / src / Functional / ContentTranslationSettingsTest.php
1 <?php
2
3 namespace Drupal\Tests\content_translation\Functional;
4
5 use Drupal\comment\Plugin\Field\FieldType\CommentItemInterface;
6 use Drupal\comment\Tests\CommentTestTrait;
7 use Drupal\Core\Field\Entity\BaseFieldOverride;
8 use Drupal\Core\Language\Language;
9 use Drupal\field\Entity\FieldConfig;
10 use Drupal\language\Entity\ContentLanguageSettings;
11 use Drupal\Tests\BrowserTestBase;
12
13 /**
14  * Tests the content translation settings UI.
15  *
16  * @group content_translation
17  */
18 class ContentTranslationSettingsTest extends BrowserTestBase {
19
20   use CommentTestTrait;
21
22   /**
23    * Modules to enable.
24    *
25    * @var array
26    */
27   public static $modules = ['language', 'content_translation', 'node', 'comment', 'field_ui', 'entity_test'];
28
29   protected function setUp() {
30     parent::setUp();
31
32     // Set up two content types to test fields shared between different
33     // bundles.
34     $this->drupalCreateContentType(['type' => 'article']);
35     $this->drupalCreateContentType(['type' => 'page']);
36     $this->addDefaultCommentField('node', 'article', 'comment_article', CommentItemInterface::OPEN, 'comment_article');
37     $this->addDefaultCommentField('node', 'page', 'comment_page');
38
39     $admin_user = $this->drupalCreateUser(['access administration pages', 'administer languages', 'administer content translation', 'administer content types', 'administer node fields', 'administer comment fields', 'administer comments', 'administer comment types', 'administer account settings']);
40     $this->drupalLogin($admin_user);
41   }
42
43   /**
44    * Tests that the settings UI works as expected.
45    */
46   public function testSettingsUI() {
47     // Check for the content_translation_menu_links_discovered_alter() changes.
48     $this->drupalGet('admin/config');
49     $this->assertLink('Content language and translation');
50     $this->assertText('Configure language and translation support for content.');
51     // Test that the translation settings are ignored if the bundle is marked
52     // translatable but the entity type is not.
53     $edit = ['settings[comment][comment_article][translatable]' => TRUE];
54     $this->assertSettings('comment', NULL, FALSE, $edit);
55
56     // Test that the translation settings are ignored if only a field is marked
57     // as translatable and not the related entity type and bundle.
58     $edit = ['settings[comment][comment_article][fields][comment_body]' => TRUE];
59     $this->assertSettings('comment', NULL, FALSE, $edit);
60
61     // Test that the translation settings are not stored if an entity type and
62     // bundle are marked as translatable but no field is.
63     $edit = [
64       'entity_types[comment]' => TRUE,
65       'settings[comment][comment_article][translatable]' => TRUE,
66       // Base fields are translatable by default.
67       'settings[comment][comment_article][fields][changed]' => FALSE,
68       'settings[comment][comment_article][fields][created]' => FALSE,
69       'settings[comment][comment_article][fields][homepage]' => FALSE,
70       'settings[comment][comment_article][fields][hostname]' => FALSE,
71       'settings[comment][comment_article][fields][mail]' => FALSE,
72       'settings[comment][comment_article][fields][name]' => FALSE,
73       'settings[comment][comment_article][fields][status]' => FALSE,
74       'settings[comment][comment_article][fields][subject]' => FALSE,
75       'settings[comment][comment_article][fields][uid]' => FALSE,
76     ];
77     $this->assertSettings('comment', 'comment_article', FALSE, $edit);
78     $xpath_err = '//div[contains(@class, "error")]';
79     $this->assertTrue($this->xpath($xpath_err), 'Enabling translation only for entity bundles generates a form error.');
80
81     // Test that the translation settings are not stored if a non-configurable
82     // language is set as default and the language selector is hidden.
83     $edit = [
84       'entity_types[comment]' => TRUE,
85       'settings[comment][comment_article][settings][language][langcode]' => Language::LANGCODE_NOT_SPECIFIED,
86       'settings[comment][comment_article][settings][language][language_alterable]' => FALSE,
87       'settings[comment][comment_article][translatable]' => TRUE,
88       'settings[comment][comment_article][fields][comment_body]' => TRUE,
89     ];
90     $this->assertSettings('comment', 'comment_article', FALSE, $edit);
91     $this->assertTrue($this->xpath($xpath_err), 'Enabling translation with a fixed non-configurable language generates a form error.');
92
93     // Test that a field shared among different bundles can be enabled without
94     // needing to make all the related bundles translatable.
95     $edit = [
96       'entity_types[comment]' => TRUE,
97       'settings[comment][comment_article][settings][language][langcode]' => 'current_interface',
98       'settings[comment][comment_article][settings][language][language_alterable]' => TRUE,
99       'settings[comment][comment_article][translatable]' => TRUE,
100       'settings[comment][comment_article][fields][comment_body]' => TRUE,
101       // Override both comment subject fields to untranslatable.
102       'settings[comment][comment_article][fields][subject]' => FALSE,
103       'settings[comment][comment][fields][subject]' => FALSE,
104     ];
105     $this->assertSettings('comment', 'comment_article', TRUE, $edit);
106     $definition = $this->entityManager()->getFieldDefinitions('comment', 'comment_article')['comment_body'];
107     $this->assertTrue($definition->isTranslatable(), 'Article comment body is translatable.');
108     $definition = $this->entityManager()->getFieldDefinitions('comment', 'comment_article')['subject'];
109     $this->assertFalse($definition->isTranslatable(), 'Article comment subject is not translatable.');
110
111     $definition = $this->entityManager()->getFieldDefinitions('comment', 'comment')['comment_body'];
112     $this->assertFalse($definition->isTranslatable(), 'Page comment body is not translatable.');
113     $definition = $this->entityManager()->getFieldDefinitions('comment', 'comment')['subject'];
114     $this->assertFalse($definition->isTranslatable(), 'Page comment subject is not translatable.');
115
116     // Test that translation can be enabled for base fields.
117     $edit = [
118       'entity_types[entity_test_mul]' => TRUE,
119       'settings[entity_test_mul][entity_test_mul][translatable]' => TRUE,
120       'settings[entity_test_mul][entity_test_mul][fields][name]' => TRUE,
121       'settings[entity_test_mul][entity_test_mul][fields][user_id]' => FALSE,
122     ];
123     $this->assertSettings('entity_test_mul', 'entity_test_mul', TRUE, $edit);
124     $field_override = BaseFieldOverride::loadByName('entity_test_mul', 'entity_test_mul', 'name');
125     $this->assertTrue($field_override->isTranslatable(), 'Base fields can be overridden with a base field bundle override entity.');
126     $definitions = $this->entityManager()->getFieldDefinitions('entity_test_mul', 'entity_test_mul');
127     $this->assertTrue($definitions['name']->isTranslatable() && !$definitions['user_id']->isTranslatable(), 'Base field bundle overrides were correctly altered.');
128
129     // Test that language settings are correctly stored.
130     $language_configuration = ContentLanguageSettings::loadByEntityTypeBundle('comment', 'comment_article');
131     $this->assertEqual($language_configuration->getDefaultLangcode(), 'current_interface', 'The default language for article comments is set to the interface text language selected for page.');
132     $this->assertTrue($language_configuration->isLanguageAlterable(), 'The language selector for article comments is shown.');
133
134     // Verify language widget appears on comment type form.
135     $this->drupalGet('admin/structure/comment/manage/comment_article');
136     $this->assertField('language_configuration[content_translation]');
137     $this->assertFieldChecked('edit-language-configuration-content-translation');
138
139     // Verify that translation may be enabled for the article content type.
140     $edit = [
141       'language_configuration[content_translation]' => TRUE,
142     ];
143     // Make sure the checkbox is available and not checked by default.
144     $this->drupalGet('admin/structure/types/manage/article');
145     $this->assertField('language_configuration[content_translation]');
146     $this->assertNoFieldChecked('edit-language-configuration-content-translation');
147     $this->drupalPostForm('admin/structure/types/manage/article', $edit, t('Save content type'));
148     $this->drupalGet('admin/structure/types/manage/article');
149     $this->assertFieldChecked('edit-language-configuration-content-translation');
150
151     // Test that the title field of nodes is available in the settings form.
152     $edit = [
153       'entity_types[node]' => TRUE,
154       'settings[node][article][settings][language][langcode]' => 'current_interface',
155       'settings[node][article][settings][language][language_alterable]' => TRUE,
156       'settings[node][article][translatable]' => TRUE,
157       'settings[node][article][fields][title]' => TRUE
158     ];
159     $this->assertSettings('node', NULL, TRUE, $edit);
160
161     foreach ([TRUE, FALSE] as $translatable) {
162       // Test that configurable field translatability is correctly switched.
163       $edit = ['settings[node][article][fields][body]' => $translatable];
164       $this->assertSettings('node', 'article', TRUE, $edit);
165       $field = FieldConfig::loadByName('node', 'article', 'body');
166       $definitions = \Drupal::entityManager()->getFieldDefinitions('node', 'article');
167       $this->assertEqual($definitions['body']->isTranslatable(), $translatable, 'Field translatability correctly switched.');
168       $this->assertEqual($field->isTranslatable(), $definitions['body']->isTranslatable(), 'Configurable field translatability correctly switched.');
169
170       // Test that also the Field UI form behaves correctly.
171       $translatable = !$translatable;
172       $edit = ['translatable' => $translatable];
173       $this->drupalPostForm('admin/structure/types/manage/article/fields/node.article.body', $edit, t('Save settings'));
174       \Drupal::entityManager()->clearCachedFieldDefinitions();
175       $field = FieldConfig::loadByName('node', 'article', 'body');
176       $definitions = \Drupal::entityManager()->getFieldDefinitions('node', 'article');
177       $this->assertEqual($definitions['body']->isTranslatable(), $translatable, 'Field translatability correctly switched.');
178       $this->assertEqual($field->isTranslatable(), $definitions['body']->isTranslatable(), 'Configurable field translatability correctly switched.');
179     }
180
181     // Test that the order of the language list is similar to other language
182     // lists, such as in Views UI.
183     $this->drupalGet('admin/config/regional/content-language');
184
185     $expected_elements = [
186       'site_default',
187       'current_interface',
188       'authors_default',
189       'en',
190       'und',
191       'zxx',
192     ];
193     $elements = $this->xpath('//select[@id="edit-settings-node-article-settings-language-langcode"]/option');
194     // Compare values inside the option elements with expected values.
195     for ($i = 0; $i < count($elements); $i++) {
196       $this->assertEqual($elements[$i]->getValue(), $expected_elements[$i]);
197     }
198   }
199
200   /**
201    * Tests the language settings checkbox on account settings page.
202    */
203   public function testAccountLanguageSettingsUI() {
204     // Make sure the checkbox is available and not checked by default.
205     $this->drupalGet('admin/config/people/accounts');
206     $this->assertField('language[content_translation]');
207     $this->assertNoFieldChecked('edit-language-content-translation');
208
209     $edit = [
210       'language[content_translation]' => TRUE,
211     ];
212     $this->drupalPostForm('admin/config/people/accounts', $edit, t('Save configuration'));
213     $this->drupalGet('admin/config/people/accounts');
214     $this->assertFieldChecked('edit-language-content-translation');
215
216     // Make sure account settings can be saved.
217     $this->drupalPostForm('admin/config/people/accounts', ['anonymous' => 'Save me please!'], 'Save configuration');
218     $this->assertFieldByName('anonymous', 'Save me please!', 'Anonymous name has been changed.');
219     $this->assertText('The configuration options have been saved.');
220   }
221
222   /**
223    * Asserts that translatability has the expected value for the given bundle.
224    *
225    * @param string $entity_type
226    *   The entity type for which to check translatability.
227    * @param string $bundle
228    *   The bundle for which to check translatability.
229    * @param bool $enabled
230    *   TRUE if translatability should be enabled, FALSE otherwise.
231    * @param array $edit
232    *   An array of values to submit to the content translation settings page.
233    *
234    * @return bool
235    *   TRUE if the assertion succeeded, FALSE otherwise.
236    */
237   protected function assertSettings($entity_type, $bundle, $enabled, $edit) {
238     $this->drupalPostForm('admin/config/regional/content-language', $edit, t('Save configuration'));
239     $args = ['@entity_type' => $entity_type, '@bundle' => $bundle, '@enabled' => $enabled ? 'enabled' : 'disabled'];
240     $message = format_string('Translation for entity @entity_type (@bundle) is @enabled.', $args);
241     \Drupal::entityManager()->clearCachedDefinitions();
242     return $this->assertEqual(\Drupal::service('content_translation.manager')->isEnabled($entity_type, $bundle), $enabled, $message);
243   }
244
245   /**
246    * Tests that field setting depends on bundle translatability.
247    */
248   public function testFieldTranslatableSettingsUI() {
249     // At least one field needs to be translatable to enable article for
250     // translation. Create an extra field to be used for this purpose. We use
251     // the UI to test our form alterations.
252     $edit = [
253       'new_storage_type' => 'text',
254       'label' => 'Test',
255       'field_name' => 'article_text',
256     ];
257     $this->drupalPostForm('admin/structure/types/manage/article/fields/add-field', $edit, 'Save and continue');
258
259     // Tests that field doesn't have translatable setting if bundle is not
260     // translatable.
261     $path = 'admin/structure/types/manage/article/fields/node.article.field_article_text';
262     $this->drupalGet($path);
263     $this->assertFieldByXPath('//input[@id="edit-translatable" and @disabled="disabled"]');
264     $this->assertText('To configure translation for this field, enable language support for this type.', 'No translatable setting for field.');
265
266     // Tests that field has translatable setting if bundle is translatable.
267     // Note: this field is not translatable when enable bundle translatability.
268     $edit = [
269       'entity_types[node]' => TRUE,
270       'settings[node][article][settings][language][language_alterable]' => TRUE,
271       'settings[node][article][translatable]' => TRUE,
272       'settings[node][article][fields][field_article_text]' => TRUE,
273     ];
274     $this->assertSettings('node', 'article', TRUE, $edit);
275     $this->drupalGet($path);
276     $this->assertFieldByXPath('//input[@id="edit-translatable" and not(@disabled) and @checked="checked"]');
277     $this->assertNoText('To enable translation of this field, enable language support for this type.', 'Translatable setting for field available.');
278   }
279
280   /**
281    * Tests the translatable settings checkbox for untranslatable entities.
282    */
283   public function testNonTranslatableTranslationSettingsUI() {
284     $this->drupalGet('admin/config/regional/content-language');
285     $this->assertNoField('settings[entity_test][entity_test][translatable]');
286   }
287
288   /**
289    * Returns the entity manager.
290    *
291    * @return \Drupal\Core\Entity\EntityManagerInterface
292    *   The entity manager;
293    */
294   protected function entityManager() {
295     return $this->container->get('entity.manager');
296   }
297
298 }