Passed
Push — master ( 1e0132...9b86f1 )
by Baptiste
02:58
created

RequestContext::set_the_body()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 7
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 7
rs 9.4285
c 0
b 0
f 0
cc 1
eloc 4
nc 1
nop 1
1
<?php declare(strict_types=1);
2
namespace Behapi\Http;
3
4
use RuntimeException;
5
6
use Psr\Http\Message\RequestInterface;
7
8
use Behat\Behat\Context\Context;
9
use Behat\Gherkin\Node\TableNode;
10
11
use Http\Client\HttpClient;
12
use Http\Message\StreamFactory;
13
use Http\Message\MessageFactory;
14
use Http\Discovery\HttpClientDiscovery;
15
16
use function trim;
17
use function is_array;
18
use function http_build_query;
19
20
class RequestContext implements Context
21
{
22
    use Builder;
23
24
    /** @var RequestInterface */
25
    private $request;
26
27
    /** @var mixed[] Query args to add */
28
    private $query;
29
30
    /** @var HttpClient|HttpAsyncClient */
31
    private $client;
32
33
    public function __construct(PluginClientBuilder $builder, StreamFactory $streamFactory, MessageFactory $messageFactory)
34
    {
35
        $this->builder = $builder;
36
        $this->streamFactory = $streamFactory;
37
        $this->messageFactory = $messageFactory;
38
39
        $this->client = HttpClientDiscovery::find();
40
    }
41
42
    /** @When /^I create a "(?P<method>GET|POST|PATCH|PUT|DELETE|OPTIONS|HEAD)" request to "(?P<url>.+?)"$/ */
43
    final public function create_a_request(string $method, string $url): void
44
    {
45
        $url = trim($url);
46
47
        $this->query = [];
48
        $this->request = $this->messageFactory->createRequest(strtoupper($method), $url);
49
50
        // let's set a default content-type
51
        $this->set_content_type($this->getDefaultContentType());
0 ignored issues
show
Bug introduced by
The method set_content_type() does not seem to exist on object<Behapi\Http\RequestContext>.

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
52
    }
53
54
    /**
55
     * @When /^I send a "(?P<method>GET|POST|PATCH|PUT|DELETE|OPTIONS|HEAD)" request to "(?P<url>.+?)"$/
56
     *
57
     * -------
58
     *
59
     * Shortcut for `When I create a X request to Then send the request`
60
     */
61
    final public function send_a_request($method, $url): void
62
    {
63
        $this->create_a_request($method, $url);
64
        $this->send_request();
65
    }
66
67
    /** @When I add/set the value :value to the parameter :parameter */
68
    final public function add_a_parameter(string $parameter, string $value): void
69
    {
70
        if (!isset($this->query[$parameter])) {
71
            $this->query[$parameter] = $value;
72
            return;
73
        }
74
75
        $current = &$this->query[$parameter];
76
77
        if (is_array($current)) {
78
            $current[] = $value;
79
            return;
80
        }
81
82
        $current = [$current, $value];
83
    }
84
85
    /** @When I set the following query arguments: */
86
    final public function set_the_parameters(TableNode $parameters): void
87
    {
88
        $this->query = [];
89
90
        foreach ($parameters->getRowsHash() as $parameter => $value) {
91
            $this->add_a_parameter($parameter, $value);
92
        }
93
    }
94
95
    /** @When I set the content-type to :type */
96
    final public function set_the_content_type(string $type): void
97
    {
98
        $request = $this->getRequest();
99
        $this->request = $request->withHeader('Content-Type', $type);
100
    }
101
102
    /** @When I set the following body: */
103
    final public function set_the_body(string $body): void
104
    {
105
        $stream = $this->streamFactory->createStream($body);
106
107
        $request = $this->getRequest();
108
        $this->request = $request->withBody($stream);
109
    }
110
111
    /** @When I add/set the value :value to the header :header */
112
    final public function add_header(string $header, string $value): void
113
    {
114
        $request = $this->getRequest();
115
        $this->request = $request->withAddedHeader($header, $value);
116
    }
117
118
    /** @When I set the headers: */
119
    final public function set_headers(TableNode $headers): void
120
    {
121
        $request = $this->getRequest();
122
123
        foreach ($headers->getRowsHash() as $header => $value) {
124
            $request = $request->withHeader($header, $value);
125
        }
126
127
        $this->request = $request;
128
    }
129
130
    /** @When I send the request */
131
    final public function send_request(): void
132
    {
133
        $request = $this->getRequest();
134
135
        if (!empty($this->query)) {
136
            $uri = $request->getUri();
137
            $current = $uri->getQuery();
138
            $query = http_build_query($this->query);
139
140
            if (!empty($current)) {
141
                $query = "{$current}&{$query}";
142
            }
143
144
            $uri = $uri->withQuery($query);
145
            $request = $request->withUri($uri);
146
        }
147
148
        $client = $this->builder->createClient($this->client);
149
        $client->sendRequest($request);
150
    }
151
152
    /** @AfterScenario @api */
153
    final public function clearCache(): void
154
    {
155
        $this->query = [];
156
        $this->request = null;
157
    }
158
159
    final public function getRequest(): RequestInterface
160
    {
161
        if (null === $this->request) {
162
            throw new RuntimeException('No request initiated');
163
        }
164
165
        return $this->request;
166
    }
167
168
    protected function getDefaultContentType(): string
169
    {
170
        return 'application/json';
171
    }
172
}
173