Completed
Pull Request — master (#554)
by Alejandro
11:37 queued 08:50
created

AuthenticationMiddlewareTest::getDummyMiddleware()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 2
nc 1
nop 0
dl 0
loc 4
rs 10
c 0
b 0
f 0
1
<?php
2
3
declare(strict_types=1);
4
5
namespace ShlinkioTest\Shlink\Rest\Middleware;
6
7
use Fig\Http\Message\RequestMethodInterface;
8
use PHPUnit\Framework\TestCase;
9
use Prophecy\Argument;
10
use Prophecy\Prophecy\ObjectProphecy;
11
use Psr\Http\Message\ResponseInterface;
12
use Psr\Http\Message\ServerRequestInterface;
13
use Psr\Http\Server\MiddlewareInterface;
14
use Psr\Http\Server\RequestHandlerInterface;
15
use Psr\Log\LoggerInterface;
16
use Shlinkio\Shlink\Rest\Action\AuthenticateAction;
17
use Shlinkio\Shlink\Rest\Authentication\Plugin\AuthenticationPluginInterface;
18
use Shlinkio\Shlink\Rest\Authentication\RequestToHttpAuthPluginInterface;
19
use Shlinkio\Shlink\Rest\Middleware\AuthenticationMiddleware;
20
use Zend\Diactoros\Response;
21
use Zend\Diactoros\ServerRequest;
22
use Zend\Expressive\Router\Route;
23
use Zend\Expressive\Router\RouteResult;
24
25
use function Zend\Stratigility\middleware;
26
27
class AuthenticationMiddlewareTest extends TestCase
28
{
29
    /** @var AuthenticationMiddleware */
30
    private $middleware;
31
    /** @var ObjectProphecy */
32
    private $requestToPlugin;
33
    /** @var ObjectProphecy */
34
    private $logger;
35
36
    public function setUp(): void
37
    {
38
        $this->requestToPlugin = $this->prophesize(RequestToHttpAuthPluginInterface::class);
39
        $this->logger = $this->prophesize(LoggerInterface::class);
40
41
        $this->middleware = new AuthenticationMiddleware(
42
            $this->requestToPlugin->reveal(),
43
            [AuthenticateAction::class],
44
            $this->logger->reveal()
0 ignored issues
show
Unused Code introduced by
The call to Shlinkio\Shlink\Rest\Mid...ddleware::__construct() has too many arguments starting with $this->logger->reveal(). ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

44
        $this->middleware = /** @scrutinizer ignore-call */ new AuthenticationMiddleware(

This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue.

If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress. Please note the @ignore annotation hint above.

Loading history...
45
        );
46
    }
47
48
    /**
49
     * @test
50
     * @dataProvider provideWhitelistedRequests
51
     */
52
    public function someWhiteListedSituationsFallbackToNextMiddleware(ServerRequestInterface $request): void
53
    {
54
        $handler = $this->prophesize(RequestHandlerInterface::class);
55
        $handle = $handler->handle($request)->willReturn(new Response());
56
        $fromRequest = $this->requestToPlugin->fromRequest(Argument::any())->willReturn(
57
            $this->prophesize(AuthenticationPluginInterface::class)->reveal()
58
        );
59
60
        $this->middleware->process($request, $handler->reveal());
61
62
        $handle->shouldHaveBeenCalledOnce();
63
        $fromRequest->shouldNotHaveBeenCalled();
64
    }
65
66
    public function provideWhitelistedRequests(): iterable
67
    {
68
        $dummyMiddleware = $this->getDummyMiddleware();
69
70
        yield 'with no route result' => [new ServerRequest()];
71
        yield 'with failure route result' => [(new ServerRequest())->withAttribute(
72
            RouteResult::class,
73
            RouteResult::fromRouteFailure([RequestMethodInterface::METHOD_GET])
74
        )];
75
        yield 'with whitelisted route' => [(new ServerRequest())->withAttribute(
76
            RouteResult::class,
77
            RouteResult::fromRoute(
78
                new Route('foo', $dummyMiddleware, Route::HTTP_METHOD_ANY, AuthenticateAction::class)
0 ignored issues
show
Bug introduced by
Zend\Expressive\Router\Route::HTTP_METHOD_ANY of type null is incompatible with the type array expected by parameter $methods of Zend\Expressive\Router\Route::__construct(). ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

78
                new Route('foo', $dummyMiddleware, /** @scrutinizer ignore-type */ Route::HTTP_METHOD_ANY, AuthenticateAction::class)
Loading history...
79
            )
80
        )];
81
        yield 'with OPTIONS method' => [(new ServerRequest())->withAttribute(
82
            RouteResult::class,
83
            RouteResult::fromRoute(new Route('bar', $dummyMiddleware), [])
84
        )->withMethod(RequestMethodInterface::METHOD_OPTIONS)];
85
    }
86
87
    /** @test */
88
    public function updatedResponseIsReturnedWhenVerificationPasses(): void
89
    {
90
        $newResponse = new Response();
91
        $request = (new ServerRequest())->withAttribute(
92
            RouteResult::class,
93
            RouteResult::fromRoute(new Route('bar', $this->getDummyMiddleware()), [])
94
        );
95
        $plugin = $this->prophesize(AuthenticationPluginInterface::class);
96
97
        $verify = $plugin->verify($request)->will(function () {
98
        });
99
        $update = $plugin->update($request, Argument::type(ResponseInterface::class))->willReturn($newResponse);
100
        $fromRequest = $this->requestToPlugin->fromRequest(Argument::any())->willReturn($plugin->reveal());
101
102
        $handler = $this->prophesize(RequestHandlerInterface::class);
103
        $handle = $handler->handle($request)->willReturn(new Response());
104
        $response = $this->middleware->process($request, $handler->reveal());
105
106
        $this->assertSame($response, $newResponse);
107
        $verify->shouldHaveBeenCalledOnce();
108
        $update->shouldHaveBeenCalledOnce();
109
        $handle->shouldHaveBeenCalledOnce();
110
        $fromRequest->shouldHaveBeenCalledOnce();
111
    }
112
113
    private function getDummyMiddleware(): MiddlewareInterface
114
    {
115
        return middleware(function () {
116
            return new Response\EmptyResponse();
117
        });
118
    }
119
}
120