-
-
Notifications
You must be signed in to change notification settings - Fork 18
Expand file tree
/
Copy pathTestCase.php
More file actions
189 lines (162 loc) · 4.64 KB
/
Copy pathTestCase.php
File metadata and controls
189 lines (162 loc) · 4.64 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
<?php
declare(strict_types=1);
namespace Bow\Testing;
use BadMethodCallException;
use Bow\Http\Client\HttpClient;
use Exception;
use PHPUnit\Framework\TestCase as PHPUnitTestCase;
class TestCase extends PHPUnitTestCase
{
/**
* The base url. If null, resolves to APP_URL env var, then to
* http://127.0.0.1:8080 (the default of `php bow run:server`).
*
* @var ?string
*/
protected ?string $url = null;
/**
* Attachments to send with the next request. Cleared after each call.
*
* @var array
*/
private array $attach = [];
/**
* Headers applied to every request made by this test instance.
* Use withHeader() / withHeaders() to populate. Persists until the
* test ends or you reset it manually.
*
* @var array
*/
private array $headers = [];
/**
* Add files / multipart attachments to the next request.
* Cleared automatically after the request is sent.
*/
public function attach(array $attach): TestCase
{
$this->attach = $attach;
return $this;
}
/**
* Replace the header map applied to every request.
*/
public function withHeaders(array $headers): TestCase
{
$this->headers = $headers;
return $this;
}
/**
* Add (or override) a single header.
*/
public function withHeader(string $key, string $value): TestCase
{
$this->headers[$key] = $value;
return $this;
}
/**
* GET request.
*
* @throws Exception
*/
public function get(string $url, array $param = []): Response
{
return new Response($this->newHttpClient()->get($url, $param));
}
/**
* POST request.
*
* @throws Exception
*/
public function post(string $url, array $param = []): Response
{
return new Response($this->newHttpClient()->post($url, $param));
}
/**
* PUT request.
*
* @throws Exception
*/
public function put(string $url, array $param = []): Response
{
return new Response($this->newHttpClient()->put($url, $param));
}
/**
* PATCH request (real HTTP PATCH — no _method POST hack).
*
* @throws Exception
*/
public function patch(string $url, array $param = []): Response
{
return new Response($this->newHttpClient()->patch($url, $param));
}
/**
* DELETE request (real HTTP DELETE — no _method POST hack).
*
* @throws Exception
*/
public function delete(string $url, array $param = []): Response
{
return new Response($this->newHttpClient()->delete($url, $param));
}
/**
* HEAD request (headers only, no body).
*
* @throws Exception
*/
public function head(string $url, array $param = []): Response
{
return new Response($this->newHttpClient()->head($url, $param));
}
/**
* OPTIONS request (typically for CORS preflight).
*
* @throws Exception
*/
public function options(string $url): Response
{
return new Response($this->newHttpClient()->options($url));
}
/**
* Dispatch a request by HTTP verb name.
*
* @throws BadMethodCallException
*/
public function visit(string $method, string $url, array $params = []): Response
{
$method = strtolower($method);
$allowed = ['get', 'post', 'put', 'patch', 'delete', 'head', 'options'];
if (!in_array($method, $allowed, true)) {
throw new BadMethodCallException(
'The HTTP [' . $method . '] method does not exists.'
);
}
return $method === 'options'
? $this->options($url)
: $this->$method($url, $params);
}
/**
* Build a fresh HttpClient pre-configured with the current headers and
* pending attachments. Attachments are consumed (reset) after this call;
* headers persist for the lifetime of the test instance.
*/
protected function newHttpClient(): HttpClient
{
$http = new HttpClient($this->getBaseUrl());
if ($this->headers !== []) {
$http->withHeaders($this->headers);
}
if ($this->attach !== []) {
$http->addAttach($this->attach);
$this->attach = []; // consume — don't leak into the next call
}
return $http;
}
/**
* Resolve the base URL. Override this in a subclass for more elaborate
* setups (per-test base URLs, computed from env, etc.).
*/
protected function getBaseUrl(): string
{
return rtrim($this->url ?? app_env('APP_URL', 'http://127.0.0.1:8080'), '/');
}
}