3 namespace Drupal\Tests\filter\Functional;
5 use Drupal\Component\Utility\SafeMarkup;
6 use Drupal\filter\Entity\FilterFormat;
7 use Drupal\Tests\BrowserTestBase;
10 * Tests form elements with associated text formats.
14 class FilterFormTest extends BrowserTestBase {
17 * Modules to enable for this test.
21 protected static $modules = ['filter', 'filter_test'];
24 * An administrative user account that can administer text formats.
26 * @var \Drupal\user\Entity\User
31 * An basic user account that can only access basic HTML text format.
33 * @var \Drupal\user\Entity\User
40 protected function setUp() {
43 /** @var \Drupal\filter\FilterFormatInterface $filter_test_format */
44 $filter_test_format = FilterFormat::load('filter_test');
45 /** @var \Drupal\filter\FilterFormatInterface $filtered_html_format */
46 $filtered_html_format = FilterFormat::load('filtered_html');
47 /** @var \Drupal\filter\FilterFormatInterface $full_html_format */
48 $full_html_format = FilterFormat::load('full_html');
51 $this->adminUser = $this->drupalCreateUser([
53 $filtered_html_format->getPermissionName(),
54 $full_html_format->getPermissionName(),
55 $filter_test_format->getPermissionName(),
58 $this->webUser = $this->drupalCreateUser([
59 $filtered_html_format->getPermissionName(),
60 $filter_test_format->getPermissionName(),
65 * Tests various different configurations of the 'text_format' element.
67 public function testFilterForm() {
68 $this->doFilterFormTestAsAdmin();
69 $this->doFilterFormTestAsNonAdmin();
70 // Ensure that enabling modules which provide filter plugins behaves
72 // @see https://www.drupal.org/node/2387983
73 \Drupal::service('module_installer')->install(['filter_test_plugin']);
74 // Force rebuild module data.
75 _system_rebuild_module_data();
79 * Tests the behavior of the 'text_format' element as an administrator.
81 protected function doFilterFormTestAsAdmin() {
82 $this->drupalLogin($this->adminUser);
83 $this->drupalGet('filter-test/text-format');
85 // Test a text format element with all formats.
86 $formats = ['filtered_html', 'full_html', 'filter_test'];
87 $this->assertEnabledTextarea('edit-all-formats-no-default-value');
88 // If no default is given, the format with the lowest weight becomes the
90 $this->assertOptions('edit-all-formats-no-default-format--2', $formats, 'filtered_html');
91 $this->assertEnabledTextarea('edit-all-formats-default-value');
92 // \Drupal\filter_test\Form\FilterTestFormatForm::buildForm() uses
93 // 'filter_test' as the default value in this case.
94 $this->assertOptions('edit-all-formats-default-format--2', $formats, 'filter_test');
95 $this->assertEnabledTextarea('edit-all-formats-default-missing-value');
96 // If a missing format is set as the default, administrators must select a
97 // valid replacement format.
98 $this->assertRequiredSelectAndOptions('edit-all-formats-default-missing-format--2', $formats);
100 // Test a text format element with a predefined list of formats.
101 $formats = ['full_html', 'filter_test'];
102 $this->assertEnabledTextarea('edit-restricted-formats-no-default-value');
103 $this->assertOptions('edit-restricted-formats-no-default-format--2', $formats, 'full_html');
104 $this->assertEnabledTextarea('edit-restricted-formats-default-value');
105 $this->assertOptions('edit-restricted-formats-default-format--2', $formats, 'full_html');
106 $this->assertEnabledTextarea('edit-restricted-formats-default-missing-value');
107 $this->assertRequiredSelectAndOptions('edit-restricted-formats-default-missing-format--2', $formats);
108 $this->assertEnabledTextarea('edit-restricted-formats-default-disallowed-value');
109 $this->assertRequiredSelectAndOptions('edit-restricted-formats-default-disallowed-format--2', $formats);
111 // Test a text format element with a fixed format.
112 $formats = ['filter_test'];
113 // When there is only a single option there is no point in choosing.
114 $this->assertEnabledTextarea('edit-single-format-no-default-value');
115 $this->assertNoSelect('edit-single-format-no-default-format--2');
116 $this->assertEnabledTextarea('edit-single-format-default-value');
117 $this->assertNoSelect('edit-single-format-default-format--2');
118 // If the select has a missing or disallowed format, administrators must
119 // explicitly choose the format.
120 $this->assertEnabledTextarea('edit-single-format-default-missing-value');
121 $this->assertRequiredSelectAndOptions('edit-single-format-default-missing-format--2', $formats);
122 $this->assertEnabledTextarea('edit-single-format-default-disallowed-value');
123 $this->assertRequiredSelectAndOptions('edit-single-format-default-disallowed-format--2', $formats);
127 * Tests the behavior of the 'text_format' element as a normal user.
129 protected function doFilterFormTestAsNonAdmin() {
130 $this->drupalLogin($this->webUser);
131 $this->drupalGet('filter-test/text-format');
133 // Test a text format element with all formats. Only formats the user has
134 // access to are shown.
135 $formats = ['filtered_html', 'filter_test'];
136 $this->assertEnabledTextarea('edit-all-formats-no-default-value');
137 // If no default is given, the format with the lowest weight becomes the
138 // default. This happens to be 'filtered_html'.
139 $this->assertOptions('edit-all-formats-no-default-format--2', $formats, 'filtered_html');
140 $this->assertEnabledTextarea('edit-all-formats-default-value');
141 // \Drupal\filter_test\Form\FilterTestFormatForm::buildForm() uses
142 // 'filter_test' as the default value in this case.
143 $this->assertOptions('edit-all-formats-default-format--2', $formats, 'filter_test');
144 // If a missing format is given as default, non-admin users are presented
145 // with a disabled textarea.
146 $this->assertDisabledTextarea('edit-all-formats-default-missing-value');
148 // Test a text format element with a predefined list of formats.
149 $this->assertEnabledTextarea('edit-restricted-formats-no-default-value');
150 // The user only has access to the 'filter_test' format, so when no default
151 // is given that is preselected and the text format select is hidden.
152 $this->assertNoSelect('edit-restricted-formats-no-default-format--2');
153 // When the format that the user does not have access to is preselected, the
154 // textarea should be disabled.
155 $this->assertDisabledTextarea('edit-restricted-formats-default-value');
156 $this->assertDisabledTextarea('edit-restricted-formats-default-missing-value');
157 $this->assertDisabledTextarea('edit-restricted-formats-default-disallowed-value');
159 // Test a text format element with a fixed format.
160 // When there is only a single option there is no point in choosing.
161 $this->assertEnabledTextarea('edit-single-format-no-default-value');
162 $this->assertNoSelect('edit-single-format-no-default-format--2');
163 $this->assertEnabledTextarea('edit-single-format-default-value');
164 $this->assertNoSelect('edit-single-format-default-format--2');
165 // If the select has a missing or disallowed format make sure the textarea
167 $this->assertDisabledTextarea('edit-single-format-default-missing-value');
168 $this->assertDisabledTextarea('edit-single-format-default-disallowed-value');
172 * Makes sure that no select element with the given ID exists on the page.
175 * The HTML ID of the select element.
177 protected function assertNoSelect($id) {
178 $select = $this->xpath('//select[@id=:id]', [':id' => $id]);
179 $this->assertEmpty($select, SafeMarkup::format('Field @id does not exist.', [
185 * Asserts that a select element has the correct options.
188 * The HTML ID of the select element.
189 * @param array $expected_options
190 * An array of option values.
191 * @param string $selected
192 * The value of the selected option.
195 * TRUE if the assertion passed; FALSE otherwise.
197 protected function assertOptions($id, array $expected_options, $selected) {
198 $select = $this->xpath('//select[@id=:id]', [':id' => $id]);
199 $this->assertNotEmpty($select, SafeMarkup::format('Field @id exists.', [
202 $select = reset($select);
203 $found_options = $select->findAll('css', 'option');
204 foreach ($found_options as $found_key => $found_option) {
205 $expected_key = array_search($found_option->getValue(), $expected_options);
206 if ($expected_key !== FALSE) {
207 $this->pass(SafeMarkup::format('Option @option for field @id exists.', [
208 '@option' => $expected_options[$expected_key],
211 unset($found_options[$found_key]);
212 unset($expected_options[$expected_key]);
216 // Make sure that all expected options were found and that there are no
217 // unexpected options.
218 foreach ($expected_options as $expected_option) {
219 $this->fail(SafeMarkup::format('Option @option for field @id exists.', [
220 '@option' => $expected_option,
224 foreach ($found_options as $found_option) {
225 $this->fail(SafeMarkup::format('Option @option for field @id does not exist.', [
226 '@option' => $found_option->getValue(),
231 $this->assertOptionSelected($id, $selected);
235 * Asserts that there is a select element with the given ID that is required.
238 * The HTML ID of the select element.
239 * @param array $options
240 * An array of option values that are contained in the select element
241 * besides the "- Select -" option.
244 * TRUE if the assertion passed; FALSE otherwise.
246 protected function assertRequiredSelectAndOptions($id, array $options) {
247 $select = $this->xpath('//select[@id=:id and contains(@required, "required")]', [
250 $this->assertNotEmpty($select, SafeMarkup::format('Required field @id exists.', [
253 // A required select element has a "- Select -" option whose key is an empty
256 $this->assertOptions($id, $options, '');
260 * Asserts that a textarea with a given ID exists and is not disabled.
263 * The HTML ID of the textarea.
266 * TRUE if the assertion passed; FALSE otherwise.
268 protected function assertEnabledTextarea($id) {
269 $textarea = $this->xpath('//textarea[@id=:id and not(contains(@disabled, "disabled"))]', [
272 $this->assertNotEmpty($textarea, SafeMarkup::format('Enabled field @id exists.', [
278 * Asserts that a textarea with a given ID has been disabled from editing.
281 * The HTML ID of the textarea.
284 * TRUE if the assertion passed; FALSE otherwise.
286 protected function assertDisabledTextarea($id) {
287 $textarea = $this->xpath('//textarea[@id=:id and contains(@disabled, "disabled")]', [
290 $this->assertNotEmpty($textarea, SafeMarkup::format('Disabled field @id exists.', [
293 $textarea = reset($textarea);
294 $expected = 'This field has been disabled because you do not have sufficient permissions to edit it.';
295 $this->assertEqual($textarea->getText(), $expected, SafeMarkup::format('Disabled textarea @id hides text in an inaccessible text format.', [
298 // Make sure the text format select is not shown.
299 $select_id = str_replace('value', 'format--2', $id);
300 $this->assertNoSelect($select_id);