9436a1a894fc19863e42c8c1080ca35532ab9b9d
[Packages/TYPO3.CMS.git] / typo3 / sysext / form / Tests / Unit / Domain / Finishers / AbstractFinisherTest.php
1 <?php
2 declare(strict_types = 1);
3 namespace TYPO3\CMS\Form\Tests\Unit\Domain\Finishers;
4
5 /*
6 * This file is part of the TYPO3 CMS project.
7 *
8 * It is free software; you can redistribute it and/or modify it under
9 * the terms of the GNU General Public License, either version 2
10 * of the License, or any later version.
11 *
12 * For the full copyright and license information, please read the
13 * LICENSE.txt file that was distributed with this source code.
14 *
15 * The TYPO3 project - inspiring people to share!
16 */
17
18 use Prophecy\Argument;
19 use TYPO3\CMS\Core\Utility\GeneralUtility;
20 use TYPO3\CMS\Extbase\Object\ObjectManager;
21 use TYPO3\CMS\Form\Domain\Finishers\AbstractFinisher;
22 use TYPO3\CMS\Form\Domain\Finishers\FinisherContext;
23 use TYPO3\CMS\Form\Domain\Runtime\FormRuntime;
24 use TYPO3\CMS\Form\Service\TranslationService;
25 use TYPO3\TestingFramework\Core\Unit\UnitTestCase;
26
27 /**
28 * Test case
29 */
30 class AbstractFinisherTest extends UnitTestCase
31 {
32 /**
33 * @var array A backup of registered singleton instances
34 */
35 protected $singletonInstances = [];
36
37 /**
38 * Set up
39 */
40 public function setUp()
41 {
42 $this->singletonInstances = GeneralUtility::getSingletonInstances();
43 }
44
45 /**
46 * Tear down
47 */
48 public function tearDown(): void
49 {
50 GeneralUtility::resetSingletonInstances($this->singletonInstances);
51 parent::tearDown();
52 }
53
54 /**
55 * @test
56 */
57 public function parseOptionReturnsNullIfOptionNameIsTranslation(): void
58 {
59 $mockAbstractFinisher = $this->getAccessibleMockForAbstractClass(
60 AbstractFinisher::class,
61 [],
62 '',
63 false
64 );
65
66 $this->assertNull($mockAbstractFinisher->_call('parseOption', 'translation'));
67 }
68
69 /**
70 * @test
71 */
72 public function parseOptionReturnsNullIfOptionNameNotExistsWithinOptions(): void
73 {
74 $mockAbstractFinisher = $this->getAccessibleMockForAbstractClass(
75 AbstractFinisher::class,
76 [],
77 '',
78 false
79 );
80
81 $mockAbstractFinisher->_set('options', []);
82
83 $this->assertNull($mockAbstractFinisher->_call('parseOption', 'foo'));
84 }
85
86 /**
87 * @test
88 */
89 public function parseOptionReturnsNullIfOptionNameNotExistsWithinDefaultOptions(): void
90 {
91 $mockAbstractFinisher = $this->getAccessibleMockForAbstractClass(
92 AbstractFinisher::class,
93 [],
94 '',
95 false
96 );
97
98 $mockAbstractFinisher->_set('options', []);
99
100 $this->assertNull($mockAbstractFinisher->_call('parseOption', 'foo'));
101 }
102
103 /**
104 * @test
105 */
106 public function parseOptionReturnsArrayOptionValuesAsArray(): void
107 {
108 $mockAbstractFinisher = $this->getAccessibleMockForAbstractClass(
109 AbstractFinisher::class,
110 [],
111 '',
112 false
113 );
114
115 $mockAbstractFinisher->_set('options', [
116 'foo' => ['bar', 'foobar']
117 ]);
118
119 $expected = ['bar', 'foobar'];
120
121 $this->assertSame($expected, $mockAbstractFinisher->_call('parseOption', 'foo'));
122 }
123
124 /**
125 * @test
126 */
127 public function parseOptionReturnsBoolOptionValuesAsBool(): void
128 {
129 $mockAbstractFinisher = $this->getAccessibleMockForAbstractClass(
130 AbstractFinisher::class,
131 [],
132 '',
133 false
134 );
135
136 $mockAbstractFinisher->_set('options', [
137 'foo1' => false,
138 ]);
139
140 $expected = false;
141
142 $this->assertSame($expected, $mockAbstractFinisher->_call('parseOption', 'foo1'));
143 }
144
145 /**
146 * @test
147 */
148 public function parseOptionReturnsValueFromFormRuntimeIfOptionNameReferenceAFormElementIdentifierWhoseValueIsAString(): void
149 {
150 $objectManagerProphecy = $this->prophesize(ObjectManager::class);
151 GeneralUtility::setSingletonInstance(ObjectManager::class, $objectManagerProphecy->reveal());
152
153 $mockTranslationService = $this->getAccessibleMock(TranslationService::class, [
154 'translateFinisherOption'
155 ], [], '', false);
156
157 $mockTranslationService
158 ->expects($this->any())
159 ->method('translateFinisherOption')
160 ->willReturnArgument(3);
161
162 $objectManagerProphecy
163 ->get(TranslationService::class)
164 ->willReturn($mockTranslationService);
165
166 $expected = 'element-value';
167 $elementIdentifier = 'element-identifier-1';
168
169 $mockAbstractFinisher = $this->getAccessibleMockForAbstractClass(
170 AbstractFinisher::class,
171 [],
172 '',
173 false
174 );
175
176 $mockAbstractFinisher->_set('options', [
177 'subject' => '{' . $elementIdentifier . '}'
178 ]);
179
180 $finisherContextProphecy = $this->prophesize(FinisherContext::class);
181
182 $formRuntimeProphecy = $this->prophesize(FormRuntime::class);
183 $formRuntimeProphecy->offsetExists(Argument::exact($elementIdentifier))->willReturn(true);
184 $formRuntimeProphecy->offsetGet(Argument::exact($elementIdentifier))->willReturn($expected);
185
186 $finisherContextProphecy->getFormRuntime(Argument::cetera())
187 ->willReturn($formRuntimeProphecy->reveal());
188
189 $mockAbstractFinisher->_set('finisherContext', $finisherContextProphecy->reveal());
190
191 $this->assertSame($expected, $mockAbstractFinisher->_call('parseOption', 'subject'));
192 }
193
194 /**
195 * @test
196 */
197 public function parseOptionReturnsNoReplacedValueFromFormRuntimeIfOptionNameReferenceAFormElementIdentifierWhoseValueIsNotAString(): void
198 {
199 $objectManagerProphecy = $this->prophesize(ObjectManager::class);
200 GeneralUtility::setSingletonInstance(ObjectManager::class, $objectManagerProphecy->reveal());
201
202 $mockTranslationService = $this->getAccessibleMock(TranslationService::class, [
203 'translateFinisherOption'
204 ], [], '', false);
205
206 $mockTranslationService
207 ->expects($this->any())
208 ->method('translateFinisherOption')
209 ->willReturnArgument(3);
210
211 $objectManagerProphecy
212 ->get(TranslationService::class)
213 ->willReturn($mockTranslationService);
214
215 $elementIdentifier = 'element-identifier-1';
216 $expected = '{' . $elementIdentifier . '}';
217
218 $mockAbstractFinisher = $this->getAccessibleMockForAbstractClass(
219 AbstractFinisher::class,
220 [],
221 '',
222 false
223 );
224
225 $mockAbstractFinisher->_set('options', [
226 'subject' => '{' . $elementIdentifier . '}'
227 ]);
228
229 $finisherContextProphecy = $this->prophesize(FinisherContext::class);
230
231 $formRuntimeProphecy = $this->prophesize(FormRuntime::class);
232 $formRuntimeProphecy->offsetExists(Argument::exact($elementIdentifier))->willReturn(true);
233 $formElementValue = new \DateTime;
234 $formRuntimeProphecy->offsetGet(Argument::exact($elementIdentifier))->willReturn($formElementValue);
235
236 $finisherContextProphecy->getFormRuntime(Argument::cetera())
237 ->willReturn($formRuntimeProphecy->reveal());
238
239 $mockAbstractFinisher->_set('finisherContext', $finisherContextProphecy->reveal());
240
241 $this->assertSame($expected, $mockAbstractFinisher->_call('parseOption', 'subject'));
242 }
243
244 /**
245 * @test
246 */
247 public function parseOptionReturnsNoReplacedValueFromFormRuntimeIfOptionNameReferenceANonExistingFormElement(): void
248 {
249 $objectManagerProphecy = $this->prophesize(ObjectManager::class);
250 GeneralUtility::setSingletonInstance(ObjectManager::class, $objectManagerProphecy->reveal());
251
252 $mockTranslationService = $this->getAccessibleMock(TranslationService::class, [
253 'translateFinisherOption'
254 ], [], '', false);
255
256 $mockTranslationService
257 ->expects($this->any())
258 ->method('translateFinisherOption')
259 ->willReturnArgument(3);
260
261 $objectManagerProphecy
262 ->get(TranslationService::class)
263 ->willReturn($mockTranslationService);
264
265 $elementIdentifier = 'element-identifier-1';
266
267 $mockAbstractFinisher = $this->getAccessibleMockForAbstractClass(
268 AbstractFinisher::class,
269 [],
270 '',
271 false
272 );
273
274 $mockAbstractFinisher->_set('options', [
275 'subject' => '{' . $elementIdentifier . '}'
276 ]);
277
278 $finisherContextProphecy = $this->prophesize(FinisherContext::class);
279
280 $formRuntimeProphecy = $this->prophesize(FormRuntime::class);
281 $formRuntimeProphecy->offsetExists(Argument::cetera())->willReturn(true);
282 $formRuntimeProphecy->offsetGet(Argument::cetera())->willReturn(false);
283
284 $finisherContextProphecy->getFormRuntime(Argument::cetera())
285 ->willReturn($formRuntimeProphecy->reveal());
286
287 $mockAbstractFinisher->_set('finisherContext', $finisherContextProphecy->reveal());
288
289 $expected = '{' . $elementIdentifier . '}';
290 $this->assertSame($expected, $mockAbstractFinisher->_call('parseOption', 'subject'));
291 }
292
293 /**
294 * @test
295 */
296 public function parseOptionReturnsDefaultOptionValueIfOptionNameNotExistsWithinOptionsButWithinDefaultOptions(): void
297 {
298 $objectManagerProphecy = $this->prophesize(ObjectManager::class);
299 GeneralUtility::setSingletonInstance(ObjectManager::class, $objectManagerProphecy->reveal());
300
301 $mockTranslationService = $this->getAccessibleMock(TranslationService::class, [
302 'translateFinisherOption'
303 ], [], '', false);
304
305 $mockTranslationService
306 ->expects($this->any())
307 ->method('translateFinisherOption')
308 ->willReturnArgument(3);
309
310 $objectManagerProphecy
311 ->get(TranslationService::class)
312 ->willReturn($mockTranslationService);
313
314 $expected = 'defaultValue';
315
316 $mockAbstractFinisher = $this->getAccessibleMockForAbstractClass(
317 AbstractFinisher::class,
318 [],
319 '',
320 false
321 );
322
323 $mockAbstractFinisher->_set('options', []);
324 $mockAbstractFinisher->_set('defaultOptions', [
325 'subject' => $expected
326 ]);
327
328 $finisherContextProphecy = $this->prophesize(FinisherContext::class);
329
330 $formRuntimeProphecy = $this->prophesize(FormRuntime::class);
331 $formRuntimeProphecy->offsetExists(Argument::cetera())->willReturn(true);
332 $formRuntimeProphecy->offsetGet(Argument::cetera())->willReturn(false);
333
334 $finisherContextProphecy->getFormRuntime(Argument::cetera())
335 ->willReturn($formRuntimeProphecy->reveal());
336
337 $mockAbstractFinisher->_set('finisherContext', $finisherContextProphecy->reveal());
338
339 $this->assertSame($expected, $mockAbstractFinisher->_call('parseOption', 'subject'));
340 }
341
342 /**
343 * @test
344 */
345 public function parseOptionReturnsDefaultOptionValueIfOptionValueIsAFormElementReferenceAndTheFormElementValueIsEmpty(): void
346 {
347 $objectManagerProphecy = $this->prophesize(ObjectManager::class);
348 GeneralUtility::setSingletonInstance(ObjectManager::class, $objectManagerProphecy->reveal());
349
350 $mockTranslationService = $this->getAccessibleMock(TranslationService::class, [
351 'translateFinisherOption'
352 ], [], '', false);
353
354 $mockTranslationService
355 ->expects($this->any())
356 ->method('translateFinisherOption')
357 ->willReturnArgument(3);
358
359 $objectManagerProphecy
360 ->get(TranslationService::class)
361 ->willReturn($mockTranslationService);
362
363 $elementIdentifier = 'element-identifier-1';
364 $expected = 'defaultValue';
365
366 $mockAbstractFinisher = $this->getAccessibleMockForAbstractClass(
367 AbstractFinisher::class,
368 [],
369 '',
370 false
371 );
372
373 $mockAbstractFinisher->_set('options', [
374 'subject' => '{' . $elementIdentifier . '}'
375 ]);
376 $mockAbstractFinisher->_set('defaultOptions', [
377 'subject' => $expected
378 ]);
379
380 $finisherContextProphecy = $this->prophesize(FinisherContext::class);
381
382 $formRuntimeProphecy = $this->prophesize(FormRuntime::class);
383 $formRuntimeProphecy->offsetExists(Argument::exact($elementIdentifier))->willReturn(true);
384 $formRuntimeProphecy->offsetGet(Argument::exact($elementIdentifier))->willReturn('');
385
386 $finisherContextProphecy->getFormRuntime(Argument::cetera())
387 ->willReturn($formRuntimeProphecy->reveal());
388
389 $mockAbstractFinisher->_set('finisherContext', $finisherContextProphecy->reveal());
390
391 $this->assertSame($expected, $mockAbstractFinisher->_call('parseOption', 'subject'));
392 }
393
394 /**
395 * @test
396 */
397 public function parseOptionReturnsTimestampIfOptionValueIsATimestampRequestTrigger(): void
398 {
399 $objectManagerProphecy = $this->prophesize(ObjectManager::class);
400 GeneralUtility::setSingletonInstance(ObjectManager::class, $objectManagerProphecy->reveal());
401
402 $mockTranslationService = $this->getAccessibleMock(TranslationService::class, [
403 'translateFinisherOption'
404 ], [], '', false);
405
406 $mockTranslationService
407 ->expects($this->any())
408 ->method('translateFinisherOption')
409 ->willReturnArgument(3);
410
411 $objectManagerProphecy
412 ->get(TranslationService::class)
413 ->willReturn($mockTranslationService);
414
415 $mockAbstractFinisher = $this->getAccessibleMockForAbstractClass(
416 AbstractFinisher::class,
417 [],
418 '',
419 false
420 );
421
422 $mockAbstractFinisher->_set('options', [
423 'crdate' => '{__currentTimestamp}'
424 ]);
425
426 $finisherContextProphecy = $this->prophesize(FinisherContext::class);
427
428 $formRuntimeProphecy = $this->prophesize(FormRuntime::class);
429
430 $finisherContextProphecy->getFormRuntime(Argument::cetera())
431 ->willReturn($formRuntimeProphecy->reveal());
432
433 $mockAbstractFinisher->_set('finisherContext', $finisherContextProphecy->reveal());
434
435 $expected = '#^([0-9]{10})$#';
436 $this->assertEquals(1, preg_match($expected, $mockAbstractFinisher->_call('parseOption', 'crdate')));
437 }
438 }