Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit d56974a

Browse files
committed
[Workflow] Added tests for the is_valid() guard expression
1 parent e8c701f commit d56974a

File tree

5 files changed

+112
-73
lines changed

5 files changed

+112
-73
lines changed

src/Symfony/Bundle/FrameworkBundle/DependencyInjection/Compiler/WorkflowGuardListenerPass.php

Lines changed: 12 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -31,20 +31,18 @@ public function process(ContainerBuilder $container)
3131

3232
$container->getParameterBag()->remove('workflow.has_guard_listeners');
3333

34-
if (!$container->has('security.token_storage')) {
35-
throw new LogicException('The "security.token_storage" service is needed to be able to use the workflow guard listener.');
36-
}
37-
38-
if (!$container->has('security.authorization_checker')) {
39-
throw new LogicException('The "security.authorization_checker" service is needed to be able to use the workflow guard listener.');
40-
}
41-
42-
if (!$container->has('security.authentication.trust_resolver')) {
43-
throw new LogicException('The "security.authentication.trust_resolver" service is needed to be able to use the workflow guard listener.');
44-
}
45-
46-
if (!$container->has('security.role_hierarchy')) {
47-
throw new LogicException('The "security.role_hierarchy" service is needed to be able to use the workflow guard listener.');
34+
$servicesNeeded = array(
35+
'security.token_storage',
36+
'security.authorization_checker',
37+
'security.authentication.trust_resolver',
38+
'security.role_hierarchy',
39+
'validator',
40+
);
41+
42+
foreach ($servicesNeeded as $service) {
43+
if (!$container->has($service)) {
44+
throw new LogicException(sprintf('The "%s" service is needed to be able to use the workflow guard listener.', $service));
45+
}
4846
}
4947
}
5048
}

src/Symfony/Bundle/FrameworkBundle/DependencyInjection/FrameworkExtension.php

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,7 @@
7474
use Symfony\Component\Translation\Command\XliffLintCommand as BaseXliffLintCommand;
7575
use Symfony\Component\Validator\ConstraintValidatorInterface;
7676
use Symfony\Component\Validator\ObjectInitializerInterface;
77+
use Symfony\Component\Validator\Validator\ValidatorInterface;
7778
use Symfony\Component\WebLink\HttpHeaderSerializer;
7879
use Symfony\Component\Workflow;
7980
use Symfony\Component\Yaml\Command\LintCommand as BaseYamlLintCommand;
@@ -645,6 +646,10 @@ private function registerWorkflowConfiguration(array $workflows, ContainerBuilde
645646
throw new LogicException('Cannot guard workflows as the Security component is not installed.');
646647
}
647648

649+
if (!interface_exists(ValidatorInterface::class)) {
650+
throw new LogicException('Cannot guard workflows as the Validator component is not installed.');
651+
}
652+
648653
$eventName = sprintf('workflow.%s.guard.%s', $name, $transitionName);
649654
$guard->addTag('kernel.event_listener', array('event' => $eventName, 'method' => 'onTransition'));
650655
$configuration[$eventName] = $config['guard'];
@@ -657,7 +662,7 @@ private function registerWorkflowConfiguration(array $workflows, ContainerBuilde
657662
new Reference('security.authorization_checker'),
658663
new Reference('security.authentication.trust_resolver'),
659664
new Reference('security.role_hierarchy'),
660-
new Reference('validator', ContainerInterface::NULL_ON_INVALID_REFERENCE),
665+
new Reference('validator'),
661666
));
662667

663668
$container->setDefinition(sprintf('%s.listener.guard', $workflowId), $guard);

src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Compiler/WorkflowGuardListenerPassTest.php

Lines changed: 29 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -14,12 +14,11 @@
1414
use PHPUnit\Framework\TestCase;
1515
use Symfony\Bundle\FrameworkBundle\DependencyInjection\Compiler\WorkflowGuardListenerPass;
1616
use Symfony\Component\DependencyInjection\ContainerBuilder;
17-
use Symfony\Component\DependencyInjection\Exception\LogicException;
1817
use Symfony\Component\Security\Core\Authentication\AuthenticationTrustResolverInterface;
1918
use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface;
2019
use Symfony\Component\Security\Core\Authorization\AuthorizationCheckerInterface;
2120
use Symfony\Component\Security\Core\Role\RoleHierarchy;
22-
use Symfony\Component\Workflow\EventListener\GuardListener;
21+
use Symfony\Component\Validator\Validator\ValidatorInterface;
2322

