You are here

public function DateRangeFieldTest::testDatelistWidget in Drupal 8

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

Tests Date Range List Widget functionality.

File

core/modules/datetime_range/tests/src/Functional/DateRangeFieldTest.php, line 641

Class

DateRangeFieldTest
Tests Daterange field functionality.

Namespace

Drupal\Tests\datetime_range\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', DateRangeItem::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' => 'daterange_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.');
  $this
    ->assertNoFieldByXPath("//*[@id=\"edit-{$field_name}-0-end-value-hour\"]", NULL, 'Hour element not found on Date Only.');
  $this
    ->assertNoFieldByXPath("//*[@id=\"edit-{$field_name}-0-end-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 is set to an all day field.
  $this->fieldStorage
    ->setSetting('datetime_type', DateRangeItem::DATETIME_TYPE_ALLDAY);
  $this->fieldStorage
    ->save();

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

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

  // 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.');
  $this
    ->assertNoFieldByXPath("//*[@id=\"edit-{$field_name}-0-end-value-hour\"]", NULL, 'Hour element not found on Date Only.');
  $this
    ->assertNoFieldByXPath("//*[@id=\"edit-{$field_name}-0-end-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', DateRangeItem::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' => 'daterange_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');
  foreach ([
    'value',
    'end-value',
  ] as $column) {
    foreach ([
      'year',
      'month',
      'day',
      'hour',
      'minute',
      'ampm',
    ] as $element) {
      $this
        ->assertFieldByXPath("//*[@id=\"edit-{$field_name}-0-{$column}-{$element}\"]", NULL, $element . ' element found.');
      $this
        ->assertOptionSelected("edit-{$field_name}-0-{$column}-{$element}", '', 'No ' . $element . ' selected.');
    }
  }

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

  // Add the ampm indicator since we are testing 12 hour time.
  $start_date_value['ampm'] = 'am';
  $end_date_value['ampm'] = 'pm';
  foreach ($start_date_value as $part => $value) {
    $edit["{$field_name}[0][value][{$part}]"] = $value;
  }
  foreach ($end_date_value as $part => $value) {
    $edit["{$field_name}[0][end_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.');
  $this
    ->assertOptionSelected("edit-{$field_name}-0-end-value-year", '2013', 'Correct year selected.');
  $this
    ->assertOptionSelected("edit-{$field_name}-0-end-value-month", '1', 'Correct month selected.');
  $this
    ->assertOptionSelected("edit-{$field_name}-0-end-value-day", '15', 'Correct day selected.');
  $this
    ->assertOptionSelected("edit-{$field_name}-0-end-value-hour", '3', 'Correct hour selected.');
  $this
    ->assertOptionSelected("edit-{$field_name}-0-end-value-minute", '30', 'Correct minute selected.');
  $this
    ->assertOptionSelected("edit-{$field_name}-0-end-value-ampm", 'pm', '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' => 'daterange_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.');
  $this
    ->assertFieldByXPath("//*[@id=\"edit-{$field_name}-0-end-value-hour\"]", NULL, 'Hour element found.');
  $this
    ->assertOptionSelected("edit-{$field_name}-0-end-value-hour", '', 'No hour selected.');
  $this
    ->assertNoFieldByXPath("//*[@id=\"edit-{$field_name}-0-end-value-ampm\"]", NULL, 'AMPM element not found.');

  // Submit a valid date and ensure it is accepted.
  $start_date_value = [
    'year' => 2012,
    'month' => 12,
    'day' => 31,
    'hour' => 17,
    'minute' => 15,
  ];
  $end_date_value = [
    'year' => 2013,
    'month' => 1,
    'day' => 15,
    'hour' => 3,
    'minute' => 30,
  ];
  $edit = [];
  foreach ($start_date_value as $part => $value) {
    $edit["{$field_name}[0][value][{$part}]"] = $value;
  }
  foreach ($end_date_value as $part => $value) {
    $edit["{$field_name}[0][end_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.');
  $this
    ->assertOptionSelected("edit-{$field_name}-0-end-value-year", '2013', 'Correct year selected.');
  $this
    ->assertOptionSelected("edit-{$field_name}-0-end-value-month", '1', 'Correct month selected.');
  $this
    ->assertOptionSelected("edit-{$field_name}-0-end-value-day", '15', 'Correct day selected.');
  $this
    ->assertOptionSelected("edit-{$field_name}-0-end-value-hour", '3', 'Correct hour selected.');
  $this
    ->assertOptionSelected("edit-{$field_name}-0-end-value-minute", '30', 'Correct minute selected.');

  // Test the widget for partial completion of fields.
  $display_repository
    ->getFormDisplay($this->field
    ->getTargetEntityTypeId(), $this->field
    ->getTargetBundle())
    ->setComponent($field_name, [
    'type' => 'daterange_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() as $data) {
    list($start_date_value, $end_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 ($start_date_value as $part => $value) {
      $edit["{$field_name}[0][value][{$part}]"] = $value;
    }
    foreach ($end_date_value as $part => $value) {
      $edit["{$field_name}[0][end_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');
  $start_date_value = [
    'year' => 2012,
    'month' => 12,
    'day' => 31,
    'hour' => 0,
    'minute' => 0,
  ];
  $end_date_value = [
    'year' => 2013,
    'month' => 1,
    'day' => 15,
    'hour' => 3,
    'minute' => 30,
  ];
  $edit = [];
  foreach ($start_date_value as $part => $value) {
    $edit["{$field_name}[0][value][{$part}]"] = $value;
  }
  foreach ($end_date_value as $part => $value) {
    $edit["{$field_name}[0][end_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');
  $start_date_value = [
    'year' => 2012,
    'month' => 12,
    'day' => 31,
    'hour' => 0,
    'minute' => 0,
  ];
  $end_date_value = [
    'year' => 2013,
    'month' => 1,
    'day' => 15,
    'hour' => 3,
    'minute' => 0,
  ];
  $edit = [];
  foreach ($start_date_value as $part => $value) {
    $edit["{$field_name}[0][value][{$part}]"] = $value;
  }
  foreach ($end_date_value as $part => $value) {
    $edit["{$field_name}[0][end_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.');
  $this
    ->assertOptionSelected("edit-{$field_name}-0-end-value-minute", '0', 'Correct minute selected.');
}