Passed
Pull Request — 2.4 (#2921)
by Han Hui
05:37
created

Client::getKernel()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 1
eloc 1
c 1
b 0
f 0
nc 1
nop 0
dl 0
loc 3
rs 10
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\Bundle\FrameworkBundle\KernelBrowser;
17
use Symfony\Component\DependencyInjection\ContainerInterface;
18
use Symfony\Component\HttpClient\HttpClientTrait;
19
use Symfony\Component\HttpKernel\KernelInterface;
20
use Symfony\Component\HttpKernel\Profiler\Profile;
21
use Symfony\Contracts\HttpClient\HttpClientInterface;
22
use Symfony\Contracts\HttpClient\ResponseInterface;
23
use Symfony\Contracts\HttpClient\ResponseStreamInterface;
24
25
/**
26
 * Convenient test client that makes requests to a Kernel object.
27
 *
28
 * @experimental
29
 *
30
 * @author Kévin Dunglas <[email protected]>
31
 */
32
final class Client implements HttpClientInterface
33
{
34
    /**
35
     * @var Response
36
     */
37
    private $response;
38
39
    /**
40
     * @see HttpClientInterface::OPTIONS_DEFAULTS
41
     */
42
    public const OPTIONS_DEFAULT = [
43
        'auth_basic' => null,
44
        'auth_bearer' => null,
45
        'query' => [],
46
        'headers' => ['accept' => ['application/ld+json']],
47
        'body' => '',
48
        'json' => null,
49
        'base_uri' => 'http://example.com',
50
    ];
51
52
    use HttpClientTrait;
53
54
    private $kernelBrowser;
55
56
    public function __construct(KernelBrowser $kernelBrowser)
57
    {
58
        $this->kernelBrowser = $kernelBrowser;
59
        $kernelBrowser->followRedirects(false);
60
    }
61
62
    /**
63
     * {@inheritdoc}
64
     *
65
     * @see Client::OPTIONS_DEFAULTS for available options
66
     *
67
     * @return Response
68
     */
69
    public function request(string $method, string $url, array $options = []): ResponseInterface
70
    {
71
        $basic = $options['auth_basic'] ?? null;
72
        [$url, $options] = self::prepareRequest($method, $url, $options, self::OPTIONS_DEFAULT);
73
        $resolvedUrl = implode('', $url);
74
75
        $server = [];
76
        // Convert headers to a $_SERVER-like array
77
        foreach ($options['headers'] as $key => $value) {
78
            if ('content-type' === $key) {
79
                $server['CONTENT_TYPE'] = $value[0] ?? '';
80
81
                continue;
82
            }
83
84
            // BrowserKit doesn't support setting several headers with the same name
85
            $server['HTTP_'.strtoupper(str_replace('-', '_', $key))] = $value[0] ?? '';
86
        }
87
88
        if ($basic) {
89
            $credentials = \is_array($basic) ? $basic : explode(':', $basic, 2);
90
            $server['PHP_AUTH_USER'] = $credentials[0];
91
            $server['PHP_AUTH_PW'] = $credentials[1] ?? '';
92
        }
93
94
        $info = [
95
            'response_headers' => [],
96
            'redirect_count' => 0,
97
            'redirect_url' => null,
98
            'start_time' => 0.0,
99
            'http_method' => $method,
100
            'http_code' => 0,
101
            'error' => null,
102
            'user_data' => $options['user_data'] ?? null,
103
            'url' => $resolvedUrl,
104
            'primary_port' => 'http:' === $url['scheme'] ? 80 : 443,
105
        ];
106
        $this->kernelBrowser->request($method, $resolvedUrl, [], [], $server, $options['body'] ?? null);
107
108
        return $this->response = new Response($this->kernelBrowser->getResponse(), $this->kernelBrowser->getInternalResponse(), $info);
109
    }
110
111
    /**
112
     * {@inheritdoc}
113
     */
114
    public function stream($responses, float $timeout = null): ResponseStreamInterface
115
    {
116
        throw new \LogicException('Not implemented yet');
117
    }
118
119
    /**
120
     * Gets the latest response.
121
     *
122
     * @internal
123
     */
124
    public function getResponse(): ?Response
125
    {
126
        return $this->response;
127
    }
128
129
    /**
130
     * Gets the underlying test client.
131
     *
132
     * @internal
133
     */
134
    public function getKernelBrowser(): KernelBrowser
135
    {
136
        return $this->kernelBrowser;
137
    }
138
139
    // The following methods are proxy methods for KernelBrowser's ones
140
141
    /**
142
     * Returns the container.
143
     *
144
     * @return ContainerInterface|null Returns null when the Kernel has been shutdown or not started yet
145
     */
146
    public function getContainer(): ?ContainerInterface
147
    {
148
        return $this->kernelBrowser->getContainer();
149
    }
150
151
    /**
152
     * Returns the kernel.
153
     */
154
    public function getKernel(): KernelInterface
155
    {
156
        return $this->kernelBrowser->getKernel();
157
    }
158
159
    /**
160
     * Gets the profile associated with the current Response.
161
     *
162
     * @return Profile|false A Profile instance
163
     */
164
    public function getProfile()
165
    {
166
        return $this->kernelBrowser->getProfile();
167
    }
168
169
    /**
170
     * Enables the profiler for the very next request.
171
     *
172
     * If the profiler is not enabled, the call to this method does nothing.
173
     */
174
    public function enableProfiler(): void
175
    {
176
        $this->kernelBrowser->enableProfiler();
177
    }
178
179
    /**
180
     * Disables kernel reboot between requests.
181
     *
182
     * By default, the Client reboots the Kernel for each request. This method
183
     * allows to keep the same kernel across requests.
184
     */
185
    public function disableReboot(): void
186
    {
187
        $this->kernelBrowser->disableReboot();
188
    }
189
190
    /**
191
     * Enables kernel reboot between requests.
192
     */
193
    public function enableReboot(): void
194
    {
195
        $this->kernelBrowser->enableReboot();
196
    }
197
}
198