1<?php
2
3namespace Drupal\Tests\system\Functional\Form;
4
5use Drupal\Component\Serialization\Json;
6use Drupal\Core\Language\LanguageInterface;
7use Drupal\language\Entity\ConfigurableLanguage;
8use Drupal\Tests\BrowserTestBase;
9
10/**
11 * Tests that the language select form element prints and submits the right
12 * options.
13 *
14 * @group Form
15 */
16class LanguageSelectElementTest extends BrowserTestBase {
17
18  /**
19   * Modules to enable.
20   *
21   * @var array
22   */
23  protected static $modules = ['form_test', 'language'];
24
25  /**
26   * {@inheritdoc}
27   */
28  protected $defaultTheme = 'stark';
29
30  /**
31   * Tests that the options printed by the language select element are correct.
32   */
33  public function testLanguageSelectElementOptions() {
34    // Add some languages.
35    ConfigurableLanguage::create([
36      'id' => 'aaa',
37      'label' => $this->randomMachineName(),
38    ])->save();
39
40    ConfigurableLanguage::create([
41      'id' => 'bbb',
42      'label' => $this->randomMachineName(),
43    ])->save();
44
45    \Drupal::languageManager()->reset();
46
47    $this->drupalGet('form-test/language_select');
48    // Check that the language fields were rendered on the page.
49    $ids = [
50        'edit-languages-all' => LanguageInterface::STATE_ALL,
51        'edit-languages-configurable' => LanguageInterface::STATE_CONFIGURABLE,
52        'edit-languages-locked' => LanguageInterface::STATE_LOCKED,
53        'edit-languages-config-and-locked' => LanguageInterface::STATE_CONFIGURABLE | LanguageInterface::STATE_LOCKED,
54    ];
55    foreach ($ids as $id => $flags) {
56      $this->assertSession()->fieldExists($id);
57      $options = [];
58      /** @var \Drupal\Core\Language\LanguageManagerInterface $language_manager */
59      $language_manager = $this->container->get('language_manager');
60      foreach ($language_manager->getLanguages($flags) as $langcode => $language) {
61        $options[$langcode] = $language->isLocked() ? t('- @name -', ['@name' => $language->getName()]) : $language->getName();
62      }
63      $this->_testLanguageSelectElementOptions($id, $options);
64    }
65
66    // Test that the #options were not altered by #languages.
67    $this->assertSession()->fieldExists('edit-language-custom-options');
68    $this->_testLanguageSelectElementOptions('edit-language-custom-options', ['opt1' => 'First option', 'opt2' => 'Second option', 'opt3' => 'Third option']);
69  }
70
71  /**
72   * Tests the case when the language select elements should not be printed.
73   *
74   * This happens when the language module is disabled.
75   */
76  public function testHiddenLanguageSelectElement() {
77    // Disable the language module, so that the language select field will not
78    // be rendered.
79    $this->container->get('module_installer')->uninstall(['language']);
80    $this->drupalGet('form-test/language_select');
81    // Check that the language fields were rendered on the page.
82    $ids = ['edit-languages-all', 'edit-languages-configurable', 'edit-languages-locked', 'edit-languages-config-and-locked'];
83    foreach ($ids as $id) {
84      $this->assertSession()->fieldNotExists($id);
85    }
86
87    // Check that the submitted values were the default values of the language
88    // field elements.
89    $edit = [];
90    $this->submitForm($edit, 'Submit');
91    $values = Json::decode($this->getSession()->getPage()->getContent());
92    $this->assertEquals('xx', $values['languages_all']);
93    $this->assertEquals('en', $values['languages_configurable']);
94    $this->assertEquals(LanguageInterface::LANGCODE_NOT_SPECIFIED, $values['languages_locked']);
95    $this->assertEquals('dummy_value', $values['languages_config_and_locked']);
96    $this->assertEquals('opt2', $values['language_custom_options']);
97  }
98
99  /**
100   * Helper function to check the options of a language select form element.
101   *
102   * @param string $id
103   *   The id of the language select element to check.
104   * @param array $options
105   *   An array with options to compare with.
106   */
107  protected function _testLanguageSelectElementOptions($id, $options) {
108    // Check that the options in the language field are exactly the same,
109    // including the order, as the languages sent as a parameter.
110    $found_options = $this->assertSession()->selectExists($id)->findAll('css', 'option');
111    $found_options = array_map(function ($item) {
112      return $item->getText();
113    }, $found_options);
114    $this->assertEquals(array_values($options), $found_options);
115  }
116
117}
118