DateTimeItemTest.php

Same filename in other branches
  1. 9 core/modules/datetime/tests/src/Kernel/DateTimeItemTest.php
  2. 8.9.x core/modules/datetime/tests/src/Kernel/DateTimeItemTest.php
  3. 11.x core/modules/datetime/tests/src/Kernel/DateTimeItemTest.php

Namespace

Drupal\Tests\datetime\Kernel

File

core/modules/datetime/tests/src/Kernel/DateTimeItemTest.php

View source
<?php

declare (strict_types=1);
namespace Drupal\Tests\datetime\Kernel;

use Drupal\Core\Field\FieldItemListInterface;
use Drupal\Core\Field\FieldItemInterface;
use Drupal\datetime\Plugin\Field\FieldType\DateTimeItem;
use Drupal\datetime\Plugin\Field\FieldType\DateTimeItemInterface;
use Drupal\entity_test\Entity\EntityTest;
use Drupal\field\Entity\FieldConfig;
use Drupal\Tests\field\Kernel\FieldKernelTestBase;
use Drupal\field\Entity\FieldStorageConfig;
use PHPUnit\Framework\AssertionFailedError;

/**
 * Tests the new entity API for the date field type.
 *
 * @group datetime
 * @group #slow
 */
class DateTimeItemTest extends FieldKernelTestBase {
    
    /**
     * A field storage to use in this test class.
     *
     * @var \Drupal\field\Entity\FieldStorageConfig
     */
    protected $fieldStorage;
    
    /**
     * The field used in this test class.
     *
     * @var \Drupal\field\Entity\FieldConfig
     */
    protected $field;
    
    /**
     * {@inheritdoc}
     */
    protected static $modules = [
        'datetime',
    ];
    
    /**
     * {@inheritdoc}
     */
    protected function setUp() : void {
        parent::setUp();
        // Create a field with settings to validate.
        $this->fieldStorage = FieldStorageConfig::create([
            'field_name' => 'field_datetime',
            'type' => 'datetime',
            'entity_type' => 'entity_test',
            'settings' => [
                'datetime_type' => DateTimeItem::DATETIME_TYPE_DATETIME,
            ],
        ]);
        $this->fieldStorage
            ->save();
        $this->field = FieldConfig::create([
            'field_storage' => $this->fieldStorage,
            'bundle' => 'entity_test',
            'settings' => [
                'default_value' => 'blank',
            ],
        ]);
        $this->field
            ->save();
    }
    
    /**
     * Tests using entity fields of the datetime field type.
     */
    public function testDateTime() : void {
        $this->fieldStorage
            ->setSetting('datetime_type', DateTimeItem::DATETIME_TYPE_DATETIME);
        $this->fieldStorage
            ->save();
        // Verify entity creation.
        $entity = EntityTest::create();
        $value = '2014-01-01T20:00:00';
        $entity->field_datetime = $value;
        $entity->name->value = $this->randomMachineName();
        $this->entityValidateAndSave($entity);
        // Verify entity has been created properly.
        $id = $entity->id();
        $entity = EntityTest::load($id);
        $this->assertInstanceOf(FieldItemListInterface::class, $entity->field_datetime);
        $this->assertInstanceOf(FieldItemInterface::class, $entity->field_datetime[0]);
        $this->assertEquals($value, $entity->field_datetime->value);
        $this->assertEquals($value, $entity->field_datetime[0]->value);
        $this->assertEquals(DateTimeItemInterface::STORAGE_TIMEZONE, $entity->field_datetime[0]
            ->getProperties()['value']
            ->getDateTime()
            ->getTimeZone()
            ->getName());
        $this->assertEquals(DateTimeItemInterface::STORAGE_TIMEZONE, $entity->field_datetime->date
            ->getTimeZone()
            ->getName());
        // Verify changing the date value.
        $new_value = '2016-11-04T00:21:00';
        $entity->field_datetime->value = $new_value;
        $this->assertEquals($new_value, $entity->field_datetime->value);
        $this->assertEquals(DateTimeItemInterface::STORAGE_TIMEZONE, $entity->field_datetime[0]
            ->getProperties()['value']
            ->getDateTime()
            ->getTimeZone()
            ->getName());
        $this->assertEquals(DateTimeItemInterface::STORAGE_TIMEZONE, $entity->field_datetime->date
            ->getTimeZone()
            ->getName());
        // Read changed entity and assert changed values.
        $this->entityValidateAndSave($entity);
        $entity = EntityTest::load($id);
        $this->assertEquals($new_value, $entity->field_datetime->value);
        $this->assertEquals(DateTimeItemInterface::STORAGE_TIMEZONE, $entity->field_datetime[0]
            ->getProperties()['value']
            ->getDateTime()
            ->getTimeZone()
            ->getName());
        $this->assertEquals(DateTimeItemInterface::STORAGE_TIMEZONE, $entity->field_datetime->date
            ->getTimeZone()
            ->getName());
        // Test the generateSampleValue() method.
        $entity = EntityTest::create();
        $entity->field_datetime
            ->generateSampleItems();
        $this->entityValidateAndSave($entity);
    }
    
