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. 10 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 241

Class

DateTimeFieldTest
Tests Datetime field functionality.

Namespace

Drupal\Tests\datetime\Functional

Code

public function testDatetimeField() {
    $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->assertFieldByName("{$field_name}[0][value][date]", '', 'Date element found.');
    $this->assertFieldByName("{$field_name}[0][value][time]", '', 'Time element found.');
    $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');
    // 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->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->assertRaw($date->format($date_format));
    $this->assertRaw($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 . '" class="datetime">' . $expected . '</time>';
                    $this->assertStringContainsString($expected_markup, $output, new FormattableMarkup('Formatted date field using %value format displayed as %expected with %expected_iso attribute.', [
                        '%value' => $new_value,
                        '%expected' => $expected,
                        '%expected_iso' => $expected_iso,
                    ]));
                    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, new FormattableMarkup('Formatted date field using plain format displayed as %expected.', [
        '%expected' => $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, new FormattableMarkup('Formatted date field using datetime_custom format displayed as %expected.', [
        '%expected' => $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, new FormattableMarkup('Formatted date field using datetime_custom format displayed as %expected.', [
        '%expected' => $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 = REQUEST_TIME - 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, new FormattableMarkup('Formatted date field using datetime_time_ago format displayed as %expected.', [
        '%expected' => $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 = REQUEST_TIME + 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, new FormattableMarkup('Formatted date field using datetime_time_ago format displayed as %expected.', [
        '%expected' => $expected,
    ]));
}

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