33
33
use Symfony \Component \Security \Core \User \InMemoryUser ;
34
34
use Symfony \Component \Security \Http \FirewallMapInterface ;
35
35
use Symfony \Component \Security \Http \Logout \LogoutUrlGenerator ;
36
+ use Symfony \Component \VarDumper \Caster \ClassStub ;
36
37
use Symfony \Contracts \EventDispatcher \EventDispatcherInterface ;
37
38
38
39
class SecurityDataCollectorTest extends TestCase
@@ -220,46 +221,111 @@ public function testGetListeners()
220
221
$ this ->assertSame (1 , $ listenerCalled );
221
222
}
222
223
223
- public static function providerCollectDecisionLog (): \ Generator
224
+ public function testCollectCollectsDecisionLogWhenStrategyIsAffirmative ()
224
225
{
225
226
$ voter1 = new DummyVoter ();
226
227
$ voter2 = new DummyVoter ();
227
228
228
- $ eventDispatcher = new class () implements EventDispatcherInterface {
229
+ $ decoratedVoter1 = new TraceableVoter ( $ voter1 , new class () implements EventDispatcherInterface {
229
230
public function dispatch (object $ event , string $ eventName = null ): object
230
231
{
231
232
return new \stdClass ();
232
233
}
233
- };
234
- $ decoratedVoter1 = new TraceableVoter ($ voter1 , $ eventDispatcher );
234
+ });
235
+
236
+ $ strategy = MainConfiguration::STRATEGY_AFFIRMATIVE ;
237
+
238
+ $ accessDecisionManager = $ this ->createMock (TraceableAccessDecisionManager::class);
239
+
240
+ $ accessDecisionManager
241
+ ->method ('getStrategy ' )
242
+ ->willReturn ($ strategy );
235
243
236
- yield [
237
- MainConfiguration::STRATEGY_AFFIRMATIVE ,
238
- [[
244
+ $ accessDecisionManager
245
+ ->method ('getVoters ' )
246
+ ->willReturn ([
247
+ $ decoratedVoter1 ,
248
+ $ decoratedVoter1 ,
249
+ ]);
250
+
251
+ $ accessDecisionManager
252
+ ->method ('getDecisionLog ' )
253
+ ->willReturn ([[
239
254
'attributes ' => ['view ' ],
240
255
'object ' => new \stdClass (),
241
256
'result ' => true ,
242
257
'voterDetails ' => [
243
258
['voter ' => $ voter1 , 'attributes ' => ['view ' ], 'vote ' => VoterInterface::ACCESS_ABSTAIN ],
244
259
['voter ' => $ voter2 , 'attributes ' => ['view ' ], 'vote ' => VoterInterface::ACCESS_ABSTAIN ],
245
260
],
246
- ]],
247
- [$ decoratedVoter1 , $ decoratedVoter1 ],
248
- [$ voter1 ::class, $ voter2 ::class],
249
- [[
250
- 'attributes ' => ['view ' ],
251
- 'object ' => new \stdClass (),
252
- 'result ' => true ,
253
- 'voter_details ' => [
254
- ['class ' => $ voter1 ::class, 'attributes ' => ['view ' ], 'vote ' => VoterInterface::ACCESS_ABSTAIN ],
255
- ['class ' => $ voter2 ::class, 'attributes ' => ['view ' ], 'vote ' => VoterInterface::ACCESS_ABSTAIN ],
256
- ],
257
- ]],
261
+ ]]);
262
+
263
+ $ dataCollector = new SecurityDataCollector (null , null , null , $ accessDecisionManager , null , null , true );
264
+
265
+ $ dataCollector ->collect (new Request (), new Response ());
266
+
267
+ $ actualDecisionLog = $ dataCollector ->getAccessDecisionLog ();
268
+
269
+ $ expectedDecisionLog = [[
270
+ 'attributes ' => ['view ' ],
271
+ 'object ' => new \stdClass (),
272
+ 'result ' => true ,
273
+ 'voter_details ' => [
274
+ ['class ' => $ voter1 ::class, 'attributes ' => ['view ' ], 'vote ' => VoterInterface::ACCESS_ABSTAIN ],
275
+ ['class ' => $ voter2 ::class, 'attributes ' => ['view ' ], 'vote ' => VoterInterface::ACCESS_ABSTAIN ],
276
+ ],
277
+ ]];
278
+
279
+ $ this ->assertEquals ($ actualDecisionLog , $ expectedDecisionLog , 'Wrong value returned by getAccessDecisionLog ' );
280
+
281
+ $ actualVoterClasses = array_map (static function (ClassStub $ classStub ): string {
282
+ return (string ) $ classStub ;
283
+ }, $ dataCollector ->getVoters ());
284
+
285
+ $ expectedVoterClasses = [
286
+ $ voter1 ::class,
287
+ $ voter2 ::class,
258
288
];
259
289
260
- yield [
261
- MainConfiguration::STRATEGY_UNANIMOUS ,
262
- [
290
+ $ this ->assertSame (
291
+ $ actualVoterClasses ,
292
+ $ expectedVoterClasses ,
293
+ 'Wrong value returned by getVoters '
294
+ );
295
+
296
+ $ this ->assertSame ($ dataCollector ->getVoterStrategy (), $ strategy , 'Wrong value returned by getVoterStrategy ' );
297
+ }
298
+
299
+ public function testCollectCollectsDecisionLogWhenStrategyIsUnanimous ()
300
+ {
301
+ $ voter1 = new DummyVoter ();
302
+ $ voter2 = new DummyVoter ();
303
+
304
+ $ decoratedVoter1 = new TraceableVoter ($ voter1 , new class () implements EventDispatcherInterface {
305
+ public function dispatch (object $ event , string $ eventName = null ): object
306
+ {
307
+ return new \stdClass ();
308
+ }
309
+ });
310
+
311
+ $ strategy = MainConfiguration::STRATEGY_UNANIMOUS ;
312
+
313
+ $ accessDecisionManager = $ this ->createMock (TraceableAccessDecisionManager::class);
314
+
315
+ $ accessDecisionManager
316
+ ->method ('getStrategy ' )
317
+ ->willReturn ($ strategy );
318
+
319
+ $ accessDecisionManager
320
+ ->method ('getVoters ' )
321
+ ->willReturn ([
322
+ $ decoratedVoter1 ,
323
+ $ decoratedVoter1 ,
324
+ ]);
325
+
326
+ $ accessDecisionManager
327
+ ->method ('getDecisionLog ' )
328
+ ->willReturn ([
263
329
[
264
330
'attributes ' => ['view ' , 'edit ' ],
265
331
'object ' => new \stdClass (),
@@ -280,78 +346,54 @@ public function dispatch(object $event, string $eventName = null): object
280
346
['voter ' => $ voter2 , 'attributes ' => ['update ' ], 'vote ' => VoterInterface::ACCESS_GRANTED ],
281
347
],
282
348
],
283
- ],
284
- [$ decoratedVoter1 , $ decoratedVoter1 ],
285
- [$ voter1 ::class, $ voter2 ::class],
349
+ ]);
350
+
351
+ $ dataCollector = new SecurityDataCollector (null , null , null , $ accessDecisionManager , null , null , true );
352
+
353
+ $ dataCollector ->collect (new Request (), new Response ());
354
+
355
+ $ actualDecisionLog = $ dataCollector ->getAccessDecisionLog ();
356
+
357
+ $ expectedDecisionLog = [
286
358
[
287
- [
288
- 'attributes ' => ['view ' , 'edit ' ],
289
- 'object ' => new \stdClass (),
290
- 'result ' => false ,
291
- 'voter_details ' => [
292
- ['class ' => $ voter1 ::class, 'attributes ' => ['view ' ], 'vote ' => VoterInterface::ACCESS_DENIED ],
293
- ['class ' => $ voter1 ::class, 'attributes ' => ['edit ' ], 'vote ' => VoterInterface::ACCESS_DENIED ],
294
- ['class ' => $ voter2 ::class, 'attributes ' => ['view ' ], 'vote ' => VoterInterface::ACCESS_GRANTED ],
295
- ['class ' => $ voter2 ::class, 'attributes ' => ['edit ' ], 'vote ' => VoterInterface::ACCESS_GRANTED ],
296
- ],
359
+ 'attributes ' => ['view ' , 'edit ' ],
360
+ 'object ' => new \stdClass (),
361
+ 'result ' => false ,
362
+ 'voter_details ' => [
363
+ ['class ' => $ voter1 ::class, 'attributes ' => ['view ' ], 'vote ' => VoterInterface::ACCESS_DENIED ],
364
+ ['class ' => $ voter1 ::class, 'attributes ' => ['edit ' ], 'vote ' => VoterInterface::ACCESS_DENIED ],
365
+ ['class ' => $ voter2 ::class, 'attributes ' => ['view ' ], 'vote ' => VoterInterface::ACCESS_GRANTED ],
366
+ ['class ' => $ voter2 ::class, 'attributes ' => ['edit ' ], 'vote ' => VoterInterface::ACCESS_GRANTED ],
297
367
],
298
- [
299
- ' attributes ' => [ ' update ' ],
300
- ' object ' => new \ stdClass () ,
301
- ' result ' => true ,
302
- ' voter_details ' => [
303
- [ ' class ' => $ voter1 ::class, ' attributes ' => [ ' update ' ], ' vote ' => VoterInterface:: ACCESS_GRANTED ],
304
- ['class ' => $ voter2 ::class, 'attributes ' => ['update ' ], 'vote ' => VoterInterface::ACCESS_GRANTED ],
305
- ],
368
+ ],
369
+ [
370
+ ' attributes ' => [ ' update ' ] ,
371
+ ' object ' => new \ stdClass () ,
372
+ ' result ' => true ,
373
+ ' voter_details ' => [
374
+ ['class ' => $ voter1 ::class, 'attributes ' => ['update ' ], 'vote ' => VoterInterface::ACCESS_GRANTED ],
375
+ [ ' class ' => $ voter2 ::class, ' attributes ' => [ ' update ' ], ' vote ' => VoterInterface:: ACCESS_GRANTED ],
306
376
],
307
377
],
308
378
];
309
- }
310
379
311
- /**
312
- * Test the returned data when AccessDecisionManager is a TraceableAccessDecisionManager.
313
- *
314
- * @param string $strategy strategy returned by the AccessDecisionManager
315
- * @param array $voters voters returned by AccessDecisionManager
316
- * @param array $decisionLog log of the votes and final decisions from AccessDecisionManager
317
- * @param array $expectedVoterClasses expected voter classes returned by the collector
318
- * @param array $expectedDecisionLog expected decision log returned by the collector
319
- *
320
- * @dataProvider providerCollectDecisionLog
321
- */
322
- public function testCollectDecisionLog (string $ strategy , array $ decisionLog , array $ voters , array $ expectedVoterClasses , array $ expectedDecisionLog )
323
- {
324
- $ accessDecisionManager = $ this
325
- ->getMockBuilder (TraceableAccessDecisionManager::class)
326
- ->disableOriginalConstructor ()
327
- ->setMethods (['getStrategy ' , 'getVoters ' , 'getDecisionLog ' ])
328
- ->getMock ();
380
+ $ this ->assertEquals ($ actualDecisionLog , $ expectedDecisionLog , 'Wrong value returned by getAccessDecisionLog ' );
329
381
330
- $ accessDecisionManager
331
- ->expects ($ this ->any ())
332
- ->method ('getStrategy ' )
333
- ->willReturn ($ strategy );
382
+ $ actualVoterClasses = array_map (static function (ClassStub $ classStub ): string {
383
+ return (string ) $ classStub ;
384
+ }, $ dataCollector ->getVoters ());
334
385
335
- $ accessDecisionManager
336
- ->expects ($ this ->any ())
337
- ->method ('getVoters ' )
338
- ->willReturn ($ voters );
339
-
340
- $ accessDecisionManager
341
- ->expects ($ this ->any ())
342
- ->method ('getDecisionLog ' )
343
- ->willReturn ($ decisionLog );
344
-
345
- $ dataCollector = new SecurityDataCollector (null , null , null , $ accessDecisionManager , null , null , true );
346
- $ dataCollector ->collect (new Request (), new Response ());
347
-
348
- $ this ->assertEquals ($ dataCollector ->getAccessDecisionLog (), $ expectedDecisionLog , 'Wrong value returned by getAccessDecisionLog ' );
386
+ $ expectedVoterClasses = [
387
+ $ voter1 ::class,
388
+ $ voter2 ::class,
389
+ ];
349
390
350
391
$ this ->assertSame (
351
- array_map ( function ( $ classStub ) { return ( string ) $ classStub ; }, $ dataCollector -> getVoters ()) ,
392
+ $ actualVoterClasses ,
352
393
$ expectedVoterClasses ,
353
394
'Wrong value returned by getVoters '
354
395
);
396
+
355
397
$ this ->assertSame ($ dataCollector ->getVoterStrategy (), $ strategy , 'Wrong value returned by getVoterStrategy ' );
356
398
}
357
399
@@ -387,7 +429,7 @@ private function getRoleHierarchy()
387
429
}
388
430
}
389
431
390
- class DummyVoter implements VoterInterface
432
+ final class DummyVoter implements VoterInterface
391
433
{
392
434
public function vote (TokenInterface $ token , mixed $ subject , array $ attributes ): int
393
435
{
0 commit comments