[TASK] Streamline phpdoc annotations in EXT:extbase
[Packages/TYPO3.CMS.git] / typo3 / sysext / extbase / Tests / Unit / Property / TypeConverter / DateTimeConverterTest.php
1 <?php
2 namespace TYPO3\CMS\Extbase\Tests\Unit\Property\TypeConverter;
3
4 /*
5 * This file is part of the TYPO3 CMS project.
6 *
7 * It is free software; you can redistribute it and/or modify it under
8 * the terms of the GNU General Public License, either version 2
9 * of the License, or any later version.
10 *
11 * For the full copyright and license information, please read the
12 * LICENSE.txt file that was distributed with this source code.
13 *
14 * The TYPO3 project - inspiring people to share!
15 */
16
17 use TYPO3\CMS\Extbase\Property\Exception\TypeConverterException;
18 use TYPO3\CMS\Extbase\Tests\Unit\Property\TypeConverter\Fixtures\DateTimeSubFixture;
19 use TYPO3\TestingFramework\Core\Unit\UnitTestCase;
20
21 /**
22 * Test case
23 */
24 class DateTimeConverterTest extends UnitTestCase
25 {
26 /**
27 * @var \TYPO3\CMS\Extbase\Property\TypeConverter\DateTimeConverter
28 */
29 protected $converter;
30
31 protected function setUp()
32 {
33 $this->converter = new \TYPO3\CMS\Extbase\Property\TypeConverter\DateTimeConverter();
34 }
35
36 /**
37 * @test
38 */
39 public function checkMetadata()
40 {
41 $this->assertEquals(['string', 'integer', 'array'], $this->converter->getSupportedSourceTypes(), 'Source types do not match');
42 $this->assertEquals('DateTime', $this->converter->getSupportedTargetType(), 'Target type does not match');
43 $this->assertEquals(10, $this->converter->getPriority(), 'Priority does not match');
44 }
45
46 /** String to DateTime testcases **/
47
48 /**
49 * @test
50 */
51 public function canConvertFromReturnsFalseIfTargetTypeIsNotDateTime()
52 {
53 $this->assertFalse($this->converter->canConvertFrom('Foo', 'SomeOtherType'));
54 }
55
56 /**
57 * @test
58 */
59 public function canConvertFromReturnsTrueIfSourceTypeIsAString()
60 {
61 $this->assertTrue($this->converter->canConvertFrom('Foo', 'DateTime'));
62 }
63
64 /**
65 * @test
66 */
67 public function canConvertFromReturnsTrueIfSourceTypeIsAnEmptyString()
68 {
69 $this->assertTrue($this->converter->canConvertFrom('', 'DateTime'));
70 }
71
72 /**
73 * @test
74 */
75 public function convertFromReturnsErrorIfGivenStringCantBeConverted()
76 {
77 $error = $this->converter->convertFrom('1980-12-13', 'DateTime');
78 $this->assertInstanceOf(\TYPO3\CMS\Extbase\Error\Error::class, $error);
79 }
80
81 /**
82 * @test
83 */
84 public function convertFromProperlyConvertsStringWithDefaultDateFormat()
85 {
86 $expectedResult = '1980-12-13T20:15:07+01:23';
87 $date = $this->converter->convertFrom($expectedResult, 'DateTime');
88 $actualResult = $date->format('Y-m-d\\TH:i:sP');
89 $this->assertSame($expectedResult, $actualResult);
90 }
91
92 /**
93 * @test
94 */
95 public function convertFromUsesDefaultDateFormatIfItIsNotConfigured()
96 {
97 $expectedResult = '1980-12-13T20:15:07+01:23';
98 $mockMappingConfiguration = $this->createMock(\TYPO3\CMS\Extbase\Property\PropertyMappingConfigurationInterface::class);
99 $mockMappingConfiguration
100 ->expects($this->atLeastOnce())
101 ->method('getConfigurationValue')
102 ->with(\TYPO3\CMS\Extbase\Property\TypeConverter\DateTimeConverter::class, \TYPO3\CMS\Extbase\Property\TypeConverter\DateTimeConverter::CONFIGURATION_DATE_FORMAT)
103 ->will($this->returnValue(null));
104
105 $date = $this->converter->convertFrom($expectedResult, 'DateTime', [], $mockMappingConfiguration);
106 $actualResult = $date->format(\TYPO3\CMS\Extbase\Property\TypeConverter\DateTimeConverter::DEFAULT_DATE_FORMAT);
107 $this->assertSame($expectedResult, $actualResult);
108 }
109
110 /**
111 * @test
112 */
113 public function convertFromEmptyStringReturnsNull()
114 {
115 $date = $this->converter->convertFrom('', 'DateTime', [], null);
116 $this->assertNull($date);
117 }
118
119 /**
120 * @return array
121 * @see convertFromStringTests()
122 */
123 public function convertFromStringDataProvider()
124 {
125 return [
126 ['1308174051', '', false],
127 ['13-12-1980', 'd.m.Y', false],
128 ['1308174051', 'Y-m-d', false],
129 ['12:13', 'H:i', true],
130 ['13.12.1980', 'd.m.Y', true],
131 ['2005-08-15T15:52:01+00:00', null, true],
132 ['2005-08-15T15:52:01+00:00', \DateTime::ATOM, true],
133 ['1308174051', 'U', true],
134 ];
135 }
136
137 /**
138 * @param string $source the string to be converted
139 * @param string $dateFormat the expected date format
140 * @param bool $isValid TRUE if the conversion is expected to be successful, otherwise FALSE
141 * @test
142 * @dataProvider convertFromStringDataProvider
143 */
144 public function convertFromStringTests($source, $dateFormat, $isValid)
145 {
146 if ($dateFormat !== null) {
147 $mockMappingConfiguration = $this->createMock(\TYPO3\CMS\Extbase\Property\PropertyMappingConfigurationInterface::class);
148 $mockMappingConfiguration
149 ->expects($this->atLeastOnce())
150 ->method('getConfigurationValue')
151 ->with(\TYPO3\CMS\Extbase\Property\TypeConverter\DateTimeConverter::class, \TYPO3\CMS\Extbase\Property\TypeConverter\DateTimeConverter::CONFIGURATION_DATE_FORMAT)
152 ->will($this->returnValue($dateFormat));
153 } else {
154 $mockMappingConfiguration = null;
155 }
156 $date = $this->converter->convertFrom($source, 'DateTime', [], $mockMappingConfiguration);
157 if ($isValid !== true) {
158 $this->assertInstanceOf(\TYPO3\CMS\Extbase\Error\Error::class, $date);
159 return;
160 }
161 $this->assertInstanceOf('DateTime', $date);
162
163 if ($dateFormat === null) {
164 $dateFormat = \TYPO3\CMS\Extbase\Property\TypeConverter\DateTimeConverter::DEFAULT_DATE_FORMAT;
165 }
166 $this->assertSame($source, $date->format($dateFormat));
167 }
168
169 /**
170 * @return array
171 * @see convertFromIntegerOrDigitStringWithoutConfigurationTests()
172 * @see convertFromIntegerOrDigitStringInArrayWithoutConfigurationTests()
173 */
174 public function convertFromIntegerOrDigitStringsWithoutConfigurationDataProvider()
175 {
176 return [
177 ['1308174051'],
178 [1308174051],
179 ];
180 }
181
182 /**
183 * @test
184 * @param $source
185 * @dataProvider convertFromIntegerOrDigitStringsWithoutConfigurationDataProvider
186 */
187 public function convertFromIntegerOrDigitStringWithoutConfigurationTests($source)
188 {
189 $date = $this->converter->convertFrom($source, 'DateTime', [], null);
190 $this->assertInstanceOf('DateTime', $date);
191 $this->assertSame(strval($source), $date->format('U'));
192 }
193
194 /** Array to DateTime testcases **/
195
196 /**
197 * @test
198 * @param $source
199 * @dataProvider convertFromIntegerOrDigitStringsWithoutConfigurationDataProvider
200 */
201 public function convertFromIntegerOrDigitStringInArrayWithoutConfigurationTests($source)
202 {
203 $date = $this->converter->convertFrom(['date' => $source], 'DateTime', [], null);
204 $this->assertInstanceOf('DateTime', $date);
205 $this->assertSame(strval($source), $date->format('U'));
206 }
207
208 /**
209 * @test
210 */
211 public function canConvertFromReturnsTrueIfSourceTypeIsAnArray()
212 {
213 $this->assertTrue($this->converter->canConvertFrom([], 'DateTime'));
214 }
215
216 /**
217 * @test
218 */
219 public function convertFromReturnsErrorIfGivenArrayCantBeConverted()
220 {
221 $error = $this->converter->convertFrom(['date' => '1980-12-13'], 'DateTime');
222 $this->assertInstanceOf(\TYPO3\CMS\Extbase\Error\Error::class, $error);
223 }
224
225 /**
226 * @test
227 */
228 public function convertFromThrowsExceptionIfGivenArrayDoesNotSpecifyTheDate()
229 {
230 $this->expectException(TypeConverterException::class);
231 $this->expectExceptionCode(1308003914);
232 $this->converter->convertFrom(['hour' => '12', 'minute' => '30'], 'DateTime');
233 }
234
235 /**
236 * @test
237 */
238 public function convertFromProperlyConvertsArrayWithDefaultDateFormat()
239 {
240 $expectedResult = '1980-12-13T20:15:07+01:23';
241 $date = $this->converter->convertFrom(['date' => $expectedResult], 'DateTime');
242 $actualResult = $date->format('Y-m-d\\TH:i:sP');
243 $this->assertSame($expectedResult, $actualResult);
244 }
245
246 /**
247 * @return array
248 * @see convertFromThrowsExceptionIfDatePartKeysHaveInvalidValuesSpecified
249 */
250 public function invalidDatePartKeyValuesDataProvider()
251 {
252 return [
253 [['day' => '13.0', 'month' => '10', 'year' => '2010']],
254 [['day' => '13', 'month' => '10.0', 'year' => '2010']],
255 [['day' => '13', 'month' => '10', 'year' => '2010.0']],
256 [['day' => '-13', 'month' => '10', 'year' => '2010']],
257 [['day' => '13', 'month' => '-10', 'year' => '2010']],
258 [['day' => '13', 'month' => '10', 'year' => '-2010']],
259 ];
260 }
261
262 /**
263 * @test
264 * @dataProvider invalidDatePartKeyValuesDataProvider
265 */
266 public function convertFromThrowsExceptionIfDatePartKeysHaveInvalidValuesSpecified($source)
267 {
268 $this->expectException(TypeConverterException::class);
269 $this->expectExceptionCode(1308003914);
270 $this->converter->convertFrom($source, 'DateTime');
271 }
272
273 /**
274 * @test
275 */
276 public function convertFromProperlyConvertsArrayWithDateAsArray()
277 {
278 $source = ['day' => '13', 'month' => '10', 'year' => '2010'];
279 $mappingConfiguration = new \TYPO3\CMS\Extbase\Property\PropertyMappingConfiguration();
280 $mappingConfiguration->setTypeConverterOption(
281 \TYPO3\CMS\Extbase\Property\TypeConverter\DateTimeConverter::class,
282 \TYPO3\CMS\Extbase\Property\TypeConverter\DateTimeConverter::CONFIGURATION_DATE_FORMAT,
283 'Y-m-d'
284 );
285
286 $date = $this->converter->convertFrom($source, 'DateTime', [], $mappingConfiguration);
287 $actualResult = $date->format('Y-m-d');
288 $this->assertSame('2010-10-13', $actualResult);
289 }
290
291 /**
292 * @test
293 */
294 public function convertFromAllowsToOverrideTheTime()
295 {
296 $source = [
297 'date' => '2011-06-16',
298 'dateFormat' => 'Y-m-d',
299 'hour' => '12',
300 'minute' => '30',
301 'second' => '59',
302 ];
303 $date = $this->converter->convertFrom($source, 'DateTime');
304 $this->assertSame('2011-06-16', $date->format('Y-m-d'));
305 $this->assertSame('12', $date->format('H'));
306 $this->assertSame('30', $date->format('i'));
307 $this->assertSame('59', $date->format('s'));
308 }
309
310 /**
311 * @test
312 */
313 public function convertFromAllowsToOverrideTheTimezone()
314 {
315 $source = [
316 'date' => '2011-06-16 12:30:59',
317 'dateFormat' => 'Y-m-d H:i:s',
318 'timezone' => 'Atlantic/Reykjavik',
319 ];
320 $date = $this->converter->convertFrom($source, 'DateTime');
321 $this->assertSame('2011-06-16', $date->format('Y-m-d'));
322 $this->assertSame('12', $date->format('H'));
323 $this->assertSame('30', $date->format('i'));
324 $this->assertSame('59', $date->format('s'));
325 $this->assertSame('Atlantic/Reykjavik', $date->getTimezone()->getName());
326 }
327
328 /**
329 * @test
330 */
331 public function convertFromThrowsExceptionIfSpecifiedTimezoneIsInvalid()
332 {
333 $this->expectException(TypeConverterException::class);
334 $this->expectExceptionCode(1308240974);
335 $source = [
336 'date' => '2011-06-16',
337 'dateFormat' => 'Y-m-d',
338 'timezone' => 'Invalid/Timezone',
339 ];
340 $this->converter->convertFrom($source, 'DateTime');
341 }
342
343 /**
344 * @test
345 */
346 public function convertFromArrayThrowsExceptionForEmptyArray()
347 {
348 $this->expectException(TypeConverterException::class);
349 $this->expectExceptionCode(1308003914);
350 $this->converter->convertFrom([], 'DateTime', [], null);
351 }
352
353 /**
354 * @test
355 */
356 public function convertFromArrayReturnsNullForEmptyDate()
357 {
358 $this->assertNull($this->converter->convertFrom(['date' => ''], 'DateTime', [], null));
359 }
360
361 /**
362 * @return array
363 * @see convertFromArrayTests()
364 */
365 public function convertFromArrayDataProvider()
366 {
367 return [
368 [['date' => '2005-08-15T15:52:01+01:00'], true],
369 [['date' => '1308174051', 'dateFormat' => ''], false],
370 [['date' => '13-12-1980', 'dateFormat' => 'd.m.Y'], false],
371 [['date' => '1308174051', 'dateFormat' => 'Y-m-d'], false],
372 [['date' => '12:13', 'dateFormat' => 'H:i'], true],
373 [['date' => '13.12.1980', 'dateFormat' => 'd.m.Y'], true],
374 [['date' => '2005-08-15T15:52:01+00:00', 'dateFormat' => ''], true],
375 [['date' => '2005-08-15T15:52:01+00:00', 'dateFormat' => \DateTime::ATOM], true],
376 [['date' => '1308174051', 'dateFormat' => 'U'], true],
377 [['date' => 1308174051, 'dateFormat' => 'U'], true],
378 ];
379 }
380
381 /**
382 * @param array $source the array to be converted
383 * @param bool $isValid TRUE if the conversion is expected to be successful, otherwise FALSE
384 * @test
385 * @dataProvider convertFromArrayDataProvider
386 */
387 public function convertFromArrayTests(array $source, $isValid)
388 {
389 $dateFormat = isset($source['dateFormat']) && $source['dateFormat'] !== '' ? $source['dateFormat'] : null;
390 if ($dateFormat !== null) {
391 $mockMappingConfiguration = $this->createMock(\TYPO3\CMS\Extbase\Property\PropertyMappingConfigurationInterface::class);
392 $mockMappingConfiguration
393 ->expects($this->atLeastOnce())
394 ->method('getConfigurationValue')
395 ->with(\TYPO3\CMS\Extbase\Property\TypeConverter\DateTimeConverter::class, \TYPO3\CMS\Extbase\Property\TypeConverter\DateTimeConverter::CONFIGURATION_DATE_FORMAT)
396 ->will($this->returnValue($dateFormat));
397 } else {
398 $mockMappingConfiguration = null;
399 }
400 $date = $this->converter->convertFrom($source, 'DateTime', [], $mockMappingConfiguration);
401
402 if ($isValid !== true) {
403 $this->assertInstanceOf(\TYPO3\CMS\Extbase\Error\Error::class, $date);
404 return;
405 }
406
407 $this->assertInstanceOf('DateTime', $date);
408 if ($dateFormat === null) {
409 $dateFormat = \TYPO3\CMS\Extbase\Property\TypeConverter\DateTimeConverter::DEFAULT_DATE_FORMAT;
410 }
411 $dateAsString = isset($source['date']) ? strval($source['date']) : '';
412 $this->assertSame($dateAsString, $date->format($dateFormat));
413 }
414
415 /**
416 * @test
417 */
418 public function convertFromSupportsDateTimeSubClasses()
419 {
420 $className = DateTimeSubFixture::class;
421 $date = $this->converter->convertFrom('2005-08-15T15:52:01+00:00', $className);
422
423 $this->assertInstanceOf($className, $date);
424 $this->assertSame('Bar', $date->foo());
425 }
426 }