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