1<?php
2
3namespace Drupal\Tests\field\FunctionalJavascript\Number;
4
5use Drupal\field\Entity\FieldConfig;
6use Drupal\field\Entity\FieldStorageConfig;
7use Drupal\FunctionalJavascriptTests\WebDriverTestBase;
8use Drupal\node\Entity\Node;
9
10/**
11 * Tests the numeric field widget.
12 *
13 * @group field
14 */
15class NumberFieldTest extends WebDriverTestBase {
16
17  /**
18   * {@inheritdoc}
19   */
20  protected static $modules = ['node', 'entity_test', 'field_ui'];
21
22  /**
23   * {@inheritdoc}
24   */
25  protected $defaultTheme = 'stark';
26
27  /**
28   * {@inheritdoc}
29   */
30  protected function setUp(): void {
31    parent::setUp();
32
33    $this->drupalLogin($this->drupalCreateUser([
34      'view test entity',
35      'administer entity_test content',
36      'administer content types',
37      'administer node fields',
38      'administer node display',
39      'bypass node access',
40      'administer entity_test fields',
41    ]));
42  }
43
44  /**
45   * Tests default formatter behavior.
46   */
47  public function testNumberFormatter() {
48    $type = mb_strtolower($this->randomMachineName());
49    $float_field = mb_strtolower($this->randomMachineName());
50    $integer_field = mb_strtolower($this->randomMachineName());
51    $thousand_separators = ['', '.', ',', ' ', chr(8201), "'"];
52    $decimal_separators = ['.', ','];
53    $prefix = $this->randomMachineName();
54    $suffix = $this->randomMachineName();
55    $random_float = rand(0, pow(10, 6));
56    $random_integer = rand(0, pow(10, 6));
57    $assert_session = $this->assertSession();
58
59    // Create a content type containing float and integer fields.
60    $this->drupalCreateContentType(['type' => $type]);
61
62    FieldStorageConfig::create([
63      'field_name' => $float_field,
64      'entity_type' => 'node',
65      'type' => 'float',
66    ])->save();
67
68    FieldStorageConfig::create([
69      'field_name' => $integer_field,
70      'entity_type' => 'node',
71      'type' => 'integer',
72    ])->save();
73
74    FieldConfig::create([
75      'field_name' => $float_field,
76      'entity_type' => 'node',
77      'bundle' => $type,
78      'settings' => [
79        'prefix' => $prefix,
80        'suffix' => $suffix,
81      ],
82    ])->save();
83
84    FieldConfig::create([
85      'field_name' => $integer_field,
86      'entity_type' => 'node',
87      'bundle' => $type,
88      'settings' => [
89        'prefix' => $prefix,
90        'suffix' => $suffix,
91      ],
92    ])->save();
93
94    \Drupal::service('entity_display.repository')->getFormDisplay('node', $type, 'default')
95      ->setComponent($float_field, [
96        'type' => 'number',
97        'settings' => [
98          'placeholder' => '0.00',
99        ],
100      ])
101      ->setComponent($integer_field, [
102        'type' => 'number',
103        'settings' => [
104          'placeholder' => '0.00',
105        ],
106      ])
107      ->save();
108
109    \Drupal::service('entity_display.repository')->getViewDisplay('node', $type)
110      ->setComponent($float_field, [
111        'type' => 'number_decimal',
112      ])
113      ->setComponent($integer_field, [
114        'type' => 'number_unformatted',
115      ])
116      ->save();
117
118    // Create a node to test formatters.
119    $node = Node::create([
120      'type' => $type,
121      'title' => $this->randomMachineName(),
122      $float_field => ['value' => $random_float],
123      $integer_field => ['value' => $random_integer],
124    ]);
125    $node->save();
126
127    // Go to manage display page.
128    $this->drupalGet("admin/structure/types/manage/$type/display");
129
130    // Configure number_decimal formatter for the 'float' field type.
131    $thousand_separator = $thousand_separators[array_rand($thousand_separators)];
132    $decimal_separator = $decimal_separators[array_rand($decimal_separators)];
133    $scale = rand(0, 10);
134
135    $page = $this->getSession()->getPage();
136    $page->pressButton("${float_field}_settings_edit");
137    $assert_session->waitForElement('css', '.ajax-new-content');
138    $edit = [
139      "fields[${float_field}][settings_edit_form][settings][prefix_suffix]" => TRUE,
140      "fields[${float_field}][settings_edit_form][settings][scale]" => $scale,
141      "fields[${float_field}][settings_edit_form][settings][decimal_separator]" => $decimal_separator,
142      "fields[${float_field}][settings_edit_form][settings][thousand_separator]" => $thousand_separator,
143    ];
144    foreach ($edit as $name => $value) {
145      $page->fillField($name, $value);
146    }
147    $page->pressButton("${float_field}_plugin_settings_update");
148    $assert_session->waitForElement('css', '.field-plugin-summary-cell > .ajax-new-content');
149    $this->submitForm([], 'Save');
150
151    // Check number_decimal and number_unformatted formatters behavior.
152    $this->drupalGet('node/' . $node->id());
153    $float_formatted = number_format($random_float, $scale, $decimal_separator, $thousand_separator);
154    $this->assertSession()->responseContains("$prefix$float_formatted$suffix");
155    $this->assertSession()->responseContains((string) $random_integer);
156
157    // Configure the number_decimal formatter.
158    \Drupal::service('entity_display.repository')->getViewDisplay('node', $type)
159      ->setComponent($integer_field, [
160        'type' => 'number_integer',
161      ])
162      ->save();
163    $this->drupalGet("admin/structure/types/manage/$type/display");
164
165    $thousand_separator = $thousand_separators[array_rand($thousand_separators)];
166
167    $page = $this->getSession()->getPage();
168    $page->pressButton("${integer_field}_settings_edit");
169    $assert_session->waitForElement('css', '.ajax-new-content');
170    $edit = [
171      "fields[${integer_field}][settings_edit_form][settings][prefix_suffix]" => FALSE,
172      "fields[${integer_field}][settings_edit_form][settings][thousand_separator]" => $thousand_separator,
173    ];
174    foreach ($edit as $name => $value) {
175      $page->fillField($name, $value);
176    }
177    $page->pressButton("${integer_field}_plugin_settings_update");
178    $assert_session->waitForElement('css', '.field-plugin-summary-cell > .ajax-new-content');
179    $this->submitForm([], 'Save');
180
181    // Check number_integer formatter behavior.
182    $this->drupalGet('node/' . $node->id());
183
184    $integer_formatted = number_format($random_integer, 0, '', $thousand_separator);
185    $this->assertSession()->responseContains($integer_formatted);
186  }
187
188}
189