1616use Symfony \Component \HttpKernel \Controller \ArgumentResolver ;
1717use Symfony \Component \HttpKernel \Controller \ArgumentResolver \DefaultValueResolver ;
1818use Symfony \Component \HttpKernel \ControllerMetadata \ArgumentMetadata ;
19+ use Symfony \Component \Security \Core \Authentication \Token \NullToken ;
1920use Symfony \Component \Security \Core \Authentication \Token \Storage \TokenStorage ;
2021use Symfony \Component \Security \Core \Authentication \Token \UsernamePasswordToken ;
22+ use Symfony \Component \Security \Core \Exception \AccessDeniedException ;
2123use Symfony \Component \Security \Core \User \InMemoryUser ;
2224use Symfony \Component \Security \Core \User \UserInterface ;
2325use Symfony \Component \Security \Http \Attribute \CurrentUser ;
2426use Symfony \Component \Security \Http \Controller \UserValueResolver ;
2527
2628class UserValueResolverTest extends TestCase
2729{
28- public function testResolveNoToken ()
30+ public function testSupportsFailsWithNoType ()
2931 {
3032 $ tokenStorage = new TokenStorage ();
3133 $ resolver = new UserValueResolver ($ tokenStorage );
32- $ metadata = new ArgumentMetadata ('foo ' , UserInterface::class , false , false , null );
34+ $ metadata = new ArgumentMetadata ('foo ' , null , false , false , null );
3335
3436 $ this ->assertFalse ($ resolver ->supports (Request::create ('/ ' ), $ metadata ));
3537 }
3638
37- public function testResolveNoUser ()
39+ public function testSupportsFailsWhenDefaultValAndNoUser ()
3840 {
39- $ mock = $ this ->createMock (UserInterface::class);
40- $ token = new UsernamePasswordToken (new InMemoryUser ('username ' , 'password ' ), 'provider ' );
4141 $ tokenStorage = new TokenStorage ();
42- $ tokenStorage ->setToken ($ token );
43-
4442 $ resolver = new UserValueResolver ($ tokenStorage );
45- $ metadata = new ArgumentMetadata ('foo ' , \get_class ( $ mock ) , false , false , null );
43+ $ metadata = new ArgumentMetadata ('foo ' , UserInterface::class , false , true , new InMemoryUser ( ' username ' , ' password ' ) );
4644
4745 $ this ->assertFalse ($ resolver ->supports (Request::create ('/ ' ), $ metadata ));
4846 }
4947
50- public function testResolveWrongType ()
48+ public function testResolveSucceedsWithUserInterface ()
5149 {
50+ $ user = new InMemoryUser ('username ' , 'password ' );
51+ $ token = new UsernamePasswordToken ($ user , 'provider ' );
5252 $ tokenStorage = new TokenStorage ();
53+ $ tokenStorage ->setToken ($ token );
54+
5355 $ resolver = new UserValueResolver ($ tokenStorage );
54- $ metadata = new ArgumentMetadata ('foo ' , null , false , false , null );
56+ $ metadata = new ArgumentMetadata ('foo ' , UserInterface::class , false , false , null );
5557
56- $ this ->assertFalse ($ resolver ->supports (Request::create ('/ ' ), $ metadata ));
58+ $ this ->assertTrue ($ resolver ->supports (Request::create ('/ ' ), $ metadata ));
59+ $ this ->assertSame ([$ user ], iterator_to_array ($ resolver ->resolve (Request::create ('/ ' ), $ metadata )));
5760 }
5861
59- public function testResolve ()
62+ public function testResolveSucceedsWithSubclassType ()
6063 {
6164 $ user = new InMemoryUser ('username ' , 'password ' );
6265 $ token = new UsernamePasswordToken ($ user , 'provider ' );
6366 $ tokenStorage = new TokenStorage ();
6467 $ tokenStorage ->setToken ($ token );
6568
6669 $ resolver = new UserValueResolver ($ tokenStorage );
67- $ metadata = new ArgumentMetadata ('foo ' , UserInterface ::class, false , false , null );
70+ $ metadata = new ArgumentMetadata ('foo ' , InMemoryUser ::class, false , false , null , false , [ new CurrentUser ()] );
6871
6972 $ this ->assertTrue ($ resolver ->supports (Request::create ('/ ' ), $ metadata ));
7073 $ this ->assertSame ([$ user ], iterator_to_array ($ resolver ->resolve (Request::create ('/ ' ), $ metadata )));
7174 }
7275
73- public function testResolveWithAttribute ()
76+ public function testResolveSucceedsWithNullableParamAndNoUser ()
77+ {
78+ $ token = new NullToken ();
79+ $ tokenStorage = new TokenStorage ();
80+ $ tokenStorage ->setToken ($ token );
81+
82+ $ resolver = new UserValueResolver ($ tokenStorage );
83+ $ metadata = new ArgumentMetadata ('foo ' , InMemoryUser::class, false , false , null , true , [new CurrentUser ()]);
84+
85+ $ this ->assertTrue ($ resolver ->supports (Request::create ('/ ' ), $ metadata ));
86+ $ this ->assertSame ([null ], iterator_to_array ($ resolver ->resolve (Request::create ('/ ' ), $ metadata )));
87+ }
88+
89+ public function testResolveSucceedsWithNullableAttribute ()
7490 {
7591 $ user = new InMemoryUser ('username ' , 'password ' );
7692 $ token = new UsernamePasswordToken ($ user , 'provider ' );
@@ -85,14 +101,59 @@ public function testResolveWithAttribute()
85101 $ this ->assertSame ([$ user ], iterator_to_array ($ resolver ->resolve (Request::create ('/ ' ), $ metadata )));
86102 }
87103
88- public function testResolveWithAttributeAndNoUser ()
104+ public function testResolveSucceedsWithTypedAttribute ()
89105 {
106+ $ user = new InMemoryUser ('username ' , 'password ' );
107+ $ token = new UsernamePasswordToken ($ user , 'provider ' );
90108 $ tokenStorage = new TokenStorage ();
109+ $ tokenStorage ->setToken ($ token );
91110
92111 $ resolver = new UserValueResolver ($ tokenStorage );
93- $ metadata = new ArgumentMetadata ('foo ' , null , false , false , null , false , [new CurrentUser ()]);
112+ $ metadata = $ this ->createMock (ArgumentMetadata::class);
113+ $ metadata = new ArgumentMetadata ('foo ' , InMemoryUser::class, false , false , null , false , [new CurrentUser ()]);
94114
95- $ this ->assertFalse ($ resolver ->supports (Request::create ('/ ' ), $ metadata ));
115+ $ this ->assertTrue ($ resolver ->supports (Request::create ('/ ' ), $ metadata ));
116+ $ this ->assertSame ([$ user ], iterator_to_array ($ resolver ->resolve (Request::create ('/ ' ), $ metadata )));
117+ }
118+
119+ public function testResolveThrowsAccessDeniedWithWrongUserClass ()
120+ {
121+ $ user = $ this ->createMock (UserInterface::class);
122+ $ token = new UsernamePasswordToken ($ user , 'provider ' );
123+ $ tokenStorage = new TokenStorage ();
124+ $ tokenStorage ->setToken ($ token );
125+
126+ $ resolver = new UserValueResolver ($ tokenStorage );
127+ $ metadata = new ArgumentMetadata ('foo ' , InMemoryUser::class, false , false , null , false , [new CurrentUser ()]);
128+
129+ $ this ->assertTrue ($ resolver ->supports (Request::create ('/ ' ), $ metadata ));
130+ $ this ->expectException (AccessDeniedException::class);
131+ $ this ->expectExceptionMessageMatches ('/^The logged-in user is an instance of "Mock_UserInterface[^"]+" and an user of type "Symfony \\\\Component \\\\Security \\\\Core \\\\User \\\\InMemoryUser" is expected.$/ ' );
132+ iterator_to_array ($ resolver ->resolve (Request::create ('/ ' ), $ metadata ));
133+ }
134+
135+ public function testResolveThrowsAccessDeniedWithAttributeAndNoUser ()
136+ {
137+ $ tokenStorage = new TokenStorage ();
138+
139+ $ resolver = new UserValueResolver ($ tokenStorage );
140+ $ metadata = new ArgumentMetadata ('foo ' , UserInterface::class, false , false , null , false , [new CurrentUser ()]);
141+
142+ $ this ->assertTrue ($ resolver ->supports (Request::create ('/ ' ), $ metadata ));
143+ $ this ->expectException (AccessDeniedException::class);
144+ $ this ->expectExceptionMessage ('There is no logged-in user to pass to $foo, make the argument nullable if you want to allow anonymous access to the action. ' );
145+ iterator_to_array ($ resolver ->resolve (Request::create ('/ ' ), $ metadata ));
146+ }
147+
148+ public function testResolveThrowsAcessDeniedWithNoToken ()
149+ {
150+ $ tokenStorage = new TokenStorage ();
151+ $ resolver = new UserValueResolver ($ tokenStorage );
152+ $ metadata = new ArgumentMetadata ('foo ' , UserInterface::class, false , false , null );
153+
154+ $ this ->assertTrue ($ resolver ->supports (Request::create ('/ ' ), $ metadata ));
155+ $ this ->expectException (AccessDeniedException::class);
156+ iterator_to_array ($ resolver ->resolve (Request::create ('/ ' ), $ metadata ));
96157 }
97158
98159 public function testIntegration ()
0 commit comments