Skip to content

Commit dd01ef1

Browse files
authored
feat(framework): extend http testing methods (#790)
1 parent 50b27c8 commit dd01ef1

File tree

7 files changed

+352
-0
lines changed

7 files changed

+352
-0
lines changed

src/Tempest/Framework/Testing/Http/HttpRouterTester.php

Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,18 @@ public function get(string $uri, array $headers = []): TestResponseHelper
3232
);
3333
}
3434

35+
public function head(string $uri, array $headers = []): TestResponseHelper
36+
{
37+
return $this->sendRequest(
38+
new GenericRequest(
39+
method: Method::HEAD,
40+
uri: $uri,
41+
body: [],
42+
headers: $headers,
43+
),
44+
);
45+
}
46+
3547
public function post(string $uri, array $body = [], array $headers = []): TestResponseHelper
3648
{
3749
return $this->sendRequest(
@@ -44,6 +56,78 @@ public function post(string $uri, array $body = [], array $headers = []): TestRe
4456
);
4557
}
4658

59+
public function put(string $uri, array $body = [], array $headers = []): TestResponseHelper
60+
{
61+
return $this->sendRequest(
62+
new GenericRequest(
63+
method: Method::PUT,
64+
uri: $uri,
65+
body: $body,
66+
headers: $headers,
67+
),
68+
);
69+
}
70+
71+
public function delete(string $uri, array $body = [], array $headers = []): TestResponseHelper
72+
{
73+
return $this->sendRequest(
74+
new GenericRequest(
75+
method: Method::DELETE,
76+
uri: $uri,
77+
body: $body,
78+
headers: $headers,
79+
),
80+
);
81+
}
82+
83+
public function connect(string $uri, array $body = [], array $headers = []): TestResponseHelper
84+
{
85+
return $this->sendRequest(
86+
new GenericRequest(
87+
method: Method::CONNECT,
88+
uri: $uri,
89+
body: $body,
90+
headers: $headers,
91+
),
92+
);
93+
}
94+
95+
public function options(string $uri, array $body = [], array $headers = []): TestResponseHelper
96+
{
97+
return $this->sendRequest(
98+
new GenericRequest(
99+
method: Method::OPTIONS,
100+
uri: $uri,
101+
body: $body,
102+
headers: $headers,
103+
),
104+
);
105+
}
106+
107+
public function trace(string $uri, array $body = [], array $headers = []): TestResponseHelper
108+
{
109+
return $this->sendRequest(
110+
new GenericRequest(
111+
method: Method::TRACE,
112+
uri: $uri,
113+
body: $body,
114+
headers: $headers,
115+
),
116+
);
117+
}
118+
119+
public function patch(string $uri, array $body = [], array $headers = []): TestResponseHelper
120+
{
121+
return $this->sendRequest(
122+
new GenericRequest(
123+
method: Method::PATCH,
124+
uri: $uri,
125+
body: $body,
126+
headers: $headers,
127+
),
128+
);
129+
}
130+
47131
public function sendRequest(Request $request): TestResponseHelper
48132
{
49133
/** @var Router $router */

src/Tempest/Http/src/Connect.php

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace Tempest\Http;
6+
7+
use Attribute;
8+
9+
#[Attribute(Attribute::IS_REPEATABLE | Attribute::TARGET_METHOD)]
10+
final class Connect extends Route
11+
{
12+
public function __construct(
13+
string $uri,
14+
15+
/**
16+
* @template MiddlewareClass of \Tempest\Http\HttpMiddleware
17+
* @var class-string<MiddlewareClass>[] $middleware
18+
*/
19+
array $middleware = [],
20+
) {
21+
parent::__construct(
22+
uri: $uri,
23+
method: Method::CONNECT,
24+
middleware: $middleware,
25+
);
26+
}
27+
}

src/Tempest/Http/src/Head.php

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace Tempest\Http;
6+
7+
use Attribute;
8+
9+
#[Attribute(Attribute::IS_REPEATABLE | Attribute::TARGET_METHOD)]
10+
final class Head extends Route
11+
{
12+
public function __construct(
13+
string $uri,
14+
15+
/**
16+
* @template MiddlewareClass of \Tempest\Http\HttpMiddleware
17+
* @var class-string<MiddlewareClass>[] $middleware
18+
*/
19+
array $middleware = [],
20+
) {
21+
parent::__construct(
22+
uri: $uri,
23+
method: Method::HEAD,
24+
middleware: $middleware,
25+
);
26+
}
27+
}

src/Tempest/Http/src/Options.php

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace Tempest\Http;
6+
7+
use Attribute;
8+
9+
#[Attribute(Attribute::IS_REPEATABLE | Attribute::TARGET_METHOD)]
10+
final class Options extends Route
11+
{
12+
public function __construct(
13+
string $uri,
14+
15+
/**
16+
* @template MiddlewareClass of \Tempest\Http\HttpMiddleware
17+
* @var class-string<MiddlewareClass>[] $middleware
18+
*/
19+
array $middleware = [],
20+
) {
21+
parent::__construct(
22+
uri: $uri,
23+
method: Method::OPTIONS,
24+
middleware: $middleware,
25+
);
26+
}
27+
}

src/Tempest/Http/src/Trace.php

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace Tempest\Http;
6+
7+
use Attribute;
8+
9+
#[Attribute(Attribute::IS_REPEATABLE | Attribute::TARGET_METHOD)]
10+
final class Trace extends Route
11+
{
12+
public function __construct(
13+
string $uri,
14+
15+
/**
16+
* @template MiddlewareClass of \Tempest\Http\HttpMiddleware
17+
* @var class-string<MiddlewareClass>[] $middleware
18+
*/
19+
array $middleware = [],
20+
) {
21+
parent::__construct(
22+
uri: $uri,
23+
method: Method::TRACE,
24+
middleware: $middleware,
25+
);
26+
}
27+
}

tests/Fixtures/Controllers/TestController.php

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,13 +4,21 @@
44

55
namespace Tests\Tempest\Fixtures\Controllers;
66

7+
use Tempest\Http\Connect;
8+
use Tempest\Http\Delete;
79
use Tempest\Http\Get;
10+
use Tempest\Http\Head;
11+
use Tempest\Http\Options;
12+
use Tempest\Http\Patch;
13+
use Tempest\Http\Post;
14+
use Tempest\Http\Put;
815
use Tempest\Http\Response;
916
use Tempest\Http\Responses\Created;
1017
use Tempest\Http\Responses\NotFound;
1118
use Tempest\Http\Responses\Ok;
1219
use Tempest\Http\Responses\Redirect;
1320
use Tempest\Http\Responses\ServerError;
21+
use Tempest\Http\Trace;
1422
use function Tempest\view;
1523
use Tempest\View\View;
1624
use Tests\Tempest\Fixtures\Views\ViewWithResponseData;
@@ -36,6 +44,14 @@ public function withComplexCustomRegexParams(string $id): Response
3644
}
3745

