NumberFieldTest.php 18.6 KB
Newer Older
1 2 3 4
<?php

/**
 * @file
5
 * Contains \Drupal\field\Tests\Number\NumberFieldTest.
6 7
 */

8
namespace Drupal\field\Tests\Number;
9

10
use Drupal\Component\Utility\Unicode;
11 12
use Drupal\simpletest\WebTestBase;

13
/**
14 15 16
 * Tests the creation of numeric fields.
 *
 * @group field
17
 */
18
class NumberFieldTest extends WebTestBase {
19 20 21 22 23 24

  /**
   * Modules to enable.
   *
   * @var array
   */
25
  public static $modules = array('node', 'entity_test', 'field_ui');
26

27
  protected function setUp() {
28
    parent::setUp();
29 30 31 32 33 34 35 36 37
    $this->drupalLogin($this->drupalCreateUser(array(
      'view test entity',
      'administer entity_test content',
      'administer content types',
      'administer node fields',
      'administer node display',
      'bypass node access',
      'administer entity_test fields',
    )));
38 39 40
  }

  /**
41
   * Test decimal field.
42 43 44
   */
  function testNumberDecimalField() {
    // Create a field with settings to validate.
45
    $field_name = Unicode::strtolower($this->randomMachineName());
46
    entity_create('field_storage_config', array(
47
      'field_name' => $field_name,
48
      'entity_type' => 'entity_test',
49
      'type' => 'decimal',
50
      'settings' => array(
51
        'precision' => 8, 'scale' => 4,
52
      )
53
    ))->save();
54
    entity_create('field_config', array(
55
      'field_name' => $field_name,
56 57
      'entity_type' => 'entity_test',
      'bundle' => 'entity_test',
58
    ))->save();
59

60
    entity_get_form_display('entity_test', 'entity_test', 'default')
61
      ->setComponent($field_name, array(
62
        'type' => 'number',
63 64 65
        'settings' => array(
          'placeholder' => '0.00'
        ),
66 67
      ))
      ->save();
68
    entity_get_display('entity_test', 'entity_test', 'default')
69
      ->setComponent($field_name, array(
70 71
        'type' => 'number_decimal',
      ))
72
      ->save();
73 74

    // Display creation form.
75
    $this->drupalGet('entity_test/add');
76
    $this->assertFieldByName("{$field_name}[0][value]", '', 'Widget is displayed');
77
    $this->assertRaw('placeholder="0.00"');
78 79 80 81

    // Submit a signed decimal value within the allowed precision and scale.
    $value = '-1234.5678';
    $edit = array(
82
      "{$field_name}[0][value]" => $value,
83
    );
84
    $this->drupalPostForm(NULL, $edit, t('Save'));
85
    preg_match('|entity_test/manage/(\d+)|', $this->url, $match);
86
    $id = $match[1];
87
    $this->assertText(t('entity_test @id has been created.', array('@id' => $id)), 'Entity was created');
88
    $this->assertRaw($value, 'Value is displayed.');
89 90 91 92 93 94 95 96 97 98 99

    // Try to create entries with more than one decimal separator; assert fail.
    $wrong_entries = array(
      '3.14.159',
      '0..45469',
      '..4589',
      '6.459.52',
      '6.3..25',
    );

    foreach ($wrong_entries as $wrong_entry) {
100
      $this->drupalGet('entity_test/add');
101
      $edit = array(
102
        "{$field_name}[0][value]" => $wrong_entry,
103
      );
104
      $this->drupalPostForm(NULL, $edit, t('Save'));
105
      $this->assertRaw(t('%name must be a number.', array('%name' => $field_name)), 'Correctly failed to save decimal value with more than one decimal point.');
106
    }
107

108
    // Try to create entries with minus sign not in the first position.
109 110 111 112 113 114 115 116 117
    $wrong_entries = array(
      '3-3',
      '4-',
      '1.3-',
      '1.2-4',
      '-10-10',
    );

    foreach ($wrong_entries as $wrong_entry) {
118
      $this->drupalGet('entity_test/add');
119
      $edit = array(
120
        "{$field_name}[0][value]" => $wrong_entry,
121
      );
122
      $this->drupalPostForm(NULL, $edit, t('Save'));
123
      $this->assertRaw(t('%name must be a number.', array('%name' => $field_name)), 'Correctly failed to save decimal value with minus sign in the wrong position.');
124
    }
125
  }
126 127

