7c1a97338a6c09e74049c95d0d5b5907df3fac5b
[Packages/TYPO3.CMS.git] / typo3 / sysext / fluid / Tests / Unit / Core / ViewHelper / AbstractViewHelperTest.php
1 <?php
2 namespace TYPO3\CMS\Fluid\Tests\Unit\Core\ViewHelper;
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 use TYPO3\CMS\Extbase\Mvc\Request;
17 use TYPO3\CMS\Extbase\Reflection\ReflectionService;
18 use TYPO3\CMS\Fluid\Core\Exception;
19 use TYPO3\CMS\Fluid\Tests\Unit\Core\Fixtures\TestViewHelper;
20 use TYPO3\CMS\Fluid\Tests\Unit\Core\Rendering\RenderingContextFixture;
21 use TYPO3Fluid\Fluid\Core\Variables\StandardVariableProvider;
22 use TYPO3Fluid\Fluid\Core\ViewHelper\ViewHelperVariableContainer;
23
24 /**
25 * Test case
26 */
27 class AbstractViewHelperTest extends \TYPO3\TestingFramework\Core\Unit\UnitTestCase
28 {
29 /**
30 * @var array
31 */
32 protected $fixtureMethodParameters = [
33 'param1' => [
34 'position' => 0,
35 'optional' => false,
36 'type' => 'integer',
37 'defaultValue' => null
38 ],
39 'param2' => [
40 'position' => 1,
41 'optional' => false,
42 'type' => 'array',
43 'array' => true,
44 'defaultValue' => null
45 ],
46 'param3' => [
47 'position' => 2,
48 'optional' => true,
49 'type' => 'string',
50 'array' => false,
51 'defaultValue' => 'default'
52 ],
53 ];
54
55 /**
56 * @var array
57 */
58 protected $fixtureMethodTags = [
59 'param' => [
60 'integer $param1 P1 Stuff',
61 'array $param2 P2 Stuff',
62 'string $param3 P3 Stuff'
63 ]
64 ];
65
66 protected function setUp()
67 {
68 $this->mockReflectionService = $this->createMock(\TYPO3\CMS\Extbase\Reflection\ReflectionService::class);
69 }
70
71 /**
72 * @test
73 * @dataProvider getCallRenderMethodTestValues
74 * @param array $arguments
75 * @param bool $expectsException
76 */
77 public function registerRenderMethodArgumentsThrowsExceptionOnMissingType(array $arguments, $expectsException = false)
78 {
79 $reflectionService = $this->getMockBuilder(ReflectionService::class)
80 ->setMethods(['getMethodParameters', 'getMethodTagsValues'])
81 ->getMock();
82 $reflectionService->expects($this->once())->method('getMethodParameters')->willReturn(
83 [
84 'param1' => [
85 'position' => 0,
86 'byReference' => false,
87 'optional' => false,
88 'allowsNull' => true
89 ]
90 ]
91 );
92 $reflectionService->expects($this->once())->method('getMethodTagsValues')->willReturn([]);
93 $fixture = $this->getAccessibleMock(TestViewHelper::class, ['render', 'getReflectionService']);
94 $fixture->expects($this->once())->method('getReflectionService')->willReturn($reflectionService);
95 $this->expectException(Exception::class);
96 $this->callInaccessibleMethod($fixture, 'registerRenderMethodArguments');
97 }
98
99 /**
100 * @test
101 * @dataProvider getCallRenderMethodTestValues
102 * @param array $arguments
103 * @param bool $expectsException
104 */
105 public function callRenderMethodBehavesAsExpected(array $arguments, $expectsException = false)
106 {
107 $reflectionService = $this->getMockBuilder(ReflectionService::class)
108 ->setMethods(['getMethodParameters', 'getMethodTagsValues'])
109 ->getMock();
110 $reflectionService->expects($this->once())->method('getMethodParameters')->willReturn(
111 [
112 'param1' => [
113 'position' => 0,
114 'type' => 'integer',
115 'byReference' => false,
116 'array' => false,
117 'optional' => false,
118 'allowsNull' => true
119 ],
120 'param2' => [
121 'position' => 1,
122 'type' => 'array',
123 'byReference' => false,
124 'array' => true,
125 'optional' => false,
126 'allowsNull' => true
127 ],
128 'param3' => [
129 'position' => 2,
130 'type' => 'string',
131 'byReference' => false,
132 'array' => false,
133 'optional' => false,
134 'allowsNull' => true
135 ],
136 ]
137 );
138 $reflectionService->expects($this->once())->method('getMethodTagsValues')->willReturn(
139 []
140 );
141 $fixture = $this->getAccessibleMock(TestViewHelper::class, ['render', 'getReflectionService']);
142 $namedArguments = array_combine(['param1', 'param2', 'param3'], $arguments);
143 $fixture->expects($this->once())->method('getReflectionService')->willReturn($reflectionService);
144 $this->callInaccessibleMethod($fixture, 'registerRenderMethodArguments');
145 $fixture->setArguments($namedArguments);
146 if ($expectsException) {
147 $exception = new \TYPO3Fluid\Fluid\Core\ViewHelper\Exception('test', 1476108352);
148 $this->expectException(get_class($exception));
149 $fixture->expects($this->once())->method('render')->willThrowException($exception);
150 $this->assertEquals('test', $this->callInaccessibleMethod($fixture, 'callRenderMethod'));
151 } else {
152 $fixture->expects($this->once())
153 ->method('render')
154 ->with($arguments[0], $arguments[1], $arguments[2])
155 ->willReturn('okay');
156 $this->assertEquals('okay', $this->callInaccessibleMethod($fixture, 'callRenderMethod'));
157 }
158 }
159
160 /**
161 * @return array
162 */
163 public function getCallRenderMethodTestValues()
164 {
165 return [
166 [[3, ['bar'], 'baz'], false],
167 [[2, ['baz'], 'bar'], false],
168 [[3, ['bar'], 'baz'], true],
169 ];
170 }
171
172 /**
173 * @test
174 */
175 public function prepareArgumentsCallsInitializeArguments()
176 {
177 $viewHelper = $this->getAccessibleMock(\TYPO3\CMS\Fluid\Core\ViewHelper\AbstractViewHelper::class, ['render', 'initializeArguments'], [], '', false);
178
179 $viewHelper->expects($this->once())->method('initializeArguments');
180
181 $viewHelper->prepareArguments();
182 }
183
184 /**
185 * @test
186 */
187 public function prepareArgumentsRegistersAnnotationBasedArgumentsWithDescriptionIfDebugModeIsEnabled()
188 {
189 $dataCacheMock = $this->createMock(\TYPO3\CMS\Core\Cache\Frontend\VariableFrontend::class);
190 $dataCacheMock->expects($this->any())->method('has')->will($this->returnValue(true));
191 $dataCacheMock->expects($this->any())->method('get')->will($this->returnValue([]));
192
193 $reflectionServiceMock = $this->getMockBuilder(ReflectionService::class)->getMock();
194 $reflectionServiceMock->expects($this->once())->method('getMethodParameters')->willReturn(['fake' => ['type' => 'int', 'defaultValue' => 'def']]);
195 $reflectionServiceMock->expects($this->once())->method('getMethodTagsValues')->willReturn(['param']);
196
197 $viewHelper = $this->getMockBuilder(\TYPO3\CMS\Fluid\Tests\Unit\Core\Fixtures\TestViewHelper::class)->setMethods(['getReflectionService'])->getMock();
198 $viewHelper->expects($this->once())->method('getReflectionService')->willReturn($reflectionServiceMock);
199
200 $expected = [
201 'fake' => new \TYPO3\CMS\Fluid\Core\ViewHelper\ArgumentDefinition('fake', 'int', '', false, 'def', true)
202 ];
203
204 $this->callInaccessibleMethod($viewHelper, 'registerRenderMethodArguments');
205 $this->assertAttributeEquals($expected, 'argumentDefinitions', $viewHelper, 'Annotation based arguments were not registered.');
206 }
207
208 /**
209 * @test
210 */
211 public function validateArgumentsCallsPrepareArguments()
212 {
213 $viewHelper = $this->getAccessibleMock(\TYPO3\CMS\Fluid\Core\ViewHelper\AbstractViewHelper::class, ['render', 'prepareArguments'], [], '', false);
214
215 $viewHelper->expects($this->once())->method('prepareArguments')->will($this->returnValue([]));
216
217 $viewHelper->validateArguments();
218 }
219
220 /**
221 * @test
222 */
223 public function validateArgumentsAcceptsAllObjectsImplemtingArrayAccessAsAnArray()
224 {
225 $viewHelper = $this->getAccessibleMock(\TYPO3\CMS\Fluid\Core\ViewHelper\AbstractViewHelper::class, ['render', 'prepareArguments'], [], '', false);
226
227 $viewHelper->setArguments(['test' => new \ArrayObject]);
228 $viewHelper->expects($this->once())->method('prepareArguments')->will($this->returnValue(['test' => new \TYPO3\CMS\Fluid\Core\ViewHelper\ArgumentDefinition('test', 'array', false, 'documentation')]));
229 $viewHelper->validateArguments();
230 }
231
232 /**
233 * @test
234 */
235 public function validateArgumentsCallsTheRightValidators()
236 {
237 $viewHelper = $this->getAccessibleMock(\TYPO3\CMS\Fluid\Core\ViewHelper\AbstractViewHelper::class, ['render', 'prepareArguments'], [], '', false);
238
239 $viewHelper->setArguments(['test' => 'Value of argument']);
240
241 $viewHelper->expects($this->once())->method('prepareArguments')->will($this->returnValue([
242 'test' => new \TYPO3\CMS\Fluid\Core\ViewHelper\ArgumentDefinition('test', 'string', false, 'documentation')
243 ]));
244
245 $viewHelper->validateArguments();
246 }
247
248 /**
249 * @test
250 */
251 public function validateArgumentsCallsTheRightValidatorsAndThrowsExceptionIfValidationIsWrong()
252 {
253 $viewHelper = $this->getAccessibleMock(\TYPO3\CMS\Fluid\Core\ViewHelper\AbstractViewHelper::class, ['render', 'prepareArguments'], [], '', false);
254
255 $this->expectException(\InvalidArgumentException::class);
256 $this->expectExceptionCode(1256475113);
257
258 $viewHelper->setArguments(['test' => 'test']);
259
260 $viewHelper->expects($this->once())->method('prepareArguments')->will($this->returnValue([
261 'test' => new \TYPO3\CMS\Fluid\Core\ViewHelper\ArgumentDefinition('test', 'stdClass', false, 'documentation')
262 ]));
263
264 $viewHelper->validateArguments();
265 }
266
267 /**
268 * @test
269 */
270 public function initializeArgumentsAndRenderCallsTheCorrectSequenceOfMethods()
271 {
272 $viewHelper = $this->getAccessibleMock(\TYPO3\CMS\Fluid\Core\ViewHelper\AbstractViewHelper::class, ['validateArguments', 'initialize', 'callRenderMethod']);
273 $viewHelper->expects($this->at(0))->method('validateArguments');
274 $viewHelper->expects($this->at(1))->method('initialize');
275 $viewHelper->expects($this->at(2))->method('callRenderMethod')->will($this->returnValue('Output'));
276
277 $expectedOutput = 'Output';
278 $actualOutput = $viewHelper->initializeArgumentsAndRender(['argument1' => 'value1']);
279 $this->assertEquals($expectedOutput, $actualOutput);
280 }
281
282 /**
283 * @test
284 */
285 public function setRenderingContextShouldSetInnerVariables()
286 {
287 $templateVariableContainer = $this->createMock(StandardVariableProvider::class);
288 $viewHelperVariableContainer = $this->createMock(ViewHelperVariableContainer::class);
289 $controllerContext = $this->getMockBuilder(\TYPO3\CMS\Extbase\Mvc\Controller\ControllerContext::class)
290 ->setMethods(['getRequest'])
291 ->disableOriginalConstructor()
292 ->getMock();
293 $controllerContext->expects($this->atLeastOnce())->method('getRequest')->willReturn($this->createMock(Request::class));
294
295 $renderingContext = $this->getAccessibleMock(RenderingContextFixture::class, ['getControllerContext']);
296 $renderingContext->expects($this->any())->method('getControllerContext')->willReturn($controllerContext);
297 $renderingContext->setVariableProvider($templateVariableContainer);
298 $renderingContext->_set('viewHelperVariableContainer', $viewHelperVariableContainer);
299 $renderingContext->setControllerContext($controllerContext);
300
301 $viewHelper = $this->getAccessibleMock(\TYPO3\CMS\Fluid\Core\ViewHelper\AbstractViewHelper::class, ['render', 'prepareArguments'], [], '', false);
302
303 $viewHelper->setRenderingContext($renderingContext);
304
305 $this->assertSame($viewHelper->_get('templateVariableContainer'), $templateVariableContainer);
306 $this->assertSame($viewHelper->_get('viewHelperVariableContainer'), $viewHelperVariableContainer);
307 $this->assertSame($viewHelper->_get('controllerContext'), $controllerContext);
308 }
309 }