You are here

public function DateTimeFieldTest::testDatelistWidget in Drupal 8

Same name and namespace in other branches
  1. 9 core/modules/datetime/tests/src/Functional/DateTimeFieldTest.php \Drupal\Tests\datetime\Functional\DateTimeFieldTest::testDatelistWidget()
  2. 10 core/modules/datetime/tests/src/Functional/DateTimeFieldTest.php \Drupal\Tests\datetime\Functional\DateTimeFieldTest::testDatelistWidget()

Tests Date List Widget functionality.

File

core/modules/datetime/tests/src/Functional/DateTimeFieldTest.php, line 392

Class

DateTimeFieldTest
Tests Datetime field functionality.

Namespace

Drupal\Tests\datetime\Functional

Code

public function testDatelistWidget() {
  $field_name = $this->fieldStorage
    ->getName();
  $field_label = $this->field
    ->label();

  // Ensure field is set to a date only field.
  $this->fieldStorage
    ->setSetting('datetime_type', 'date');
  $this->fieldStorage
    ->save();

  /** @var \Drupal\Core\Entity\EntityDisplayRepositoryInterface $display_repository */
  $display_repository = \Drupal::service('entity_display.repository');

  // Change the widget to a datelist widget.
  $display_repository
    ->getFormDisplay($this->field
    ->getTargetEntityTypeId(), $this->field
    ->getTargetBundle())
    ->setComponent($field_name, [
    'type' => 'datetime_datelist',
    'settings' => [
      'date_order' => 'YMD',
    ],
  ])
    ->save();
  \Drupal::service('entity_field.manager')
    ->clearCachedFieldDefinitions();

  // Display creation form.
  $this
    ->drupalGet('entity_test/add');
  $this
    ->assertFieldByXPath('//fieldset[@id="edit-' . $field_name . '-0"]/legend', $field_label, 'Fieldset and label found');
  $this
    ->assertFieldByXPath('//fieldset[@aria-describedby="edit-' . $field_name . '-0--description"]', NULL, 'ARIA described-by found');
  $this
    ->assertFieldByXPath('//div[@id="edit-' . $field_name . '-0--description"]', NULL, 'ARIA description found');

  // Assert that Hour and Minute Elements do not appear on Date Only
  $this
    ->assertNoFieldByXPath("//*[@id=\"edit-{$field_name}-0-value-hour\"]", NULL, 'Hour element not found on Date Only.');
  $this
    ->assertNoFieldByXPath("//*[@id=\"edit-{$field_name}-0-value-minute\"]", NULL, 'Minute element not found on Date Only.');

  // Go to the form display page to assert that increment option does not appear on Date Only
  $fieldEditUrl = 'entity_test/structure/entity_test/form-display';
  $this
    ->drupalGet($fieldEditUrl);

  // Click on the widget settings button to open the widget settings form.
  $this
    ->drupalPostForm(NULL, [], $field_name . "_settings_edit");
  $xpathIncr = "//select[starts-with(@id, \"edit-fields-{$field_name}-settings-edit-form-settings-increment\")]";
  $this
    ->assertNoFieldByXPath($xpathIncr, NULL, 'Increment element not found for Date Only.');

  // Change the field to a datetime field.
  $this->fieldStorage
    ->setSetting('datetime_type', 'datetime');
  $this->fieldStorage
    ->save();

  // Change the widget to a datelist widget.
  $display_repository
    ->getFormDisplay($this->field
    ->getTargetEntityTypeId(), $this->field
    ->getTargetBundle())
    ->setComponent($field_name, [
    'type' => 'datetime_datelist',
    'settings' => [
      'increment' => 1,
      'date_order' => 'YMD',
      'time_type' => '12',
    ],
  ])
    ->save();
  \Drupal::service('entity_field.manager')
    ->clearCachedFieldDefinitions();

  // Go to the form display page to assert that increment option does appear on Date Time
  $fieldEditUrl = 'entity_test/structure/entity_test/form-display';
  $this
    ->drupalGet($fieldEditUrl);

  // Click on the widget settings button to open the widget settings form.
  $this
    ->drupalPostForm(NULL, [], $field_name . "_settings_edit");
  $this
    ->assertFieldByXPath($xpathIncr, NULL, 'Increment element found for Date and time.');

  // Display creation form.
  $this
    ->drupalGet('entity_test/add');
  $this
    ->assertFieldByXPath("//*[@id=\"edit-{$field_name}-0-value-year\"]", NULL, 'Year element found.');
  $this
    ->assertOptionSelected("edit-{$field_name}-0-value-year", '', 'No year selected.');
  $this
    ->assertSession()
    ->optionExists("edit-{$field_name}-0-value-year", t('Year'));
  $this
    ->assertFieldByXPath("//*[@id=\"edit-{$field_name}-0-value-month\"]", NULL, 'Month element found.');
  $this
    ->assertOptionSelected("edit-{$field_name}-0-value-month", '', 'No month selected.');
  $this
    ->assertSession()
    ->optionExists("edit-{$field_name}-0-value-month", t('Month'));
  $this
    ->assertFieldByXPath("//*[@id=\"edit-{$field_name}-0-value-day\"]", NULL, 'Day element found.');
  $this
    ->assertOptionSelected("edit-{$field_name}-0-value-day", '', 'No day selected.');
  $this
    ->assertSession()
    ->optionExists("edit-{$field_name}-0-value-day", t('Day'));
  $this
    ->assertFieldByXPath("//*[@id=\"edit-{$field_name}-0-value-hour\"]", NULL, 'Hour element found.');
  $this
    ->assertOptionSelected("edit-{$field_name}-0-value-hour", '', 'No hour selected.');
  $this
    ->assertSession()
    ->optionExists("edit-{$field_name}-0-value-hour", t('Hour'));
  $this
    ->assertFieldByXPath("//*[@id=\"edit-{$field_name}-0-value-minute\"]", NULL, 'Minute element found.');
  $this
    ->assertOptionSelected("edit-{$field_name}-0-value-minute", '', 'No minute selected.');
  $this
    ->assertSession()
    ->optionExists("edit-{$field_name}-0-value-minute", t('Minute'));
  $this
    ->assertNoFieldByXPath("//*[@id=\"edit-{$field_name}-0-value-second\"]", NULL, 'Second element not found.');
  $this
    ->assertFieldByXPath("//*[@id=\"edit-{$field_name}-0-value-ampm\"]", NULL, 'AMPM element found.');
  $this
    ->assertOptionSelected("edit-{$field_name}-0-value-ampm", '', 'No ampm selected.');
  $this
    ->assertSession()
    ->optionExists("edit-{$field_name}-0-value-ampm", t('AM/PM'));

  // Submit a valid date and ensure it is accepted.
  $date_value = [
    'year' => 2012,
    'month' => 12,
    'day' => 31,
    'hour' => 5,
    'minute' => 15,
  ];
  $edit = [];

  // Add the ampm indicator since we are testing 12 hour time.
  $date_value['ampm'] = 'am';
  foreach ($date_value as $part => $value) {
    $edit["{$field_name}[0][value][{$part}]"] = $value;
  }
  $this
    ->drupalPostForm(NULL, $edit, t('Save'));
  preg_match('|entity_test/manage/(\\d+)|', $this
    ->getUrl(), $match);
  $id = $match[1];
  $this
    ->assertText(t('entity_test @id has been created.', [
    '@id' => $id,
  ]));
  $this
    ->assertOptionSelected("edit-{$field_name}-0-value-year", '2012', 'Correct year selected.');
  $this
    ->assertOptionSelected("edit-{$field_name}-0-value-month", '12', 'Correct month selected.');
  $this
    ->assertOptionSelected("edit-{$field_name}-0-value-day", '31', 'Correct day selected.');
  $this
    ->assertOptionSelected("edit-{$field_name}-0-value-hour", '5', 'Correct hour selected.');
  $this
    ->assertOptionSelected("edit-{$field_name}-0-value-minute", '15', 'Correct minute selected.');
  $this
    ->assertOptionSelected("edit-{$field_name}-0-value-ampm", 'am', 'Correct ampm selected.');

  // Test the widget using increment other than 1 and 24 hour mode.
  $display_repository
    ->getFormDisplay($this->field
    ->getTargetEntityTypeId(), $this->field
    ->getTargetBundle())
    ->setComponent($field_name, [
    'type' => 'datetime_datelist',
    'settings' => [
      'increment' => 15,
      'date_order' => 'YMD',
      'time_type' => '24',
    ],
  ])
    ->save();
  \Drupal::service('entity_field.manager')
    ->clearCachedFieldDefinitions();

  // Display creation form.
  $this
    ->drupalGet('entity_test/add');

  // Other elements are unaffected by the changed settings.
  $this
    ->assertFieldByXPath("//*[@id=\"edit-{$field_name}-0-value-hour\"]", NULL, 'Hour element found.');
  $this
    ->assertOptionSelected("edit-{$field_name}-0-value-hour", '', 'No hour selected.');
  $this
    ->assertNoFieldByXPath("//*[@id=\"edit-{$field_name}-0-value-ampm\"]", NULL, 'AMPM element not found.');

  // Submit a valid date and ensure it is accepted.
  $date_value = [
    'year' => 2012,
    'month' => 12,
    'day' => 31,
    'hour' => 17,
    'minute' => 15,
  ];
  $edit = [];
  foreach ($date_value as $part => $value) {
    $edit["{$field_name}[0][value][{$part}]"] = $value;
  }
  $this
    ->drupalPostForm(NULL, $edit, t('Save'));
  preg_match('|entity_test/manage/(\\d+)|', $this
    ->getUrl(), $match);
  $id = $match[1];
  $this
    ->assertText(t('entity_test @id has been created.', [
    '@id' => $id,
  ]));
  $this
    ->assertOptionSelected("edit-{$field_name}-0-value-year", '2012', 'Correct year selected.');
  $this
    ->assertOptionSelected("edit-{$field_name}-0-value-month", '12', 'Correct month selected.');
  $this
    ->assertOptionSelected("edit-{$field_name}-0-value-day", '31', 'Correct day selected.');
  $this
    ->assertOptionSelected("edit-{$field_name}-0-value-hour", '17', 'Correct hour selected.');
  $this
    ->assertOptionSelected("edit-{$field_name}-0-value-minute", '15', 'Correct minute selected.');

  // Test the widget for partial completion of fields.
  $display_repository
    ->getFormDisplay($this->field
    ->getTargetEntityTypeId(), $this->field
    ->getTargetBundle())
    ->setComponent($field_name, [
    'type' => 'datetime_datelist',
    'settings' => [
      'increment' => 1,
      'date_order' => 'YMD',
      'time_type' => '24',
    ],
  ])
    ->save();
  \Drupal::service('entity_field.manager')
    ->clearCachedFieldDefinitions();

  // Test the widget for validation notifications.
  foreach ($this
    ->datelistDataProvider($field_label) as $data) {
    list($date_value, $expected) = $data;

    // Display creation form.
    $this
      ->drupalGet('entity_test/add');

    // Submit a partial date and ensure and error message is provided.
    $edit = [];
    foreach ($date_value as $part => $value) {
      $edit["{$field_name}[0][value][{$part}]"] = $value;
    }
    $this
      ->drupalPostForm(NULL, $edit, t('Save'));
    $this
      ->assertSession()
      ->statusCodeEquals(200);
    foreach ($expected as $expected_text) {
      $this
        ->assertText(t($expected_text));
    }
  }

  // Test the widget for complete input with zeros as part of selections.
  $this
    ->drupalGet('entity_test/add');
  $date_value = [
    'year' => 2012,
    'month' => '12',
    'day' => '31',
    'hour' => '0',
    'minute' => '0',
  ];
  $edit = [];
  foreach ($date_value as $part => $value) {
    $edit["{$field_name}[0][value][{$part}]"] = $value;
  }
  $this
    ->drupalPostForm(NULL, $edit, t('Save'));
  $this
    ->assertSession()
    ->statusCodeEquals(200);
  preg_match('|entity_test/manage/(\\d+)|', $this
    ->getUrl(), $match);
  $id = $match[1];
  $this
    ->assertText(t('entity_test @id has been created.', [
    '@id' => $id,
  ]));

  // Test the widget to ensure zeros are not deselected on validation.
  $this
    ->drupalGet('entity_test/add');
  $date_value = [
    'year' => 2012,
    'month' => '12',
    'day' => '31',
    'hour' => '',
    'minute' => '0',
  ];
  $edit = [];
  foreach ($date_value as $part => $value) {
    $edit["{$field_name}[0][value][{$part}]"] = $value;
  }
  $this
    ->drupalPostForm(NULL, $edit, t('Save'));
  $this
    ->assertSession()
    ->statusCodeEquals(200);
  $this
    ->assertOptionSelected("edit-{$field_name}-0-value-minute", '0', 'Correct minute selected.');
}