comparison core/modules/field/src/Tests/Number/NumberFieldTest.php @ 0:4c8ae668cc8c

Initial import (non-working)
author Chris Cannam
date Wed, 29 Nov 2017 16:09:58 +0000
parents
children
comparison
equal deleted inserted replaced
-1:000000000000 0:4c8ae668cc8c
1 <?php
2
3 namespace Drupal\field\Tests\Number;
4
5 use Drupal\Component\Utility\Unicode;
6 use Drupal\field\Entity\FieldConfig;
7 use Drupal\node\Entity\Node;
8 use Drupal\simpletest\WebTestBase;
9 use Drupal\field\Entity\FieldStorageConfig;
10
11 /**
12 * Tests the creation of numeric fields.
13 *
14 * @group field
15 */
16 class NumberFieldTest extends WebTestBase {
17
18 /**
19 * Modules to enable.
20 *
21 * @var array
22 */
23 public static $modules = ['node', 'entity_test', 'field_ui'];
24
25 protected function setUp() {
26 parent::setUp();
27 $this->drupalLogin($this->drupalCreateUser([
28 'view test entity',
29 'administer entity_test content',
30 'administer content types',
31 'administer node fields',
32 'administer node display',
33 'bypass node access',
34 'administer entity_test fields',
35 ]));
36 }
37
38 /**
39 * Test decimal field.
40 */
41 public function testNumberDecimalField() {
42 // Create a field with settings to validate.
43 $field_name = Unicode::strtolower($this->randomMachineName());
44 FieldStorageConfig::create([
45 'field_name' => $field_name,
46 'entity_type' => 'entity_test',
47 'type' => 'decimal',
48 'settings' => ['precision' => 8, 'scale' => 4],
49 ])->save();
50 FieldConfig::create([
51 'field_name' => $field_name,
52 'entity_type' => 'entity_test',
53 'bundle' => 'entity_test',
54 ])->save();
55
56 entity_get_form_display('entity_test', 'entity_test', 'default')
57 ->setComponent($field_name, [
58 'type' => 'number',
59 'settings' => [
60 'placeholder' => '0.00'
61 ],
62 ])
63 ->save();
64 entity_get_display('entity_test', 'entity_test', 'default')
65 ->setComponent($field_name, [
66 'type' => 'number_decimal',
67 ])
68 ->save();
69
70 // Display creation form.
71 $this->drupalGet('entity_test/add');
72 $this->assertFieldByName("{$field_name}[0][value]", '', 'Widget is displayed');
73 $this->assertRaw('placeholder="0.00"');
74
75 // Submit a signed decimal value within the allowed precision and scale.
76 $value = '-1234.5678';
77 $edit = [
78 "{$field_name}[0][value]" => $value,
79 ];
80 $this->drupalPostForm(NULL, $edit, t('Save'));
81 preg_match('|entity_test/manage/(\d+)|', $this->url, $match);
82 $id = $match[1];
83 $this->assertText(t('entity_test @id has been created.', ['@id' => $id]), 'Entity was created');
84 $this->assertRaw($value, 'Value is displayed.');
85
86 // Try to create entries with more than one decimal separator; assert fail.
87 $wrong_entries = [
88 '3.14.159',
89 '0..45469',
90 '..4589',
91 '6.459.52',
92 '6.3..25',
93 ];
94
95 foreach ($wrong_entries as $wrong_entry) {
96 $this->drupalGet('entity_test/add');
97 $edit = [
98 "{$field_name}[0][value]" => $wrong_entry,
99 ];
100 $this->drupalPostForm(NULL, $edit, t('Save'));
101 $this->assertRaw(t('%name must be a number.', ['%name' => $field_name]), 'Correctly failed to save decimal value with more than one decimal point.');
102 }
103
104 // Try to create entries with minus sign not in the first position.
105 $wrong_entries = [
106 '3-3',
107 '4-',
108 '1.3-',
109 '1.2-4',
110 '-10-10',
111 ];
112
113 foreach ($wrong_entries as $wrong_entry) {
114 $this->drupalGet('entity_test/add');
115 $edit = [
116 "{$field_name}[0][value]" => $wrong_entry,
117 ];
118 $this->drupalPostForm(NULL, $edit, t('Save'));
119 $this->assertRaw(t('%name must be a number.', ['%name' => $field_name]), 'Correctly failed to save decimal value with minus sign in the wrong position.');
120 }
121 }
122
123 /**
124 * Test integer field.
125 */
126 public function testNumberIntegerField() {
127 $minimum = rand(-4000, -2000);
128 $maximum = rand(2000, 4000);
129
130 // Create a field with settings to validate.
131 $field_name = Unicode::strtolower($this->randomMachineName());
132 $storage = FieldStorageConfig::create([
133 'field_name' => $field_name,
134 'entity_type' => 'entity_test',
135 'type' => 'integer',
136 ]);
137 $storage->save();
138
139 FieldConfig::create([
140 'field_name' => $field_name,
141 'entity_type' => 'entity_test',
142 'bundle' => 'entity_test',
143 'settings' => [
144 'min' => $minimum,
145 'max' => $maximum,
146 'prefix' => 'ThePrefix',
147 ],
148 ])->save();
149
150 entity_get_form_display('entity_test', 'entity_test', 'default')
151 ->setComponent($field_name, [
152 'type' => 'number',
153 'settings' => [
154 'placeholder' => '4'
155 ],
156 ])
157 ->save();
158 entity_get_display('entity_test', 'entity_test', 'default')
159 ->setComponent($field_name, [
160 'type' => 'number_integer',
161 'settings' => [
162 'prefix_suffix' => FALSE,
163 ],
164 ])
165 ->save();
166
167 // Check the storage schema.
168 $expected = [
169 'columns' => [
170 'value' => [
171 'type' => 'int',
172 'unsigned' => '',
173 'size' => 'normal'
174 ],
175 ],
176 'unique keys' => [],
177 'indexes' => [],
178 'foreign keys' => []
179 ];
180 $this->assertEqual($storage->getSchema(), $expected);
181
182 // Display creation form.
183 $this->drupalGet('entity_test/add');
184 $this->assertFieldByName("{$field_name}[0][value]", '', 'Widget is displayed');
185 $this->assertRaw('placeholder="4"');
186
187 // Submit a valid integer
188 $value = rand($minimum, $maximum);
189 $edit = [
190 "{$field_name}[0][value]" => $value,
191 ];
192 $this->drupalPostForm(NULL, $edit, t('Save'));
193 preg_match('|entity_test/manage/(\d+)|', $this->url, $match);
194 $id = $match[1];
195 $this->assertText(t('entity_test @id has been created.', ['@id' => $id]), 'Entity was created');
196
197 // Try to set a value below the minimum value
198 $this->drupalGet('entity_test/add');
199 $edit = [
200 "{$field_name}[0][value]" => $minimum - 1,
201 ];
202 $this->drupalPostForm(NULL, $edit, t('Save'));
203 $this->assertRaw(t('%name must be higher than or equal to %minimum.', ['%name' => $field_name, '%minimum' => $minimum]), 'Correctly failed to save integer value less than minimum allowed value.');
204
205 // Try to set a decimal value
206 $this->drupalGet('entity_test/add');
207 $edit = [
208 "{$field_name}[0][value]" => 1.5,
209 ];
210 $this->drupalPostForm(NULL, $edit, t('Save'));
211 $this->assertRaw(t('%name is not a valid number.', ['%name' => $field_name]), 'Correctly failed to save decimal value to integer field.');
212
213 // Try to set a value above the maximum value
214 $this->drupalGet('entity_test/add');
215 $edit = [
216 "{$field_name}[0][value]" => $maximum + 1,
217 ];
218 $this->drupalPostForm(NULL, $edit, t('Save'));
219 $this->assertRaw(t('%name must be lower than or equal to %maximum.', ['%name' => $field_name, '%maximum' => $maximum]), 'Correctly failed to save integer value greater than maximum allowed value.');
220
221 // Try to set a wrong integer value.
222 $this->drupalGet('entity_test/add');
223 $edit = [
224 "{$field_name}[0][value]" => '20-40',
225 ];
226 $this->drupalPostForm(NULL, $edit, t('Save'));
227 $this->assertRaw(t('%name must be a number.', ['%name' => $field_name]), 'Correctly failed to save wrong integer value.');
228
229 // Test with valid entries.
230 $valid_entries = [
231 '-1234',
232 '0',
233 '1234',
234 ];
235
236 foreach ($valid_entries as $valid_entry) {
237 $this->drupalGet('entity_test/add');
238 $edit = [
239 "{$field_name}[0][value]" => $valid_entry,
240 ];
241 $this->drupalPostForm(NULL, $edit, t('Save'));
242 preg_match('|entity_test/manage/(\d+)|', $this->url, $match);
243 $id = $match[1];
244 $this->assertText(t('entity_test @id has been created.', ['@id' => $id]), 'Entity was created');
245 $this->assertRaw($valid_entry, 'Value is displayed.');
246 $this->assertNoFieldByXpath('//div[@content="' . $valid_entry . '"]', NULL, 'The "content" attribute is not present since the Prefix is not being displayed');
247 }
248
249 // Test for the content attribute when a Prefix is displayed. Presumably this also tests for the attribute when a Suffix is displayed.
250 entity_get_display('entity_test', 'entity_test', 'default')
251 ->setComponent($field_name, [
252 'type' => 'number_integer',
253 'settings' => [
254 'prefix_suffix' => TRUE,
255 ],
256 ])
257 ->save();
258 $integer_value = '123';
259 $this->drupalGet('entity_test/add');
260 $edit = [
261 "{$field_name}[0][value]" => $integer_value,
262 ];
263 $this->drupalPostForm(NULL, $edit, t('Save'));
264 preg_match('|entity_test/manage/(\d+)|', $this->url, $match);
265 $id = $match[1];
266 $this->assertText(t('entity_test @id has been created.', ['@id' => $id]), 'Entity was created');
267 $this->drupalGet('entity_test/' . $id);
268 $this->assertFieldByXPath('//div[@content="' . $integer_value . '"]', 'ThePrefix' . $integer_value, 'The "content" attribute has been set to the value of the field, and the prefix is being displayed.');
269 }
270
271 /**
272 * Test float field.
273 */
274 public function testNumberFloatField() {
275 // Create a field with settings to validate.
276 $field_name = Unicode::strtolower($this->randomMachineName());
277 FieldStorageConfig::create([
278 'field_name' => $field_name,
279 'entity_type' => 'entity_test',
280 'type' => 'float',
281 ])->save();
282
283 FieldConfig::create([
284 'field_name' => $field_name,
285 'entity_type' => 'entity_test',
286 'bundle' => 'entity_test',
287 ])->save();
288
289 entity_get_form_display('entity_test', 'entity_test', 'default')
290 ->setComponent($field_name, [
291 'type' => 'number',
292 'settings' => [
293 'placeholder' => '0.00'
294 ],
295 ])
296 ->save();
297
298 entity_get_display('entity_test', 'entity_test', 'default')
299 ->setComponent($field_name, [
300 'type' => 'number_decimal',
301 ])
302 ->save();
303
304 // Display creation form.
305 $this->drupalGet('entity_test/add');
306 $this->assertFieldByName("{$field_name}[0][value]", '', 'Widget is displayed');
307 $this->assertRaw('placeholder="0.00"');
308
309 // Submit a signed decimal value within the allowed precision and scale.
310 $value = '-1234.5678';
311 $edit = [
312 "{$field_name}[0][value]" => $value,
313 ];
314 $this->drupalPostForm(NULL, $edit, t('Save'));
315 preg_match('|entity_test/manage/(\d+)|', $this->url, $match);
316 $id = $match[1];
317 $this->assertText(t('entity_test @id has been created.', ['@id' => $id]), 'Entity was created');
318
319 // Ensure that the 'number_decimal' formatter displays the number with the
320 // expected rounding.
321 $this->drupalGet('entity_test/' . $id);
322 $this->assertRaw(round($value, 2));
323
324 // Try to create entries with more than one decimal separator; assert fail.
325 $wrong_entries = [
326 '3.14.159',
327 '0..45469',
328 '..4589',
329 '6.459.52',
330 '6.3..25',
331 ];
332
333 foreach ($wrong_entries as $wrong_entry) {
334 $this->drupalGet('entity_test/add');
335 $edit = [
336 "{$field_name}[0][value]" => $wrong_entry,
337 ];
338 $this->drupalPostForm(NULL, $edit, t('Save'));
339 $this->assertRaw(t('%name must be a number.', ['%name' => $field_name]), 'Correctly failed to save float value with more than one decimal point.');
340 }
341
342 // Try to create entries with minus sign not in the first position.
343 $wrong_entries = [
344 '3-3',
345 '4-',
346 '1.3-',
347 '1.2-4',
348 '-10-10',
349 ];
350
351 foreach ($wrong_entries as $wrong_entry) {
352 $this->drupalGet('entity_test/add');
353 $edit = [
354 "{$field_name}[0][value]" => $wrong_entry,
355 ];
356 $this->drupalPostForm(NULL, $edit, t('Save'));
357 $this->assertRaw(t('%name must be a number.', ['%name' => $field_name]), 'Correctly failed to save float value with minus sign in the wrong position.');
358 }
359 }
360
361 /**
362 * Test default formatter behavior
363 */
364 public function testNumberFormatter() {
365 $type = Unicode::strtolower($this->randomMachineName());
366 $float_field = Unicode::strtolower($this->randomMachineName());
367 $integer_field = Unicode::strtolower($this->randomMachineName());
368 $thousand_separators = ['', '.', ',', ' ', chr(8201), "'"];
369 $decimal_separators = ['.', ','];
370 $prefix = $this->randomMachineName();
371 $suffix = $this->randomMachineName();
372 $random_float = rand(0, pow(10, 6));
373 $random_integer = rand(0, pow(10, 6));
374
375 // Create a content type containing float and integer fields.
376 $this->drupalCreateContentType(['type' => $type]);
377
378 FieldStorageConfig::create([
379 'field_name' => $float_field,
380 'entity_type' => 'node',
381 'type' => 'float',
382 ])->save();
383
384 FieldStorageConfig::create([
385 'field_name' => $integer_field,
386 'entity_type' => 'node',
387 'type' => 'integer',
388 ])->save();
389
390 FieldConfig::create([
391 'field_name' => $float_field,
392 'entity_type' => 'node',
393 'bundle' => $type,
394 'settings' => [
395 'prefix' => $prefix,
396 'suffix' => $suffix
397 ],
398 ])->save();
399
400 FieldConfig::create([
401 'field_name' => $integer_field,
402 'entity_type' => 'node',
403 'bundle' => $type,
404 'settings' => [
405 'prefix' => $prefix,
406 'suffix' => $suffix
407 ],
408 ])->save();
409
410 entity_get_form_display('node', $type, 'default')
411 ->setComponent($float_field, [
412 'type' => 'number',
413 'settings' => [
414 'placeholder' => '0.00'
415 ],
416 ])
417 ->setComponent($integer_field, [
418 'type' => 'number',
419 'settings' => [
420 'placeholder' => '0.00'
421 ],
422 ])
423 ->save();
424
425 entity_get_display('node', $type, 'default')
426 ->setComponent($float_field, [
427 'type' => 'number_decimal',
428 ])
429 ->setComponent($integer_field, [
430 'type' => 'number_unformatted',
431 ])
432 ->save();
433
434 // Create a node to test formatters.
435 $node = Node::create([
436 'type' => $type,
437 'title' => $this->randomMachineName(),
438 $float_field => ['value' => $random_float],
439 $integer_field => ['value' => $random_integer],
440 ]);
441 $node->save();
442
443 // Go to manage display page.
444 $this->drupalGet("admin/structure/types/manage/$type/display");
445
446 // Configure number_decimal formatter for the 'float' field type.
447 $thousand_separator = $thousand_separators[array_rand($thousand_separators)];
448 $decimal_separator = $decimal_separators[array_rand($decimal_separators)];
449 $scale = rand(0, 10);
450
451 $this->drupalPostAjaxForm(NULL, [], "${float_field}_settings_edit");
452 $edit = [
453 "fields[${float_field}][settings_edit_form][settings][prefix_suffix]" => TRUE,
454 "fields[${float_field}][settings_edit_form][settings][scale]" => $scale,
455 "fields[${float_field}][settings_edit_form][settings][decimal_separator]" => $decimal_separator,
456 "fields[${float_field}][settings_edit_form][settings][thousand_separator]" => $thousand_separator,
457 ];
458 $this->drupalPostAjaxForm(NULL, $edit, "${float_field}_plugin_settings_update");
459 $this->drupalPostForm(NULL, [], t('Save'));
460
461 // Check number_decimal and number_unformatted formatters behavior.
462 $this->drupalGet('node/' . $node->id());
463 $float_formatted = number_format($random_float, $scale, $decimal_separator, $thousand_separator);
464 $this->assertRaw("$prefix$float_formatted$suffix", 'Prefix and suffix added');
465 $this->assertRaw((string) $random_integer);
466
467 // Configure the number_decimal formatter.
468 entity_get_display('node', $type, 'default')
469 ->setComponent($integer_field, [
470 'type' => 'number_integer',
471 ])
472 ->save();
473 $this->drupalGet("admin/structure/types/manage/$type/display");
474
475 $thousand_separator = $thousand_separators[array_rand($thousand_separators)];
476
477 $this->drupalPostAjaxForm(NULL, [], "${integer_field}_settings_edit");
478 $edit = [
479 "fields[${integer_field}][settings_edit_form][settings][prefix_suffix]" => FALSE,
480 "fields[${integer_field}][settings_edit_form][settings][thousand_separator]" => $thousand_separator,
481 ];
482 $this->drupalPostAjaxForm(NULL, $edit, "${integer_field}_plugin_settings_update");
483 $this->drupalPostForm(NULL, [], t('Save'));
484
485 // Check number_integer formatter behavior.
486 $this->drupalGet('node/' . $node->id());
487
488 $integer_formatted = number_format($random_integer, 0, '', $thousand_separator);
489 $this->assertRaw($integer_formatted, 'Random integer formatted');
490 }
491
492 /**
493 * Tests setting the minimum value of a float field through the interface.
494 */
495 public function testCreateNumberFloatField() {
496 // Create a float field.
497 $field_name = Unicode::strtolower($this->randomMachineName());
498 FieldStorageConfig::create([
499 'field_name' => $field_name,
500 'entity_type' => 'entity_test',
501 'type' => 'float',
502 ])->save();
503
504 $field = FieldConfig::create([
505 'field_name' => $field_name,
506 'entity_type' => 'entity_test',
507 'bundle' => 'entity_test',
508 ]);
509 $field->save();
510
511 // Set the minimum value to a float value.
512 $this->assertSetMinimumValue($field, 0.0001);
513 // Set the minimum value to an integer value.
514 $this->assertSetMinimumValue($field, 1);
515 }
516
517 /**
518 * Tests setting the minimum value of a decimal field through the interface.
519 */
520 public function testCreateNumberDecimalField() {
521 // Create a decimal field.
522 $field_name = Unicode::strtolower($this->randomMachineName());
523 FieldStorageConfig::create([
524 'field_name' => $field_name,
525 'entity_type' => 'entity_test',
526 'type' => 'decimal',
527 ])->save();
528
529 $field = FieldConfig::create([
530 'field_name' => $field_name,
531 'entity_type' => 'entity_test',
532 'bundle' => 'entity_test',
533 ]);
534 $field->save();
535
536 // Set the minimum value to a decimal value.
537 $this->assertSetMinimumValue($field, 0.1);
538 // Set the minimum value to an integer value.
539 $this->assertSetMinimumValue($field, 1);
540 }
541
542 /**
543 * Helper function to set the minimum value of a field.
544 */
545 public function assertSetMinimumValue($field, $minimum_value) {
546 $field_configuration_url = 'entity_test/structure/entity_test/fields/entity_test.entity_test.' . $field->getName();
547
548 // Set the minimum value.
549 $edit = [
550 'settings[min]' => $minimum_value,
551 ];
552 $this->drupalPostForm($field_configuration_url, $edit, t('Save settings'));
553 // Check if an error message is shown.
554 $this->assertNoRaw(t('%name is not a valid number.', ['%name' => t('Minimum')]), 'Saved ' . gettype($minimum_value) . ' value as minimal value on a ' . $field->getType() . ' field');
555 // Check if a success message is shown.
556 $this->assertRaw(t('Saved %label configuration.', ['%label' => $field->getLabel()]));
557 // Check if the minimum value was actually set.
558 $this->drupalGet($field_configuration_url);
559 $this->assertFieldById('edit-settings-min', $minimum_value, 'Minimal ' . gettype($minimum_value) . ' value was set on a ' . $field->getType() . ' field.');
560 }
561
562 }