1
|
|
|
<?php |
2
|
|
|
|
3
|
|
|
namespace Vectorface\SnappyRouterTests\Handler; |
4
|
|
|
|
5
|
|
|
use \PHPUnit_Framework_TestCase; |
6
|
|
|
use Vectorface\SnappyRouter\SnappyRouter; |
7
|
|
|
use Vectorface\SnappyRouter\Config\Config; |
8
|
|
|
use Vectorface\SnappyRouter\Encoder\NullEncoder; |
9
|
|
|
use Vectorface\SnappyRouter\Handler\ControllerHandler; |
10
|
|
|
|
11
|
|
|
/** |
12
|
|
|
* Tests the ControllerHandler. |
13
|
|
|
* @copyright Copyright (c) 2014, VectorFace, Inc. |
14
|
|
|
* @author Dan Bruce <[email protected]> |
15
|
|
|
*/ |
16
|
|
|
class ControllerHandlerTest extends PHPUnit_Framework_TestCase |
17
|
|
|
{ |
18
|
|
|
/** |
19
|
|
|
* An overview of how to use the ControllerHandler. |
20
|
|
|
* @test |
21
|
|
|
*/ |
22
|
|
|
public function synopsis() |
23
|
|
|
{ |
24
|
|
|
$options = array( |
25
|
|
|
ControllerHandler::KEY_BASE_PATH => '/', |
26
|
|
|
Config::KEY_CONTROLLERS => array( |
27
|
|
|
'ControllerController' => 'Vectorface\\SnappyRouterTests\\Controller\\TestDummyController', |
28
|
|
|
'IndexController' => 'Vectorface\\SnappyRouterTests\\Controller\\TestDummyController' |
29
|
|
|
) |
30
|
|
|
); |
31
|
|
|
$handler = new ControllerHandler($options); |
32
|
|
|
|
33
|
|
|
$path = '/controller/default/param1/param2'; |
34
|
|
|
$query = array('id' => '1234'); |
35
|
|
|
$post = array('key' => 'value'); |
36
|
|
|
|
37
|
|
|
// a route with parameters |
38
|
|
|
$this->assertTrue($handler->isAppropriate($path, $query, $post, 'POST')); |
39
|
|
|
$request = $handler->getRequest(); |
40
|
|
|
$this->assertEquals('ControllerController', $request->getController()); |
41
|
|
|
$this->assertEquals('defaultAction', $request->getAction()); |
42
|
|
|
$this->assertEquals('POST', $request->getVerb()); |
43
|
|
|
$this->assertFalse($request->isGet()); |
44
|
|
|
$this->assertTrue($request->isPost()); |
45
|
|
|
|
46
|
|
|
// a route with only an action, no params |
47
|
|
|
$this->assertTrue($handler->isAppropriate('/controller/action/', $query, $post, 'POST')); |
48
|
|
|
|
49
|
|
|
// a route with only a controller, no action nor params |
50
|
|
|
$this->assertTrue($handler->isAppropriate('/controller/', $query, $post, 'POST')); |
51
|
|
|
|
52
|
|
|
// a route with nothing |
53
|
|
|
$this->assertTrue($handler->isAppropriate('/', $query, $post, 'POST')); |
54
|
|
|
|
55
|
|
|
// encoder and decoder methods |
56
|
|
|
$this->assertEquals( |
57
|
|
|
$handler->getEncoder(), |
58
|
|
|
$handler->setEncoder($handler->getEncoder())->getEncoder() |
59
|
|
|
); |
60
|
|
|
|
61
|
|
|
// test the DI integration in the handler |
62
|
|
|
$handler->set('MyKey', 'myValue'); |
63
|
|
|
$this->assertEquals('myValue', $handler->get('MyKey')); |
64
|
|
|
} |
65
|
|
|
|
66
|
|
|
/** |
67
|
|
|
* Tests the handler returns false for a route to an unknown controller. |
68
|
|
|
* @expectedException Vectorface\SnappyRouter\Exception\ResourceNotFoundException |
69
|
|
|
* @expectedExceptionMessage No such controller found "TestController". |
70
|
|
|
*/ |
71
|
|
|
public function testRouteToNonExistantController() |
72
|
|
|
{ |
73
|
|
|
$options = array(); |
74
|
|
|
$handler = new ControllerHandler($options); |
75
|
|
|
|
76
|
|
|
$path = '/test/test'; |
77
|
|
|
$this->assertTrue($handler->isAppropriate($path, array(), array(), 'GET')); |
78
|
|
|
$handler->performRoute(); |
79
|
|
|
} |
80
|
|
|
|
81
|
|
|
/** |
82
|
|
|
* Tests that an exception is thrown if we try to route to a controller |
83
|
|
|
* action that does not exist. |
84
|
|
|
* @expectedException Vectorface\SnappyRouter\Exception\ResourceNotFoundException |
85
|
|
|
* @expectedExceptionMessage TestController does not have method notexistsAction |
86
|
|
|
*/ |
87
|
|
|
public function testRouteToNonExistantControllerAction() |
88
|
|
|
{ |
89
|
|
|
$options = array( |
90
|
|
|
Config::KEY_CONTROLLERS => array( |
91
|
|
|
'TestController' => 'Vectorface\\SnappyRouterTests\\Controller\\TestDummyController' |
92
|
|
|
) |
93
|
|
|
); |
94
|
|
|
$handler = new ControllerHandler($options); |
95
|
|
|
|
96
|
|
|
$path = '/test/notExists'; |
97
|
|
|
$this->assertTrue($handler->isAppropriate($path, array(), array(), 'GET')); |
98
|
|
|
|
99
|
|
|
$handler->performRoute(); |
100
|
|
|
} |
101
|
|
|
|
102
|
|
|
/** |
103
|
|
|
* Tests that an exception is thrown if the handler has a plugin missing |
104
|
|
|
* the class field. |
105
|
|
|
* @expectedException Vectorface\SnappyRouter\Exception\PluginException |
106
|
|
|
* @expectedExceptionMessage Invalid or missing class for plugin TestPlugin |
107
|
|
|
*/ |
108
|
|
|
public function testMissingClassOnPlugin() |
109
|
|
|
{ |
110
|
|
|
$options = array( |
111
|
|
|
Config::KEY_PLUGINS => array( |
112
|
|
|
'TestPlugin' => array() |
113
|
|
|
) |
114
|
|
|
); |
115
|
|
|
new ControllerHandler($options); |
116
|
|
|
} |
117
|
|
|
|
118
|
|
|
/** |
119
|
|
|
* Tests that an exception is thrown if the handler lists a non-existant |
120
|
|
|
* plugin class. |
121
|
|
|
* @expectedException Vectorface\SnappyRouter\Exception\PluginException |
122
|
|
|
* @expectedExceptionMessage Invalid or missing class for plugin TestPlugin |
123
|
|
|
*/ |
124
|
|
|
public function testInvalidClassOnPlugin() |
125
|
|
|
{ |
126
|
|
|
$options = array( |
127
|
|
|
Config::KEY_PLUGINS => array( |
128
|
|
|
'TestPlugin' => array( |
129
|
|
|
'class' => 'Vectorface\\SnappyRouter\\Plugin\\NonExistantPlugin' |
130
|
|
|
) |
131
|
|
|
) |
132
|
|
|
); |
133
|
|
|
new ControllerHandler($options); |
134
|
|
|
} |
135
|
|
|
|
136
|
|
|
/** |
137
|
|
|
* Tests that an invalid view configuration throws an exception. |
138
|
|
|
* @expectedException Vectorface\SnappyRouter\Exception\InternalErrorException |
139
|
|
|
* @expectedExceptionMessage View environment missing views path. |
140
|
|
|
*/ |
141
|
|
|
public function testInvalidViewConfiguration() |
142
|
|
|
{ |
143
|
|
|
$options = array( |
144
|
|
|
ControllerHandler::KEY_BASE_PATH => '/', |
145
|
|
|
Config::KEY_CONTROLLERS => array( |
146
|
|
|
'ControllerController' => 'Vectorface\\SnappyRouterTests\\Controller\\TestDummyController', |
147
|
|
|
), |
148
|
|
|
ControllerHandler::KEY_VIEWS => array() |
149
|
|
|
); |
150
|
|
|
$handler = new ControllerHandler($options); |
151
|
|
|
$handler->isAppropriate('/controller', array(), array(), 'GET'); |
152
|
|
|
} |
153
|
|
|
|
154
|
|
|
/** |
155
|
|
|
* Tests that the default action of a controller is to render a default |
156
|
|
|
* view from the view engine. |
157
|
|
|
*/ |
158
|
|
|
public function testRenderDefaultView() |
159
|
|
|
{ |
160
|
|
|
$routerOptions = array( |
161
|
|
|
Config::KEY_DI => 'Vectorface\\SnappyRouter\\Di\\Di', |
162
|
|
|
Config::KEY_HANDLERS => array( |
163
|
|
|
'ControllerHandler' => array( |
164
|
|
|
Config::KEY_CLASS => 'Vectorface\\SnappyRouter\\Handler\\ControllerHandler', |
165
|
|
|
Config::KEY_OPTIONS => array( |
166
|
|
|
Config::KEY_CONTROLLERS => array( |
167
|
|
|
'TestController' => 'Vectorface\\SnappyRouterTests\\Controller\\TestDummyController' |
168
|
|
|
), |
169
|
|
|
ControllerHandler::KEY_VIEWS => array( |
170
|
|
|
ControllerHandler::KEY_VIEWS_PATH => __DIR__.'/../Controller/Views' |
171
|
|
|
) |
172
|
|
|
) |
173
|
|
|
) |
174
|
|
|
) |
175
|
|
|
); |
176
|
|
|
$router = new SnappyRouter(new Config($routerOptions)); |
177
|
|
|
|
178
|
|
|
$path = '/test/default'; |
179
|
|
|
$response = $router->handleHttpRoute($path, array(), array(), 'GET'); |
180
|
|
|
$expected = file_get_contents(__DIR__.'/../Controller/Views/test/default.twig'); |
181
|
|
|
$this->assertEquals($expected, $response); |
182
|
|
|
} |
183
|
|
|
|
184
|
|
|
/** |
185
|
|
|
* Tests that when an action returns a string, the string is rendered |
186
|
|
|
* without going through the view engine. |
187
|
|
|
*/ |
188
|
|
View Code Duplication |
public function testActionReturnsString() |
|
|
|
|
189
|
|
|
{ |
190
|
|
|
$options = array( |
191
|
|
|
Config::KEY_CONTROLLERS => array( |
192
|
|
|
'TestController' => 'Vectorface\\SnappyRouterTests\\Controller\\TestDummyController' |
193
|
|
|
), |
194
|
|
|
ControllerHandler::KEY_VIEWS => array( |
195
|
|
|
ControllerHandler::KEY_VIEWS_PATH => __DIR__.'/../Controller/Views' |
196
|
|
|
) |
197
|
|
|
); |
198
|
|
|
$handler = new ControllerHandler($options); |
199
|
|
|
$this->assertTrue($handler->isAppropriate('/test/test', array(), array(), 'GET')); |
200
|
|
|
$this->assertEquals('This is a test service.', $handler->performRoute()); |
201
|
|
|
} |
202
|
|
|
|
203
|
|
|
/** |
204
|
|
|
* Tests that when an action returns an array, the twig view is rendered |
205
|
|
|
* with the array values as the variables in the view. |
206
|
|
|
*/ |
207
|
|
View Code Duplication |
public function testActionReturnsArray() |
|
|
|
|
208
|
|
|
{ |
209
|
|
|
$options = array( |
210
|
|
|
Config::KEY_CONTROLLERS => array( |
211
|
|
|
'TestController' => 'Vectorface\\SnappyRouterTests\\Controller\\TestDummyController' |
212
|
|
|
), |
213
|
|
|
ControllerHandler::KEY_VIEWS => array( |
214
|
|
|
ControllerHandler::KEY_VIEWS_PATH => __DIR__.'/../Controller/Views' |
215
|
|
|
) |
216
|
|
|
); |
217
|
|
|
$handler = new ControllerHandler($options); |
218
|
|
|
$this->assertTrue($handler->isAppropriate('/test/array', array(), array(), 'GET')); |
219
|
|
|
$this->assertEquals('This is a test service.', $handler->performRoute()); |
220
|
|
|
} |
221
|
|
|
|
222
|
|
|
/** |
223
|
|
|
* Tests that an action can render a different view that its default. |
224
|
|
|
*/ |
225
|
|
View Code Duplication |
public function testActionRendersNonDefaultView() |
|
|
|
|
226
|
|
|
{ |
227
|
|
|
$options = array( |
228
|
|
|
Config::KEY_CONTROLLERS => array( |
229
|
|
|
'TestController' => 'Vectorface\\SnappyRouterTests\\Controller\\TestDummyController' |
230
|
|
|
), |
231
|
|
|
ControllerHandler::KEY_VIEWS => array( |
232
|
|
|
ControllerHandler::KEY_VIEWS_PATH => __DIR__.'/../Controller/Views' |
233
|
|
|
) |
234
|
|
|
); |
235
|
|
|
$handler = new ControllerHandler($options); |
236
|
|
|
$this->assertTrue($handler->isAppropriate('/test/otherView', array(), array(), 'GET')); |
237
|
|
|
$this->assertEquals('This is a test service.', $handler->performRoute()); |
238
|
|
|
} |
239
|
|
|
|
240
|
|
|
/** |
241
|
|
|
* Tests that an exception is thrown if we "renderView" with a NullEncoder |
242
|
|
|
* @expectedException Exception |
243
|
|
|
* @expectedExceptionMessage The current encoder does not support the render view method. |
244
|
|
|
*/ |
245
|
|
View Code Duplication |
public function testExceptionForNullEncoderRenderView() |
|
|
|
|
246
|
|
|
{ |
247
|
|
|
$options = array( |
248
|
|
|
Config::KEY_CONTROLLERS => array( |
249
|
|
|
'TestController' => 'Vectorface\\SnappyRouterTests\\Controller\\TestDummyController' |
250
|
|
|
), |
251
|
|
|
ControllerHandler::KEY_VIEWS => array( |
252
|
|
|
ControllerHandler::KEY_VIEWS_PATH => __DIR__.'/../Controller/Views' |
253
|
|
|
) |
254
|
|
|
); |
255
|
|
|
$handler = new ControllerHandler($options); |
256
|
|
|
$this->assertTrue($handler->isAppropriate('/test/otherView', array(), array(), 'GET')); |
257
|
|
|
$handler->setEncoder(new NullEncoder()); |
258
|
|
|
$handler->performRoute(); |
259
|
|
|
} |
260
|
|
|
|
261
|
|
|
/** |
262
|
|
|
* Tests that we can use namespace provisioning to retrieve a controller. |
263
|
|
|
*/ |
264
|
|
View Code Duplication |
public function testNamespaceProvisioning() |
|
|
|
|
265
|
|
|
{ |
266
|
|
|
$options = array( |
267
|
|
|
Config::KEY_NAMESPACES => array( |
268
|
|
|
'Vectorface\\SnappyRouterTests\\Controller' |
269
|
|
|
), |
270
|
|
|
ControllerHandler::KEY_VIEWS => array( |
271
|
|
|
ControllerHandler::KEY_VIEWS_PATH => __DIR__.'/../Controller/Views' |
272
|
|
|
) |
273
|
|
|
); |
274
|
|
|
$handler = new ControllerHandler($options); |
275
|
|
|
$this->assertTrue($handler->isAppropriate('/testDummy/test', array(), array(), 'GET')); |
276
|
|
|
$this->assertEquals('This is a test service.', $handler->performRoute()); |
277
|
|
|
} |
278
|
|
|
|
279
|
|
|
/** |
280
|
|
|
* Tests that we can use folder provisioning to retrieve a controller. |
281
|
|
|
*/ |
282
|
|
View Code Duplication |
public function testFolderProvisioning() |
|
|
|
|
283
|
|
|
{ |
284
|
|
|
$options = array( |
285
|
|
|
Config::KEY_FOLDERS => array( |
286
|
|
|
realpath(__DIR__.'/../Controller') |
287
|
|
|
), |
288
|
|
|
ControllerHandler::KEY_VIEWS => array( |
289
|
|
|
ControllerHandler::KEY_VIEWS_PATH => __DIR__.'/../Controller/Views' |
290
|
|
|
) |
291
|
|
|
); |
292
|
|
|
$handler = new ControllerHandler($options); |
293
|
|
|
$this->assertTrue($handler->isAppropriate('/nonNamespaced/test', array(), array(), 'GET')); |
294
|
|
|
$this->assertEquals('This is a test string.', $handler->performRoute()); |
295
|
|
|
} |
296
|
|
|
} |
297
|
|
|
|
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.
You can also find more detailed suggestions in the “Code” section of your repository.