  /**
128
   * Test integer field.
129 130
   */
  function testNumberIntegerField() {
131 132 133 134
    $minimum = rand(-4000, -2000);
    $maximum = rand(2000, 4000);

    // Create a field with settings to validate.
135
    $field_name = Unicode::strtolower($this->randomMachineName());
136
    $storage = entity_create('field_storage_config', array(
137
      'field_name' => $field_name,
138
      'entity_type' => 'entity_test',
139
      'type' => 'integer',
140 141
    ));
    $storage->save();
142

143
    entity_create('field_config', array(
144 145 146 147
      'field_name' => $field_name,
      'entity_type' => 'entity_test',
      'bundle' => 'entity_test',
      'settings' => array(
148
        'min' => $minimum, 'max' => $maximum, 'prefix' => 'ThePrefix',
149 150 151 152 153 154 155 156 157 158 159 160 161 162
      )
    ))->save();

    entity_get_form_display('entity_test', 'entity_test', 'default')
      ->setComponent($field_name, array(
        'type' => 'number',
        'settings' => array(
          'placeholder' => '4'
        ),
      ))
      ->save();
    entity_get_display('entity_test', 'entity_test', 'default')
      ->setComponent($field_name, array(
        'type' => 'number_integer',
163 164 165
        'settings' => array(
          'prefix_suffix' => FALSE,
        ),
166 167 168
      ))
      ->save();

169 170 171 172 173 174 175 176 177 178 179 180 181 182 183
    // Check the storage schema.
    $expected = array(
      'columns' => array(
        'value' => array(
          'type' => 'int',
          'unsigned' => '',
          'size' => 'normal'
        ),
      ),
      'unique keys' => array(),
      'indexes' => array(),
      'foreign keys' => array()
    );
    $this->assertEqual($storage->getSchema(), $expected);

184 185 186 187 188 189 190
    // Display creation form.
    $this->drupalGet('entity_test/add');
    $this->assertFieldByName("{$field_name}[0][value]", '', 'Widget is displayed');
    $this->assertRaw('placeholder="4"');

    // Submit a valid integer
    $value = rand($minimum, $maximum);
191
    $edit = array(
192
      "{$field_name}[0][value]" => $value,
193
    );
194
    $this->drupalPostForm(NULL, $edit, t('Save'));
195 196 197
    preg_match('|entity_test/manage/(\d+)|', $this->url, $match);
    $id = $match[1];
    $this->assertText(t('entity_test @id has been created.', array('@id' => $id)), 'Entity was created');
198

199 200
    // Try to set a value below the minimum value
    $this->drupalGet('entity_test/add');
201
    $edit = array(
202
      "{$field_name}[0][value]" => $minimum - 1,
203
    );
204 205
    $this->drupalPostForm(NULL, $edit, t('Save'));
    $this->assertRaw(t('%name must be higher than or equal to %minimum.', array('%name' => $field_name, '%minimum' => $minimum)), 'Correctly failed to save integer value less than minimum allowed value.');
206

207 208
    // Try to set a decimal value
    $this->drupalGet('entity_test/add');
209
    $edit = array(
210
      "{$field_name}[0][value]" => 1.5,
211
    );
212
    $this->drupalPostForm(NULL, $edit, t('Save'));
213 214 215 216
    $this->assertRaw(t('%name is not a valid number.', array('%name' => $field_name)), 'Correctly failed to save decimal value to integer field.');

    // Try to set a value above the maximum value
    $this->drupalGet('entity_test/add');
217
    $edit = array(
218
      "{$field_name}[0][value]" => $maximum + 1,
219
    );
220
    $this->drupalPostForm(NULL, $edit, t('Save'));
221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239
    $this->assertRaw(t('%name must be lower than or equal to %maximum.', array('%name' => $field_name, '%maximum' => $maximum)), 'Correctly failed to save integer value greater than maximum allowed value.');

    // Test with valid entries.
    $valid_entries = array(
      '-1234',
      '0',
      '1234',
    );

    foreach ($valid_entries as $valid_entry) {
      $this->drupalGet('entity_test/add');
      $edit = array(
        "{$field_name}[0][value]" => $valid_entry,
      );
      $this->drupalPostForm(NULL, $edit, t('Save'));
      preg_match('|entity_test/manage/(\d+)|', $this->url, $match);
      $id = $match[1];
      $this->assertText(t('entity_test @id has been created.', array('@id' => $id)), 'Entity was created');
      $this->assertRaw($valid_entry, 'Value is displayed.');
240
      $this->assertNoFieldByXpath('//div[@content="' . $valid_entry . '"]', NULL, 'The "content" attribute is not present since the Prefix is not being displayed');
241
    }
242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262

    // Test for the content attribute when a Prefix is displayed. Presumably this also tests for the attribute when a Suffix is displayed.
    entity_get_display('entity_test', 'entity_test', 'default')
      ->setComponent($field_name, array(
        'type' => 'number_integer',
        'settings' => array(
          'prefix_suffix' => TRUE,
        ),
      ))
      ->save();
    $integer_value = '123';
    $this->drupalGet('entity_test/add');
    $edit = array(
      "{$field_name}[0][value]" => $integer_value,
    );
    $this->drupalPostForm(NULL, $edit, t('Save'));
    preg_match('|entity_test/manage/(\d+)|', $this->url, $match);
    $id = $match[1];
    $this->assertText(t('entity_test @id has been created.', array('@id' => $id)), 'Entity was created');
    $this->drupalGet('entity_test/' . $id);
    $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.');
263 264 265
  }

