function DateTimeFieldTest::testDatetimeField

Same name and namespace in other branches
  1. 9 core/modules/datetime/tests/src/Functional/DateTimeFieldTest.php \Drupal\Tests\datetime\Functional\DateTimeFieldTest::testDatetimeField()
  2. 8.9.x core/modules/datetime/tests/src/Functional/DateTimeFieldTest.php \Drupal\Tests\datetime\Functional\DateTimeFieldTest::testDatetimeField()
  3. 11.x core/modules/datetime/tests/src/Functional/DateTimeFieldTest.php \Drupal\Tests\datetime\Functional\DateTimeFieldTest::testDatetimeField()

Tests date and time field.

File

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

Class

DateTimeFieldTest
Tests Datetime field functionality.

Namespace

Drupal\Tests\datetime\Functional

Code

public function testDatetimeField() : void {
  $field_name = $this->fieldStorage
    ->getName();
  $field_label = $this->field
    ->label();
  // Change the field to a datetime field.
  $this->fieldStorage
    ->setSetting('datetime_type', 'datetime');
  $this->fieldStorage
    ->save();
  // Display creation form.
  $this->drupalGet('entity_test/add');
  $this->assertSession()
    ->fieldValueEquals("{$field_name}[0][value][date]", '');
  $this->assertSession()
    ->fieldValueEquals("{$field_name}[0][value][time]", '');
  $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"]');
  // Build up a date in the UTC timezone.
  $value = '2012-12-31 00:00:00';
  $date = new DrupalDateTime($value, 'UTC');
  // Update the timezone to the system default.
  $date->setTimezone(timezone_open(date_default_timezone_get()));
  // Submit a valid date and ensure it is accepted.
  $date_format = DateFormat::load('html_date')->getPattern();
  $time_format = DateFormat::load('html_time')->getPattern();
  $edit = [
    "{$field_name}[0][value][date]" => $date->format($date_format),
    "{$field_name}[0][value][time]" => $date->format($time_format),
  ];
  $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->assertSession()
    ->responseContains($date->format($date_format));
  $this->assertSession()
    ->responseContains($date->format($time_format));
  /** @var \Drupal\Core\Entity\EntityDisplayRepositoryInterface $display_repository */
  $display_repository = \Drupal::service('entity_display.repository');
  // Verify that the date is output according to the formatter settings.
  $options = [
    'format_type' => [
      'short',
      'medium',
      'long',
    ],
  ];
  foreach ($options as $setting => $values) {
    foreach ($values as $new_value) {
      // Update the entity display settings.
      $this->displayOptions['settings'] = [
        $setting => $new_value,
      ] + $this->defaultSettings;
      $display_repository->getViewDisplay($this->field
        ->getTargetEntityTypeId(), $this->field
        ->getTargetBundle(), 'full')
        ->setComponent($field_name, $this->displayOptions)
        ->save();
      $this->renderTestEntity($id);
      switch ($setting) {
        case 'format_type':
          // Verify that a date is displayed.
          $date_formatter = $this->container
            ->get('date.formatter');
          $expected = $date_formatter->format($date->getTimestamp(), $new_value);
          $expected_iso = $date_formatter->format($date->getTimestamp(), 'custom', 'Y-m-d\\TH:i:s\\Z', 'UTC');
          $output = $this->renderTestEntity($id);
          $expected_markup = '<time datetime="' . $expected_iso . '">' . $expected . '</time>';
          $this->assertStringContainsString($expected_markup, $output, "Formatted date field using {$new_value} format displayed as {$expected} with {$expected_iso} attribute.");
          break;

      }
    }
  }
  // Verify that the plain formatter works.
  $this->displayOptions['type'] = 'datetime_plain';
  $this->displayOptions['settings'] = $this->defaultSettings;
  $display_repository->getViewDisplay($this->field
    ->getTargetEntityTypeId(), $this->field
    ->getTargetBundle(), 'full')
    ->setComponent($field_name, $this->displayOptions)
    ->save();
  $expected = $date->format(DateTimeItemInterface::DATETIME_STORAGE_FORMAT);
  $output = $this->renderTestEntity($id);
  $this->assertStringContainsString($expected, $output, "Formatted date field using plain format displayed as {$expected}.");
  // Verify that the 'datetime_custom' formatter works.
  $this->displayOptions['type'] = 'datetime_custom';
  $this->displayOptions['settings'] = [
    'date_format' => 'm/d/Y g:i:s A',
  ] + $this->defaultSettings;
  $display_repository->getViewDisplay($this->field
    ->getTargetEntityTypeId(), $this->field
    ->getTargetBundle(), 'full')
    ->setComponent($field_name, $this->displayOptions)
    ->save();
  $expected = $date->format($this->displayOptions['settings']['date_format']);
  $output = $this->renderTestEntity($id);
  $this->assertStringContainsString($expected, $output, "Formatted date field using datetime_custom format displayed as {$expected}.");
  // Verify that the 'timezone_override' setting works.
  $this->displayOptions['type'] = 'datetime_custom';
  $this->displayOptions['settings'] = [
    'date_format' => 'm/d/Y g:i:s A',
    'timezone_override' => 'America/New_York',
  ] + $this->defaultSettings;
  $display_repository->getViewDisplay($this->field
    ->getTargetEntityTypeId(), $this->field
    ->getTargetBundle(), 'full')
    ->setComponent($field_name, $this->displayOptions)
    ->save();
  $expected = $date->format($this->displayOptions['settings']['date_format'], [
    'timezone' => 'America/New_York',
  ]);
  $output = $this->renderTestEntity($id);
  $this->assertStringContainsString($expected, $output, "Formatted date field using datetime_custom format displayed as {$expected}.");
  // Verify that the 'datetime_time_ago' formatter works for intervals in the
  // past.  First update the test entity so that the date difference always
  // has the same interval.  Since the database always stores UTC, and the
  // interval will use this, force the test date to use UTC and not the local
  // or user timezone.
  $timestamp = \Drupal::time()->getRequestTime() - 87654321;
  $entity = EntityTest::load($id);
  $field_name = $this->fieldStorage
    ->getName();
  $date = DrupalDateTime::createFromTimestamp($timestamp, 'UTC');
  $entity->{$field_name}->value = $date->format(DateTimeItemInterface::DATETIME_STORAGE_FORMAT);
  $entity->save();
  $this->displayOptions['type'] = 'datetime_time_ago';
  $this->displayOptions['settings'] = [
    'future_format' => '@interval from now',
    'past_format' => '@interval earlier',
    'granularity' => 3,
  ];
  $display_repository->getViewDisplay($this->field
    ->getTargetEntityTypeId(), $this->field
    ->getTargetBundle(), 'full')
    ->setComponent($field_name, $this->displayOptions)
    ->save();
  $expected = new FormattableMarkup($this->displayOptions['settings']['past_format'], [
    '@interval' => $this->dateFormatter
      ->formatTimeDiffSince($timestamp, [
      'granularity' => $this->displayOptions['settings']['granularity'],
    ]),
  ]);
  $output = $this->renderTestEntity($id);
  $this->assertStringContainsString((string) $expected, $output, "Formatted date field using datetime_time_ago format displayed as {$expected}.");
  // Verify that the 'datetime_time_ago' formatter works for intervals in the
  // future.  First update the test entity so that the date difference always
  // has the same interval.  Since the database always stores UTC, and the
  // interval will use this, force the test date to use UTC and not the local
  // or user timezone.
  $timestamp = \Drupal::time()->getRequestTime() + 87654321;
  $entity = EntityTest::load($id);
  $field_name = $this->fieldStorage
    ->getName();
  $date = DrupalDateTime::createFromTimestamp($timestamp, 'UTC');
  $entity->{$field_name}->value = $date->format(DateTimeItemInterface::DATETIME_STORAGE_FORMAT);
  $entity->save();
  $display_repository->getViewDisplay($this->field
    ->getTargetEntityTypeId(), $this->field
    ->getTargetBundle(), 'full')
    ->setComponent($field_name, $this->displayOptions)
    ->save();
  $expected = new FormattableMarkup($this->displayOptions['settings']['future_format'], [
    '@interval' => $this->dateFormatter
      ->formatTimeDiffUntil($timestamp, [
      'granularity' => $this->displayOptions['settings']['granularity'],
    ]),
  ]);
  $output = $this->renderTestEntity($id);
  $this->assertStringContainsString((string) $expected, $output, "Formatted date field using datetime_time_ago format displayed as {$expected}.");
  // Test the required field validation error message.
  $entity = EntityTest::create([
    'name' => 'test datetime required message',
  ]);
  $form = \Drupal::entityTypeManager()->getFormObject('entity_test', 'default')
    ->setEntity($entity);
  $form_state = new FormState();
  \Drupal::formBuilder()->submitForm($form, $form_state);
  $errors = $form_state->getErrors();
  $expected_error_message = new FormattableMarkup('The %field date is required.', [
    '%field' => $field_label,
  ]);
  $actual_error_message = $errors["{$field_name}][0][value"]->__toString();
  $this->assertEquals($expected_error_message->__toString(), $actual_error_message);
}

Buggy or inaccurate documentation? Please file an issue. Need support? Need help programming? Connect with the Drupal community.