[BUGFIX] Correctly treat relative date specification in date-VH
[Packages/TYPO3.CMS.git] / typo3 / sysext / fluid / Tests / Unit / ViewHelpers / Format / DateViewHelperTest.php
1 <?php
2 namespace TYPO3\CMS\Fluid\Tests\Unit\ViewHelpers\Format;
3
4 /* *
5 * This script is backported from the TYPO3 Flow package "TYPO3.Fluid". *
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 3 of the *
9 * License, or (at your option) any later version. *
10 * *
11 * The TYPO3 project - inspiring people to share! *
12 * */
13 use TYPO3\CMS\Core\Tests\UnitTestCase;
14 use TYPO3\CMS\Fluid\Core\Rendering\RenderingContext;
15 use TYPO3\CMS\Fluid\ViewHelpers\Format\DateViewHelper;
16
17 /**
18 * Test case
19 */
20 class DateViewHelperTest extends UnitTestCase {
21
22 /**
23 * @var array Backup of current locale, it is manipulated in tests
24 */
25 protected $backupLocales = array();
26
27 /**
28 * @var DateViewHelper|\PHPUnit_Framework_MockObject_MockObject|\TYPO3\CMS\Core\Tests\AccessibleObjectInterface
29 */
30 protected $subject;
31
32 /**
33 * @var string Backup of current timezone, it is manipulated in tests
34 */
35 protected $timezone;
36
37 protected function setUp() {
38 parent::setUp();
39 // Store all locale categories manipulated in tests for reconstruction in tearDown
40 $this->backupLocales = array(
41 'LC_COLLATE' => setlocale(LC_COLLATE, 0),
42 'LC_CTYPE' => setlocale(LC_CTYPE, 0),
43 'LC_MONETARY' => setlocale(LC_MONETARY, 0),
44 'LC_TIME' => setlocale(LC_TIME, 0),
45 );
46 $this->timezone = @date_default_timezone_get();
47 $GLOBALS['TYPO3_CONF_VARS']['SYS']['ddmmyy'] = 'Y-m-d';
48 $this->subject = $this->getAccessibleMock(DateViewHelper::class, array('renderChildren'));
49 /** @var RenderingContext $renderingContext */
50 $renderingContext = $this->getMock(RenderingContext::class);
51 $this->subject->_set('renderingContext', $renderingContext);
52 }
53
54 protected function tearDown() {
55 foreach ($this->backupLocales as $category => $locale) {
56 setlocale(constant($category), $locale);
57 }
58 date_default_timezone_set($this->timezone);
59 parent::tearDown();
60 }
61
62 /**
63 * @test
64 */
65 public function viewHelperFormatsDateCorrectly() {
66 $actualResult = $this->subject->render(new \DateTime('1980-12-13'));
67 $this->assertEquals('1980-12-13', $actualResult);
68 }
69
70 /**
71 * @test
72 */
73 public function viewHelperFormatsDateStringCorrectly() {
74 $actualResult = $this->subject->render('1980-12-13');
75 $this->assertEquals('1980-12-13', $actualResult);
76 }
77
78 /**
79 * @test
80 */
81 public function viewHelperRespectsCustomFormat() {
82 $actualResult = $this->subject->render(new \DateTime('1980-02-01'), 'd.m.Y');
83 $this->assertEquals('01.02.1980', $actualResult);
84 }
85
86 /**
87 * @test
88 */
89 public function viewHelperReturnsEmptyStringIfNULLIsGiven() {
90 $this->subject->expects($this->once())->method('renderChildren')->will($this->returnValue(NULL));
91 $actualResult = $this->subject->render();
92 $this->assertEquals('', $actualResult);
93 }
94
95 /**
96 * @test
97 */
98 public function viewHelperUsesDefaultIfNoSystemFormatIsAvailable() {
99 $GLOBALS['TYPO3_CONF_VARS']['SYS']['ddmmyy'] = '';
100 $actualResult = $this->subject->render('@1391876733');
101 $this->assertEquals('2014-02-08', $actualResult);
102 }
103
104 /**
105 * @test
106 */
107 public function viewHelperUsesSystemFormat() {
108 $GLOBALS['TYPO3_CONF_VARS']['SYS']['ddmmyy'] = 'l, j. M y';
109 $actualResult = $this->subject->render('@1391876733');
110 $this->assertEquals('Saturday, 8. Feb 14', $actualResult);
111 }
112
113 /**
114 * @test
115 * @expectedException \TYPO3\CMS\Fluid\Core\ViewHelper\Exception
116 */
117 public function viewHelperThrowsExceptionIfDateStringCantBeParsed() {
118 $this->subject->render('foo');
119 }
120
121 /**
122 * @test
123 */
124 public function viewHelperUsesChildNodesIfDateAttributeIsNotSpecified() {
125 $this->subject->expects($this->once())->method('renderChildren')->will($this->returnValue(new \DateTime('1980-12-13')));
126 $actualResult = $this->subject->render();
127 $this->assertEquals('1980-12-13', $actualResult);
128 }
129
130 /**
131 * @test
132 */
133 public function viewHelperUsesChildNodesWithTimestamp() {
134 $this->subject->expects($this->once())->method('renderChildren')->will($this->returnValue('1359891658'));
135 $actualResult = $this->subject->render();
136 $this->assertEquals('2013-02-03', $actualResult);
137 }
138
139 /**
140 * @test
141 */
142 public function dateArgumentHasPriorityOverChildNodes() {
143 $this->subject->expects($this->never())->method('renderChildren');
144 $actualResult = $this->subject->render('1980-12-12');
145 $this->assertEquals('1980-12-12', $actualResult);
146 }
147
148 /**
149 * @test
150 */
151 public function relativeDateCalculationWorksWithoutBase() {
152 $this->subject->expects($this->never())->method('renderChildren');
153 $actualResult = $this->subject->render('now', 'Y');
154 $this->assertEquals(date('Y'), $actualResult);
155 }
156
157 /**
158 * @test
159 */
160 public function baseArgumentIsConsideredForRelativeDate() {
161 $this->subject->expects($this->never())->method('renderChildren');
162 $actualResult = $this->subject->render('-1 year', 'Y', '2017-01-01');
163 $this->assertEquals('2016', $actualResult);
164 }
165
166 /**
167 * @test
168 */
169 public function baseArgumentAsDateTimeIsConsideredForRelativeDate() {
170 $this->subject->expects($this->never())->method('renderChildren');
171 $actualResult = $this->subject->render('-1 year', 'Y', new \DateTime('2017-01-01'));
172 $this->assertEquals('2016', $actualResult);
173 }
174
175 /**
176 * @test
177 */
178 public function baseArgumentDoesNotAffectAbsoluteTime() {
179 $this->subject->expects($this->never())->method('renderChildren');
180 $actualResult = $this->subject->render('@1435784732', 'Y', 1485907200); // somewhere in 2017
181 $this->assertEquals('2015', $actualResult);
182 }
183
184 /**
185 * Data provider for viewHelperRespectsDefaultTimezoneForIntegerTimestamp
186 *
187 * @return array
188 */
189 public function viewHelperRespectsDefaultTimezoneForIntegerTimestampDataProvider() {
190 return array(
191 'Europe/Berlin' => array(
192 'Europe/Berlin',
193 '2013-02-03 12:40',
194 ),
195 'Asia/Riyadh' => array(
196 'Asia/Riyadh',
197 '2013-02-03 14:40',
198 ),
199 );
200 }
201
202 /**
203 * @test
204 * @dataProvider viewHelperRespectsDefaultTimezoneForIntegerTimestampDataProvider
205 */
206 public function viewHelperRespectsDefaultTimezoneForIntegerTimestamp($timezone, $expected) {
207 $date = 1359891658; // 2013-02-03 11:40 UTC
208 $format = 'Y-m-d H:i';
209
210 date_default_timezone_set($timezone);
211 $this->assertEquals($expected, $this->subject->render($date, $format));
212 }
213
214 /**
215 * Data provider for viewHelperRespectsDefaultTimezoneForStringTimestamp
216 *
217 * @return array
218 */
219 public function viewHelperRespectsDefaultTimezoneForStringTimestampDataProvider() {
220 return array(
221 'Europe/Berlin UTC' => array(
222 'Europe/Berlin',
223 '@1359891658',
224 '2013-02-03 12:40'
225 ),
226 'Europe/Berlin Moscow' => array(
227 'Europe/Berlin',
228 '03/Oct/2000:14:55:36 +0400',
229 '2000-10-03 12:55'
230 ),
231 'Asia/Riyadh UTC' => array(
232 'Asia/Riyadh',
233 '@1359891658',
234 '2013-02-03 14:40'
235 ),
236 'Asia/Riyadh Moscow' => array(
237 'Asia/Riyadh',
238 '03/Oct/2000:14:55:36 +0400',
239 '2000-10-03 13:55'
240 ),
241 );
242 }
243
244 /**
245 * @dataProvider viewHelperRespectsDefaultTimezoneForStringTimestampDataProvider
246 *
247 * @test
248 */
249 public function viewHelperRespectsDefaultTimezoneForStringTimestamp($timeZone, $date, $expected) {
250 $format = 'Y-m-d H:i';
251
252 date_default_timezone_set($timeZone);
253 $this->assertEquals($expected, $this->subject->render($date, $format));
254 }
255
256 /**
257 * Data provider for dateViewHelperFormatsDateLocalizedDataProvider
258 *
259 * @return array
260 */
261 public function dateViewHelperFormatsDateLocalizedDataProvider() {
262 return array(
263 'de_DE.UTF-8' => array(
264 'de_DE.UTF-8',
265 '03. Februar 2013'
266 ),
267 'en_ZW.utf8' => array(
268 'en_ZW.utf8',
269 '03. February 2013'
270 )
271 );
272 }
273
274 /**
275 * @dataProvider dateViewHelperFormatsDateLocalizedDataProvider
276 *
277 * @test
278 */
279 public function dateViewHelperFormatsDateLocalized($locale, $expected) {
280 $format = '%d. %B %Y';
281 // 2013-02-03 11:40 UTC
282 $timestamp = '@1359891658';
283
284 if (!setlocale(LC_COLLATE, $locale)) {
285 $this->markTestSkipped('Locale ' . $locale . ' is not available.');
286 }
287 $this->setCustomLocale($locale);
288 $this->assertEquals($expected, $this->subject->render($timestamp, $format));
289 }
290
291 /**
292 * @param string $locale
293 */
294 protected function setCustomLocale($locale) {
295 setlocale(LC_CTYPE, $locale);
296 setlocale(LC_MONETARY, $locale);
297 setlocale(LC_TIME, $locale);
298 }
299
300 }