  /**
266
  * Test float field.
267 268 269
  */
  function testNumberFloatField() {
    // Create a field with settings to validate.
270
    $field_name = Unicode::strtolower($this->randomMachineName());
271
    entity_create('field_storage_config', array(
272
      'field_name' => $field_name,
273
      'entity_type' => 'entity_test',
274
      'type' => 'float',
275 276
    ))->save();

277
    entity_create('field_config', array(
278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311
      'field_name' => $field_name,
      'entity_type' => 'entity_test',
      'bundle' => 'entity_test',
    ))->save();

    entity_get_form_display('entity_test', 'entity_test', 'default')
      ->setComponent($field_name, array(
        'type' => 'number',
        'settings' => array(
          'placeholder' => '0.00'
        ),
      ))
      ->save();

    entity_get_display('entity_test', 'entity_test', 'default')
      ->setComponent($field_name, array(
        'type' => 'number_decimal',
      ))
      ->save();

    // Display creation form.
    $this->drupalGet('entity_test/add');
    $this->assertFieldByName("{$field_name}[0][value]", '', 'Widget is displayed');
    $this->assertRaw('placeholder="0.00"');

    // Submit a signed decimal value within the allowed precision and scale.
    $value = '-1234.5678';
    $edit = array(
      "{$field_name}[0][value]" => $value,
    );
    $this->drupalPostForm(NULL, $edit, t('Save'));
    preg_match('|entity_test/manage/(\d+)|', $this->url, $match);
    $id = $match[1];
    $this->assertText(t('entity_test @id has been created.', array('@id' => $id)), 'Entity was created');
312 313 314 315 316

    // Ensure that the 'number_decimal' formatter displays the number with the
    // expected rounding.
    $this->drupalGet('entity_test/' . $id);
    $this->assertRaw(round($value, 2));
317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352

    // Try to create entries with more than one decimal separator; assert fail.
    $wrong_entries = array(
      '3.14.159',
      '0..45469',
      '..4589',
      '6.459.52',
      '6.3..25',
    );

    foreach ($wrong_entries as $wrong_entry) {
      $this->drupalGet('entity_test/add');
      $edit = array(
        "{$field_name}[0][value]" => $wrong_entry,
      );
      $this->drupalPostForm(NULL, $edit, t('Save'));
      $this->assertRaw(t('%name must be a number.', array('%name' => $field_name)), 'Correctly failed to save float value with more than one decimal point.');
    }

    // Try to create entries with minus sign not in the first position.
    $wrong_entries = array(
      '3-3',
      '4-',
      '1.3-',
      '1.2-4',
      '-10-10',
    );

    foreach ($wrong_entries as $wrong_entry) {
      $this->drupalGet('entity_test/add');
      $edit = array(
        "{$field_name}[0][value]" => $wrong_entry,
      );
      $this->drupalPostForm(NULL, $edit, t('Save'));
      $this->assertRaw(t('%name must be a number.', array('%name' => $field_name)), 'Correctly failed to save float value with minus sign in the wrong position.');
    }
353 354 355 356 357 358
  }

