Completed
Push — master ( bd4c23...b341c0 )
by Filipe
10:29
created

DispatcherMiddlewareSpec::let()   B

Complexity

Conditions 1
Paths 1

Size

Total Lines 36
Code Lines 30

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 36
rs 8.8571
c 0
b 0
f 0
cc 1
eloc 30
nc 1
nop 5
1
<?php
2
3
namespace spec\Slick\Mvc\Http;
4
5
use Aura\Router\Route;
6
use PhpSpec\ObjectBehavior;
7
use PhpSpec\Wrapper\Collaborator;
8
use Prophecy\Argument;
9
use Psr\Http\Message\ResponseInterface;
10
use Psr\Http\Message\ServerRequestInterface;
11
use Slick\Di\ContainerInterface;
12
use Slick\Di\Exception\ClassNotFoundException;
13
use Slick\Http\Response;
14
use Slick\Http\Server\MiddlewareInterface;
15
use Slick\Mvc\Controller\Context;
16
use Slick\Mvc\Controller\ControllerContextInterface;
17
use Slick\Mvc\ControllerInterface;
18
use Slick\Mvc\Exception\ControllerNotFoundException;
19
use Slick\Mvc\Http\Dispatcher\ControllerDispatch;
20
use Slick\Mvc\Http\Dispatcher\ControllerDispatchInflectorInterface;
21
use Slick\Mvc\Http\Dispatcher\ControllerInvokerInterface;
22
use Slick\Mvc\Http\DispatcherMiddleware;
23
24
class DispatcherMiddlewareSpec extends ObjectBehavior
25
{
26
27
    /**
28
     * @var ControllerDispatchInflectorInterface|Collaborator
29
     */
30
    private $dispatchInflector;
31
32
    /**
33
     * @var ControllerInvokerInterface|Collaborator
34
     */
35
    private $invokerMock;
36
37
    /**
38
     * @var ContainerInterface|Collaborator
39
     */
40
    private $containerMock;
41
42
    /**
43
     * @var TestController|Collaborator
44
     */
45
    private $controllerMock;
46
47
    /**
48
     * @var Collaborator|ControllerContextInterface
49
     */
50
    private $contextMock;
51
52
    /**
53
     * Set SUT object
54
     *
55
     * @param Collaborator|ControllerDispatchInflectorInterface $controllerDispatchInflector
56
     * @param Collaborator|ControllerInvokerInterface $invoker
57
     * @param Collaborator|ContainerInterface $container
58
     * @param Collaborator|TestController $controller
59
     * @param Collaborator|ControllerContextInterface $context
60
     */
61
    function let(
62
        ControllerDispatchInflectorInterface $controllerDispatchInflector,
63
        ControllerInvokerInterface $invoker,
64
        ContainerInterface $container,
65
        TestController $controller,
66
        ControllerContextInterface $context
67
    ) {
68
        $this->beConstructedWith(
69
            $controllerDispatchInflector,
70
            $invoker,
71
            $container
72
        );
73
        $this->dispatchInflector = $controllerDispatchInflector;
74
        $this->invokerMock = $invoker;
75
        $this->controllerMock = $controller;
76
        $this->containerMock = $container;
77
        $this->contextMock = $context;
78
79
        $dispatch = new ControllerDispatch('controllerClass', 'index', [123]);
80
        $controllerDispatchInflector
81
            ->inflect(Argument::any())
82
            ->willReturn($dispatch);
83
84
        $container->make("controllerClass")->willReturn($controller);
85
        $container->has('controller.context.class')->willReturn(false);
86
        $container->make(DispatcherMiddleware::CONTEXT_CLASS)
87
            ->willReturn($context);
88
89
        $invoker
90
            ->invoke($controller, Argument::type(ControllerDispatch::class))
91
            ->willReturn([]);
92
        $context->register(
93
            Argument::type(ServerRequestInterface::class),
94
            Argument::type(ResponseInterface::class)
95
        )->willReturn(true);
96
    }
97
98
    function it_is_initializable()
99
    {
100
        $this->shouldHaveType(DispatcherMiddleware::class);
101
    }
102
103
    function its_an_http_middleware()
104
    {
105
        $this->shouldBeAnInstanceOf(MiddlewareInterface::class);
106
    }
107
108
    function it_inflects_controller_information_from_http_request(
109
        ServerRequestInterface $request,
110
        ResponseInterface $response,
111
        Route $route
112
    )
113
    {
114
        $this->prepareRequest($request, $route);
115
116
        $this->handle($request, $response);
117
        $this->dispatchInflector
118
            ->inflect($route)
119
            ->shouldHaveBeenCalled();
120
    }
121
122
    function it_uses_the_container_to_create_the_controller(
123
        ServerRequestInterface $request,
124
        ResponseInterface $response
125
    )
126
    {
127
        $this->prepareRequest($request);
128
129
        $this->handle($request, $response);
130
        $this->containerMock
131
            ->make("controllerClass")
132
            ->shouldHaveBeenCalled();
133
    }
134
135
    function it_sets_a_context_for_created_controllers(
136
        ServerRequestInterface $request,
137
        ResponseInterface $response
138
    )
139
    {
140
        $this->prepareRequest($request);
141
142
        $this->handle($request, $response);
143
        $this->controllerMock
144
            ->setContext($this->contextMock)
145
            ->shouldHaveBeenCalled();
146
    }
147
148
    function it_passes_the_request_and_response_to_controller_context(
149
        ServerRequestInterface $request,
150
        ResponseInterface $response
151
    )
152
    {
153
        $this->prepareRequest($request);
154
155
        $this->handle($request, $response);
156
        $this->contextMock
157
            ->register($request, $response)
158
            ->shouldHaveBeenCalled();
159
    }
160
161
    function it_uses_invoker_to_invoke_controller_handler(
162
        ServerRequestInterface $request,
163
        ResponseInterface $response
164
    )
165
    {
166
167
        $this->prepareRequest($request);
168
169
        $this->handle($request, $response);
170
        $this->invokerMock
171
            ->invoke(
172
                $this->controllerMock,
173
                Argument::type(ControllerDispatch::class)
174
            )
175
            ->shouldHaveBeenCalled();
176
    }
177
178
    function it_will_create_a_request_with_view_data(
179
        ServerRequestInterface $request,
180
        ResponseInterface $response
181
    )
182
    {
183
        $this->prepareRequest($request);
184
185
        $this->handle($request, $response);
186
        $request->withAttribute('viewData', [])
187
            ->shouldHaveBeenCalled();
188
    }
189
190
    function it_will_forward_the_request_from_controller_context(
191
        ServerRequestInterface $request,
192
        ResponseInterface $response
193
    )
194
    {
195
        $this->prepareRequest($request);
196
197
        $this->contextMock->getRequest()
198
            ->shouldBeCalled()
199
            ->willReturn($request);
200
        $this->handle($request, $response);
201
    }
202
203
    function it_will_forward_the_response_from_controller_context(
204
        ServerRequestInterface $request,
205
        ResponseInterface $response
206
    ) {
207
        $this->prepareRequest($request);
208
209
        $this->contextMock->getResponse()
210
            ->shouldBeCalled()
211
            ->willReturn($response);
212
213
        $this->handle($request, $response);
214
    }
215
216
    function it_throws_unknown_controller_exception_for_an_undefined_controller_class(
217
        ServerRequestInterface $request,
218
        ResponseInterface $response
219
    )
220
    {
221
        $this->prepareRequest($request);
222
        $this->containerMock
223
            ->make("controllerClass")
224
            ->willThrow(new ClassNotFoundException());
225
        $this->shouldThrow(ControllerNotFoundException::class)
226
            ->during('handle', [$request, $response]);
227
    }
228
229
230
    private function prepareRequest(
231
        ServerRequestInterface $request,
232
        Route $route = null
233
    )
234
    {
235
        $route = !$route ? new Route() : $route;
236
        $request->getAttribute('route', false)
237
            ->willReturn($route);
238
        $request->withAttribute('viewData', [])
239
            ->willReturn($request);
240
        $this->contextMock->getRequest()->willReturn($request);
241
        $this->contextMock->getResponse()->willReturn(new Response());
242
    }
243
244
}
245
246
class TestController implements ControllerInterface
0 ignored issues
show
Coding Style Compatibility introduced by
PSR1 recommends that each class should be in its own file to aid autoloaders.

Having each class in a dedicated file usually plays nice with PSR autoloaders and is therefore a well established practice. If you use other autoloaders, you might not want to follow this rule.

Loading history...
247
{
248
249
    public function setContext(ControllerContextInterface $context)
250
    {
251
        // do nothing
252
        return $this;
253
    }
254
255
    public function set($name, $value = null)
256
    {
257
        // do nothing
258
        return $this;
259
    }
260
261
    public function index($test)
0 ignored issues
show
Unused Code introduced by
The parameter $test is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
262
    {
263
        // Do controller stuff
264
    }
265
266
    /**
267
     * A view data model used by renderer
268
     *
269
     * @return array
270
     */
271
    public function getViewData()
272
    {
273
        // do nothing
274
        return [];
275
    }
276
}
277