diff --git a/core/modules/datetime/config/schema/datetime.schema.yml b/core/modules/datetime/config/schema/datetime.schema.yml index e627ce0..200751a 100644 --- a/core/modules/datetime/config/schema/datetime.schema.yml +++ b/core/modules/datetime/config/schema/datetime.schema.yml @@ -104,12 +104,18 @@ field.value.daterange: type: mapping label: 'Default value' mapping: - default_date_type: + default_start_date_type: type: string - label: 'Default date type' - default_date: + label: 'Default start date type' + default_start_date: type: string - label: 'Default date value' + label: 'Default start date value' + default_end_date_type: + type: string + label: 'Default end date type' + default_end_date: + type: string + label: 'Default end date value' field.formatter.settings.daterange_base: type: mapping diff --git a/core/modules/datetime/src/Plugin/Field/FieldType/DateRangeFieldItemList.php b/core/modules/datetime/src/Plugin/Field/FieldType/DateRangeFieldItemList.php index 2c1409d..d6dbf7d 100644 --- a/core/modules/datetime/src/Plugin/Field/FieldType/DateRangeFieldItemList.php +++ b/core/modules/datetime/src/Plugin/Field/FieldType/DateRangeFieldItemList.php @@ -32,25 +32,47 @@ public function defaultValuesForm(array &$form, FormStateInterface $form_state) $element = [ '#parents' => ['default_value_input'], - 'default_date_type' => [ + 'default_start_date_type' => [ '#type' => 'select', - '#title' => t('Default dates'), - '#description' => t('Set a default value for these dates.'), - '#default_value' => isset($default_value[0]['default_date_type']) ? $default_value[0]['default_date_type'] : '', + '#title' => $this->t('Default start date'), + '#description' => $this->t('Set a default value for the start date.'), + '#default_value' => isset($default_value[0]['default_start_date_type']) ? $default_value[0]['default_start_date_type'] : '', '#options' => [ - static::DEFAULT_VALUE_NOW => t('Current date'), - static::DEFAULT_VALUE_CUSTOM => t('Relative date'), + static::DEFAULT_VALUE_NOW => $this->t('Current date'), + static::DEFAULT_VALUE_CUSTOM => $this->t('Relative date'), ], '#empty_value' => '', ], - 'default_date' => [ + 'default_start_date' => [ '#type' => 'textfield', - '#title' => t('Relative default value'), - '#description' => t("Describe a time by reference to the current day, like '+90 days' (90 days from the day the field is created) or '+1 Saturday' (the next Saturday). See strtotime for more details."), - '#default_value' => (isset($default_value[0]['default_date_type']) && $default_value[0]['default_date_type'] == static::DEFAULT_VALUE_CUSTOM) ? $default_value[0]['default_date'] : '', + '#title' => $this->t('Relative default value'), + '#description' => $this->t("Describe a time by reference to the current day, like '+90 days' (90 days from the day the field is created) or '+1 Saturday' (the next Saturday). See strtotime for more details."), + '#default_value' => (isset($default_value[0]['default_start_date_type']) && $default_value[0]['default_start_date_type'] == static::DEFAULT_VALUE_CUSTOM) ? $default_value[0]['default_start_date'] : '', '#states' => [ 'visible' => [ - ':input[id="edit-default-value-input-default-date-type"]' => ['value' => static::DEFAULT_VALUE_CUSTOM], + ':input[id="edit-default-value-input-default-start-date-type"]' => ['value' => static::DEFAULT_VALUE_CUSTOM], + ], + ], + ], + 'default_end_date_type' => [ + '#type' => 'select', + '#title' => $this->t('Default end date'), + '#description' => $this->t('Set a default value for the end date.'), + '#default_value' => isset($default_value[0]['default_end_date_type']) ? $default_value[0]['default_end_date_type'] : '', + '#options' => [ + static::DEFAULT_VALUE_NOW => $this->t('Current date'), + static::DEFAULT_VALUE_CUSTOM => $this->t('Relative date'), + ], + '#empty_value' => '', + ], + 'default_end_date' => [ + '#type' => 'textfield', + '#title' => $this->t('Relative default value'), + '#description' => $this->t("Describe a time by reference to the current day, like '+90 days' (90 days from the day the field is created) or '+1 Saturday' (the next Saturday). See strtotime for more details."), + '#default_value' => (isset($default_value[0]['default_end_date_type']) && $default_value[0]['default_end_date_type'] == static::DEFAULT_VALUE_CUSTOM) ? $default_value[0]['default_end_date'] : '', + '#states' => [ + 'visible' => [ + ':input[id="edit-default-value-input-default-end-date-type"]' => ['value' => static::DEFAULT_VALUE_CUSTOM], ], ], ], @@ -64,10 +86,17 @@ public function defaultValuesForm(array &$form, FormStateInterface $form_state) * {@inheritdoc} */ public function defaultValuesFormValidate(array $element, array &$form, FormStateInterface $form_state) { - if ($form_state->getValue(['default_value_input', 'default_date_type']) == static::DEFAULT_VALUE_CUSTOM) { - $is_strtotime = @strtotime($form_state->getValue(['default_value_input', 'default_date'])); + if ($form_state->getValue(['default_value_input', 'default_start_date_type']) == static::DEFAULT_VALUE_CUSTOM) { + $is_strtotime = @strtotime($form_state->getValue(['default_value_input', 'default_start_date'])); + if (!$is_strtotime) { + $form_state->setErrorByName('default_value_input][default_start_date', $this->t('The relative start date value entered is invalid.')); + } + } + + if ($form_state->getValue(['default_value_input', 'default_end_date_type']) == static::DEFAULT_VALUE_CUSTOM) { + $is_strtotime = @strtotime($form_state->getValue(['default_value_input', 'default_end_date'])); if (!$is_strtotime) { - $form_state->setErrorByName('default_value_input][default_date', t('The relative date value entered is invalid.')); + $form_state->setErrorByName('default_value_input][default_end_date', $this->t('The relative end date value entered is invalid.')); } } } @@ -76,9 +105,12 @@ public function defaultValuesFormValidate(array $element, array &$form, FormStat * {@inheritdoc} */ public function defaultValuesFormSubmit(array $element, array &$form, FormStateInterface $form_state) { - if ($form_state->getValue(['default_value_input', 'default_date_type'])) { - if ($form_state->getValue(['default_value_input', 'default_date_type']) == static::DEFAULT_VALUE_NOW) { - $form_state->setValueForElement($element['default_date'], static::DEFAULT_VALUE_NOW); + if ($form_state->getValue(['default_value_input', 'default_start_date_type']) && $form_state->getValue(['default_value_input', 'default_end_date_type'])) { + if ($form_state->getValue(['default_value_input', 'default_start_date_type']) == static::DEFAULT_VALUE_NOW) { + $form_state->setValueForElement($element['default_start_date'], static::DEFAULT_VALUE_NOW); + } + if ($form_state->getValue(['default_value_input', 'default_end_date_type']) == static::DEFAULT_VALUE_NOW) { + $form_state->setValueForElement($element['default_end_date'], static::DEFAULT_VALUE_NOW); } return [$form_state->getValue('default_value_input')]; } @@ -91,21 +123,23 @@ public function defaultValuesFormSubmit(array $element, array &$form, FormStateI public static function processDefaultValue($default_value, FieldableEntityInterface $entity, FieldDefinitionInterface $definition) { $default_value = parent::processDefaultValue($default_value, $entity, $definition); - if (isset($default_value[0]['default_date_type'])) { + if (isset($default_value[0]['default_start_date_type']) && isset($default_value[0]['default_end_date_type'])) { // A default value should be in the format and timezone used for date // storage. All-day ranges are stored the same as date+time ranges. - $date = new DrupalDateTime($default_value[0]['default_date'], DATETIME_STORAGE_TIMEZONE); $storage_format = $definition->getSetting('daterange_type') == DateRangeItem::DATERANGE_TYPE_DATE ? DATETIME_DATE_STORAGE_FORMAT : DATETIME_DATETIME_STORAGE_FORMAT; - $value = $date->format($storage_format); + $start_date = new DrupalDateTime($default_value[0]['default_start_date'], DATETIME_STORAGE_TIMEZONE); + $start_value = $start_date->format($storage_format); + $end_date = new DrupalDateTime($default_value[0]['default_end_date'], DATETIME_STORAGE_TIMEZONE); + $end_value = $end_date->format($storage_format); // We only provide a default value for the first item, as do all fields. // Otherwise, there is no way to clear out unwanted values on multiple // value fields. $default_value = [ [ - 'value' => $value, - 'start_date' => $date, - 'value2' => $value, - 'end_date' => $date, + 'value' => $start_value, + 'start_date' => $start_date, + 'value2' => $end_value, + 'end_date' => $end_date, ], ]; } diff --git a/core/modules/datetime/src/Tests/DateRangeFieldTest.php b/core/modules/datetime/src/Tests/DateRangeFieldTest.php index 5ef4c71..8266183 100644 --- a/core/modules/datetime/src/Tests/DateRangeFieldTest.php +++ b/core/modules/datetime/src/Tests/DateRangeFieldTest.php @@ -6,6 +6,8 @@ use Drupal\Component\Utility\Unicode; use Drupal\Core\Datetime\DrupalDateTime; use Drupal\Core\Entity\Entity\EntityViewDisplay; +use Drupal\datetime\Plugin\Field\FieldType\DateRangeItem; +use Drupal\entity_test\Entity\EntityTest; use Drupal\field\Entity\FieldConfig; use Drupal\field\Entity\FieldStorageConfig; use Drupal\node\Entity\Node; @@ -75,12 +77,12 @@ protected function setUp() { // Create a field with settings to validate. $field_name = Unicode::strtolower($this->randomMachineName()); - $this->fieldStorage = FieldStorageConfig::create(array( + $this->fieldStorage = FieldStorageConfig::create([ 'field_name' => $field_name, 'entity_type' => 'entity_test', 'type' => 'daterange', - 'settings' => array('daterange_type' => 'date'), - )); + 'settings' => array('daterange_type' => DateRangeItem::DATERANGE_TYPE_DATE), + ]); $this->fieldStorage->save(); $this->field = FieldConfig::create([ 'field_storage' => $this->fieldStorage, @@ -95,16 +97,16 @@ protected function setUp() { )) ->save(); - $this->defaultSettings = array( + $this->defaultSettings = [ 'separator' => '-', 'timezone_override' => '', - ); + ]; - $this->displayOptions = array( + $this->displayOptions = [ 'type' => 'daterange_default', 'label' => 'hidden', 'settings' => array('format_type' => 'medium') + $this->defaultSettings, - ); + ]; entity_get_display($this->field->getTargetEntityTypeId(), $this->field->getTargetBundle(), 'full') ->setComponent($field_name, $this->displayOptions) ->save(); @@ -125,6 +127,13 @@ function testDatetimeRangeField() { } /** + * Tests all-day field. + */ + function testAlldayRangeField() { + $this->fail('Write a real test.'); + } + + /** * Tests Date Range List Widget functionality. */ function testDatelistWidget() { @@ -135,21 +144,383 @@ function testDatelistWidget() { * Test default value functionality. */ function testDefaultValue() { - $this->fail('Write a real test.'); + // Create a test content type. + $this->drupalCreateContentType(['type' => 'date_content']); + + // Create a field storage with settings to validate. + $field_name = Unicode::strtolower($this->randomMachineName()); + $field_storage = FieldStorageConfig::create([ + 'field_name' => $field_name, + 'entity_type' => 'node', + 'type' => 'daterange', + 'settings' => ['daterange_type' => DateRangeItem::DATERANGE_TYPE_DATE], + ]); + $field_storage->save(); + + $field = FieldConfig::create([ + 'field_storage' => $field_storage, + 'bundle' => 'date_content', + ]); + $field->save(); + + // Set now as default_value. + $field_edit = [ + 'default_value_input[default_start_date_type]' => 'now', + 'default_value_input[default_end_date_type]' => 'now', + ]; + $this->drupalPostForm('admin/structure/types/manage/date_content/fields/node.date_content.' . $field_name, $field_edit, t('Save settings')); + + // Check that default value is selected in default value form. + $this->drupalGet('admin/structure/types/manage/date_content/fields/node.date_content.' . $field_name); + $this->assertOptionSelected('edit-default-value-input-default-start-date-type', 'now', 'The default start value is selected in instance settings page'); + $this->assertFieldByName('default_value_input[default_start_date]', '', 'The relative start default value is empty in instance settings page'); + $this->assertOptionSelected('edit-default-value-input-default-end-date-type', 'now', 'The default end value is selected in instance settings page'); + $this->assertFieldByName('default_value_input[default_end_date]', '', 'The relative end default value is empty in instance settings page'); + + // Check if default_date has been stored successfully. + $config_entity = $this->config('field.field.node.date_content.' . $field_name)->get(); + $this->assertEqual($config_entity['default_value'][0], [ + 'default_start_date_type' => 'now', + 'default_start_date' => 'now', + 'default_end_date_type' => 'now', + 'default_end_date' => 'now' + ], 'Default value has been stored successfully'); + + // Clear field cache in order to avoid stale cache values. + \Drupal::entityManager()->clearCachedFieldDefinitions(); + + // Create a new node to check that datetime field default value is today. + $new_node = Node::create(['type' => 'date_content']); + $expected_date = new DrupalDateTime('now', DATETIME_STORAGE_TIMEZONE); + $this->assertEqual($new_node->get($field_name)->offsetGet(0)->value, $expected_date->format(DATETIME_DATE_STORAGE_FORMAT)); + $this->assertEqual($new_node->get($field_name)->offsetGet(0)->value2, $expected_date->format(DATETIME_DATE_STORAGE_FORMAT)); + + // Set an invalid relative default_value to test validation. + $field_edit = [ + 'default_value_input[default_start_date_type]' => 'relative', + 'default_value_input[default_start_date]' => 'invalid date', + 'default_value_input[default_end_date_type]' => 'relative', + 'default_value_input[default_end_date]' => '+1 day', + ]; + $this->drupalPostForm('admin/structure/types/manage/date_content/fields/node.date_content.' . $field_name, $field_edit, t('Save settings')); + $this->assertText('The relative start date value entered is invalid.'); + + $field_edit = [ + 'default_value_input[default_start_date_type]' => 'relative', + 'default_value_input[default_start_date]' => '+1 day', + 'default_value_input[default_end_date_type]' => 'relative', + 'default_value_input[default_end_date]' => 'invalid date', + ]; + $this->drupalPostForm('admin/structure/types/manage/date_content/fields/node.date_content.' . $field_name, $field_edit, t('Save settings')); + $this->assertText('The relative end date value entered is invalid.'); + + // Set a relative default_value. + $field_edit = [ + 'default_value_input[default_start_date_type]' => 'relative', + 'default_value_input[default_start_date]' => '+45 days', + 'default_value_input[default_end_date_type]' => 'relative', + 'default_value_input[default_end_date]' => '+90 days', + ]; + $this->drupalPostForm('admin/structure/types/manage/date_content/fields/node.date_content.' . $field_name, $field_edit, t('Save settings')); + + // Check that default value is selected in default value form. + $this->drupalGet('admin/structure/types/manage/date_content/fields/node.date_content.' . $field_name); + $this->assertOptionSelected('edit-default-value-input-default-start-date-type', 'relative', 'The default start value is selected in instance settings page'); + $this->assertFieldByName('default_value_input[default_start_date]', '+45 days', 'The relative default start value is displayed in instance settings page'); + $this->assertOptionSelected('edit-default-value-input-default-end-date-type', 'relative', 'The default end value is selected in instance settings page'); + $this->assertFieldByName('default_value_input[default_end_date]', '+90 days', 'The relative default end value is displayed in instance settings page'); + + // Check if default_date has been stored successfully. + $config_entity = $this->config('field.field.node.date_content.' . $field_name)->get(); + $this->assertEqual($config_entity['default_value'][0], [ + 'default_start_date_type' => 'relative', + 'default_start_date' => '+45 days', + 'default_end_date_type' => 'relative', + 'default_end_date' => '+90 days', + ], 'Default value has been stored successfully'); + + // Clear field cache in order to avoid stale cache values. + \Drupal::entityManager()->clearCachedFieldDefinitions(); + + // Create a new node to check that datetime field default value is +90 days. + $new_node = Node::create(['type' => 'date_content']); + $expected_start_date = new DrupalDateTime('+45 days', DATETIME_STORAGE_TIMEZONE); + $expected_end_date = new DrupalDateTime('+90 days', DATETIME_STORAGE_TIMEZONE); + $this->assertEqual($new_node->get($field_name)->offsetGet(0)->value, $expected_start_date->format(DATETIME_DATE_STORAGE_FORMAT)); + $this->assertEqual($new_node->get($field_name)->offsetGet(0)->value2, $expected_end_date->format(DATETIME_DATE_STORAGE_FORMAT)); + + // Remove default value. + $field_edit = [ + 'default_value_input[default_start_date_type]' => '', + 'default_value_input[default_end_date_type]' => '', + ]; + $this->drupalPostForm('admin/structure/types/manage/date_content/fields/node.date_content.' . $field_name, $field_edit, t('Save settings')); + + // Check that default value is selected in default value form. + $this->drupalGet('admin/structure/types/manage/date_content/fields/node.date_content.' . $field_name); + $this->assertOptionSelected('edit-default-value-input-default-start-date-type', '', 'The default start value is selected in instance settings page'); + $this->assertFieldByName('default_value_input[default_start_date]', '', 'The relative default start value is empty in instance settings page'); + $this->assertOptionSelected('edit-default-value-input-default-end-date-type', '', 'The default end value is selected in instance settings page'); + $this->assertFieldByName('default_value_input[default_end_date]', '', 'The relative default end value is empty in instance settings page'); + + // Check if default_date has been stored successfully. + $config_entity = $this->config('field.field.node.date_content.' . $field_name)->get(); + $this->assertTrue(empty($config_entity['default_value']), 'Empty default value has been stored successfully'); + + // Clear field cache in order to avoid stale cache values. + \Drupal::entityManager()->clearCachedFieldDefinitions(); + + // Create a new node to check that datetime field default value is not set. + $new_node = Node::create(['type' => 'date_content']); + $this->assertNull($new_node->get($field_name)->value, 'Default value is not set'); } /** * Test that invalid values are caught and marked as invalid. */ function testInvalidField() { - $this->fail('Write a real test.'); + // Change the field to a datetime field. + $this->fieldStorage->setSetting('daterange_type', DateRangeItem::DATERANGE_TYPE_DATETIME); + $this->fieldStorage->save(); + $field_name = $this->fieldStorage->getName(); + + // Display creation form. + $this->drupalGet('entity_test/add'); + $this->assertFieldByName("{$field_name}[0][value][date]", '', 'Start date element found.'); + $this->assertFieldByName("{$field_name}[0][value][time]", '', 'Start time element found.'); + $this->assertFieldByName("{$field_name}[0][value2][date]", '', 'End date element found.'); + $this->assertFieldByName("{$field_name}[0][value2][time]", '', 'End time element found.'); + + // Submit invalid start dates and ensure they is not accepted. + $date_value = ''; + $edit = [ + "{$field_name}[0][value][date]" => $date_value, + "{$field_name}[0][value][time]" => '12:00:00', + "{$field_name}[0][value2][date]" => '2012-12-01', + "{$field_name}[0][value2][time]" => '12:00:00', + ]; + $this->drupalPostForm(NULL, $edit, t('Save')); + $this->assertText('date is invalid', 'Empty start date value has been caught.'); + + $date_value = 'aaaa-12-01'; + $edit = [ + "{$field_name}[0][value][date]" => $date_value, + "{$field_name}[0][value][time]" => '00:00:00', + "{$field_name}[0][value2][date]" => '2012-12-01', + "{$field_name}[0][value2][time]" => '12:00:00', + ]; + $this->drupalPostForm(NULL, $edit, t('Save')); + $this->assertText('date is invalid', format_string('Invalid start year value %date has been caught.', ['%date' => $date_value])); + + $date_value = '2012-75-01'; + $edit = [ + "{$field_name}[0][value][date]" => $date_value, + "{$field_name}[0][value][time]" => '00:00:00', + "{$field_name}[0][value2][date]" => '2012-12-01', + "{$field_name}[0][value2][time]" => '12:00:00', + ]; + $this->drupalPostForm(NULL, $edit, t('Save')); + $this->assertText('date is invalid', format_string('Invalid start month value %date has been caught.', ['%date' => $date_value])); + + $date_value = '2012-12-99'; + $edit = [ + "{$field_name}[0][value][date]" => $date_value, + "{$field_name}[0][value][time]" => '00:00:00', + "{$field_name}[0][value2][date]" => '2012-12-01', + "{$field_name}[0][value2][time]" => '12:00:00', + ]; + $this->drupalPostForm(NULL, $edit, t('Save')); + $this->assertText('date is invalid', format_string('Invalid start day value %date has been caught.', ['%date' => $date_value])); + + // Submit invalid start times and ensure they is not accepted. + $time_value = ''; + $edit = [ + "{$field_name}[0][value][date]" => '2012-12-01', + "{$field_name}[0][value][time]" => $time_value, + "{$field_name}[0][value2][date]" => '2012-12-01', + "{$field_name}[0][value2][time]" => '12:00:00', + ]; + $this->drupalPostForm(NULL, $edit, t('Save')); + $this->assertText('date is invalid', 'Empty start time value has been caught.'); + + $time_value = '49:00:00'; + $edit = [ + "{$field_name}[0][value][date]" => '2012-12-01', + "{$field_name}[0][value][time]" => $time_value, + "{$field_name}[0][value2][date]" => '2012-12-01', + "{$field_name}[0][value2][time]" => '12:00:00', + ]; + $this->drupalPostForm(NULL, $edit, t('Save')); + $this->assertText('date is invalid', format_string('Invalid start hour value %time has been caught.', ['%time' => $time_value])); + + $time_value = '12:99:00'; + $edit = [ + "{$field_name}[0][value][date]" => '2012-12-01', + "{$field_name}[0][value][time]" => $time_value, + "{$field_name}[0][value2][date]" => '2012-12-01', + "{$field_name}[0][value2][time]" => '12:00:00', + ]; + $this->drupalPostForm(NULL, $edit, t('Save')); + $this->assertText('date is invalid', format_string('Invalid start minute value %time has been caught.', ['%time' => $time_value])); + + $time_value = '12:15:99'; + $edit = [ + "{$field_name}[0][value][date]" => '2012-12-01', + "{$field_name}[0][value][time]" => $time_value, + "{$field_name}[0][value2][date]" => '2012-12-01', + "{$field_name}[0][value2][time]" => '12:00:00', + ]; + $this->drupalPostForm(NULL, $edit, t('Save')); + $this->assertText('date is invalid', format_string('Invalid start second value %time has been caught.', ['%time' => $time_value])); + + // Submit invalid end dates and ensure they is not accepted. + $date_value = ''; + $edit = [ + "{$field_name}[0][value][date]" => '2012-12-01', + "{$field_name}[0][value][time]" => '12:00:00', + "{$field_name}[0][value2][date]" => $date_value, + "{$field_name}[0][value2][time]" => '12:00:00', + ]; + $this->drupalPostForm(NULL, $edit, t('Save')); + $this->assertText('date is invalid', 'Empty end date value has been caught.'); + + $date_value = 'aaaa-12-01'; + $edit = [ + "{$field_name}[0][value][date]" => '2012-12-01', + "{$field_name}[0][value][time]" => '12:00:00', + "{$field_name}[0][value2][date]" => $date_value, + "{$field_name}[0][value2][time]" => '00:00:00', + ]; + $this->drupalPostForm(NULL, $edit, t('Save')); + $this->assertText('date is invalid', format_string('Invalid end year value %date has been caught.', ['%date' => $date_value])); + + $date_value = '2012-75-01'; + $edit = [ + "{$field_name}[0][value][date]" => '2012-12-01', + "{$field_name}[0][value][time]" => '12:00:00', + "{$field_name}[0][value2][date]" => $date_value, + "{$field_name}[0][value2][time]" => '00:00:00', + ]; + $this->drupalPostForm(NULL, $edit, t('Save')); + $this->assertText('date is invalid', format_string('Invalid end month value %date has been caught.', ['%date' => $date_value])); + + $date_value = '2012-12-99'; + $edit = [ + "{$field_name}[0][value][date]" => '2012-12-01', + "{$field_name}[0][value][time]" => '12:00:00', + "{$field_name}[0][value2][date]" => $date_value, + "{$field_name}[0][value2][time]" => '00:00:00', + ]; + $this->drupalPostForm(NULL, $edit, t('Save')); + $this->assertText('date is invalid', format_string('Invalid end day value %date has been caught.', ['%date' => $date_value])); + + // Submit invalid start times and ensure they is not accepted. + $time_value = ''; + $edit = [ + "{$field_name}[0][value][date]" => '2012-12-01', + "{$field_name}[0][value][time]" => '12:00:00', + "{$field_name}[0][value2][date]" => '2012-12-01', + "{$field_name}[0][value2][time]" => $time_value, + ]; + $this->drupalPostForm(NULL, $edit, t('Save')); + $this->assertText('date is invalid', 'Empty end time value has been caught.'); + + $time_value = '49:00:00'; + $edit = [ + "{$field_name}[0][value][date]" => '2012-12-01', + "{$field_name}[0][value][time]" => '12:00:00', + "{$field_name}[0][value2][date]" => '2012-12-01', + "{$field_name}[0][value2][time]" => $time_value, + ]; + $this->drupalPostForm(NULL, $edit, t('Save')); + $this->assertText('date is invalid', format_string('Invalid end hour value %time has been caught.', ['%time' => $time_value])); + + $time_value = '12:99:00'; + $edit = [ + "{$field_name}[0][value][date]" => '2012-12-01', + "{$field_name}[0][value][time]" => '12:00:00', + "{$field_name}[0][value2][date]" => '2012-12-01', + "{$field_name}[0][value2][time]" => $time_value, + ]; + $this->drupalPostForm(NULL, $edit, t('Save')); + $this->assertText('date is invalid', format_string('Invalid end minute value %time has been caught.', ['%time' => $time_value])); + + $time_value = '12:15:99'; + $edit = [ + "{$field_name}[0][value][date]" => '2012-12-01', + "{$field_name}[0][value][time]" => '12:00:00', + "{$field_name}[0][value2][date]" => '2012-12-01', + "{$field_name}[0][value2][time]" => $time_value, + ]; + $this->drupalPostForm(NULL, $edit, t('Save')); + $this->assertText('date is invalid', format_string('Invalid end second value %time has been caught.', ['%time' => $time_value])); } /** * Tests that 'Date' field storage setting form is disabled if field has data. */ public function testDateStorageSettings() { - $this->fail('Write a real test.'); + // Create a test content type. + $this->drupalCreateContentType(['type' => 'date_content']); + + // Create a field storage with settings to validate. + $field_name = Unicode::strtolower($this->randomMachineName()); + $field_storage = FieldStorageConfig::create([ + 'field_name' => $field_name, + 'entity_type' => 'node', + 'type' => 'daterange', + 'settings' => [ + 'daterange_type' => DateRangeItem::DATERANGE_TYPE_DATE, + ], + ]); + $field_storage->save(); + $field = FieldConfig::create([ + 'field_storage' => $field_storage, + 'field_name' => $field_name, + 'bundle' => 'date_content', + ]); + $field->save(); + + entity_get_form_display('node', 'date_content', 'default') + ->setComponent($field_name, [ + 'type' => 'datetime_default', + ]) + ->save(); + $edit = [ + 'title[0][value]' => $this->randomString(), + 'body[0][value]' => $this->randomString(), + $field_name . '[0][value][date]' => '2016-04-01', + $field_name . '[0][value2][date]' => '2016-04-02', + ]; + $this->drupalPostForm('node/add/date_content', $edit, t('Save')); + $this->drupalGet('admin/structure/types/manage/date_content/fields/node.date_content.' . $field_name . '/storage'); + $result = $this->xpath("//*[@id='edit-settings-daterange-type' and contains(@disabled, 'disabled')]"); + $this->assertEqual(count($result), 1, "Changing daterange setting is disabled."); + $this->assertText('There is data for this field in the database. The field settings can no longer be changed.'); + } + + + /** + * Renders a entity_test and sets the output in the internal browser. + * + * @param int $id + * The entity_test ID to render. + * @param string $view_mode + * (optional) The view mode to use for rendering. Defaults to 'full'. + * @param bool $reset + * (optional) Whether to reset the entity_test controller cache. Defaults to + * TRUE to simplify testing. + */ + protected function renderTestEntity($id, $view_mode = 'full', $reset = TRUE) { + if ($reset) { + \Drupal::service('entity_type.manager')->getStorage('entity_test')->resetCache([$id]); + } + $entity = EntityTest::load($id); + $display = EntityViewDisplay::collectRenderDisplay($entity, $view_mode); + $build = $display->build($entity); + $output = \Drupal::service('renderer')->renderRoot($build); + $this->setRawContent($output); + $this->verbose($output); } }