Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit 06d8198

Browse filesBrowse files
committed
[Workflow] Added tests for the is_valid() guard expression
1 parent 9499bc2 commit 06d8198
Copy full SHA for 06d8198

File tree

Expand file treeCollapse file tree

7 files changed

+95
-74
lines changed
Filter options
Expand file treeCollapse file tree

7 files changed

+95
-74
lines changed

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

Copy file name to clipboardExpand all lines: src/Symfony/Bundle/FrameworkBundle/DependencyInjection/Compiler/WorkflowGuardListenerPass.php
+12-14Lines changed: 12 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717

1818
/**
1919
* @author Christian Flothmann <christian.flothmann@sensiolabs.de>
20+
* @author Grégoire Pineau <lyrixx@lyrixx.info>
2021
*/
2122
class WorkflowGuardListenerPass implements CompilerPassInterface
2223
{
@@ -31,20 +32,17 @@ public function process(ContainerBuilder $container)
3132

3233
$container->getParameterBag()->remove('workflow.has_guard_listeners');
3334

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.');
35+
$servicesNeeded = array(
36+
'security.token_storage',
37+
'security.authorization_checker',
38+
'security.authentication.trust_resolver',
39+
'security.role_hierarchy',
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

Copy file name to clipboardExpand all lines: src/Symfony/Bundle/FrameworkBundle/DependencyInjection/FrameworkExtension.php
+1Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,7 @@
8585
use Symfony\Component\Translation\Translator;
8686
use Symfony\Component\Validator\ConstraintValidatorInterface;
8787
use Symfony\Component\Validator\ObjectInitializerInterface;
88+
use Symfony\Component\Validator\Validator\ValidatorInterface;
8889
use Symfony\Component\WebLink\HttpHeaderSerializer;
8990
use Symfony\Component\Workflow;
9091
use Symfony\Component\Yaml\Command\LintCommand as BaseYamlLintCommand;

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

Copy file name to clipboardExpand all lines: src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Compiler/WorkflowGuardListenerPassTest.php
+14-31Lines changed: 14 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,9 +98,9 @@ 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()
119102
{
120-
$this->container->setParameter('workflow.has_guard_listeners', array('foo.listener.guard', 'bar.listener.guard'));
103+
$this->container->setParameter('workflow.has_guard_listeners', true);
121104
$this->container->register('security.token_storage', TokenStorageInterface::class);
122105
$this->container->register('security.authorization_checker', AuthorizationCheckerInterface::class);
123106
$this->container->register('security.authentication.trust_resolver', AuthenticationTrustResolverInterface::class);

‎src/Symfony/Component/Workflow/CHANGELOG.md

Copy file name to clipboardExpand all lines: src/Symfony/Component/Workflow/CHANGELOG.md
+1-1Lines 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+
* Added 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/EventListener/ExpressionLanguage.php

Copy file name to clipboardExpand all lines: src/Symfony/Component/Workflow/EventListener/ExpressionLanguage.php
+1-1Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ protected function registerFunctions()
3636
return sprintf('0 === count($validator->validate(%s, null, %s))', $object, $groups);
3737
}, function (array $variables, $object = null, $groups = null) {
3838
if (!$variables['validator'] instanceof ValidatorInterface) {
39-
throw new RuntimeException('Validator not defined, did you install the component?');
39+
throw new RuntimeException('"is_valid" cannot be used as the Validator component is not installed.');
4040
}
4141

4242
$errors = $variables['validator']->validate($object, null, $groups);

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

Copy file name to clipboardExpand all lines: src/Symfony/Component/Workflow/Tests/EventListener/GuardListenerTest.php
+64-26Lines 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
}

‎src/Symfony/Component/Workflow/composer.json

Copy file name to clipboardExpand all lines: src/Symfony/Component/Workflow/composer.json
+2-1Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,8 @@
2828
"symfony/dependency-injection": "~2.8|~3.0|~4.0",
2929
"symfony/event-dispatcher": "~2.1|~3.0|~4.0",
3030
"symfony/expression-language": "~2.8|~3.0|~4.0",
31-
"symfony/security-core": "~2.8|~3.0|~4.0"
31+
"symfony/security-core": "~2.8|~3.0|~4.0",
32+
"symfony/validator": "~2.8|~3.4|~4.0"
3233
},
3334
"autoload": {
3435
"psr-4": { "Symfony\\Component\\Workflow\\": "" }

0 commit comments

Comments
0 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.