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

mapsDeprecatedPropertiesWhenRequestIsPerformedToVersionOne()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 20
Code Lines 14

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 1
eloc 14
nc 1
nop 1
dl 0
loc 20
rs 9.7998
c 1
b 0
f 0
1
<?php
2
3
declare(strict_types=1);
4
5
namespace ShlinkioTest\Shlink\Rest\Middleware;
6
7
use PHPUnit\Framework\TestCase;
8
use Prophecy\Prophecy\ObjectProphecy;
9
use Psr\Http\Server\RequestHandlerInterface;
10
use Shlinkio\Shlink\Rest\Middleware\BackwardsCompatibleProblemDetailsMiddleware;
11
use Zend\Diactoros\Response;
12
use Zend\Diactoros\ServerRequestFactory;
13
use Zend\Diactoros\Uri;
14
15
class BackwardsCompatibleProblemDetailsMiddlewareTest extends TestCase
16
{
17
    /** @var BackwardsCompatibleProblemDetailsMiddleware */
18
    private $middleware;
19
    /** @var ObjectProphecy */
20
    private $handler;
21
22
    public function setUp(): void
23
    {
24
        $this->handler = $this->prophesize(RequestHandlerInterface::class);
25
        $this->middleware = new BackwardsCompatibleProblemDetailsMiddleware([
26
            404 => 'NOT_FOUND',
27
            500 => 'INTERNAL_SERVER_ERROR',
28
        ], 0);
29
    }
30
31
    /**
32
     * @test
33
     * @dataProvider provideNonProcessableResponses
34
     */
35
    public function nonProblemDetailsOrInvalidResponsesAreReturnedAsTheyAre(Response $response): void
0 ignored issues
show
Unused Code introduced by
The parameter $response is not used and could be removed. ( Ignorable by Annotation )

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

35
    public function nonProblemDetailsOrInvalidResponsesAreReturnedAsTheyAre(/** @scrutinizer ignore-unused */ Response $response): void

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

Loading history...
36
    {
37
        $request = ServerRequestFactory::fromGlobals();
38
        $response = new Response();
39
        $handle = $this->handler->handle($request)->willReturn($response);
40
41
        $result = $this->middleware->process($request, $this->handler->reveal());
42
43
        $this->assertSame($response, $result);
44
        $handle->shouldHaveBeenCalledOnce();
45
    }
46
47
    public function provideNonProcessableResponses(): iterable
48
    {
49
        yield 'no problem details' => [new Response()];
50
        yield 'invalid JSON' => [(new Response('data://text/plain,{invalid-json'))->withHeader(
51
            'Content-Type',
52
            'application/problem+json'
53
        )];
54
    }
55
56
    /**
57
     * @test
58
     * @dataProvider provideStatusAndTypes
59
     */
60
    public function properlyMapsTypesBasedOnResponseStatus(Response\JsonResponse $response, string $expectedType): void
61
    {
62
        $request = ServerRequestFactory::fromGlobals()->withUri(new Uri('/v2/something'));
63
        $handle = $this->handler->handle($request)->willReturn($response);
64
65
        /** @var Response\JsonResponse $result */
66
        $result = $this->middleware->process($request, $this->handler->reveal());
67
        $payload = $result->getPayload();
68
69
        $this->assertEquals($expectedType, $payload['type']);
70
        $this->assertArrayNotHasKey('error', $payload);
71
        $this->assertArrayNotHasKey('message', $payload);
72
        $handle->shouldHaveBeenCalledOnce();
73
    }
74
75
    public function provideStatusAndTypes(): iterable
76
    {
77
        yield [$this->jsonResponse(['type' => 'https://httpstatus.es/404'], 404), 'NOT_FOUND'];
78
        yield [$this->jsonResponse(['type' => 'https://httpstatus.es/500'], 500), 'INTERNAL_SERVER_ERROR'];
79
        yield [$this->jsonResponse(['type' => 'https://httpstatus.es/504'], 504), 'https://httpstatus.es/504'];
80
        yield [$this->jsonResponse(['type' => 'something_else'], 404), 'something_else'];
81
        yield [$this->jsonResponse(['type' => 'something_else'], 500), 'something_else'];
82
        yield [$this->jsonResponse(['type' => 'something_else'], 504), 'something_else'];
83
    }
84
85
    /**
86
     * @test
87
     * @dataProvider provideRequestPath
88
     */
89
    public function mapsDeprecatedPropertiesWhenRequestIsPerformedToVersionOne(string $requestPath): void
90
    {
91
        $request = ServerRequestFactory::fromGlobals()->withUri(new Uri($requestPath));
92
        $response = $this->jsonResponse([
93
            'type' => 'the_type',
94
            'detail' => 'the_detail',
95
        ]);
96
        $handle = $this->handler->handle($request)->willReturn($response);
97
98
        /** @var Response\JsonResponse $result */
99
        $result = $this->middleware->process($request, $this->handler->reveal());
100
        $payload = $result->getPayload();
101
102
        $this->assertEquals([
103
            'type' => 'the_type',
104
            'detail' => 'the_detail',
105
            'error' => 'the_type',
106
            'message' => 'the_detail',
107
        ], $payload);
108
        $handle->shouldHaveBeenCalledOnce();
109
    }
110
111
    public function provideRequestPath(): iterable
112
    {
113
        yield 'no version' => ['/foo'];
114
        yield 'version one' => ['/v1/foo'];
115
    }
116
117
    private function jsonResponse(array $payload, int $status = 200): Response\JsonResponse
118
    {
119
        $headers = ['Content-Type' => 'application/problem+json'];
120
        return new Response\JsonResponse($payload, $status, $headers);
121
    }
122
}
123