PageRenderTime 48ms CodeModel.GetById 20ms RepoModel.GetById 0ms app.codeStats 0ms

/core/modules/options/src/Tests/OptionsFieldUITest.php

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