13
13
14
14
use Psr \Container \ContainerInterface ;
15
15
use Psr \Log \LoggerInterface ;
16
- use Symfony \Component \Debug \ErrorHandler ;
17
16
use Symfony \Component \DependencyInjection \Container ;
18
17
use Symfony \Component \HttpFoundation \Request ;
19
18
use Symfony \Component \HttpKernel \Controller \ContainerControllerResolver ;
20
19
21
20
class ContainerControllerResolverTest extends ControllerResolverTest
22
21
{
23
- public function testGetControllerService ()
22
+ public function testGetControllerServiceWithSingleColon ()
24
23
{
24
+ $ service = new ControllerTestService ('foo ' );
25
+
25
26
$ container = $ this ->createMockContainer ();
26
27
$ container ->expects ($ this ->once ())
27
28
->method ('has ' )
@@ -30,191 +31,163 @@ public function testGetControllerService()
30
31
$ container ->expects ($ this ->once ())
31
32
->method ('get ' )
32
33
->with ('foo ' )
33
- ->willReturn ($ this )
34
+ ->willReturn ($ service )
34
35
;
35
36
36
37
$ resolver = $ this ->createControllerResolver (null , $ container );
37
38
$ request = Request::create ('/ ' );
38
- $ request ->attributes ->set ('_controller ' , 'foo:controllerMethod1 ' );
39
+ $ request ->attributes ->set ('_controller ' , 'foo:action ' );
39
40
40
41
$ controller = $ resolver ->getController ($ request );
41
42
42
- $ this ->assertInstanceOf ( \get_class ( $ this ) , $ controller [0 ]);
43
- $ this ->assertSame ('controllerMethod1 ' , $ controller [1 ]);
43
+ $ this ->assertSame ( $ service , $ controller [0 ]);
44
+ $ this ->assertSame ('action ' , $ controller [1 ]);
44
45
}
45
46
46
- public function testGetControllerInvokableService ()
47
+ public function testGetControllerService ()
47
48
{
48
- $ invokableController = new InvokableController ( ' bar ' );
49
+ $ service = new ControllerTestService ( ' foo ' );
49
50
50
51
$ container = $ this ->createMockContainer ();
51
52
$ container ->expects ($ this ->once ())
52
53
->method ('has ' )
53
54
->with ('foo ' )
54
- ->willReturn (true )
55
- ;
55
+ ->willReturn (true );
56
56
$ container ->expects ($ this ->once ())
57
57
->method ('get ' )
58
58
->with ('foo ' )
59
- ->willReturn ($ invokableController )
59
+ ->willReturn ($ service )
60
60
;
61
61
62
62
$ resolver = $ this ->createControllerResolver (null , $ container );
63
63
$ request = Request::create ('/ ' );
64
- $ request ->attributes ->set ('_controller ' , 'foo ' );
64
+ $ request ->attributes ->set ('_controller ' , 'foo::action ' );
65
65
66
66
$ controller = $ resolver ->getController ($ request );
67
67
68
- $ this ->assertEquals ($ invokableController , $ controller );
68
+ $ this ->assertSame ($ service , $ controller [0 ]);
69
+ $ this ->assertSame ('action ' , $ controller [1 ]);
69
70
}
70
71
71
- public function testGetControllerInvokableServiceWithClassNameAsName ()
72
+ public function testGetControllerInvokableService ()
72
73
{
73
- $ invokableController = new InvokableController ('bar ' );
74
- $ className = __NAMESPACE__ .'\InvokableController ' ;
74
+ $ service = new InvokableControllerService ('bar ' );
75
75
76
76
$ container = $ this ->createMockContainer ();
77
77
$ container ->expects ($ this ->once ())
78
78
->method ('has ' )
79
- ->with ($ className )
79
+ ->with (' foo ' )
80
80
->willReturn (true )
81
81
;
82
82
$ container ->expects ($ this ->once ())
83
83
->method ('get ' )
84
- ->with ($ className )
85
- ->willReturn ($ invokableController )
84
+ ->with (' foo ' )
85
+ ->willReturn ($ service )
86
86
;
87
87
88
88
$ resolver = $ this ->createControllerResolver (null , $ container );
89
89
$ request = Request::create ('/ ' );
90
- $ request ->attributes ->set ('_controller ' , $ className );
90
+ $ request ->attributes ->set ('_controller ' , ' foo ' );
91
91
92
92
$ controller = $ resolver ->getController ($ request );
93
93
94
- $ this ->assertEquals ( $ invokableController , $ controller );
94
+ $ this ->assertSame ( $ service , $ controller );
95
95
}
96
96
97
- public function testNonInstantiableController ()
97
+ public function testGetControllerInvokableServiceWithClassNameAsName ()
98
98
{
99
+ $ service = new InvokableControllerService ('bar ' );
100
+
99
101
$ container = $ this ->createMockContainer ();
100
102
$ container ->expects ($ this ->once ())
101
103
->method ('has ' )
102
- ->with (NonInstantiableController::class)
103
- ->willReturn (false )
104
+ ->with (InvokableControllerService::class)
105
+ ->willReturn (true )
106
+ ;
107
+ $ container ->expects ($ this ->once ())
108
+ ->method ('get ' )
109
+ ->with (InvokableControllerService::class)
110
+ ->willReturn ($ service )
104
111
;
105
112
106
113
$ resolver = $ this ->createControllerResolver (null , $ container );
107
114
$ request = Request::create ('/ ' );
108
- $ request ->attributes ->set ('_controller ' , [NonInstantiableController ::class, ' action ' ] );
115
+ $ request ->attributes ->set ('_controller ' , InvokableControllerService ::class);
109
116
110
117
$ controller = $ resolver ->getController ($ request );
111
118
112
- $ this ->assertSame ([NonInstantiableController::class, '
10000
action ' ] , $ controller );
119
+ $ this ->assertSame ($ service , $ controller );
113
120
}
114
121
115
- public function testNonConstructController ()
116
- {
117
- $ this ->expectException ('LogicException ' );
118
- $ this ->expectExceptionMessage ('Controller "Symfony\Component\HttpKernel\Tests\Controller\ImpossibleConstructController" cannot be fetched from the container because it is private. Did you forget to tag the service with "controller.service_arguments"? ' );
119
- $ container = $ this ->getMockBuilder (Container::class)->getMock ();
120
- $ container ->expects ($ this ->at (0 ))
121
- ->method ('has ' )
122
- ->with (ImpossibleConstructController::class)
123
- ->willReturn (true )
124
- ;
125
-
126
- $ container ->expects ($ this ->at (1 ))
127
- ->method ('has ' )
128
- ->with (ImpossibleConstructController::class)
129
- ->willReturn (false )
130
- ;
131
-
132
- $ container ->expects ($ this ->atLeastOnce ())
133
- ->method ('getRemovedIds ' )
134
- ->with ()
135
- ->willReturn ([ImpossibleConstructController::class => true ])
136
- ;
137
-
138
- $ resolver = $ this ->createControllerResolver (null , $ container );
139
- $ request = Request::create ('/ ' );
140
- $ request ->attributes ->set ('_controller ' , [ImpossibleConstructController::class, 'action ' ]);
141
-
142
- if (\PHP_VERSION_ID < 70100 ) {
143
- ErrorHandler::register ();
144
- try {
145
- $ resolver ->getController ($ request );
146
- } finally {
147
- restore_error_handler ();
148
- restore_exception_handler ();
149
- }
150
- } else {
151
- $ resolver ->getController ($ request );
152
- }
153
- }
154
-
155
- public function testNonInstantiableControllerWithCorrespondingService ()
122
+ /**
123
+ * @dataProvider getControllers
124
+ */
125
+ public function testInstantiateControllerWhenControllerStartsWithABackslash ($ controller )
156
126
{
157
- $ service = new \stdClass ();
127
+ $ service = new ControllerTestService ('foo ' );
128
+ $ class = ControllerTestService::class;
158
129
159
130
$ container = $ this ->createMockContainer ();
160
- $ container ->expects ($ this ->atLeastOnce ())
161
- ->method ('has ' )
162
- ->with (NonInstantiableController::class)
163
- ->willReturn (true )
164
- ;
165
- $ container ->expects ($ this ->atLeastOnce ())
166
- ->method ('get ' )
167
- ->with (NonInstantiableController::class)
168
- ->willReturn ($ service )
169
- ;
131
+ $ container ->expects ($ this ->once ())->method ('has ' )->with ($ class )->willReturn (true );
132
+ $ container ->expects ($ this ->once ())->method ('get ' )->with ($ class )->willReturn ($ service );
170
133
171
134
$ resolver = $ this ->createControllerResolver (null , $ container );
172
135
$ request = Request::create ('/ ' );
173
- $ request ->attributes ->set ('_controller ' , [NonInstantiableController::class, ' action ' ] );
136
+ $ request ->attributes ->set ('_controller ' , $ controller );
174
137
175
138
$ controller = $ resolver ->getController ($ request );
176
139
177
- $ this ->assertSame ([$ service , 'action ' ], $ controller );
140
+ $ this ->assertInstanceOf (ControllerTestService::class, $ controller [0 ]);
141
+ $ this ->assertSame ('action ' , $ controller [1 ]);
178
142
}
179
143
180
- public function testExceptionWhenUsingRemovedControllerService ()
144
+ public function getControllers ()
181
145
{
182
- $ this ->expectException ('LogicException ' );
183
- $ this ->expectExceptionMessage ('Controller "app.my_controller" cannot be fetched from the container because it is private. Did you forget to tag the service with "controller.service_arguments"? ' );
146
+ return [
147
+ ['\\' .ControllerTestService::class.'::action ' ],
148
+ ['\\' .ControllerTestService::class.':action ' ],
149
+ ];
150
+ }
151
+
152
+ public function testExceptionWhenUsingRemovedControllerServiceWithClassNameAsName ()
153
+ {
154
+ $ this ->expectException ('InvalidArgumentException ' );
155
+ $ this ->expectExceptionMessage ('Controller "Symfony\Component\HttpKernel\Tests\Controller\ControllerTestService" cannot be fetched from the container because it is private. Did you forget to tag the service with "controller.service_arguments"? ' );
184
156
$ container = $ this ->getMockBuilder (Container::class)->getMock ();
185
- $ container ->expects ($ this ->at ( 0 ))
157
+ $ container ->expects ($ this ->once ( ))
186
158
->method ('has ' )
187
- ->with (' app.my_controller ' )
159
+ ->with (ControllerTestService::class )
188
160
->willReturn (false )
189
161
;
190
162
191
163
$ container ->expects ($ this ->atLeastOnce ())
192
164
->method ('getRemovedIds ' )
193
165
->with ()
194
- ->willReturn ([' app.my_controller ' => true ])
166
+ ->willReturn ([ControllerTestService::class => true ])
195
167
;
196
168
197
169
$ resolver = $ this ->createControllerResolver (null , $ container );
198
-
199
170
$ request = Request::create ('/ ' );
200
- $ request ->attributes ->set ('_controller ' , 'app.my_controller ' );
171
+ $ request ->attributes ->set ('_controller ' , [ControllerTestService::class, 'action ' ]);
172
+
201
173
$ resolver ->getController ($ request );
202
174
}
203
175
204
- public function testExceptionWhenUsingControllerWithoutAnInvokeMethod ()
176
+ public function testExceptionWhenUsingRemovedControllerService ()
205
177
{
206
- $ this ->expectException ('LogicException ' );
207
- $ this ->expectExceptionMessage ('Controller "app.my_controller" cannot be called without a method name . Did you forget an "__invoke" method ? ' );
178
+ $ this ->expectException ('InvalidArgumentException ' );
179
+ $ this ->expectExceptionMessage ('Controller "app.my_controller" cannot be fetched from the container because it is private . Did you forget to tag the service with "controller.service_arguments" ? ' );
208
180
$ container = $ this ->getMockBuilder (Container::class)->getMock ();
209
181
$ container ->expects ($ this ->once ())
210
182
->method ('has ' )
211
183
->with ('app.my_controller ' )
212
- ->willReturn (true )
184
+ ->willReturn (false )
213
185
;
214
- $ container ->expects ($ this ->once ())
215
- ->method ('get ' )
216
- ->with ('app.my_controller ' )
217
- ->willReturn (new ImpossibleConstructController ('toto ' , 'controller ' ))
186
+
187
+ $ container ->expects ($ this ->atLeastOnce ())
188
+ ->method ('getRemovedIds ' )
189
+ ->with ()
190
+ ->willReturn (['app.my_controller ' => true ])
218
191
;
219
192
220
193
$ resolver = $ this ->createControllerResolver (null , $ container );
@@ -224,33 +197,28 @@ public function testExceptionWhenUsingControllerWithoutAnInvokeMethod()
224
197
$ resolver ->getController ($ request );
225
198
}
226
199
227
- /**
228
- * @dataProvider getUndefinedControllers
229
- */
230
- public function testGetControllerOnNonUndefinedFunction ($ controller , $ exceptionName = null , $ exceptionMessage = null )
231
- {
232
- // All this logic needs to be duplicated, since calling parent::testGetControllerOnNonUndefinedFunction will override the expected excetion and not use the regex
233
- $ resolver = $ this ->createControllerResolver ();
234
- $ this ->expectException ($ exceptionName );
235
- $ this ->expectExceptionMessageRegExp ($ exceptionMessage );
236
-
237
- $ request = Request::create ('/ ' );
238
- $ request ->attributes ->set ('_controller ' , $ controller );
239
- $ resolver ->getController ($ request );
240
- }
241
-
242
200
public function getUndefinedControllers ()
243
201
{
244
- return [
245
- ['foo ' , \LogicException::class, '/Controller not found: service "foo" does not exist\./ ' ],
246
- ['oof::bar ' , \InvalidArgumentException::class, '/Class "oof" does not exist\./ ' ],
247
- ['stdClass ' , \LogicException::class, '/Controller not found: service "stdClass" does not exist\./ ' ],
248
- [
249
- 'Symfony\Component\HttpKernel\Tests\Controller\ControllerResolverTest::bar ' ,
250
- \InvalidArgumentException::class,
251
- '/.?[cC]ontroller(.*?) for URI "\/" is not callable\.( Expected method(.*) Available methods)?/ ' ,
252
- ],
202
+ $ tests = parent ::getUndefinedControllers ();
203
+ $ tests [0 ] = ['foo ' , \InvalidArgumentException::class, 'Controller "foo" does neither exist as service nor as class ' ];
204
+ $ tests [1 ] = ['oof::bar ' , \InvalidArgumentException::class, 'Controller "oof" does neither exist as service nor as class ' ];
205
+ $ tests [2 ] = [['oof ' , 'bar ' ], \InvalidArgumentException::class, 'Controller "oof" does neither exist as service nor as class ' ];
206
+ $ tests [] = [
207
+ [ControllerTestService::class, 'action ' ],
208
+ \InvalidArgumentException::class,
209
+ 'Controller "Symfony\Component\HttpKernel\Tests\Controller\ControllerTestService" has required constructor arguments and does not exist in the container. Did you forget to define such a service? ' ,
210
+ ];
211
+ $ tests [] = [
212
+ ControllerTestService::class.'::action ' ,
213
+ \InvalidArgumentException::class, 'Controller "Symfony\Component\HttpKernel\Tests\Controller\ControllerTestService" has required constructor arguments and does not exist in the container. Did you forget to define such a service? ' ,
214
+ ];
215
+ $ tests [] = [
216
+ InvokableControllerService::class,
217
+ \InvalidArgumentException::class,
218
+ 'Controller "Symfony\Component\HttpKernel\Tests\Controller\InvokableControllerService" has required constructor arguments and does not exist in the container. Did you forget to define such a service? ' ,
253
219
];
220
+
221
+ return $ tests ;
254
222
}
255
223
256
224
protected function createControllerResolver (LoggerInterface $ logger = null , ContainerInterface $ container = null )
@@ -268,7 +236,7 @@ protected function createMockContainer()
268
236
}
269
237
}
270
238
271
- class InvokableController
239
+ class InvokableControllerService
272
240
{
273
241
public function __construct ($ bar ) // mandatory argument to prevent automatic instantiation
274
242
{
@@ -279,16 +247,9 @@ public function __invoke()
279
247
}
280
248
}
281
249
282
- abstract class NonInstantiableController
283
- {
284
- public static function action ()
285
- {
286
- }
287
- }
288
-
289
- class ImpossibleConstructController
250
+ class ControllerTestService
290
251
{
291
- public function __construct ($ toto , $ controller )
252
+ public function __construct ($ foo )
292
253
{
293
254
}
294
255
0 commit comments