annotate core/modules/options/tests/src/Functional/OptionsFieldUITest.php @ 19:fa3358dc1485 tip

Add ndrum files
author Chris Cannam
date Wed, 28 Aug 2019 13:14:47 +0100
parents 129ea1e6d783
children
rev   line source
Chris@0 1 <?php
Chris@0 2
Chris@0 3 namespace Drupal\Tests\options\Functional;
Chris@0 4
Chris@0 5 use Drupal\field\Entity\FieldConfig;
Chris@0 6 use Drupal\field\Entity\FieldStorageConfig;
Chris@17 7 use Drupal\Tests\field\Functional\FieldTestBase;
Chris@0 8
Chris@0 9 /**
Chris@0 10 * Tests the Options field UI functionality.
Chris@0 11 *
Chris@0 12 * @group options
Chris@0 13 */
Chris@0 14 class OptionsFieldUITest extends FieldTestBase {
Chris@0 15
Chris@0 16 /**
Chris@0 17 * Modules to enable.
Chris@0 18 *
Chris@0 19 * @var array
Chris@0 20 */
Chris@0 21 public static $modules = ['node', 'options', 'field_test', 'taxonomy', 'field_ui'];
Chris@0 22
Chris@0 23 /**
Chris@0 24 * The name of the created content type.
Chris@0 25 *
Chris@0 26 * @var string
Chris@0 27 */
Chris@0 28 protected $typeName;
Chris@0 29
Chris@0 30 /**
Chris@0 31 * Machine name of the created content type.
Chris@0 32 *
Chris@0 33 * @var string
Chris@0 34 */
Chris@0 35 protected $type;
Chris@0 36
Chris@0 37 /**
Chris@0 38 * Name of the option field.
Chris@0 39 *
Chris@0 40 * @var string
Chris@0 41 */
Chris@0 42 protected $fieldName;
Chris@0 43
Chris@0 44 /**
Chris@0 45 * Admin path to manage field storage settings.
Chris@0 46 *
Chris@0 47 * @var string
Chris@0 48 */
Chris@0 49 protected $adminPath;
Chris@0 50
Chris@0 51 protected function setUp() {
Chris@0 52 parent::setUp();
Chris@0 53
Chris@0 54 // Create test user.
Chris@0 55 $admin_user = $this->drupalCreateUser(['access content', 'administer taxonomy', 'access administration pages', 'administer site configuration', 'administer content types', 'administer nodes', 'bypass node access', 'administer node fields', 'administer node display']);
Chris@0 56 $this->drupalLogin($admin_user);
Chris@0 57
Chris@0 58 // Create content type, with underscores.
Chris@0 59 $this->typeName = 'test_' . strtolower($this->randomMachineName());
Chris@0 60 $type = $this->drupalCreateContentType(['name' => $this->typeName, 'type' => $this->typeName]);
Chris@0 61 $this->type = $type->id();
Chris@0 62 }
Chris@0 63
Chris@0 64 /**
Chris@0 65 * Options (integer) : test 'allowed values' input.
Chris@0 66 */
Chris@0 67 public function testOptionsAllowedValuesInteger() {
Chris@0 68 $this->fieldName = 'field_options_integer';
Chris@0 69 $this->createOptionsField('list_integer');
Chris@0 70
Chris@0 71 // Flat list of textual values.
Chris@0 72 $string = "Zero\nOne";
Chris@0 73 $array = ['0' => 'Zero', '1' => 'One'];
Chris@0 74 $this->assertAllowedValuesInput($string, $array, 'Unkeyed lists are accepted.');
Chris@0 75 // Explicit integer keys.
Chris@0 76 $string = "0|Zero\n2|Two";
Chris@0 77 $array = ['0' => 'Zero', '2' => 'Two'];
Chris@0 78 $this->assertAllowedValuesInput($string, $array, 'Integer keys are accepted.');
Chris@0 79 // Check that values can be added and removed.
Chris@0 80 $string = "0|Zero\n1|One";
Chris@0 81 $array = ['0' => 'Zero', '1' => 'One'];
Chris@0 82 $this->assertAllowedValuesInput($string, $array, 'Values can be added and removed.');
Chris@0 83 // Non-integer keys.
Chris@0 84 $this->assertAllowedValuesInput("1.1|One", 'keys must be integers', 'Non integer keys are rejected.');
Chris@0 85 $this->assertAllowedValuesInput("abc|abc", 'keys must be integers', 'Non integer keys are rejected.');
Chris@0 86 // Mixed list of keyed and unkeyed values.
Chris@0 87 $this->assertAllowedValuesInput("Zero\n1|One", 'invalid input', 'Mixed lists are rejected.');
Chris@0 88
Chris@0 89 // Create a node with actual data for the field.
Chris@0 90 $settings = [
Chris@0 91 'type' => $this->type,
Chris@0 92 $this->fieldName => [['value' => 1]],
Chris@0 93 ];
Chris@0 94 $node = $this->drupalCreateNode($settings);
Chris@0 95
Chris@0 96 // Check that a flat list of values is rejected once the field has data.
Chris@0 97 $this->assertAllowedValuesInput("Zero\nOne", 'invalid input', 'Unkeyed lists are rejected once the field has data.');
Chris@0 98
Chris@0 99 // Check that values can be added but values in use cannot be removed.
Chris@0 100 $string = "0|Zero\n1|One\n2|Two";
Chris@0 101 $array = ['0' => 'Zero', '1' => 'One', '2' => 'Two'];
Chris@0 102 $this->assertAllowedValuesInput($string, $array, 'Values can be added.');
Chris@0 103 $string = "0|Zero\n1|One";
Chris@0 104 $array = ['0' => 'Zero', '1' => 'One'];
Chris@0 105 $this->assertAllowedValuesInput($string, $array, 'Values not in use can be removed.');
Chris@0 106 $this->assertAllowedValuesInput("0|Zero", 'some values are being removed while currently in use', 'Values in use cannot be removed.');
Chris@0 107
Chris@0 108 // Delete the node, remove the value.
Chris@0 109 $node->delete();
Chris@0 110 $string = "0|Zero";
Chris@0 111 $array = ['0' => 'Zero'];
Chris@0 112 $this->assertAllowedValuesInput($string, $array, 'Values not in use can be removed.');
Chris@0 113
Chris@0 114 // Check that the same key can only be used once.
Chris@0 115 $string = "0|Zero\n0|One";
Chris@0 116 $array = ['0' => 'One'];
Chris@0 117 $this->assertAllowedValuesInput($string, $array, 'Same value cannot be used multiple times.');
Chris@0 118 }
Chris@0 119
Chris@0 120 /**
Chris@0 121 * Options (float) : test 'allowed values' input.
Chris@0 122 */
Chris@0 123 public function testOptionsAllowedValuesFloat() {
Chris@0 124 $this->fieldName = 'field_options_float';
Chris@0 125 $this->createOptionsField('list_float');
Chris@0 126
Chris@0 127 // Flat list of textual values.
Chris@0 128 $string = "Zero\nOne";
Chris@0 129 $array = ['0' => 'Zero', '1' => 'One'];
Chris@0 130 $this->assertAllowedValuesInput($string, $array, 'Unkeyed lists are accepted.');
Chris@0 131 // Explicit numeric keys.
Chris@0 132 $string = "0|Zero\n.5|Point five";
Chris@0 133 $array = ['0' => 'Zero', '0.5' => 'Point five'];
Chris@0 134 $this->assertAllowedValuesInput($string, $array, 'Integer keys are accepted.');
Chris@0 135 // Check that values can be added and removed.
Chris@0 136 $string = "0|Zero\n.5|Point five\n1.0|One";
Chris@0 137 $array = ['0' => 'Zero', '0.5' => 'Point five', '1' => 'One'];
Chris@0 138 $this->assertAllowedValuesInput($string, $array, 'Values can be added and removed.');
Chris@0 139 // Non-numeric keys.
Chris@0 140 $this->assertAllowedValuesInput("abc|abc\n", 'each key must be a valid integer or decimal', 'Non numeric keys are rejected.');
Chris@0 141 // Mixed list of keyed and unkeyed values.
Chris@0 142 $this->assertAllowedValuesInput("Zero\n1|One\n", 'invalid input', 'Mixed lists are rejected.');
Chris@0 143
Chris@0 144 // Create a node with actual data for the field.
Chris@0 145 $settings = [
Chris@0 146 'type' => $this->type,
Chris@0 147 $this->fieldName => [['value' => .5]],
Chris@0 148 ];
Chris@0 149 $node = $this->drupalCreateNode($settings);
Chris@0 150
Chris@0 151 // Check that a flat list of values is rejected once the field has data.
Chris@0 152 $this->assertAllowedValuesInput("Zero\nOne", 'invalid input', 'Unkeyed lists are rejected once the field has data.');
Chris@0 153
Chris@0 154 // Check that values can be added but values in use cannot be removed.
Chris@0 155 $string = "0|Zero\n.5|Point five\n2|Two";
Chris@0 156 $array = ['0' => 'Zero', '0.5' => 'Point five', '2' => 'Two'];
Chris@0 157 $this->assertAllowedValuesInput($string, $array, 'Values can be added.');
Chris@0 158 $string = "0|Zero\n.5|Point five";
Chris@0 159 $array = ['0' => 'Zero', '0.5' => 'Point five'];
Chris@0 160 $this->assertAllowedValuesInput($string, $array, 'Values not in use can be removed.');
Chris@0 161 $this->assertAllowedValuesInput("0|Zero", 'some values are being removed while currently in use', 'Values in use cannot be removed.');
Chris@0 162
Chris@0 163 // Delete the node, remove the value.
Chris@0 164 $node->delete();
Chris@0 165 $string = "0|Zero";
Chris@0 166 $array = ['0' => 'Zero'];
Chris@0 167 $this->assertAllowedValuesInput($string, $array, 'Values not in use can be removed.');
Chris@0 168
Chris@0 169 // Check that the same key can only be used once.
Chris@0 170 $string = "0.5|Point five\n0.5|Half";
Chris@0 171 $array = ['0.5' => 'Half'];
Chris@0 172 $this->assertAllowedValuesInput($string, $array, 'Same value cannot be used multiple times.');
Chris@0 173
Chris@0 174 // Check that different forms of the same float value cannot be used.
Chris@0 175 $string = "0|Zero\n.5|Point five\n0.5|Half";
Chris@0 176 $array = ['0' => 'Zero', '0.5' => 'Half'];
Chris@0 177 $this->assertAllowedValuesInput($string, $array, 'Different forms of the same value cannot be used.');
Chris@0 178 }
Chris@0 179
Chris@0 180 /**
Chris@0 181 * Options (text) : test 'allowed values' input.
Chris@0 182 */
Chris@0 183 public function testOptionsAllowedValuesText() {
Chris@0 184 $this->fieldName = 'field_options_text';
Chris@0 185 $this->createOptionsField('list_string');
Chris@0 186
Chris@0 187 // Flat list of textual values.
Chris@0 188 $string = "Zero\nOne";
Chris@0 189 $array = ['Zero' => 'Zero', 'One' => 'One'];
Chris@0 190 $this->assertAllowedValuesInput($string, $array, 'Unkeyed lists are accepted.');
Chris@0 191 // Explicit keys.
Chris@0 192 $string = "zero|Zero\none|One";
Chris@0 193 $array = ['zero' => 'Zero', 'one' => 'One'];
Chris@0 194 $this->assertAllowedValuesInput($string, $array, 'Explicit keys are accepted.');
Chris@0 195 // Check that values can be added and removed.
Chris@0 196 $string = "zero|Zero\ntwo|Two";
Chris@0 197 $array = ['zero' => 'Zero', 'two' => 'Two'];
Chris@0 198 $this->assertAllowedValuesInput($string, $array, 'Values can be added and removed.');
Chris@0 199 // Mixed list of keyed and unkeyed values.
Chris@0 200 $string = "zero|Zero\nOne\n";
Chris@0 201 $array = ['zero' => 'Zero', 'One' => 'One'];
Chris@0 202 $this->assertAllowedValuesInput($string, $array, 'Mixed lists are accepted.');
Chris@0 203 // Overly long keys.
Chris@0 204 $this->assertAllowedValuesInput("zero|Zero\n" . $this->randomMachineName(256) . "|One", 'each key must be a string at most 255 characters long', 'Overly long keys are rejected.');
Chris@0 205
Chris@0 206 // Create a node with actual data for the field.
Chris@0 207 $settings = [
Chris@0 208 'type' => $this->type,
Chris@0 209 $this->fieldName => [['value' => 'One']],
Chris@0 210 ];
Chris@0 211 $node = $this->drupalCreateNode($settings);
Chris@0 212
Chris@0 213 // Check that flat lists of values are still accepted once the field has
Chris@0 214 // data.
Chris@0 215 $string = "Zero\nOne";
Chris@0 216 $array = ['Zero' => 'Zero', 'One' => 'One'];
Chris@0 217 $this->assertAllowedValuesInput($string, $array, 'Unkeyed lists are still accepted once the field has data.');
Chris@0 218
Chris@0 219 // Check that values can be added but values in use cannot be removed.
Chris@0 220 $string = "Zero\nOne\nTwo";
Chris@0 221 $array = ['Zero' => 'Zero', 'One' => 'One', 'Two' => 'Two'];
Chris@0 222 $this->assertAllowedValuesInput($string, $array, 'Values can be added.');
Chris@0 223 $string = "Zero\nOne";
Chris@0 224 $array = ['Zero' => 'Zero', 'One' => 'One'];
Chris@0 225 $this->assertAllowedValuesInput($string, $array, 'Values not in use can be removed.');
Chris@0 226 $this->assertAllowedValuesInput("Zero", 'some values are being removed while currently in use', 'Values in use cannot be removed.');
Chris@0 227
Chris@0 228 // Delete the node, remove the value.
Chris@0 229 $node->delete();
Chris@0 230 $string = "Zero";
Chris@0 231 $array = ['Zero' => 'Zero'];
Chris@0 232 $this->assertAllowedValuesInput($string, $array, 'Values not in use can be removed.');
Chris@0 233
Chris@0 234 // Check that string values with dots can be used.
Chris@0 235 $string = "Zero\nexample.com|Example";
Chris@0 236 $array = ['Zero' => 'Zero', 'example.com' => 'Example'];
Chris@0 237 $this->assertAllowedValuesInput($string, $array, 'String value with dot is supported.');
Chris@0 238
Chris@0 239 // Check that the same key can only be used once.
Chris@0 240 $string = "zero|Zero\nzero|One";
Chris@0 241 $array = ['zero' => 'One'];
Chris@0 242 $this->assertAllowedValuesInput($string, $array, 'Same value cannot be used multiple times.');
Chris@0 243 }
Chris@0 244
Chris@0 245 /**
Chris@0 246 * Options (text) : test 'trimmed values' input.
Chris@0 247 */
Chris@0 248 public function testOptionsTrimmedValuesText() {
Chris@0 249 $this->fieldName = 'field_options_trimmed_text';
Chris@0 250 $this->createOptionsField('list_string');
Chris@0 251
Chris@0 252 // Explicit keys.
Chris@0 253 $string = "zero |Zero\none | One";
Chris@0 254 $array = ['zero' => 'Zero', 'one' => 'One'];
Chris@0 255 $this->assertAllowedValuesInput($string, $array, 'Explicit keys are accepted and trimmed.');
Chris@0 256 }
Chris@0 257
Chris@0 258 /**
Chris@0 259 * Helper function to create list field of a given type.
Chris@0 260 *
Chris@0 261 * @param string $type
Chris@0 262 * One of 'list_integer', 'list_float' or 'list_string'.
Chris@0 263 */
Chris@0 264 protected function createOptionsField($type) {
Chris@0 265 // Create a field.
Chris@0 266 FieldStorageConfig::create([
Chris@0 267 'field_name' => $this->fieldName,
Chris@0 268 'entity_type' => 'node',
Chris@0 269 'type' => $type,
Chris@0 270 ])->save();
Chris@0 271 FieldConfig::create([
Chris@0 272 'field_name' => $this->fieldName,
Chris@0 273 'entity_type' => 'node',
Chris@0 274 'bundle' => $this->type,
Chris@0 275 ])->save();
Chris@0 276
Chris@0 277 entity_get_form_display('node', $this->type, 'default')->setComponent($this->fieldName)->save();
Chris@0 278
Chris@0 279 $this->adminPath = 'admin/structure/types/manage/' . $this->type . '/fields/node.' . $this->type . '.' . $this->fieldName . '/storage';
Chris@0 280 }
Chris@0 281
Chris@0 282 /**
Chris@0 283 * Tests a string input for the 'allowed values' form element.
Chris@0 284 *
Chris@0 285 * @param $input_string
Chris@0 286 * The input string, in the pipe-linefeed format expected by the form
Chris@0 287 * element.
Chris@0 288 * @param $result
Chris@0 289 * Either an expected resulting array in
Chris@0 290 * $field->getSetting('allowed_values'), or an expected error message.
Chris@0 291 * @param $message
Chris@0 292 * Message to display.
Chris@0 293 */
Chris@0 294 public function assertAllowedValuesInput($input_string, $result, $message) {
Chris@0 295 $edit = ['settings[allowed_values]' => $input_string];
Chris@0 296 $this->drupalPostForm($this->adminPath, $edit, t('Save field settings'));
Chris@0 297 $this->assertNoRaw('&amp;lt;', 'The page does not have double escaped HTML tags.');
Chris@0 298
Chris@0 299 if (is_string($result)) {
Chris@0 300 $this->assertText($result, $message);
Chris@0 301 }
Chris@0 302 else {
Chris@0 303 $field_storage = FieldStorageConfig::loadByName('node', $this->fieldName);
Chris@0 304 $this->assertIdentical($field_storage->getSetting('allowed_values'), $result, $message);
Chris@0 305 }
Chris@0 306 }
Chris@0 307
Chris@0 308 /**
Chris@0 309 * Tests normal and key formatter display on node display.
Chris@0 310 */
Chris@0 311 public function testNodeDisplay() {
Chris@0 312 $this->fieldName = strtolower($this->randomMachineName());
Chris@0 313 $this->createOptionsField('list_integer');
Chris@0 314 $node = $this->drupalCreateNode(['type' => $this->type]);
Chris@0 315
Chris@0 316 $on = $this->randomMachineName();
Chris@0 317 $off = $this->randomMachineName();
Chris@0 318 $edit = [
Chris@0 319 'settings[allowed_values]' =>
Chris@0 320 "1|$on
Chris@0 321 0|$off",
Chris@0 322 ];
Chris@0 323
Chris@0 324 $this->drupalPostForm($this->adminPath, $edit, t('Save field settings'));
Chris@0 325 $this->assertText(format_string('Updated field @field_name field settings.', ['@field_name' => $this->fieldName]), "The 'On' and 'Off' form fields work for boolean fields.");
Chris@0 326
Chris@0 327 // Select a default value.
Chris@0 328 $edit = [
Chris@0 329 $this->fieldName => '1',
Chris@0 330 ];
Chris@0 331 $this->drupalPostForm('node/' . $node->id() . '/edit', $edit, t('Save'));
Chris@0 332
Chris@0 333 // Check the node page and see if the values are correct.
Chris@0 334 $file_formatters = ['list_default', 'list_key'];
Chris@0 335 foreach ($file_formatters as $formatter) {
Chris@0 336 $edit = [
Chris@0 337 "fields[$this->fieldName][type]" => $formatter,
Chris@0 338 "fields[$this->fieldName][region]" => 'content',
Chris@0 339 ];
Chris@0 340 $this->drupalPostForm('admin/structure/types/manage/' . $this->typeName . '/display', $edit, t('Save'));
Chris@0 341 $this->drupalGet('node/' . $node->id());
Chris@0 342
Chris@0 343 if ($formatter == 'list_default') {
Chris@0 344 $output = $on;
Chris@0 345 }
Chris@0 346 else {
Chris@0 347 $output = '1';
Chris@0 348 }
Chris@0 349
Chris@0 350 $elements = $this->xpath('//div[text()="' . $output . '"]');
Chris@0 351 $this->assertEqual(count($elements), 1, 'Correct options found.');
Chris@0 352 }
Chris@0 353 }
Chris@0 354
Chris@0 355 }