2423
class WorkflowGuardListenerPassTest extends TestCase
2524
{
@@ -29,53 +28,37 @@ class WorkflowGuardListenerPassTest extends TestCase
2928
protected function setUp()
3029
{
3130
$this->container = new ContainerBuilder();
32-
$this->container->register('foo.listener.guard', GuardListener::class);
33-
$this->container->register('bar.listener.guard', GuardListener::class);
3431
$this->compilerPass = new WorkflowGuardListenerPass();
3532
}
3633

37-
public function testListenersAreNotRemovedIfParameterIsNotSet()
34+
public function testNoExeptionIfParameterIsNotSet()
3835
{
3936
$this->compilerPass->process($this->container);
4037

41-
$this->assertTrue($this->container->hasDefinition('foo.listener.guard'));
42-
$this->assertTrue($this->container->hasDefinition('bar.listener.guard'));
43-
}
44-
45-
public function testParameterIsRemovedWhenThePassIsProcessed()
46-
{
47-
$this->container->setParameter('workflow.has_guard_listeners', array('foo.listener.guard', 'bar.listener.guard'));
48-
49-
try {
50-
$this->compilerPass->process($this->container);
51-
} catch (LogicException $e) {
52-
// Here, we are not interested in the exception handling. This is tested further down.
53-
}
54-
5538
$this->assertFalse($this->container->hasParameter('workflow.has_guard_listeners'));
5639
}
5740

58-
public function testListenersAreNotRemovedIfAllDependenciesArePresent()
41+
public function testNoExeptionIfAllDependenciesArePresent()
5942
{
60-
$this->container->setParameter('workflow.has_guard_listeners', array('foo.listener.guard', 'bar.listener.guard'));
43+
$this->container->setParameter('workflow.has_guard_listeners', true);
6144
$this->container->register('security.token_storage', TokenStorageInterface::class);
6245
$this->container->register('security.authorization_checker', AuthorizationCheckerInterface::class);
6346
$this->container->register('security.authentication.trust_resolver', AuthenticationTrustResolverInterface::class);
6447
$this->container->register('security.role_hierarchy', RoleHierarchy::class);
48+
$this->container->register('validator', ValidatorInterface::class);
6549

6650
$this->compilerPass->process($this->container);
6751

68-
$this->assertTrue($this->container->hasDefinition('foo.listener.guard'));
69-
$this->assertTrue($this->container->hasDefinition('bar.listener.guard'));
52+
$this->assertFalse($this->container->hasParameter('workflow.has_guard_listeners'));
7053
}
7154

7255
/**
7356
* @expectedException \Symfony\Component\DependencyInjection\Exception\LogicException
7457
* @expectedExceptionMessage The "security.token_storage" service is needed to be able to use the workflow guard listener.
7558
*/
76-
public function testListenersAreRemovedIfTheTokenStorageServiceIsNotPresent()
59+
public function testExceptionIfTheTokenStorageServiceIsNotPresent()
7760
{
78-
$this->container->setParameter('workflow.has_guard_listeners', array('foo.listener.guard', 'bar.listener.guard'));
61+
$this->container->setParameter('workflow.has_guard_listeners', true);
7962
$this->container->register('security.authorization_checker', AuthorizationCheckerInterface::class);
8063
$this->container->register('security.authentication.trust_resolver', AuthenticationTrustResolverInterface::class);
8164
$this->container->register('security.role_hierarchy', RoleHierarchy::class);
@@ -87,9 +70,9 @@ public function testListenersAreRemovedIfTheTokenStorageServiceIsNotPresent()
8770
* @expectedException \Symfony\Component\DependencyInjection\Exception\LogicException
8871
* @expectedExceptionMessage The "security.authorization_checker" service is needed to be able to use the workflow guard listener.
8972
*/
90-
public function testListenersAreRemovedIfTheAuthorizationCheckerServiceIsNotPresent()
73+
public function testExceptionIfTheAuthorizationCheckerServiceIsNotPresent()
9174
{
92-
$this->container->setParameter('workflow.has_guard_listeners', array('foo.listener.guard', 'bar.listener.guard'));
75+
$this->container->setParameter('workflow.has_guard_listeners', true);
9376
$this->container->register('security.token_storage', TokenStorageInterface::class);
9477
$this->container->register('security.authentication.trust_resolver', AuthenticationTrustResolverInterface::class);
9578
$this->container->register('security.role_hierarchy', RoleHierarchy::class);
@@ -101,9 +84,9 @@ public function testListenersAreRemovedIfTheAuthorizationCheckerServiceIsNotPres
10184
* @expectedException \Symfony\Component\DependencyInjection\Exception\LogicException
10285
* @expectedExceptionMessage The "security.authentication.trust_resolver" service is needed to be able to use the workflow guard listener.
10386
*/
104-
public function testListenersAreRemovedIfTheAuthenticationTrustResolverServiceIsNotPresent()
87+
public function testExceptionIfTheAuthenticationTrustResolverServiceIsNotPresent()
10588
{
106-
$this->container->setParameter('workflow.has_guard_listeners', array('foo.listener.guard', 'bar.listener.guard'));
89+
$this->container->setParameter('workflow.has_guard_listeners', true);
10790
$this->container->register('security.token_storage', TokenStorageInterface::class);
10891
$this->container->register('security.authorization_checker', AuthorizationCheckerInterface::class);
10992
$this->container->register('security.role_hierarchy', RoleHierarchy::class);
@@ -115,12 +98,27 @@ public function testListenersAreRemovedIfTheAuthenticationTrustResolverServiceIs
11598
* @expectedException \Symfony\Component\DependencyInjection\Exception\LogicException
11699
* @expectedExceptionMessage The "security.role_hierarchy" service is needed to be able to use the workflow guard listener.
117100
*/
118-
public function testListenersAreRemovedIfTheRoleHierarchyServiceIsNotPresent()
101+
public function testExceptionIfTheRoleHierarchyServiceIsNotPresent()
102+
{
103+
$this->container->setParameter('workflow.has_guard_listeners', true);
104+
$this->container->register('security.token_storage', TokenStorageInterface::class);
105+
$this->container->register('security.authorization_checker', AuthorizationCheckerInterface::class);
106+
$this->container->register('security.authentication.trust_resolver', AuthenticationTrustResolverInterface::class);
107+
108+
$this->compilerPass->process($this->container);
109+
}
110+
111+
/**
112+
* @expectedException \Symfony\Component\DependencyInjection\Exception\LogicException
113+
* The "validator" service is needed to be able to use the workflow guard listener.
114+
*/
115+
public function testExceptionIfTheValidatorIsNotPresent()
119116
{
120-
$this->container->setParameter('workflow.has_guard_listeners', array('foo.listener.guard', 'bar.listener.guard'));
117+
$this->container->setParameter('workflow.has_guard_listeners', true);
121118
$this->container->register('security.token_storage', TokenStorageInterface::class);
122119
$this->container->register('security.authorization_checker', AuthorizationCheckerInterface::class);
123120
$this->container->register('security.authentication.trust_resolver', AuthenticationTrustResolverInterface::class);
121+
$this->container->register('security.role_hierarchy', RoleHierarchy::class);
124122

125123
$this->compilerPass->process($this->container);
126124
}

src/Symfony/Component/Workflow/CHANGELOG.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ CHANGELOG
44
3.4.0
55
-----
66

7-
* Add guard `is_valid()` method support
7+
* Add guard `is_valid()` method support.
88
* Added support for `Event::getWorkflowName()` for "announce" events.
99
* Added `workflow.completed` events which are fired after a transition is completed.
1010

src/Symfony/Component/Workflow/Tests/EventListener/GuardListenerTest.php

Lines changed: 64 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
99
use Symfony\Component\Security\Core\Authorization\AuthorizationCheckerInterface;
1010
use Symfony\Component\Security\Core\Role\Role;
11+
use Symfony\Component\Validator\Validator\ValidatorInterface;
1112
use Symfony\Component\Workflow\EventListener\ExpressionLanguage;
1213
use Symfony\Component\Workflow\EventListener\GuardListener;
1314
use Symfony\Component\Workflow\Event\GuardEvent;
@@ -16,59 +17,85 @@
1617

1718
class GuardListenerTest extends TestCase
1819
{
19-
private $tokenStorage;
20+
private $authenticationChecker;
21+
private $validator;
2022
private $listener;
2123

2224
protected function setUp()
2325
{
2426
$configuration = array(
25-
'event_name_a' => 'true',
26-
'event_name_b' => 'false',
27+
'test_is_granted' => 'is_granted("something")',
28+
'test_is_valid' => 'is_valid(subject)',
2729
);
28-
2930
$expressionLanguage = new ExpressionLanguage();
30-
$this->tokenStorage = $this->getMockBuilder(TokenStorageInterface::class)->getMock();
31-
$authenticationChecker = $this->getMockBuilder(AuthorizationCheckerInterface::class)->getMock();
31+
$token = $this->getMockBuilder(TokenInterface::class)->getMock();
32+
$token->expects($this->any())->method('getRoles')->willReturn(array(new Role('ROLE_USER')));
33+
$tokenStorage = $this->getMockBuilder(TokenStorageInterface::class)->getMock();
34+
$tokenStorage->expects($this->any())->method('getToken')->willReturn($token);
35+
$this->authenticationChecker = $this->getMockBuilder(AuthorizationCheckerInterface::class)->getMock();
3236
$trustResolver = $this->getMockBuilder(AuthenticationTrustResolverInterface::class)->getMock();
33-
34-
$this->listener = new GuardListener($configuration, $expressionLanguage, $this->tokenStorage, $authenticationChecker, $trustResolver);
37+
$this->validator = $this->getMockBuilder(ValidatorInterface::class)->getMock();
38+
$this->listener = new GuardListener($configuration, $expressionLanguage, $tokenStorage, $this->authenticationChecker, $trustResolver, null, $this->validator);
3539
}
3640

3741
protected function tearDown()
3842
{
43+
$this->authenticationChecker = null;
44+
$this->validator = null;
3945
$this->listener = null;
4046
}
4147

4248
public function testWithNotSupportedEvent()
4349
{
4450
$event = $this->createEvent();
45-
$this->configureTokenStorage(false);
51+
$this->configureAuthenticationChecker(false);
52+
$this->configureValidator(false);
4653

4754
$this->listener->onTransition($event, 'not supported');
4855

4956
$this->assertFalse($event->isBlocked());
5057
}
5158

52-
public function testWithSupportedEventAndReject()
59+
public function testWithSecuritySupportedEventAndReject()
5360
{
5461
$event = $this->createEvent();
55-
$this->configureTokenStorage(true);
62+
$this->configureAuthenticationChecker(true, false);
5663

57-
$this->listener->onTransition($event, 'event_name_a');
64+
$this->listener->onTransition($event, 'test_is_granted');
65+
66+
$this->assertTrue($event->isBlocked());
67+
}
68+
69+
public function testWithSecuritySupportedEventAndAccept()
70+
{
71+
$event = $this->createEvent();
72+
$this->configureAuthenticationChecker(true, true);
73+
74+
$this->listener->onTransition($event, 'test_is_granted');
5875

5976
$this->assertFalse($event->isBlocked());
6077
}
6178

62-
public function testWithSupportedEventAndAccept()
79+
public function testWithValidatorSupportedEventAndReject()
6380
{
6481
$event = $this->createEvent();
65-
$this->configureTokenStorage(true);
82+
$this->configureValidator(true, false);
6683

67-
$this->listener->onTransition($event, 'event_name_b');
84+
$this->listener->onTransition($event, 'test_is_valid');
6885

6986
$this->assertTrue($event->isBlocked());
7087
}
7188

89+
public function testWithValidatorSupportedEventAndAccept()
90+
{
91+
$event = $this->createEvent();
92+
$this->configureValidator(true, true);
93+
94+
$this->listener->onTransition($event, 'test_is_valid');
95+
96+
$this->assertFalse($event->isBlocked());
97+
}
98+
7299
private function createEvent()
73100
{
74101
$subject = new \stdClass();
@@ -78,28 +105,39 @@ private function createEvent()
78105
return new GuardEvent($subject, $subject->marking, $transition);
79106
}
80107

81-
private function configureTokenStorage($hasUser)
108+
private function configureAuthenticationChecker($isUsed, $granted = true)
82109
{
83-
if (!$hasUser) {
84-
$this->tokenStorage
110+
if (!$isUsed) {
111+
$this->authenticationChecker
85112
->expects($this->never())
86-
->method('getToken')
113+
->method('isGranted')
87114
;
88115

89116
return;
90117
}
91118

92-
$token = $this->getMockBuilder(TokenInterface::class)->getMock();
93-
$token
119+
$this->authenticationChecker
94120
->expects($this->once())
95-
->method('getRoles')
96-
->willReturn(array(new Role('ROLE_ADMIN')))
121+
->method('isGranted')
122+
->willReturn($granted)
97123
;
124+
}
125+
126+
private function configureValidator($isUsed, $valid = true)
127+
{
128+
if (!$isUsed) {
129+
$this->validator
130+
->expects($this->never())
131+
->method('validate')
132+
;
133+
134+
return;
135+
}
98136

99-
$this->tokenStorage
137+
$this->validator
100138
->expects($this->once())
101-
->method('getToken')
102-
->willReturn($token)
139+
->method('validate')
140+
->willReturn($valid ? array() : array('a violation'))
103141
;
104142
}
105143
}

0 commit comments

Comments
 (0)