    /**
     * Tests using entity fields of the date field type.
     */
    public function testDateOnly() : void {
        $this->fieldStorage
            ->setSetting('datetime_type', DateTimeItem::DATETIME_TYPE_DATE);
        $this->fieldStorage
            ->save();
        // Verify entity creation.
        $entity = EntityTest::create();
        $value = '2014-01-01';
        $entity->field_datetime = $value;
        $entity->name->value = $this->randomMachineName();
        $this->entityValidateAndSave($entity);
        // Verify entity has been created properly.
        $id = $entity->id();
        $entity = EntityTest::load($id);
        $this->assertInstanceOf(FieldItemListInterface::class, $entity->field_datetime);
        $this->assertInstanceOf(FieldItemInterface::class, $entity->field_datetime[0]);
        $this->assertEquals($value, $entity->field_datetime->value);
        $this->assertEquals($value, $entity->field_datetime[0]->value);
        $this->assertEquals(DateTimeItemInterface::STORAGE_TIMEZONE, $entity->field_datetime->date
            ->getTimeZone()
            ->getName());
        $this->assertEquals('12:00:00', $entity->field_datetime->date
            ->format('H:i:s'));
        $entity->field_datetime->date
            ->setDefaultDateTime();
        $this->assertEquals('12:00:00', $entity->field_datetime->date
            ->format('H:i:s'));
        // Verify changing the date value.
        $new_value = '2016-11-04';
        $entity->field_datetime->value = $new_value;
        $this->assertEquals($new_value, $entity->field_datetime->value);
        $this->assertEquals(DateTimeItemInterface::STORAGE_TIMEZONE, $entity->field_datetime->date
            ->getTimeZone()
            ->getName());
        $this->assertEquals('12:00:00', $entity->field_datetime->date
            ->format('H:i:s'));
        $entity->field_datetime->date
            ->setDefaultDateTime();
        $this->assertEquals('12:00:00', $entity->field_datetime->date
            ->format('H:i:s'));
        // Read changed entity and assert changed values.
        $this->entityValidateAndSave($entity);
        $entity = EntityTest::load($id);
        $this->assertEquals($new_value, $entity->field_datetime->value);
        $this->assertEquals(DateTimeItemInterface::STORAGE_TIMEZONE, $entity->field_datetime->date
            ->getTimeZone()
            ->getName());
        $this->assertEquals('12:00:00', $entity->field_datetime->date
            ->format('H:i:s'));
        $entity->field_datetime->date
            ->setDefaultDateTime();
        $this->assertEquals('12:00:00', $entity->field_datetime->date
            ->format('H:i:s'));
        // Test the generateSampleValue() method.
        $entity = EntityTest::create();
        $entity->field_datetime
            ->generateSampleItems();
        $this->assertEquals('12:00:00', $entity->field_datetime->date
            ->format('H:i:s'));
        $entity->field_datetime->date
            ->setDefaultDateTime();
        $this->assertEquals('12:00:00', $entity->field_datetime->date
            ->format('H:i:s'));
        $this->entityValidateAndSave($entity);
    }
    
