You are here

public function DateRangeFieldTest::testDatelistWidget in Drupal 9

Same name and namespace in other branches
  1. 8 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
    ->assertSession()
    ->elementTextContains('xpath', '//fieldset[@id="edit-' . $field_name . '-0"]/legend', $field_label);
  $this
    ->assertSession()
    ->elementExists('xpath', '//fieldset[@aria-describedby="edit-' . $field_name . '-0--description"]');
  $this
    ->assertSession()
    ->elementExists('xpath', '//div[@id="edit-' . $field_name . '-0--description"]');

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

  // 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
    ->submitForm([], $field_name . "_settings_edit");
  $xpathIncr = "//select[starts-with(@id, \"edit-fields-{$field_name}-settings-edit-form-settings-increment\")]";
  $this
    ->assertSession()
    ->elementNotExists('xpath', $xpathIncr);

  // 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
    ->assertSession()
    ->elementNotExists('xpath', "//*[@id=\"edit-{$field_name}-0-value-hour\"]");
  $this
    ->assertSession()
    ->elementNotExists('xpath', "//*[@id=\"edit-{$field_name}-0-value-minute\"]");
  $this
    ->assertSession()
    ->elementNotExists('xpath', "//*[@id=\"edit-{$field_name}-0-end-value-hour\"]");
  $this
    ->assertSession()
    ->elementNotExists('xpath', "//*[@id=\"edit-{$field_name}-0-end-value-minute\"]");

  // 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
    ->submitForm([], $field_name . "_settings_edit");
  $xpathIncr = "//select[starts-with(@id, \"edit-fields-{$field_name}-settings-edit-form-settings-increment\")]";
  $this
    ->assertSession()
    ->elementNotExists('xpath', $xpathIncr);

  // 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
    ->submitForm([], $field_name . "_settings_edit");
  $this
    ->assertSession()
    ->elementExists('xpath', $xpathIncr);

  // Display creation form.
  $this
    ->drupalGet('entity_test/add');
  foreach ([
    'value',
    'end-value',
  ] as $column) {
    foreach ([
      'year',
      'month',
      'day',
      'hour',
      'minute',
      'ampm',
    ] as $element) {
      $this
        ->assertSession()
        ->elementExists('xpath', "//*[@id=\"edit-{$field_name}-0-{$column}-{$element}\"]");
      $this
        ->assertTrue($this
        ->assertSession()
        ->optionExists("edit-{$field_name}-0-{$column}-{$element}", '')
        ->isSelected());
    }
  }

  // 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
    ->submitForm($edit, 'Save');
  preg_match('|entity_test/manage/(\\d+)|', $this
    ->getUrl(), $match);
  $id = $match[1];
  $this
    ->assertSession()
    ->pageTextContains('entity_test ' . $id . ' has been created.');
  $this
    ->assertTrue($this
    ->assertSession()
    ->optionExists("edit-{$field_name}-0-value-year", '2012')
    ->isSelected());
  $this
    ->assertTrue($this
    ->assertSession()
    ->optionExists("edit-{$field_name}-0-value-month", '12')
    ->isSelected());
  $this
    ->assertTrue($this
    ->assertSession()
    ->optionExists("edit-{$field_name}-0-value-day", '31')
    ->isSelected());
  $this
    ->assertTrue($this
    ->assertSession()
    ->optionExists("edit-{$field_name}-0-value-hour", '5')
    ->isSelected());
  $this
    ->assertTrue($this
    ->assertSession()
    ->optionExists("edit-{$field_name}-0-value-minute", '15')
    ->isSelected());
  $this
    ->assertTrue($this
    ->assertSession()
    ->optionExists("edit-{$field_name}-0-value-ampm", 'am')
    ->isSelected());
  $this
    ->assertTrue($this
    ->assertSession()
    ->optionExists("edit-{$field_name}-0-end-value-year", '2013')
    ->isSelected());
  $this
    ->assertTrue($this
    ->assertSession()
    ->optionExists("edit-{$field_name}-0-end-value-month", '1')
    ->isSelected());
  $this
    ->assertTrue($this
    ->assertSession()
    ->optionExists("edit-{$field_name}-0-end-value-day", '15')
    ->isSelected());
  $this
    ->assertTrue($this
    ->assertSession()
    ->optionExists("edit-{$field_name}-0-end-value-hour", '3')
    ->isSelected());
  $this
    ->assertTrue($this
    ->assertSession()
    ->optionExists("edit-{$field_name}-0-end-value-minute", '30')
    ->isSelected());
  $this
    ->assertTrue($this
    ->assertSession()
    ->optionExists("edit-{$field_name}-0-end-value-ampm", 'pm')
    ->isSelected());

  // 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
    ->assertSession()
    ->elementExists('xpath', "//*[@id=\"edit-{$field_name}-0-value-hour\"]");
  $this
    ->assertTrue($this
    ->assertSession()
    ->optionExists("edit-{$field_name}-0-value-hour", '')
    ->isSelected());
  $this
    ->assertSession()
    ->elementNotExists('xpath', "//*[@id=\"edit-{$field_name}-0-value-ampm\"]");
  $this
    ->assertSession()
    ->elementExists('xpath', "//*[@id=\"edit-{$field_name}-0-end-value-hour\"]");
  $this
    ->assertTrue($this
    ->assertSession()
    ->optionExists("edit-{$field_name}-0-end-value-hour", '')
    ->isSelected());
  $this
    ->assertSession()
    ->elementNotExists('xpath', "//*[@id=\"edit-{$field_name}-0-end-value-ampm\"]");

  // 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
    ->submitForm($edit, 'Save');
  preg_match('|entity_test/manage/(\\d+)|', $this
    ->getUrl(), $match);
  $id = $match[1];
  $this
    ->assertSession()
    ->pageTextContains('entity_test ' . $id . ' has been created.');
  $this
    ->assertTrue($this
    ->assertSession()
    ->optionExists("edit-{$field_name}-0-value-year", '2012')
    ->isSelected());
  $this
    ->assertTrue($this
    ->assertSession()
    ->optionExists("edit-{$field_name}-0-value-month", '12')
    ->isSelected());
  $this
    ->assertTrue($this
    ->assertSession()
    ->optionExists("edit-{$field_name}-0-value-day", '31')
    ->isSelected());
  $this
    ->assertTrue($this
    ->assertSession()
    ->optionExists("edit-{$field_name}-0-value-hour", '17')
    ->isSelected());
  $this
    ->assertTrue($this
    ->assertSession()
    ->optionExists("edit-{$field_name}-0-value-minute", '15')
    ->isSelected());
  $this
    ->assertTrue($this
    ->assertSession()
    ->optionExists("edit-{$field_name}-0-end-value-year", '2013')
    ->isSelected());
  $this
    ->assertTrue($this
    ->assertSession()
    ->optionExists("edit-{$field_name}-0-end-value-month", '1')
    ->isSelected());
  $this
    ->assertTrue($this
    ->assertSession()
    ->optionExists("edit-{$field_name}-0-end-value-day", '15')
    ->isSelected());
  $this
    ->assertTrue($this
    ->assertSession()
    ->optionExists("edit-{$field_name}-0-end-value-hour", '3')
    ->isSelected());
  $this
    ->assertTrue($this
    ->assertSession()
    ->optionExists("edit-{$field_name}-0-end-value-minute", '30')
    ->isSelected());

  // 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
      ->submitForm($edit, 'Save');
    $this
      ->assertSession()
      ->statusCodeEquals(200);
    foreach ($expected as $expected_text) {
      $this
        ->assertSession()
        ->pageTextContains($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
    ->submitForm($edit, 'Save');
  $this
    ->assertSession()
    ->statusCodeEquals(200);
  preg_match('|entity_test/manage/(\\d+)|', $this
    ->getUrl(), $match);
  $id = $match[1];
  $this
    ->assertSession()
    ->pageTextContains('entity_test ' . $id . ' has been created.');

  // 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
    ->submitForm($edit, 'Save');
  $this
    ->assertSession()
    ->statusCodeEquals(200);
  $this
    ->assertTrue($this
    ->assertSession()
    ->optionExists("edit-{$field_name}-0-value-minute", '0')
    ->isSelected());
  $this
    ->assertTrue($this
    ->assertSession()
    ->optionExists("edit-{$field_name}-0-end-value-minute", '0')
    ->isSelected());
}