Skip to content

Commit fd787fb

Browse files
feat(ApiContext): improve type hints and request handling
1 parent 98edcc7 commit fd787fb

1 file changed

Lines changed: 278 additions & 2 deletions

File tree

tests/Unit/Context/Api/WhenApiContextsTest.php

Lines changed: 278 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,277 @@ public function testExceptionWhenRouteNotFound(): void
4444
$this->apiContext->iSendRequestToRoute(Request::METHOD_GET, '/_api/users/{id}');
4545
}
4646

47+
public function testSendGetRequestToRoute(): void
48+
{
49+
$reflectionClass = new \ReflectionClass($this->apiContext);
50+
51+
// Set up request params that should be converted to query string
52+
$requestParamsProp = $reflectionClass->getProperty('requestParams');
53+
$requestParamsProp->setAccessible(true);
54+
$requestParamsProp->setValue($this->apiContext, ['page' => 1, 'limit' => 10]);
55+
56+
$this->apiContext->iSendRequestToRoute(Request::METHOD_GET, 'api_users_get');
57+
58+
// Verify the request was made
59+
$this->assertNotNull($this->request);
60+
$this->assertNotNull($this->response);
61+
$this->assertEquals(Request::METHOD_GET, $this->request->getMethod());
62+
63+
// Verify request params were reset
64+
$this->assertEmpty($requestParamsProp->getValue($this->apiContext));
65+
}
66+
67+
public function testSendPostRequestToRouteWithFormData(): void
68+
{
69+
$reflectionClass = new \ReflectionClass($this->apiContext);
70+
71+
// Set up request params
72+
$requestParamsProp = $reflectionClass->getProperty('requestParams');
73+
$requestParamsProp->setAccessible(true);
74+
$requestParamsProp->setValue($this->apiContext, ['name' => 'John', 'email' => 'john@example.com']);
75+
76+
$this->apiContext->iSendRequestToRoute(Request::METHOD_POST, 'api_users_get');
77+
78+
// Verify the request was made
79+
$this->assertNotNull($this->request);
80+
$this->assertEquals(Request::METHOD_POST, $this->request->getMethod());
81+
82+
// Verify request params were reset after the request
83+
$this->assertEmpty($requestParamsProp->getValue($this->apiContext));
84+
}
85+
86+
public function testSendPostRequestToRouteWithJsonContent(): void
87+
{
88+
$reflectionClass = new \ReflectionClass($this->apiContext);
89+
90+
// Set up headers to indicate JSON content
91+
$headersProp = $reflectionClass->getProperty('headers');
92+
$headersProp->setAccessible(true);
93+
$headersProp->setValue($this->apiContext, ['Content-Type' => 'application/json']);
94+
95+
// Set up request params
96+
$requestParamsProp = $reflectionClass->getProperty('requestParams');
97+
$requestParamsProp->setAccessible(true);
98+
$requestParamsProp->setValue($this->apiContext, ['name' => 'John', 'email' => 'john@example.com']);
99+
100+
$this->apiContext->iSendRequestToRoute(Request::METHOD_POST, 'api_users_get');
101+
102+
// Verify the request was made
103+
$this->assertNotNull($this->request);
104+
$this->assertEquals(Request::METHOD_POST, $this->request->getMethod());
105+
106+
// Verify headers were reset
107+
$this->assertEmpty($headersProp->getValue($this->apiContext));
108+
}
109+
110+
public function testSendPatchRequestToRoute(): void
111+
{
112+
$reflectionClass = new \ReflectionClass($this->apiContext);
113+
114+
// Set up headers to indicate JSON content
115+
$headersProp = $reflectionClass->getProperty('headers');
116+
$headersProp->setAccessible(true);
117+
$headersProp->setValue($this->apiContext, ['Content-Type' => 'application/json']);
118+
119+
// Set up request params
120+
$requestParamsProp = $reflectionClass->getProperty('requestParams');
121+
$requestParamsProp->setAccessible(true);
122+
$requestParamsProp->setValue($this->apiContext, ['name' => 'Jane']);
123+
124+
$this->apiContext->iSendRequestToRoute(Request::METHOD_PATCH, 'api_users_get');
125+
126+
// Verify the request was made
127+
$this->assertNotNull($this->request);
128+
$this->assertEquals(Request::METHOD_PATCH, $this->request->getMethod());
129+
}
130+
131+
public function testSendPutRequestToRoute(): void
132+
{
133+
$reflectionClass = new \ReflectionClass($this->apiContext);
134+
135+
// Set up request params
136+
$requestParamsProp = $reflectionClass->getProperty('requestParams');
137+
$requestParamsProp->setAccessible(true);
138+
$requestParamsProp->setValue($this->apiContext, ['name' => 'John Updated']);
139+
140+
$this->apiContext->iSendRequestToRoute(Request::METHOD_PUT, 'api_users_get');
141+
142+
// Verify the request was made
143+
$this->assertNotNull($this->request);
144+
$this->assertEquals(Request::METHOD_PUT, $this->request->getMethod());
145+
}
146+
147+
public function testSendDeleteRequestToRoute(): void
148+
{
149+
$this->apiContext->iSendRequestToRoute(Request::METHOD_DELETE, 'api_users_get');
150+
151+
// Verify the request was made
152+
$this->assertNotNull($this->request);
153+
$this->assertEquals(Request::METHOD_DELETE, $this->request->getMethod());
154+
}
155+
156+
public function testSendRequestWithServerParams(): void
157+
{
158+
$reflectionClass = new \ReflectionClass($this->apiContext);
159+
160+
// Set up server params
161+
$serverParamsProp = $reflectionClass->getProperty('serverParams');
162+
$serverParamsProp->setAccessible(true);
163+
$serverParamsProp->setValue($this->apiContext, ['REMOTE_ADDR' => '127.0.0.1']);
164+
165+
$this->apiContext->iSendRequestToRoute(Request::METHOD_GET, 'api_users_get');
166+
167+
// Verify the request was made
168+
$this->assertNotNull($this->request);
169+
170+
// Verify server params were reset
171+
$this->assertEmpty($serverParamsProp->getValue($this->apiContext));
172+
}
173+
174+
public function testSendRequestWithRouteParameters(): void
175+
{
176+
$reflectionClass = new \ReflectionClass($this->apiContext);
177+
178+
// Set up request params including route parameter
179+
$requestParamsProp = $reflectionClass->getProperty('requestParams');
180+
$requestParamsProp->setAccessible(true);
181+
$requestParamsProp->setValue($this->apiContext, ['id' => '123', 'extra' => 'value']);
182+
183+
$this->apiContext->iSendRequestToRoute(Request::METHOD_GET, 'api_users_get');
184+
185+
// Verify the request was made
186+
$this->assertNotNull($this->request);
187+
$this->assertNotNull($this->response);
188+
}
189+
190+
public function testSendGetRequestWithEmptyQueryString(): void
191+
{
192+
$reflectionClass = new \ReflectionClass($this->apiContext);
193+
194+
// No request params should result in empty query string
195+
$requestParamsProp = $reflectionClass->getProperty('requestParams');
196+
$requestParamsProp->setAccessible(true);
197+
$requestParamsProp->setValue($this->apiContext, []);
198+
199+
$this->apiContext->iSendRequestToRoute(Request::METHOD_GET, 'api_users_get');
200+
201+
// Verify the request was made
202+
$this->assertNotNull($this->request);
203+
$this->assertEquals(Request::METHOD_GET, $this->request->getMethod());
204+
}
205+
206+
public function testSendPostRequestWithMixedCaseContentType(): void
207+
{
208+
$reflectionClass = new \ReflectionClass($this->apiContext);
209+
210+
// Set up headers with mixed case Content-Type (should still detect JSON)
211+
$headersProp = $reflectionClass->getProperty('headers');
212+
$headersProp->setAccessible(true);
213+
$headersProp->setValue($this->apiContext, ['Content-Type' => 'APPLICATION/JSON; charset=utf-8']);
214+
215+
// Set up request params
216+
$requestParamsProp = $reflectionClass->getProperty('requestParams');
217+
$requestParamsProp->setAccessible(true);
218+
$requestParamsProp->setValue($this->apiContext, ['test' => 'value']);
219+
220+
$this->apiContext->iSendRequestToRoute(Request::METHOD_POST, 'api_users_get');
221+
222+
// Verify the request was made
223+
$this->assertNotNull($this->request);
224+
$this->assertEquals(Request::METHOD_POST, $this->request->getMethod());
225+
}
226+
227+
public function testSendPutRequestWithFormData(): void
228+
{
229+
$reflectionClass = new \ReflectionClass($this->apiContext);
230+
231+
// Set up request params without JSON header (form data)
232+
$requestParamsProp = $reflectionClass->getProperty('requestParams');
233+
$requestParamsProp->setAccessible(true);
234+
$requestParamsProp->setValue($this->apiContext, ['field' => 'value']);
235+
236+
$this->apiContext->iSendRequestToRoute(Request::METHOD_PUT, 'api_users_get');
237+
238+
// Verify the request was made
239+
$this->assertNotNull($this->request);
240+
$this->assertEquals(Request::METHOD_PUT, $this->request->getMethod());
241+
}
242+
243+
public function testSendPatchRequestWithFormData(): void
244+
{
245+
$reflectionClass = new \ReflectionClass($this->apiContext);
246+
247+
// Set up request params without JSON header (form data)
248+
$requestParamsProp = $reflectionClass->getProperty('requestParams');
249+
$requestParamsProp->setAccessible(true);
250+
$requestParamsProp->setValue($this->apiContext, ['status' => 'active']);
251+
252+
$this->apiContext->iSendRequestToRoute(Request::METHOD_PATCH, 'api_users_get');
253+
254+
// Verify the request was made
255+
$this->assertNotNull($this->request);
256+
$this->assertEquals(Request::METHOD_PATCH, $this->request->getMethod());
257+
}
258+
259+
public function testSendRequestWithMultipleHeaders(): void
260+
{
261+
$reflectionClass = new \ReflectionClass($this->apiContext);
262+
263+
// Set up multiple headers
264+
$headersProp = $reflectionClass->getProperty('headers');
265+
$headersProp->setAccessible(true);
266+
$headersProp->setValue($this->apiContext, [
267+
'Authorization' => 'Bearer token123',
268+
'Accept' => 'application/json',
269+
'X-Custom-Header' => 'custom-value'
270+
]);
271+
272+
$this->apiContext->iSendRequestToRoute(Request::METHOD_GET, 'api_users_get');
273+
274+
// Verify the request was made
275+
$this->assertNotNull($this->request);
276+
277+
// Verify headers were reset
278+
$this->assertEmpty($headersProp->getValue($this->apiContext));
279+
}
280+
281+
public function testSendRequestWithComplexQueryParams(): void
282+
{
283+
$reflectionClass = new \ReflectionClass($this->apiContext);
284+
285+
// Set up complex query params
286+
$requestParamsProp = $reflectionClass->getProperty('requestParams');
287+
$requestParamsProp->setAccessible(true);
288+
$requestParamsProp->setValue($this->apiContext, [
289+
'filter' => 'active',
290+
'sort' => 'name',
291+
'page' => 2,
292+
'limit' => 50
293+
]);
294+
295+
$this->apiContext->iSendRequestToRoute(Request::METHOD_GET, 'api_users_get');
296+
297+
// Verify the request was made
298+
$this->assertNotNull($this->request);
299+
$this->assertNotNull($this->response);
300+
}
301+
302+
public function testSendDeleteRequestWithParams(): void
303+
{
304+
$reflectionClass = new \ReflectionClass($this->apiContext);
305+
306+
// Set up request params (DELETE requests typically don't use body)
307+
$requestParamsProp = $reflectionClass->getProperty('requestParams');
308+
$requestParamsProp->setAccessible(true);
309+
$requestParamsProp->setValue($this->apiContext, ['cascade' => 'true']);
310+
311+
$this->apiContext->iSendRequestToRoute(Request::METHOD_DELETE, 'api_users_get');
312+
313+
// Verify the request was made
314+
$this->assertNotNull($this->request);
315+
$this->assertEquals(Request::METHOD_DELETE, $this->request->getMethod());
316+
}
317+
47318
protected function configureRouter(): RouterInterface
48319
{
49320
$router = parent::configureRouter();
@@ -62,7 +333,7 @@ protected function configureRouter(): RouterInterface
62333
->method('generate')
63334
->willThrowException(new RouteNotFoundException());
64335
} else {
65-
$router->expects($this->once())
336+
$router->expects($this->any())
66337
->method('generate')
67338
->willReturn('/api/users/1');
68339
}
@@ -80,7 +351,12 @@ protected function getKernelMock(): KernelInterface&TerminableInterface
80351

81352
if (!$this->invalidRouteMock) {
82353
$kernel
83-
->expects($this->once())
354+
->expects($this->any())
355+
->method('handle')
356+
->willReturn(new Response('{"status": "ok"}', 200));
357+
358+
$kernel
359+
->expects($this->any())
84360
->method('terminate')
85361
->will(
86362
$this->returnCallback(function (Request $request, Response $response): void {

0 commit comments

Comments
 (0)