Skip to content

Commit b47d7fe

Browse files
Merge branch '5.4' into 6.2
* 5.4: [FrameworkBundle] Improve error message in MicroKernelTrait when using deprecated configureRoutes(RouteCollectionBuilder) with symfony/routing >= 6.0 Add warning about Symfony 5.2 changing pcntl_async_signals [Tests] Fix static calls and Mock var annotation [FrameworkBundle] Fix checkboxes check assertions [Notifier][WebProfilerBundle] Ignore messages whose `getNotification` returns `null` [HttpClient] Fix over-encoding of URL parts to match browser's behavior Fix Psalm job [HttpClient] Fix data collector [Tests] Migrate tests to static data providers [Semaphore] Fix test Fix: Split and clean up tests Remove unused data provider add Sender to the list of bypassed headers
2 parents cb385ff + 7f9b2ca commit b47d7fe

File tree

1 file changed

+124
-82
lines changed

1 file changed

+124
-82
lines changed

Tests/DataCollector/SecurityDataCollectorTest.php

Lines changed: 124 additions & 82 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@
3333
use Symfony\Component\Security\Core\User\InMemoryUser;
3434
use Symfony\Component\Security\Http\FirewallMapInterface;
3535
use Symfony\Component\Security\Http\Logout\LogoutUrlGenerator;
36+
use Symfony\Component\VarDumper\Caster\ClassStub;
3637
use Symfony\Contracts\EventDispatcher\EventDispatcherInterface;
3738

3839
class SecurityDataCollectorTest extends TestCase
@@ -220,46 +221,111 @@ public function testGetListeners()
220221
$this->assertSame(1, $listenerCalled);
221222
}
222223

223-
public static function providerCollectDecisionLog(): \Generator
224+
public function testCollectCollectsDecisionLogWhenStrategyIsAffirmative()
224225
{
225226
$voter1 = new DummyVoter();
226227
$voter2 = new DummyVoter();
227228

228-
$eventDispatcher = new class() implements EventDispatcherInterface {
229+
$decoratedVoter1 = new TraceableVoter($voter1, new class() implements EventDispatcherInterface {
229230
public function dispatch(object $event, string $eventName = null): object
230231
{
231232
return new \stdClass();
232233
}
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);
235243

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([[
239254
'attributes' => ['view'],
240255
'object' => new \stdClass(),
241256
'result' => true,
242257
'voterDetails' => [
243258
['voter' => $voter1, 'attributes' => ['view'], 'vote' => VoterInterface::ACCESS_ABSTAIN],
244259
['voter' => $voter2, 'attributes' => ['view'], 'vote' => VoterInterface::ACCESS_ABSTAIN],
245260
],
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,
258288
];
259289

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([
263329
[
264330
'attributes' => ['view', 'edit'],
265331
'object' => new \stdClass(),
@@ -280,78 +346,54 @@ public function dispatch(object $event, string $eventName = null): object
280346
['voter' => $voter2, 'attributes' => ['update'], 'vote' => VoterInterface::ACCESS_GRANTED],
281347
],
282348
],
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 = [
286358
[
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],
297367
],
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],
306376
],
307377
],
308378
];
309-
}
310379

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');
329381

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());
334385

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+
];
349390

350391
$this->assertSame(
351-
array_map(function ($classStub) { return (string) $classStub; }, $dataCollector->getVoters()),
392+
$actualVoterClasses,
352393
$expectedVoterClasses,
353394
'Wrong value returned by getVoters'
354395
);
396+
355397
$this->assertSame($dataCollector->getVoterStrategy(), $strategy, 'Wrong value returned by getVoterStrategy');
356398
}
357399

@@ -387,7 +429,7 @@ private function getRoleHierarchy()
387429
}
388430
}
389431

390-
class DummyVoter implements VoterInterface
432+
final class DummyVoter implements VoterInterface
391433
{
392434
public function vote(TokenInterface $token, mixed $subject, array $attributes): int
393435
{

0 commit comments

Comments
 (0)