1
|
|
|
<?php |
2
|
|
|
/** |
3
|
|
|
* This file is part of the Global Trading Technologies Ltd workflow-extension-bundle package. |
4
|
|
|
* |
5
|
|
|
* For the full copyright and license information, please view the LICENSE |
6
|
|
|
* file that was distributed with this source code. |
7
|
|
|
* |
8
|
|
|
* (c) fduch <[email protected]> |
9
|
|
|
* @date 18.07.16 |
10
|
|
|
*/ |
11
|
|
|
|
12
|
|
|
namespace Gtt\Bundle\WorkflowExtensionsBundle\Tests\Guard; |
13
|
|
|
|
14
|
|
|
use Gtt\Bundle\WorkflowExtensionsBundle\Guard\ExpressionGuard; |
15
|
|
|
use Gtt\Bundle\WorkflowExtensionsBundle\WorkflowSubject\SubjectManipulator; |
16
|
|
|
use Psr\Log\LoggerInterface; |
17
|
|
|
use Symfony\Component\ExpressionLanguage\ExpressionLanguage; |
18
|
|
|
use Symfony\Component\Workflow\Event\GuardEvent; |
19
|
|
|
use Symfony\Component\Workflow\Registry; |
20
|
|
|
use Symfony\Component\Workflow\Transition; |
21
|
|
|
use Symfony\Component\Workflow\Workflow; |
22
|
|
|
|
23
|
|
|
class ExpressionGuardTest extends \PHPUnit_Framework_TestCase |
24
|
|
|
{ |
25
|
|
|
/** |
26
|
|
|
* @expectedException \Gtt\Bundle\WorkflowExtensionsBundle\Exception\UnsupportedGuardEventException |
27
|
|
|
*/ |
28
|
|
|
public function testHandlingUnsupportedEventsTriggersException() |
29
|
|
|
{ |
30
|
|
|
$guard = new ExpressionGuard( |
31
|
|
|
$this->getMock(ExpressionLanguage::class), |
32
|
|
|
$this->getMockBuilder(SubjectManipulator::class)->disableOriginalConstructor()->getMock(), |
33
|
|
|
$this->getMock(Registry::class), |
34
|
|
|
$this->getMock(LoggerInterface::class) |
35
|
|
|
); |
36
|
|
|
$event = $this->getMockBuilder(GuardEvent::class)->disableOriginalConstructor()->getMock(); |
37
|
|
|
|
38
|
|
|
$guard->guardTransition($event, "ghost_event"); |
39
|
|
|
} |
40
|
|
|
|
41
|
|
|
public function testGuardExpressionFailuresAreReportedByLogger() |
42
|
|
|
{ |
43
|
|
|
$logger = $this->getMock(LoggerInterface::class); |
44
|
|
|
$logger->expects(self::once())->method('error'); |
45
|
|
|
|
46
|
|
|
$invalidExpression = "expression"; |
47
|
|
|
$language = $this->getMockBuilder(ExpressionLanguage::class)->disableOriginalConstructor()->getMock(); |
48
|
|
|
$language->expects(self::once())->method("evaluate")->with($invalidExpression)->willThrowException(new \Exception()); |
49
|
|
|
|
50
|
|
|
$guard = new ExpressionGuard( |
51
|
|
|
$language, |
52
|
|
|
$this->getMockBuilder(SubjectManipulator::class)->disableOriginalConstructor()->getMock(), |
53
|
|
|
$this->prepareValidWorkflowRegistryMock(), |
|
|
|
|
54
|
|
|
$logger |
55
|
|
|
); |
56
|
|
|
|
57
|
|
|
$guard->registerGuardExpression("eventName", "workflow", $invalidExpression); |
58
|
|
|
|
59
|
|
|
$guard->guardTransition( |
60
|
|
|
$this->getMockBuilder(GuardEvent::class)->disableOriginalConstructor()->getMock(), |
61
|
|
|
"eventName" |
62
|
|
|
); |
63
|
|
|
} |
64
|
|
|
|
65
|
|
|
public function testGuardExpressionFailuresDoNotBlocksTransition() |
66
|
|
|
{ |
67
|
|
|
$logger = $this->getMock(LoggerInterface::class); |
68
|
|
|
$logger->expects(self::once())->method('error'); |
69
|
|
|
|
70
|
|
|
$invalidExpression = "expression"; |
71
|
|
|
$language = $this->getMockBuilder(ExpressionLanguage::class)->disableOriginalConstructor()->getMock(); |
72
|
|
|
$language->expects(self::once())->method("evaluate")->with($invalidExpression)->willThrowException(new \Exception()); |
73
|
|
|
|
74
|
|
|
$guard = new ExpressionGuard( |
75
|
|
|
$language, |
76
|
|
|
$this->getMockBuilder(SubjectManipulator::class)->disableOriginalConstructor()->getMock(), |
77
|
|
|
$this->prepareValidWorkflowRegistryMock(), |
|
|
|
|
78
|
|
|
$logger |
79
|
|
|
); |
80
|
|
|
|
81
|
|
|
$event = $this->getMockBuilder(GuardEvent::class)->disableOriginalConstructor()->getMock(); |
82
|
|
|
$event->expects(self::never())->method("setBlocked"); |
83
|
|
|
|
84
|
|
|
$guard->registerGuardExpression("eventName", "workflow", "expression"); |
85
|
|
|
$guard->guardTransition($event ,"eventName"); |
86
|
|
|
} |
87
|
|
|
|
88
|
|
|
/** |
89
|
|
|
* @dataProvider expressionProvider |
90
|
|
|
*/ |
91
|
|
|
public function testValidExpressionAllowsOrBlocksTransitionWithLogReport($expression, $blockTransition, $convertToBoolean = false) |
92
|
|
|
{ |
93
|
|
|
$logger = $this->getMock(LoggerInterface::class); |
94
|
|
|
|
95
|
|
|
$language = $this->getMockBuilder(ExpressionLanguage::class)->disableOriginalConstructor()->getMock(); |
96
|
|
|
$language->expects(self::once())->method("evaluate")->with($expression)->willReturn($blockTransition); |
97
|
|
|
|
98
|
|
|
$guard = new ExpressionGuard( |
99
|
|
|
$language, |
100
|
|
|
$this->getMockBuilder(SubjectManipulator::class)->disableOriginalConstructor()->getMock(), |
101
|
|
|
$this->prepareValidWorkflowRegistryMock(), |
|
|
|
|
102
|
|
|
$logger |
103
|
|
|
); |
104
|
|
|
|
105
|
|
|
$event = $this->getMockBuilder(GuardEvent::class)->disableOriginalConstructor()->getMock(); |
106
|
|
|
$event->expects(self::once())->method("setBlocked")->with($blockTransition); |
107
|
|
|
|
108
|
|
|
$loggerInvocationCount = 0; |
109
|
|
|
if ($convertToBoolean) { |
110
|
|
|
// in case of convertation logger should report about it |
111
|
|
|
$loggerInvocationCount++; |
112
|
|
|
} |
113
|
|
|
if ($blockTransition) { |
114
|
|
|
// in case of transition blocking logger should report about it |
115
|
|
|
$loggerInvocationCount++; |
116
|
|
|
$transition = $this->getMockBuilder(Transition::class)->disableOriginalConstructor()->getMock(); |
117
|
|
|
$transition->expects(self::once())->method("getName"); |
118
|
|
|
$event->expects(self::once())->method("getTransition")->willReturn($transition); |
119
|
|
|
} |
120
|
|
|
$logger->expects($this->exactly($loggerInvocationCount))->method("debug"); |
121
|
|
|
|
122
|
|
|
$guard->registerGuardExpression("eventName", "workflow", $expression); |
123
|
|
|
$guard->guardTransition($event ,"eventName"); |
124
|
|
|
} |
125
|
|
|
|
126
|
|
|
public function expressionProvider() |
127
|
|
|
{ |
128
|
|
|
return [ |
129
|
|
|
["boolenFalseExpression", false], |
130
|
|
|
["boolenTrueExpression", true], |
131
|
|
|
// convertations to boolean |
132
|
|
|
["convertableToTrueExpression", "1", true], |
133
|
|
|
["convertableToFalseExpression", "0", true] |
134
|
|
|
]; |
135
|
|
|
} |
136
|
|
|
|
137
|
|
|
/** |
138
|
|
|
* @return \PHPUnit_Framework_MockObject_MockObject|Registry |
139
|
|
|
*/ |
140
|
|
|
private function prepareValidWorkflowRegistryMock() |
141
|
|
|
{ |
142
|
|
|
$workflow = $this->getMockBuilder(Workflow::class)->disableOriginalConstructor()->getMock(); |
143
|
|
|
$workflow->expects(self::once())->method('getName')->willReturn('test'); |
144
|
|
|
$workflowRegistry = $this->getMock(Registry::class); |
145
|
|
|
$workflowRegistry->expects(self::once())->method('get')->willReturn($workflow); |
146
|
|
|
|
147
|
|
|
return $workflowRegistry; |
148
|
|
|
} |
149
|
|
|
} |
150
|
|
|
|
This check looks at variables that are passed out again to other methods.
If the outgoing method call has stricter type requirements than the method itself, an issue is raised.
An additional type check may prevent trouble.