1
|
|
|
<?php |
2
|
|
|
|
3
|
|
|
namespace spec\Odiseo\SyliusReportPlugin\Controller; |
4
|
|
|
|
5
|
|
|
use Doctrine\Persistence\ObjectManager; |
6
|
|
|
use FOS\RestBundle\View\View; |
7
|
|
|
use Odiseo\SyliusReportPlugin\Controller\ReportController; |
8
|
|
|
use PhpSpec\ObjectBehavior; |
9
|
|
|
use PhpSpec\Wrapper\Collaborator; |
10
|
|
|
use Prophecy\Argument; |
11
|
|
|
use Sylius\Bundle\ResourceBundle\Controller\AuthorizationCheckerInterface; |
12
|
|
|
use Sylius\Bundle\ResourceBundle\Controller\EventDispatcherInterface; |
13
|
|
|
use Sylius\Bundle\ResourceBundle\Controller\FlashHelperInterface; |
14
|
|
|
use Sylius\Bundle\ResourceBundle\Controller\NewResourceFactoryInterface; |
15
|
|
|
use Sylius\Bundle\ResourceBundle\Controller\RedirectHandlerInterface; |
16
|
|
|
use Sylius\Bundle\ResourceBundle\Controller\RequestConfiguration; |
17
|
|
|
use Sylius\Bundle\ResourceBundle\Controller\RequestConfigurationFactoryInterface; |
18
|
|
|
use Sylius\Bundle\ResourceBundle\Controller\ResourceController; |
19
|
|
|
use Sylius\Bundle\ResourceBundle\Controller\ResourceDeleteHandlerInterface; |
20
|
|
|
use Sylius\Bundle\ResourceBundle\Controller\ResourceFormFactoryInterface; |
21
|
|
|
use Sylius\Bundle\ResourceBundle\Controller\ResourcesCollectionProviderInterface; |
22
|
|
|
use Sylius\Bundle\ResourceBundle\Controller\ResourceUpdateHandlerInterface; |
23
|
|
|
use Sylius\Bundle\ResourceBundle\Controller\SingleResourceProviderInterface; |
24
|
|
|
use Sylius\Bundle\ResourceBundle\Controller\StateMachineInterface; |
25
|
|
|
use Sylius\Bundle\ResourceBundle\Controller\ViewHandlerInterface; |
26
|
|
|
use Sylius\Component\Resource\Factory\FactoryInterface; |
27
|
|
|
use Sylius\Component\Resource\Metadata\MetadataInterface; |
28
|
|
|
use Sylius\Component\Resource\Model\ResourceInterface; |
29
|
|
|
use Sylius\Component\Resource\Repository\RepositoryInterface; |
30
|
|
|
use Sylius\Component\Resource\ResourceActions; |
31
|
|
|
use Symfony\Component\HttpFoundation\Request; |
32
|
|
|
use Symfony\Component\HttpFoundation\Response; |
33
|
|
|
use Symfony\Component\Security\Core\Exception\AccessDeniedException; |
34
|
|
|
|
35
|
|
|
/** |
36
|
|
|
* @author Diego D'amico <[email protected]> |
37
|
|
|
*/ |
38
|
|
|
class ReportControllerSpec extends ObjectBehavior |
39
|
|
|
{ |
40
|
|
|
function let( |
|
|
|
|
41
|
|
|
MetadataInterface $metadata, |
42
|
|
|
RequestConfigurationFactoryInterface $requestConfigurationFactory, |
43
|
|
|
ViewHandlerInterface $viewHandler, |
44
|
|
|
RepositoryInterface $repository, |
45
|
|
|
FactoryInterface $factory, |
46
|
|
|
NewResourceFactoryInterface $newResourceFactory, |
47
|
|
|
ObjectManager $manager, |
48
|
|
|
SingleResourceProviderInterface $singleResourceProvider, |
49
|
|
|
ResourcesCollectionProviderInterface $resourcesFinder, |
50
|
|
|
ResourceFormFactoryInterface $resourceFormFactory, |
51
|
|
|
RedirectHandlerInterface $redirectHandler, |
52
|
|
|
FlashHelperInterface $flashHelper, |
53
|
|
|
AuthorizationCheckerInterface $authorizationChecker, |
54
|
|
|
EventDispatcherInterface $eventDispatcher, |
55
|
|
|
StateMachineInterface $stateMachine, |
56
|
|
|
ResourceUpdateHandlerInterface $resourceUpdateHandler, |
57
|
|
|
ResourceDeleteHandlerInterface $resourceDeleteHandler |
58
|
|
|
) |
59
|
|
|
{ |
60
|
|
|
$this->beConstructedWith( |
61
|
|
|
$metadata, $requestConfigurationFactory, $viewHandler, $repository, $factory, $newResourceFactory, |
62
|
|
|
$manager, $singleResourceProvider, $resourcesFinder, $resourceFormFactory, $redirectHandler, $flashHelper, |
63
|
|
|
$authorizationChecker, $eventDispatcher, $stateMachine, $resourceUpdateHandler, $resourceDeleteHandler |
64
|
|
|
); |
65
|
|
|
} |
66
|
|
|
|
67
|
|
|
function it_is_initializable() |
|
|
|
|
68
|
|
|
{ |
69
|
|
|
$this->shouldHaveType(ReportController::class); |
70
|
|
|
} |
71
|
|
|
|
72
|
|
|
function it_should_extends_resource_controller_interface() |
73
|
|
|
{ |
74
|
|
|
$this->shouldBeAnInstanceOf(ResourceController::class); |
75
|
|
|
} |
76
|
|
|
|
77
|
|
|
function it_throws_a_403_exception_if_user_is_unauthorized_to_render_the_report( |
78
|
|
|
MetadataInterface $metadata, |
79
|
|
|
RequestConfigurationFactoryInterface $requestConfigurationFactory, |
80
|
|
|
RequestConfiguration $configuration, |
81
|
|
|
Request $request, |
82
|
|
|
AuthorizationCheckerInterface $authorizationChecker |
83
|
|
|
): void { |
84
|
|
|
$requestConfigurationFactory->create($metadata, $request)->willReturn($configuration); |
|
|
|
|
85
|
|
|
$configuration->hasPermission()->willReturn(true); |
86
|
|
|
$configuration->getPermission(ResourceActions::SHOW)->willReturn('odiseo_sylius_report.report.show'); |
87
|
|
|
|
88
|
|
|
$authorizationChecker->isGranted($configuration, 'odiseo_sylius_report.report.show')->willReturn(false); |
89
|
|
|
|
90
|
|
|
$this |
91
|
|
|
->shouldThrow(new AccessDeniedException()) |
92
|
|
|
->during('renderAction', [$request]) |
93
|
|
|
; |
94
|
|
|
} |
95
|
|
|
|
96
|
|
|
function it_returns_a_response_for_non_html_view_of_single_resource( |
97
|
|
|
MetadataInterface $metadata, |
98
|
|
|
RequestConfigurationFactoryInterface $requestConfigurationFactory, |
99
|
|
|
RequestConfiguration $configuration, |
100
|
|
|
AuthorizationCheckerInterface $authorizationChecker, |
101
|
|
|
RepositoryInterface $repository, |
102
|
|
|
SingleResourceProviderInterface $singleResourceProvider, |
103
|
|
|
ResourceInterface $resource, |
104
|
|
|
ViewHandlerInterface $viewHandler, |
105
|
|
|
EventDispatcherInterface $eventDispatcher, |
106
|
|
|
Request $request, |
107
|
|
|
Response $response |
108
|
|
|
): void { |
109
|
|
|
$metadata->getApplicationName()->willReturn('sylius'); |
110
|
|
|
$metadata->getName()->willReturn('product'); |
111
|
|
|
|
112
|
|
|
$requestConfigurationFactory->create($metadata, $request)->willReturn($configuration); |
113
|
|
|
$configuration->hasPermission()->willReturn(true); |
114
|
|
|
$configuration->getPermission(ResourceActions::SHOW)->willReturn('sylius.product.show'); |
115
|
|
|
|
116
|
|
|
$authorizationChecker->isGranted($configuration, 'sylius.product.show')->willReturn(true); |
117
|
|
|
$singleResourceProvider->get($configuration, $repository)->willReturn($resource); |
|
|
|
|
118
|
|
|
|
119
|
|
|
$configuration->isHtmlRequest()->willReturn(false); |
120
|
|
|
|
121
|
|
|
$eventDispatcher->dispatch(ResourceActions::SHOW, $configuration, $resource)->shouldBeCalled(); |
|
|
|
|
122
|
|
|
|
123
|
|
|
$expectedView = View::create($resource); |
124
|
|
|
|
125
|
|
|
$viewHandler->handle($configuration, Argument::that($this->getViewComparingCallback($expectedView)))->willReturn($response); |
|
|
|
|
126
|
|
|
|
127
|
|
|
$this->showAction($request)->shouldReturn($response); |
|
|
|
|
128
|
|
|
} |
129
|
|
|
|
130
|
|
|
private function getViewComparingCallback(View $expectedView) |
131
|
|
|
{ |
132
|
|
|
return function ($value) use ($expectedView) { |
133
|
|
|
if (!$value instanceof View) { |
134
|
|
|
return false; |
135
|
|
|
} |
136
|
|
|
|
137
|
|
|
// Need to unwrap phpspec's Collaborators to ensure proper comparison. |
138
|
|
|
$this->unwrapViewData($expectedView); |
139
|
|
|
$this->nullifyDates($value); |
140
|
|
|
$this->nullifyDates($expectedView); |
141
|
|
|
|
142
|
|
|
return |
143
|
|
|
$expectedView->getStatusCode() === $value->getStatusCode() && |
144
|
|
|
$expectedView->getHeaders() === $value->getHeaders() && |
145
|
|
|
$expectedView->getFormat() === $value->getFormat() && |
146
|
|
|
$expectedView->getData() === $value->getData() |
147
|
|
|
; |
148
|
|
|
}; |
149
|
|
|
} |
150
|
|
|
|
151
|
|
|
/** |
152
|
|
|
* @param View $view |
153
|
|
|
*/ |
154
|
|
|
private function unwrapViewData(View $view) |
155
|
|
|
{ |
156
|
|
|
$view->setData($this->unwrapIfCollaborator($view->getData())); |
157
|
|
|
} |
158
|
|
|
|
159
|
|
|
/** |
160
|
|
|
* @param mixed $value |
161
|
|
|
* |
162
|
|
|
* @return mixed |
163
|
|
|
*/ |
164
|
|
|
private function unwrapIfCollaborator($value) |
165
|
|
|
{ |
166
|
|
|
if (null === $value) { |
167
|
|
|
return null; |
168
|
|
|
} |
169
|
|
|
|
170
|
|
|
if ($value instanceof Collaborator) { |
171
|
|
|
return $value->getWrappedObject(); |
172
|
|
|
} |
173
|
|
|
|
174
|
|
|
if (is_array($value)) { |
175
|
|
|
foreach ($value as $key => $childValue) { |
176
|
|
|
$value[$key] = $this->unwrapIfCollaborator($childValue); |
177
|
|
|
} |
178
|
|
|
} |
179
|
|
|
|
180
|
|
|
return $value; |
181
|
|
|
} |
182
|
|
|
|
183
|
|
|
/** |
184
|
|
|
* @param View $view |
185
|
|
|
*/ |
186
|
|
|
private function nullifyDates(View $view) |
187
|
|
|
{ |
188
|
|
|
$headers = $view->getHeaders(); |
189
|
|
|
unset($headers['date']); |
190
|
|
|
$view->setHeaders($headers); |
191
|
|
|
} |
192
|
|
|
} |
193
|
|
|
|
Adding explicit visibility (
private
,protected
, orpublic
) is generally recommend to communicate to other developers how, and from where this method is intended to be used.