  /**
   * Test default formatter behavior
   */
  function testNumberFormatter() {
359 360 361
    $type = Unicode::strtolower($this->randomMachineName());
    $float_field = Unicode::strtolower($this->randomMachineName());
    $integer_field = Unicode::strtolower($this->randomMachineName());
362 363
    $thousand_separators = array('', '.', ',', ' ', chr(8201), "'");
    $decimal_separators = array('.', ',');
364 365
    $prefix = $this->randomMachineName();
    $suffix = $this->randomMachineName();
366 367 368 369 370 371
    $random_float = rand(0,pow(10,6));
    $random_integer = rand(0, pow(10,6));

    // Create a content type containing float and integer fields.
    $this->drupalCreateContentType(array('type' => $type));

372
    entity_create('field_storage_config', array(
373
      'field_name' => $float_field,
374
      'entity_type' => 'node',
375
      'type' => 'float',
376 377
    ))->save();

378
    entity_create('field_storage_config', array(
379
      'field_name' => $integer_field,
380
      'entity_type' => 'node',
381
      'type' => 'integer',
382 383
    ))->save();

384
    entity_create('field_config', array(
385 386 387 388 389 390 391 392 393
      'field_name' => $float_field,
      'entity_type' => 'node',
      'bundle' => $type,
      'settings' => array(
        'prefix' => $prefix,
        'suffix' => $suffix
      ),
    ))->save();

394
    entity_create('field_config', array(
395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430
      'field_name' => $integer_field,
      'entity_type' => 'node',
      'bundle' => $type,
      'settings' => array(
        'prefix' => $prefix,
        'suffix' => $suffix
      ),
    ))->save();

    entity_get_form_display('node', $type, 'default')
      ->setComponent($float_field, array(
        'type' => 'number',
        'settings' => array(
          'placeholder' => '0.00'
        ),
      ))
      ->setComponent($integer_field, array(
        'type' => 'number',
        'settings' => array(
          'placeholder' => '0.00'
        ),
      ))
      ->save();

    entity_get_display('node', $type, 'default')
      ->setComponent($float_field, array(
        'type' => 'number_decimal',
      ))
      ->setComponent($integer_field, array(
        'type' => 'number_unformatted',
      ))
      ->save();

    // Create a node to test formatters.
    $node = entity_create('node', array(
      'type' => $type,
431
      'title' => $this->randomMachineName(),
432 433 434 435 436 437 438 439
      $float_field => array(
        'value' => $random_float,
      ),
      $integer_field => array(
        'value' => $random_integer,
      ),
    ));
    $node->save();
440

441 442 443
    // Go to manage display page.
    $this->drupalGet("admin/structure/types/manage/$type/display");

444
    // Configure number_decimal formatter for the 'float' field type.
445 446 447 448 449 450 451 452 453 454 455 456
    $thousand_separator = $thousand_separators[array_rand($thousand_separators)];
    $decimal_separator = $decimal_separators[array_rand($decimal_separators)];
    $scale = rand(0, 10);

    $this->drupalPostAjaxForm(NULL, array(), "${float_field}_settings_edit");
    $edit = array(
      "fields[${float_field}][settings_edit_form][settings][prefix_suffix]" => TRUE,
      "fields[${float_field}][settings_edit_form][settings][scale]" => $scale,
      "fields[${float_field}][settings_edit_form][settings][decimal_separator]" => $decimal_separator,
      "fields[${float_field}][settings_edit_form][settings][thousand_separator]" => $thousand_separator,
    );
    $this->drupalPostAjaxForm(NULL, $edit, "${float_field}_plugin_settings_update");
457
    $this->drupalPostForm(NULL, array(), t('Save'));
458

459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475
    // Check number_decimal and number_unformatted formatters behavior.
    $this->drupalGet('node/' . $node->id());
    $float_formatted = number_format($random_float, $scale, $decimal_separator, $thousand_separator);
    $this->assertRaw("$prefix$float_formatted$suffix", 'Prefix and suffix added');
    $this->assertRaw((string) $random_integer);

    // Configure the number_decimal formatter.
    entity_get_display('node', $type, 'default')
      ->setComponent($integer_field, array(
        'type' => 'number_integer',
      ))
      ->save();
    $this->drupalGet("admin/structure/types/manage/$type/display");

    $thousand_separator = $thousand_separators[array_rand($thousand_separators)];

    $this->drupalPostAjaxForm(NULL, array(), "${integer_field}_settings_edit");
476
    $edit = array(
477 478
      "fields[${integer_field}][settings_edit_form][settings][prefix_suffix]" => FALSE,
      "fields[${integer_field}][settings_edit_form][settings][thousand_separator]" => $thousand_separator,
479
    );
480 481 482 483 484
    $this->drupalPostAjaxForm(NULL, $edit, "${integer_field}_plugin_settings_update");
    $this->drupalPostForm(NULL, array(), t('Save'));

    // Check number_integer formatter behavior.
    $this->drupalGet('node/' . $node->id());
485

486 487
    $integer_formatted = number_format($random_integer, 0, '', $thousand_separator);
    $this->assertRaw($integer_formatted, 'Random integer formatted');
488
  }
489

490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547
  /**
   * Tests setting the minimum value of a float field through the interface.
   */
  function testCreateNumberFloatField() {
    // Create a float field.
    $field_name = Unicode::strtolower($this->randomMachineName());
    entity_create('field_storage_config', array(
      'field_name' => $field_name,
      'entity_type' => 'entity_test',
      'type' => 'float',
    ))->save();

    $field = entity_create('field_config', array(
      'field_name' => $field_name,
      'entity_type' => 'entity_test',
      'bundle' => 'entity_test',
    ));
    $field->save();

    // Set the minimum value to a float value.
    $this->assertSetMinimumValue($field, 0.0001);
    // Set the minimum value to an integer value.
    $this->assertSetMinimumValue($field, 1);
  }