    /**
     * Tests DateTimeItem::setValue().
     */
    public function testSetValue() : void {
        // Test a date+time field.
        $this->fieldStorage
            ->setSetting('datetime_type', DateTimeItem::DATETIME_TYPE_DATETIME);
        $this->fieldStorage
            ->save();
        // Test DateTimeItem::setValue() using string.
        $entity = EntityTest::create();
        $value = '2014-01-01T20:00:00';
        $entity->get('field_datetime')
            ->set(0, $value);
        $this->entityValidateAndSave($entity);
        // Load the entity and ensure the field was saved correctly.
        $id = $entity->id();
        $entity = EntityTest::load($id);
        $this->assertEquals($value, $entity->field_datetime[0]->value, 'DateTimeItem::setValue() works with string value.');
        $this->assertEquals(DateTimeItemInterface::STORAGE_TIMEZONE, $entity->field_datetime->date
            ->getTimeZone()
            ->getName());
        // Test DateTimeItem::setValue() using property array.
        $entity = EntityTest::create();
        $value = '2014-01-01T20:00:00';
        $entity->set('field_datetime', $value);
        $this->entityValidateAndSave($entity);
        // Load the entity and ensure the field was saved correctly.
        $id = $entity->id();
        $entity = EntityTest::load($id);
        $this->assertEquals($value, $entity->field_datetime[0]->value, 'DateTimeItem::setValue() works with array value.');
        $this->assertEquals(DateTimeItemInterface::STORAGE_TIMEZONE, $entity->field_datetime->date
            ->getTimeZone()
            ->getName());
        // Test a date-only field.
        $this->fieldStorage
            ->setSetting('datetime_type', DateTimeItem::DATETIME_TYPE_DATE);
        $this->fieldStorage
            ->save();
        // Test DateTimeItem::setValue() using string.
        $entity = EntityTest::create();
        $value = '2014-01-01';
        $entity->get('field_datetime')
            ->set(0, $value);
        $this->entityValidateAndSave($entity);
        // Load the entity and ensure the field was saved correctly.
        $id = $entity->id();
        $entity = EntityTest::load($id);
        $this->assertEquals($value, $entity->field_datetime[0]->value, 'DateTimeItem::setValue() works with string value.');
        $this->assertEquals(DateTimeItemInterface::STORAGE_TIMEZONE, $entity->field_datetime->date
            ->getTimeZone()
            ->getName());
        // Test DateTimeItem::setValue() using property array.
        $entity = EntityTest::create();
        $value = '2014-01-01';
        $entity->set('field_datetime', $value);
        $this->entityValidateAndSave($entity);
        // Load the entity and ensure the field was saved correctly.
        $id = $entity->id();
        $entity = EntityTest::load($id);
        $this->assertEquals($value, $entity->field_datetime[0]->value, 'DateTimeItem::setValue() works with array value.');
        $this->assertEquals(DateTimeItemInterface::STORAGE_TIMEZONE, $entity->field_datetime->date
            ->getTimeZone()
            ->getName());
    }
    
    /**
     * Tests setting the value of the DateTimeItem directly.
     */
    public function testSetValueProperty() : void {
        // Test Date::setValue() with a date+time field.
        // Test a date+time field.
        $this->fieldStorage
            ->setSetting('datetime_type', DateTimeItem::DATETIME_TYPE_DATETIME);
        $this->fieldStorage
            ->save();
        $entity = EntityTest::create();
        $value = '2014-01-01T20:00:00';
        $entity->set('field_datetime', $value);
        $this->entityValidateAndSave($entity);
        // Load the entity and ensure the field was saved correctly.
        $id = $entity->id();
        $entity = EntityTest::load($id);
        $this->assertEquals($value, $entity->field_datetime[0]->value, '"Value" property can be set directly.');
        $this->assertEquals(DateTimeItemInterface::STORAGE_TIMEZONE, $entity->field_datetime->date
            ->getTimeZone()
            ->getName());
        // Test Date::setValue() with a date-only field.
        // Test a date+time field.
        $this->fieldStorage
            ->setSetting('datetime_type', DateTimeItem::DATETIME_TYPE_DATE);
        $this->fieldStorage
            ->save();
        $entity = EntityTest::create();
        $value = '2014-01-01';
        $entity->set('field_datetime', $value);
        $this->entityValidateAndSave($entity);
        // Load the entity and ensure the field was saved correctly.
        $id = $entity->id();
        $entity = EntityTest::load($id);
        $this->assertEquals($value, $entity->field_datetime[0]->value, '"Value" property can be set directly.');
        $this->assertEquals(DateTimeItemInterface::STORAGE_TIMEZONE, $entity->field_datetime->date
            ->getTimeZone()
            ->getName());
    }
    
