3 namespace Drupal\Tests\system\Functional\System;
5 use Drupal\Core\Datetime\Entity\DateFormat;
7 use Drupal\Tests\BrowserTestBase;
10 * Configure date and time settings. Test date formatting and time zone
11 * handling, including daylight saving time.
15 class DateTimeTest extends BrowserTestBase {
22 public static $modules = ['block', 'node', 'language', 'field', 'field_ui', 'datetime', 'options'];
24 protected function setUp() {
27 // Create admin user and log in admin user.
28 $this->drupalLogin ($this->drupalCreateUser([
29 'administer site configuration',
30 'administer content types',
32 'administer node fields',
33 'administer node form display',
34 'administer node display',
36 $this->drupalPlaceBlock('local_actions_block');
40 * Test time zones and DST handling.
42 public function testTimeZoneHandling() {
43 // Setup date/time settings for Honolulu time.
44 $config = $this->config('system.date')
45 ->set('timezone.default', 'Pacific/Honolulu')
46 ->set('timezone.user.configurable', 0)
48 DateFormat::load('medium')
49 ->setPattern('Y-m-d H:i:s O')
52 // Create some nodes with different authored-on dates.
53 $date1 = '2007-01-31 21:00:00 -1000';
54 $date2 = '2007-07-31 21:00:00 -1000';
55 $this->drupalCreateContentType(['type' => 'article']);
56 $node1 = $this->drupalCreateNode(['created' => strtotime($date1), 'type' => 'article']);
57 $node2 = $this->drupalCreateNode(['created' => strtotime($date2), 'type' => 'article']);
59 // Confirm date format and time zone.
60 $this->drupalGet('node/' . $node1->id());
61 $this->assertText('2007-01-31 21:00:00 -1000', 'Date should be identical, with GMT offset of -10 hours.');
62 $this->drupalGet('node/' . $node2->id());
63 $this->assertText('2007-07-31 21:00:00 -1000', 'Date should be identical, with GMT offset of -10 hours.');
65 // Set time zone to Los Angeles time.
66 $config->set('timezone.default', 'America/Los_Angeles')->save();
67 \Drupal::entityManager()->getViewBuilder('node')->resetCache([$node1, $node2]);
69 // Confirm date format and time zone.
70 $this->drupalGet('node/' . $node1->id());
71 $this->assertText('2007-01-31 23:00:00 -0800', 'Date should be two hours ahead, with GMT offset of -8 hours.');
72 $this->drupalGet('node/' . $node2->id());
73 $this->assertText('2007-08-01 00:00:00 -0700', 'Date should be three hours ahead, with GMT offset of -7 hours.');
77 * Test date format configuration.
79 public function testDateFormatConfiguration() {
80 // Confirm 'no custom date formats available' message appears.
81 $this->drupalGet('admin/config/regional/date-time');
83 // Add custom date format.
84 $this->clickLink(t('Add format'));
85 $date_format_id = strtolower($this->randomMachineName(8));
86 $name = ucwords($date_format_id);
87 $date_format = 'd.m.Y - H:i';
89 'id' => $date_format_id,
91 'date_format_pattern' => $date_format,
93 $this->drupalPostForm('admin/config/regional/date-time/formats/add', $edit, t('Add format'));
94 $this->assertUrl(\Drupal::url('entity.date_format.collection', [], ['absolute' => TRUE]), [], 'Correct page redirection.');
95 $this->assertText(t('Custom date format added.'), 'Date format added confirmation message appears.');
96 $this->assertText($name, 'Custom date format appears in the date format list.');
97 $this->assertText(t('Delete'), 'Delete link for custom date format appears.');
99 // Edit the custom date format and re-save without editing the format.
100 $this->drupalGet('admin/config/regional/date-time');
101 $this->clickLink(t('Edit'));
102 $this->drupalPostForm(NULL, NULL, t('Save format'));
103 $this->assertUrl('admin/config/regional/date-time', ['absolute' => TRUE], 'Correct page redirection.');
104 $this->assertText(t('Custom date format updated.'), 'Custom date format successfully updated.');
106 // Edit custom date format.
107 $this->drupalGet('admin/config/regional/date-time');
108 $this->clickLink(t('Edit'));
110 'date_format_pattern' => 'Y m',
112 $this->drupalPostForm($this->getUrl(), $edit, t('Save format'));
113 $this->assertUrl(\Drupal::url('entity.date_format.collection', [], ['absolute' => TRUE]), [], 'Correct page redirection.');
114 $this->assertText(t('Custom date format updated.'), 'Custom date format successfully updated.');
116 // Delete custom date format.
117 $this->clickLink(t('Delete'));
118 $this->drupalPostForm('admin/config/regional/date-time/formats/manage/' . $date_format_id . '/delete', [], t('Delete'));
119 $this->assertUrl(\Drupal::url('entity.date_format.collection', [], ['absolute' => TRUE]), [], 'Correct page redirection.');
120 $this->assertRaw(t('The date format %format has been deleted.', ['%format' => $name]), 'Custom date format removed.');
122 // Make sure the date does not exist in config.
123 $date_format = DateFormat::load($date_format_id);
124 $this->assertFalse($date_format);
126 // Add a new date format with an existing format.
127 $date_format_id = strtolower($this->randomMachineName(8));
128 $name = ucwords($date_format_id);
131 'id' => $date_format_id,
133 'date_format_pattern' => $date_format,
135 $this->drupalPostForm('admin/config/regional/date-time/formats/add', $edit, t('Add format'));
136 $this->assertUrl(\Drupal::url('entity.date_format.collection', [], ['absolute' => TRUE]), [], 'Correct page redirection.');
137 $this->assertText(t('Custom date format added.'), 'Date format added confirmation message appears.');
138 $this->assertText($name, 'Custom date format appears in the date format list.');
139 $this->assertText(t('Delete'), 'Delete link for custom date format appears.');
141 $date_format = DateFormat::create([
143 'label' => 'XSS format',
144 'pattern' => '\<\s\c\r\i\p\t\>\a\l\e\r\t\(\'\X\S\S\'\)\;\<\/\s\c\r\i\p\t\>',
146 $date_format->save();
148 $this->drupalGet(Url::fromRoute('entity.date_format.collection'));
149 $this->assertEscaped("<script>alert('XSS');</script>", 'The date format was properly escaped');
151 // Add a new date format with HTML in it.
152 $date_format_id = strtolower($this->randomMachineName(8));
153 $name = ucwords($date_format_id);
154 $date_format = '& \<\e\m\>Y\<\/\e\m\>';
156 'id' => $date_format_id,
158 'date_format_pattern' => $date_format,
160 $this->drupalPostForm('admin/config/regional/date-time/formats/add', $edit, t('Add format'));
161 $this->assertUrl(\Drupal::url('entity.date_format.collection', [], ['absolute' => TRUE]), [], 'Correct page redirection.');
162 $this->assertText(t('Custom date format added.'), 'Date format added confirmation message appears.');
163 $this->assertText($name, 'Custom date format appears in the date format list.');
164 $this->assertEscaped('<em>' . date("Y") . '</em>');
168 * Test handling case with invalid data in selectors (like February, 31st).
170 public function testEnteringDateTimeViaSelectors() {
172 $this->drupalCreateContentType(['type' => 'page_with_date', 'name' => 'Page with date']);
174 $this->drupalGet('admin/structure/types/manage/page_with_date');
175 $this->assertResponse(200, 'Content type created.');
177 $this->drupalGet('admin/structure/types/manage/page_with_date/fields/add-field');
179 'new_storage_type' => 'datetime',
181 'field_name' => 'dt',
183 $this->drupalPostForm('admin/structure/types/manage/page_with_date/fields/add-field', $edit, t('Save and continue'));
184 $this->assertText(t('These settings apply to the'), 'New datetime field created, now configuring');
186 $this->drupalGet('admin/structure/types/manage/page_with_date/fields/node.page_with_date.field_dt/storage');
188 'settings[datetime_type]' => 'datetime',
189 'cardinality' => 'number',
190 'cardinality_number' => '1',
192 $this->drupalPostForm('admin/structure/types/manage/page_with_date/fields/node.page_with_date.field_dt/storage', $edit, t('Save field settings'));
194 $this->drupalGet('admin/structure/types/manage/page_with_date/fields');
195 $this->assertText('field_dt', 'New field is in place');
197 $this->drupalGet('admin/structure/types/manage/page_with_date/form-display');
199 'fields[field_dt][type]' => 'datetime_datelist',
200 'fields[field_dt][region]' => 'content',
202 $this->drupalPostForm('admin/structure/types/manage/page_with_date/form-display', $edit, t('Save'));
203 $this->drupalLogout();
205 // Now log in as a regular editor.
206 $this->drupalLogin($this->drupalCreateUser(['create page_with_date content']));
208 $this->drupalGet('node/add/page_with_date');
210 'title[0][value]' => 'sample doc',
211 'field_dt[0][value][year]' => '2016',
212 'field_dt[0][value][month]' => '2',
213 'field_dt[0][value][day]' => '31',
214 'field_dt[0][value][hour]' => '1',
215 'field_dt[0][value][minute]' => '30',
217 $this->drupalPostForm('node/add/page_with_date', $edit, t('Save'));
218 $this->assertText(t('Selected combination of day and month is not valid.'), 'Inorrect date failed validation');
220 $edit['field_dt[0][value][day]'] = '29';
221 $this->drupalPostForm('node/add/page_with_date', $edit, t('Save'));
222 $this->assertNoText(t('Selected combination of day and month is not valid.'), 'Correct date passed validation.');
224 $this->drupalGet('node/1');
225 $this->assertText(t('Mon, 02/29/2016 - 01:30'), 'Node successfully created with valid date.');