function DateRangeFieldTest::testDatelistWidget

Same name in other branches
  1. 9 core/modules/datetime_range/tests/src/Functional/DateRangeFieldTest.php \Drupal\Tests\datetime_range\Functional\DateRangeFieldTest::testDatelistWidget()
  2. 8.9.x core/modules/datetime_range/tests/src/Functional/DateRangeFieldTest.php \Drupal\Tests\datetime_range\Functional\DateRangeFieldTest::testDatelistWidget()
  3. 10 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 615

Class

DateRangeFieldTest
Tests Daterange field functionality.

Namespace

Drupal\Tests\datetime_range\Functional

Code

public function testDatelistWidget() : void {
    $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 (static::datelistDataProvider() as $data) {
        [
            $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());
}

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