Passed
Pull Request — master (#2608)
by Kévin
04:57
created

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