8000 Split and clean up tests by localheinz · Pull Request #49286 · symfony/symfony · GitHub
[go: up one dir, main page]

Skip to content
Dismiss alert

Split and clean up tests #49286

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Feb 10, 2023
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@
use Symfony\Component\Security\Core\User\InMemoryUser;
use Symfony\Component\Security\Http\FirewallMapInterface;
use Symfony\Component\Security\Http\Logout\LogoutUrlGenerator;
use Symfony\Component\VarDumper\Caster\ClassStub;
use Symfony\Contracts\EventDispatcher\EventDispatcherInterface;

class SecurityDataCollectorTest extends TestCase
Expand Down Expand Up @@ -223,46 +224,111 @@ public function testGetListeners()
$this->assertSame(1, $listenerCalled);
}

public static function providerCollectDecisionLog(): \Generator
public function testCollectCollectsDecisionLogWhenStrategyIsAffirmative()
{
$voter1 = new DummyVoter();
$voter2 = new DummyVoter();

$eventDispatcher = new class() implements EventDispatcherInterface {
$decoratedVoter1 = new TraceableVoter($voter1, new class() implements EventDispatcherInterface {
public function dispatch(object $event, string $eventName = null): object
{
return new \stdClass();
}
};
$decoratedVoter1 = new TraceableVoter($voter1, $eventDispatcher);
});

$strategy = MainConfiguration::STRATEGY_AFFIRMATIVE;

$accessDecisionManager = $this->createMock(TraceableAccessDecisionManager::class);

$accessDecisionManager
->method('getStrategy')
->willReturn($strategy);

yield [
MainConfiguration::STRATEGY_AFFIRMATIVE,
[[
$accessDecisionManager
->method('getVoters')
->willReturn([
$decoratedVoter1,
$decoratedVoter1,
]);

$accessDecisionManager
->method('getDecisionLog')
->willReturn([[
'attributes' => ['view'],
'object' => new \stdClass(),
'result' => true,
'voterDetails' => [
['voter' => $voter1, 'attributes' => ['view'], 'vote' => VoterInterface::ACCESS_ABSTAIN],
['voter' => $voter2, 'attributes' => ['view'], 'vote' => VoterInterface::ACCESS_ABSTAIN],
],
]],
[$decoratedVoter1, $decoratedVoter1],
[\get_class($voter1), \get_class($voter2)],
[[
'attributes' => ['view'],
'object' => new \stdClass(),
'result' => true,
'voter_details' => [
['class' => \get_class($voter1), 'attributes' => ['view'], 'vote' => VoterInterface::ACCESS_ABSTAIN],
['class' => \get_class($voter2), 'attributes' => ['view'], 'vote' => VoterInterface::ACCESS_ABSTAIN],
],
]],
]]);

$dataCollector = new SecurityDataCollector(null, null, null, $accessDecisionManager, null, null, true);

$dataCollector->collect(new Request(), new Response());

$actualDecisionLog = $dataCollector->getAccessDecisionLog();

$expectedDecisionLog = [[
'attributes' => ['view'],
'object' => new \stdClass(),
'result' => true,
'voter_details' => [
['class' => \get_class($voter1), 'attributes' => ['view'], 'vote' => VoterInterface::ACCESS_ABSTAIN],
['class' => \get_class($voter2), 'attributes' => ['view'], 'vote' => VoterInterface::ACCESS_ABSTAIN],
],
]];

$this->assertEquals($actualDecisionLog, $expectedDecisionLog, 'Wrong value returned by getAccessDecisionLog');

$actualVoterClasses = array_map(static function (ClassStub $classStub): string {
return (string) $classStub;
}, $dataCollector->getVoters());

$expectedVoterClasses = [
\get_class($voter1),
\get_class($voter2),
];

yield [
MainConfiguration::STRATEGY_UNANIMOUS,
[
$this->assertSame(
$actualVoterClasses,
$expectedVoterClasses,
'Wrong value returned by getVoters'
);

$this->assertSame($dataCollector->getVoterStrategy(), $strategy, 'Wrong value returned by getVoterStrategy');
}

public function testCollectCollectsDecisionLogWhenStrategyIsUnanimous()
{
$voter1 = new DummyVoter();
$voter2 = new DummyVoter();

$decoratedVoter1 = new TraceableVoter($voter1, new class() implements EventDispatcherInterface {
public function dispatch(object $event, string $eventName = null): object
{
return new \stdClass();
}
});

$strategy = MainConfiguration::STRATEGY_UNANIMOUS;

$accessDecisionManager = $this->createMock(TraceableAccessDecisionManager::class);

$accessDecisionManager
->method('getStrategy')
->willReturn($strategy);

$accessDecisionManager
->method('getVoters')
->willReturn([
$decoratedVoter1,
$decoratedVoter1,
]);

$accessDecisionManager
->method('getDecisionLog')
->willReturn([
[
'attributes' => ['view', 'edit'],
'object' => new \stdClass(),
Expand All @@ -283,78 +349,54 @@ public function dispatch(object $event, string $eventName = null): object
['voter' => $voter2, 'attributes' => ['update'], 'vote' => VoterInterface::ACCESS_GRANTED],
],
],
],
[$decoratedVoter1, $decoratedVoter1],
[\get_class($voter1), \get_class($voter2)],
]);

$dataCollector = new SecurityDataCollector(null, null, null, $accessDecisionManager, null, null, true);

$dataCollector->collect(new Request(), new Response());

$actualDecisionLog = $dataCollector->getAccessDecisionLog();

$expectedDecisionLog = [
[
[
'attributes' => ['view', 'edit'],
'object' => new \stdClass(),
'result' => false,
'voter_details' => [
['class' => \get_class($voter1), 'attributes' => ['view'], 'vote' => VoterInterface::ACCESS_DENIED],
['class' => \get_class($voter1), 'attributes' => ['edit'], 'vote' => VoterInterface::ACCESS_DENIED],
['class' => \get_class($voter2), 'attributes' => ['view'], 'vote' => VoterInterface::ACCESS_GRANTED],
['class' => \get_class($voter2), 'attributes' => ['edit'], 'vote' => VoterInterface::ACCESS_GRANTED],
],
'attributes' => ['view', 'edit'],
'object' => new \stdClass(),
'result' => false,
'voter_details' => [
['class' => \get_class($voter1), 'attributes' => ['view'], 'vote' => VoterInterface::ACCESS_DENIED],
['class' => \get_class($voter1), 'attributes' => ['edit'], 'vote' => VoterInterface::ACCESS_DENIED],
['class' => \get_class($voter2), 'attributes' => ['view'], 'vote' => VoterInterface::ACCESS_GRANTED],
['class' => \get_class($voter2), 'attributes' => ['edit'], 'vote' => VoterInterface::ACCESS_GRANTED],
],
[
'attributes' => ['update'],
'object' => new \stdClass(),
'result' => true,
'voter_details' => [
['class' => \get_class($voter1), 'attributes' => ['update'], 'vote' => VoterInterface::ACCESS_GRANTED],
['class' => \get_class($voter2), 'attributes' => ['update'], 'vote' => VoterInterface::ACCESS_GRANTED],
],
],
[
'attributes' => ['update'],
'object' => new \stdClass(),
'result' => true,
'voter_details' => [
['class' => \get_class($voter1), 'attributes' => ['update'], 'vote' => VoterInterface::ACCESS_GRANTED],
['class' => \get_class($voter2), 'attributes' => ['update'], 'vote' => VoterInterface::ACCESS_GRANTED],
],
],
];
}

/**
* Test the returned data when AccessDecisionManager is a TraceableAccessDecisionManager.
*
* @param string $strategy strategy returned by the AccessDecisionManager
* @param array $voters voters returned by AccessDecisionManager
* @param array $decisionLog log of the votes and final decisions from AccessDecisionManager
* @param array $expectedVoterClasses expected voter classes returned by the collector
* @param array $expectedDecisionLog expected decision log returned by the collector
*
* @dataProvider providerCollectDecisionLog
*/
public function testCollectDecisionLog(string $strategy, array $decisionLog, array $voters, array $expectedVoterClasses, array $expectedDecisionLog)
{
$accessDecisionManager = $this
->getMockBuilder(TraceableAccessDecisionManager::class)
->disableOriginalConstructor()
->setMethods(['getStrategy', 'getVoters', 'getDecisionLog'])
->getMock();
$this->assertEquals($actualDecisionLog, $expectedDecisionLog, 'Wrong value returned by getAccessDecisionLog');

$accessDecisionManager
->expects($this->any())
->method('getStrategy')
->willReturn($strategy);
$actualVoterClasses = array_map(static function (ClassStub $classStub): string {
return (string) $classStub;
}, $dataCollector->getVoters());

$accessDecisionManager
->expects($this->any())
->method('getVoters')
->willReturn($voters);

$accessDecisionManager
->expects($this->any())
->method('getDecisionLog')
->willReturn($decisionLog);

$dataCollector = new SecurityDataCollector(null, null, null, $accessDecisionManager, null, null, true);
$dataCollector->collect(new Request(), new Response());

$this->assertEquals($dataCollector->getAccessDecisionLog(), $expectedDecisionLog, 'Wrong value returned by getAccessDecisionLog');
$expectedVoterClasses = [
\get_class($voter1),
\get_class($voter2),
];

$this->assertSame(
array_map(function ($classStub) { return (string) $classStub; }, $dataCollector->getVoters()),
$actualVoterClasses,
$expectedVoterClasses,
'Wrong value returned by getVoters'
);

$this->assertSame($dataCollector->getVoterStrategy(), $strategy, 'Wrong value returned by getVoterStrategy');
}

Expand Down Expand Up @@ -390,7 +432,7 @@ private function getRoleHierarchy()
}
}

class DummyVoter implements VoterInterface
final class DummyVoter implements VoterInterface
{
public function vote(TokenInterface $token, $subject, array $attributes)
{
Expand Down
0