3846
#[Get(uri: '/test')]
47+
#[Head(uri: '/test')]
48+
#[Post(uri: '/test')]
49+
#[Put(uri: '/test')]
50+
#[Delete(uri: '/test')]
51+
#[Connect(uri: '/test')]
52+
#[Options(uri: '/test')]
53+
#[Trace(uri: '/test')]
54+
#[Patch(uri: '/test')]
3955
public function __invoke(): Response
4056
{
4157
return new Ok('test');

tests/Integration/Testing/Http/HttpRouterTesterIntegrationTest.php

Lines changed: 144 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,4 +29,148 @@ public function test_get_requests_failure(): void
2929
->get('/this-route-does-not-exist')
3030
->assertOk();
3131
}
32+
33+
public function test_head_requests(): void
34+
{
35+
$this
36+
->http
37+
->head('/test')
38+
->assertOk();
39+
}
40+
41+
public function test_head_requests_failure(): void
42+
{
43+
$this->expectException(AssertionFailedError::class);
44+
45+
$this
46+
->http
47+
->head('/this-route-does-not-exist')
48+
->assertOk();
49+
}
50+
51+
public function test_post_requests(): void
52+
{
53+
$this
54+
->http
55+
->post('/test')
56+
->assertOk();
57+
}
58+
59+
public function test_post_requests_failure(): void
60+
{
61+
$this->expectException(AssertionFailedError::class);
62+
63+
$this
64+
->http
65+
->post('/this-route-does-not-exist')
66+
->assertOk();
67+
}
68+
69+
public function test_put_requests(): void
70+
{
71+
$this
72+
->http
73+
->put('/test')
74+
->assertOk();
75+
}
76+
77+
public function test_put_requests_failure(): void
78+
{
79+
$this->expectException(AssertionFailedError::class);
80+
81+
$this
82+
->http
83+
->put('/this-route-does-not-exist')
84+
->assertOk();
85+
}
86+
87+
public function test_delete_requests(): void
88+
{
89+
$this
90+
->http
91+
->delete('/test')
92+
->assertOk();
93+
}
94+
95+
public function test_delete_requests_failure(): void
96+
{
97+
$this->expectException(AssertionFailedError::class);
98+
99+
$this
100+
->http
101+
->delete('/this-route-does-not-exist')
102+
->assertOk();
103+
}
104+
105+
public function test_connect_requests(): void
106+
{
107+
$this
108+
->http
109+
->connect('/test')
110+
->assertOk();
111+
}
112+
113+
public function test_connect_requests_failure(): void
114+
{
115+
$this->expectException(AssertionFailedError::class);
116+
117+
$this
118+
->http
119+
->connect('/this-route-does-not-exist')
120+
->assertOk();
121+
}
122+
123+
public function test_options_requests(): void
124+
{
125+
$this
126+
->http
127+
->options('/test')
128+
->assertOk();
129+
}
130+
131+
public function test_options_requests_failure(): void
132+
{
133+
$this->expectException(AssertionFailedError::class);
134+
135+
$this
136+
->http
137+
->options('/this-route-does-not-exist')
138+
->assertOk();
139+
}
140+
141+
public function test_trace_requests(): void
142+
{
143+
$this
144+
->http
145+
->trace('/test')
146+
->assertOk();
147+
}
148+
149+
public function test_trace_requests_failure(): void
150+
{
151+
$this->expectException(AssertionFailedError::class);
152+
153+
$this
154+
->http
155+
->trace('/this-route-does-not-exist')
156+
->assertOk();
157+
}
158+
159+
public function test_patch_requests(): void
160+
{
161+
$this
162+
->http
163+
->patch('/test')
164+
->assertOk();
165+
}
166+
167+
public function test_patch_requests_failure(): void
168+
{
169+
$this->expectException(AssertionFailedError::class);
170+
171+
$this
172+
->http
173+
->patch('/this-route-does-not-exist')
174+
->assertOk();
175+
}
32176
}

0 commit comments

Comments
 (0)