DatetimeFormElementTest.php

Namespace

Drupal\KernelTests\Core\Datetime\Element

File

core/tests/Drupal/KernelTests/Core/Datetime/Element/DatetimeFormElementTest.php

View source
<?php

declare (strict_types=1);
namespace Drupal\KernelTests\Core\Datetime\Element;

use Drupal\Core\Datetime\DrupalDateTime;
use Drupal\Core\Datetime\Element\Datetime;
use Drupal\Core\Form\FormInterface;
use Drupal\Core\Form\FormState;
use Drupal\Core\Form\FormStateInterface;
use Drupal\KernelTests\Core\Entity\EntityKernelTestBase;
use Drupal\Tests\EntityViewTrait;
use PHPUnit\Framework\Attributes\CoversClass;
use PHPUnit\Framework\Attributes\Group;
use PHPUnit\Framework\Attributes\RunTestsInSeparateProcesses;

/**
 * Tests static callbacks returns and form submission with datetime elements.
 */
class DatetimeFormElementTest extends EntityKernelTestBase implements FormInterface {
  use EntityViewTrait;
  
  /**
   * Form builder service.
   *
   * @var \Drupal\Core\Form\FormBuilder
   */
  protected $formBuilder;
  
  /**
   * {@inheritdoc}
   */
  public function setUp() : void {
    parent::setUp();
    $this->installEntitySchema('date_format');
    $this->installConfig([
      'system',
    ]);
    $this->formBuilder = $this->container
      ->get('form_builder');
  }
  
  /**
   * {@inheritdoc}
   */
  public function getFormId() : string {
    return 'datetime_form_element_test';
  }
  
  /**
   * {@inheritdoc}
   */
  public function buildForm(array $form, FormStateInterface $form_state) : array {
    // Test datetime-local element.
    $form['datetime_local_picker'] = [
      '#type' => 'datetime',
      '#date_date_element' => 'datetime-local',
      '#date_time_element' => 'none',
    ];
    // Test time-only element.
    $form['datetime_time_only'] = [
      '#type' => 'datetime',
      '#date_date_element' => 'none',
      '#date_time_element' => 'time',
      '#date_time_format' => 'H:i',
    ];
    $form['submit'] = [
      '#type' => 'submit',
      '#value' => 'Submit',
    ];
    return $form;
  }
  
  /**
   * {@inheritdoc}
   */
  public function submitForm(array &$form, FormStateInterface $form_state) : void {
  }
  
  /**
   * {@inheritdoc}
   */
  public function validateForm(array &$form, FormStateInterface $form_state) : void {
  }
  
  /**
   * Checks we have no errors on form submit.
   *
   * @legacy-covers ::validateDatetime
   */
  public function testNoErrorMetOnFormSubmit() : void {
    // No error expected when form elements have no value.
    $form_state = new FormState();
    $this->formBuilder
      ->submitForm($this, $form_state);
    $this->assertEmpty($form_state->getErrors());
    // No error expected when a datetime-local element has a valid value.
    $form_state = new FormState();
    $form_state->setValue('datetime_local_picker', [
      'date' => '2025-02-18T12:00',
    ]);
    $form_state->setValue('datetime_time_only', [
      'time' => '12:00',
    ]);
    $this->formBuilder
      ->submitForm($this, $form_state);
    $this->assertEmpty($form_state->getErrors());
  }
  
  /**
   * Checks expected values are returned by ::valueCallback().
   *
   * Test only applied to 'datetime-local' date element.
   *
   * @legacy-covers ::valueCallback
   */
  public function testDatetimeLocalValueCallback() : void {
    $element = [
      '#type' => 'datetime',
      '#date_date_element' => 'datetime-local',
      '#date_time_element' => 'none',
    ];
    $input = [
      'date' => '2025-02-18T12:00',
    ];
    $form_state = new FormState();
    $form_state->setValue('datetime_local_picker', [
      'date' => '2025-02-18T12:00',
    ]);
    $result = Datetime::valueCallback($element, $input, $form_state);
    $this->assertIsArray($result);
    $this->assertArrayHasKey('date', $result);
    $this->assertEquals('2025-02-18', $result['date']);
    $this->assertArrayHasKey('time', $result);
    $this->assertEquals('12:00:00', $result['time']);
    $this->assertArrayHasKey('object', $result);
    $this->assertNotEmpty($result['object']);
    $this->assertInstanceOf(DrupalDateTime::class, $result['object']);
  }
  
  /**
   * Checks expected values are returned by ::processDatetime().
   *
   * Test only applied to 'datetime-local' date element.
   *
   * @legacy-covers ::processDatetime
   */
  public function testDatetimeLocalProcessDatetime() : void {
    $form = [
      'datetime_local_picker' => [
        '#type' => 'datetime',
        '#date_date_element' => 'datetime-local',
        '#date_date_format' => 'Y-m-d',
        '#date_time_element' => 'none',
        '#date_time_format' => 'H:i:s',
        '#value' => [
          'object' => new DrupalDateTime('2025-02-18T12:00'),
          'date' => '2025-02-18',
          'time' => '12:00:00',
        ],
        '#date_year_range' => '1900:2050',
        '#attributes' => [],
        '#required' => TRUE,
      ],
      'submit' => [
        '#type' => 'submit',
        '#value' => 'Submit',
      ],
    ];
    $element = $form['datetime_local_picker'];
    $form_state = new FormState();
    $form_state->setValue('datetime_local_picker', [
      'date' => '2025-02-18T12:00',
    ]);
    $result = Datetime::processDatetime($element, $form_state, $form);
    $this->assertIsArray($result);
    $this->assertArrayHasKey('date', $result);
    $this->assertIsArray($result['date']);
    $this->assertArrayHasKey('#error_no_message', $result['date']);
    $this->assertTrue($result['date']['#error_no_message']);
    $this->assertArrayHasKey('#attributes', $result['date']);
    $this->assertArrayHasKey('min', $result['date']['#attributes']);
    $this->assertEquals('1900-01-01T00:00:00', $result['date']['#attributes']['min']);
    $this->assertArrayHasKey('max', $result['date']['#attributes']);
    $this->assertEquals('2050-12-31T23:59:59', $result['date']['#attributes']['max']);
    $this->assertArrayNotHasKey('time', $result);
  }
  
  /**
   * Checks expected values are returned by ::valueCallback().
   *
   * Test only applied to time-only datetime element.
   *
   * @legacy-covers ::valueCallback
   */
  public function testDatetimeTimeOnlyValueCallback() : void {
    $element = [
      '#type' => 'datetime',
      '#date_date_element' => 'none',
      '#date_time_element' => 'time',
      '#date_time_format' => 'H:i:s',
    ];
    $input = [
      'time' => '14:30:00',
    ];
    $form_state = new FormState();
    $form_state->setValue('datetime_time_only', [
      'time' => '14:30',
    ]);
    $result = Datetime::valueCallback($element, $input, $form_state);
    $this->assertIsArray($result);
    $this->assertArrayHasKey('time', $result);
    $this->assertEquals('14:30:00', $result['time']);
    $this->assertArrayHasKey('object', $result);
    $this->assertInstanceOf(DrupalDateTime::class, $result['object']);
    $this->assertEquals('14:30:00', $result['object']->format('H:i:s'));
  }

}

Classes

Title Deprecated Summary
DatetimeFormElementTest Tests static callbacks returns and form submission with datetime elements.

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