  /**
   * Tests setting the minimum value of a decimal field through the interface.
   */
  function testCreateNumberDecimalField() {
    // Create a decimal field.
    $field_name = Unicode::strtolower($this->randomMachineName());
    entity_create('field_storage_config', array(
      'field_name' => $field_name,
      'entity_type' => 'entity_test',
      'type' => 'decimal',
    ))->save();

    $field = entity_create('field_config', array(
      'field_name' => $field_name,
      'entity_type' => 'entity_test',
      'bundle' => 'entity_test',
    ));
    $field->save();

    // Set the minimum value to a decimal value.
    $this->assertSetMinimumValue($field, 0.1);
    // Set the minimum value to an integer value.
    $this->assertSetMinimumValue($field, 1);
  }

  /**
   * Helper function to set the minimum value of a field.
   */
  function assertSetMinimumValue($field, $minimum_value) {
    $field_configuration_url = 'entity_test/structure/entity_test/fields/entity_test.entity_test.' . $field->getName();

    // Set the minimum value.
    $edit = array(
548
      'settings[min]' => $minimum_value,
549 550 551 552 553 554 555 556
    );
    $this->drupalPostForm($field_configuration_url, $edit, t('Save settings'));
    // Check if an error message is shown.
    $this->assertNoRaw(t('%name is not a valid number.', array('%name' => t('Minimum'))), 'Saved ' . gettype($minimum_value) .'  value as minimal value on a ' . $field->getType() . ' field');
    // Check if a success message is shown.
    $this->assertRaw(t('Saved %label configuration.', array('%label' => $field->getLabel())));
    // Check if the minimum value was actually set.
    $this->drupalGet($field_configuration_url);
557
    $this->assertFieldById('edit-settings-min', $minimum_value, 'Minimal ' . gettype($minimum_value) .'  value was set on a ' . $field->getType() . ' field.');
558
  }
559
}