    /**
     * Tests the constraint validations for fields with date and time.
     *
     * @dataProvider datetimeValidationProvider
     */
    public function testDatetimeValidation($value) : void {
        $this->expectException(AssertionFailedError::class);
        $this->fieldStorage
            ->setSetting('datetime_type', DateTimeItem::DATETIME_TYPE_DATETIME);
        $this->fieldStorage
            ->save();
        $entity = EntityTest::create();
        $entity->set('field_datetime', $value);
        $this->entityValidateAndSave($entity);
    }
    
    /**
     * Provider for testDatetimeValidation().
     */
    public static function datetimeValidationProvider() {
        return [
            // Valid ISO 8601 dates, but unsupported by DateTimeItem.
[
                '2014-01-01T20:00:00Z',
            ],
            [
                '2014-01-01T20:00:00+04:00',
            ],
            [
                '2014-01-01T20:00:00+0400',
            ],
            [
                '2014-01-01T20:00:00+04',
            ],
            [
                '2014-01-01T20:00:00.123',
            ],
            [
                '2014-01-01T200000',
            ],
            [
                '2014-01-01T2000',
            ],
            [
                '2014-01-01T20',
            ],
            [
                '20140101T20:00:00',
            ],
            [
                '2014-01T20:00:00',
            ],
            [
                '2014-001T20:00:00',
            ],
            [
                '2014001T20:00:00',
            ],
            // Valid date strings, but unsupported by DateTimeItem.
[
                '2016-11-03 20:52:00',
            ],
            [
                'Thu, 03 Nov 2014 20:52:00 -0400',
            ],
            [
                'Thursday, November 3, 2016 - 20:52',
            ],
            [
                'Thu, 11/03/2016 - 20:52',
            ],
            [
                '11/03/2016 - 20:52',
            ],
            // Invalid date strings.
[
                'YYYY-01-01T20:00:00',
            ],
            [
                '2014-MM-01T20:00:00',
            ],
            [
                '2014-01-DDT20:00:00',
            ],
            [
                '2014-01-01Thh:00:00',
            ],
            [
                '2014-01-01T20:mm:00',
            ],
            [
                '2014-01-01T20:00:ss',
            ],
            // Invalid dates.
[
                '2014-13-13T20:00:00',
            ],
            [
                '2014-01-55T20:00:00',
            ],
            [
                '2014-01-01T25:00:00',
            ],
            [
                '2014-01-01T00:70:00',
            ],
            [
                '2014-01-01T00:00:70',
            ],
            // Proper format for different field setting.
[
                '2014-01-01',
            ],
            // Wrong input type.
[
                [
                    '2014',
                    '01',
                    '01',
                    '00',
                    '00',
                    '00',
                ],
            ],
        ];
    }
    
    /**
     * Tests the constraint validations for fields with date only.
     *
     * @dataProvider dateOnlyValidationProvider
     */
    public function testDateOnlyValidation($value) : void {
        $this->expectException(AssertionFailedError::class);
        $this->fieldStorage
            ->setSetting('datetime_type', DateTimeItem::DATETIME_TYPE_DATE);
        $this->fieldStorage
            ->save();
        $entity = EntityTest::create();
        $entity->set('field_datetime', $value);
        $this->entityValidateAndSave($entity);
    }
    
    /**
     * Provider for testDatetimeValidation().
     */
    public static function dateOnlyValidationProvider() {
        return [
            // Valid date strings, but unsupported by DateTimeItem.
[
                'Thu, 03 Nov 2014',
            ],
            [
                'Thursday, November 3, 2016',
            ],
            [
                'Thu, 11/03/2016',
            ],
            [
                '11/03/2016',
            ],
            // Invalid date strings.
[
                'YYYY-01-01',
            ],
            [
                '2014-MM-01',
            ],
            [
                '2014-01-DD',
            ],
            // Invalid dates.
[
                '2014-13-01',
            ],
            [
                '2014-01-55',
            ],
            // Proper format for different field setting.
[
                '2014-01-01T20:00:00',
            ],
            // Wrong input type.
[
                [
                    '2014',
                    '01',
                    '01',
                ],
            ],
        ];
    }

}

Classes

Title Deprecated Summary
DateTimeItemTest Tests the new entity API for the date field type.

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