Passed
Pull Request — master (#2608)
by Kévin
03:22
created

Response::getInfo()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 7
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 2
eloc 3
nc 2
nop 1
dl 0
loc 7
rs 10
c 0
b 0
f 0
1
<?php
2
3
/*
4
 * This file is part of the API Platform project.
5
 *
6
 * (c) Kévin Dunglas <[email protected]>
7
 *
8
 * For the full copyright and license information, please view the LICENSE
9
 * file that was distributed with this source code.
10
 */
11
12
declare(strict_types=1);
13
14
namespace ApiPlatform\Core\Bridge\Symfony\Bundle\Test;
15
16
use Symfony\Component\BrowserKit\Response as BrowserKitResponse;
17
use Symfony\Component\HttpClient\Exception\JsonException;
18
use Symfony\Component\HttpFoundation\Response as HttpFoundationResponse;
19
use Symfony\Contracts\HttpClient\Exception\ClientExceptionInterface;
20
use Symfony\Contracts\HttpClient\Exception\RedirectionExceptionInterface;
21
use Symfony\Contracts\HttpClient\Exception\ServerExceptionInterface;
22
use Symfony\Contracts\HttpClient\Exception\TransportExceptionInterface;
23
use Symfony\Contracts\HttpClient\ResponseInterface;
24
25
/**
26
 * HTTP Response.
27
 *
28
 * @internal
29
 *
30
 * Partially copied from \Symfony\Component\HttpClient\Response\ResponseTrait
31
 *
32
 * @author Kévin Dunglas <[email protected]>
33
 */
34
final class Response implements ResponseInterface
35
{
36
    private $httpFoundationResponse;
37
    private $browserKitResponse;
38
    private $info;
39
    private $content;
40
    private $jsonData;
41
42
    public function __construct(HttpFoundationResponse $httpFoundationResponse, BrowserKitResponse $browserKitResponse, array $info)
43
    {
44
        $this->httpFoundationResponse = $httpFoundationResponse;
45
        $this->browserKitResponse = $browserKitResponse;
46
47
        $this->headers = $httpFoundationResponse->headers->all();
48
        $this->content = $httpFoundationResponse->getContent();
49
        $this->info = $info + [
50
            'http_code' => $httpFoundationResponse->getStatusCode(),
51
            'error' => null,
52
            'raw_headers' => $this->headers,
0 ignored issues
show
Bug Best Practice introduced by
The property headers does not exist on ApiPlatform\Core\Bridge\...ny\Bundle\Test\Response. Did you maybe forget to declare it?
Loading history...
53
        ];
54
    }
55
56
    /**
57
     * {@inheritdoc}
58
     */
59
    public function getInfo(string $type = null)
60
    {
61
        if ($type) {
62
            return $this->info[$type] ?? null;
63
        }
64
65
        return $this->info;
66
    }
67
68
    private function checkStatusCode()
69
    {
70
        if (500 <= $this->info['http_code']) {
71
            throw new class('', $this->info['http_code']) extends \RuntimeException implements ServerExceptionInterface {
72
            };
73
        }
74
75
        if (400 <= $this->info['http_code']) {
76
            throw new class('', $this->info['http_code']) extends \RuntimeException implements ClientExceptionInterface {
77
            };
78
        }
79
80
        if (300 <= $this->info['http_code']) {
81
            throw new class('', $this->info['http_code']) extends \RuntimeException implements RedirectionExceptionInterface {
82
            };
83
        }
84
    }
85
86
    /**
87
     * {@inheritdoc}
88
     */
89
    public function getContent(bool $throw = true): string
90
    {
91
        if ($throw) {
92
            $this->checkStatusCode();
93
        }
94
95
        return $this->content;
96
    }
97
98
    /**
99
     * {@inheritdoc}
100
     */
101
    public function getStatusCode(): int
102
    {
103
        return $this->info['http_code'];
104
    }
105
106
    /**
107
     * {@inheritdoc}
108
     */
109
    public function getHeaders(bool $throw = true): array
110
    {
111
        if ($throw) {
112
            $this->checkStatusCode();
113
        }
114
115
        return $this->headers;
0 ignored issues
show
Bug Best Practice introduced by
The property headers does not exist on ApiPlatform\Core\Bridge\...ny\Bundle\Test\Response. Did you maybe forget to declare it?
Loading history...
116
    }
117
118
    /**
119
     * {@inheritdoc}
120
     */
121
    public function toArray(bool $throw = true): array
122
    {
123
        if (null !== $this->jsonData) {
124
            return $this->jsonData;
125
        }
126
127
        if ('' === $content = $this->getContent($throw)) {
128
            throw new class(sprintf('Response body is empty.', $contentType)) extends \Exception implements TransportExceptionInterface {
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $contentType does not exist. Did you maybe mean $content?
Loading history...
129
            };
130
        }
131
132
        $contentType = $this->headers['content-type'][0] ?? 'application/json';
0 ignored issues
show
Bug Best Practice introduced by
The property headers does not exist on ApiPlatform\Core\Bridge\...ny\Bundle\Test\Response. Did you maybe forget to declare it?
Loading history...
133
134
        if (!preg_match('/\bjson\b/i', $contentType)) {
135
            throw new class(sprintf('Response content-type is "%s" while a JSON-compatible one was expected.', $contentType)) extends \JsonException implements TransportExceptionInterface {
136
            };
137
        }
138
139
        try {
140
            $content = json_decode($content, true, 512, JSON_BIGINT_AS_STRING | (\PHP_VERSION_ID >= 70300 ? JSON_THROW_ON_ERROR : 0));
0 ignored issues
show
Bug introduced by
The constant ApiPlatform\Core\Bridge\...est\JSON_THROW_ON_ERROR was not found. Maybe you did not declare it correctly or list all dependencies?
Loading history...
141
        } catch (\JsonException $e) {
142
            throw new class($e->getMessage(), $e->getCode()) extends \JsonException implements TransportExceptionInterface {
143
            };
144
        }
145
146
        if (\PHP_VERSION_ID < 70300 && JSON_ERROR_NONE !== json_last_error()) {
147
            throw new JsonException(json_last_error_msg(), json_last_error());
148
        }
149
150
        if (!\is_array($content)) {
151
            throw new class(sprintf('JSON content was expected to decode to an array, %s returned.', \gettype($content))) extends \JsonException implements TransportExceptionInterface {
152
            };
153
        }
154
155
        return $this->jsonData = $content;
156
    }
157
158
    /**
159
     * Returns the internal HttpKernel response.
160
     */
161
    public function getKernelResponse(): HttpFoundationResponse
162
    {
163
        return $this->httpFoundationResponse;
164
    }
165
166
    /**
167
     * Returns the internal BrowserKit reponse.
168
     */
169
    public function getBrowserKitResponse(): BrowserKitResponse
170
    {
171
        return $this->browserKitResponse;
172
    }
173
}
174