Total Complexity | 41 |
Total Lines | 486 |
Duplicated Lines | 0 % |
Changes | 0 |
Complex classes like RequestParsingTest often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes.
Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.
While breaking up the class, it is a good idea to analyze how other classes use RequestParsingTest, and based on these observations, apply Extract Interface, too.
1 | <?php |
||
17 | class RequestParsingTest extends TestCase |
||
18 | { |
||
19 | public function testParsesGraphqlRequest() : void |
||
20 | { |
||
21 | $query = '{my query}'; |
||
22 | $parsed = [ |
||
23 | 'raw' => $this->parseRawRequest('application/graphql', $query), |
||
24 | 'psr' => $this->parsePsrRequest('application/graphql', $query), |
||
25 | ]; |
||
26 | |||
27 | foreach ($parsed as $source => $parsedBody) { |
||
28 | self::assertValidOperationParams($parsedBody, $query, null, null, null, null, $source); |
||
29 | self::assertFalse($parsedBody->isReadOnly(), $source); |
||
30 | } |
||
31 | } |
||
32 | |||
33 | /** |
||
34 | * @param string $contentType |
||
35 | * @param string $content |
||
36 | * |
||
37 | * @return OperationParams|OperationParams[] |
||
38 | */ |
||
39 | private function parseRawRequest($contentType, $content, string $method = 'POST') |
||
40 | { |
||
41 | $_SERVER['CONTENT_TYPE'] = $contentType; |
||
42 | $_SERVER['REQUEST_METHOD'] = $method; |
||
43 | |||
44 | $helper = new Helper(); |
||
45 | |||
46 | return $helper->parseHttpRequest(static function () use ($content) { |
||
47 | return $content; |
||
48 | }); |
||
49 | } |
||
50 | |||
51 | /** |
||
52 | * @param string $contentType |
||
53 | * @param string $content |
||
54 | * |
||
55 | * @return OperationParams|OperationParams[] |
||
56 | */ |
||
57 | private function parsePsrRequest($contentType, $content, string $method = 'POST') |
||
79 | } |
||
80 | |||
81 | /** |
||
82 | * @param OperationParams $params |
||
83 | * @param string $query |
||
84 | * @param string $queryId |
||
85 | * @param mixed|null $variables |
||
86 | * @param string $operation |
||
87 | */ |
||
88 | private static function assertValidOperationParams( |
||
89 | $params, |
||
90 | $query, |
||
91 | $queryId = null, |
||
92 | $variables = null, |
||
93 | $operation = null, |
||
94 | $extensions = null, |
||
95 | $message = '' |
||
96 | ) { |
||
97 | self::assertInstanceOf(OperationParams::class, $params, $message); |
||
98 | |||
99 | self::assertSame($query, $params->query, $message); |
||
100 | self::assertSame($queryId, $params->queryId, $message); |
||
101 | self::assertSame($variables, $params->variables, $message); |
||
102 | self::assertSame($operation, $params->operation, $message); |
||
103 | self::assertSame($extensions, $params->extensions, $message); |
||
104 | } |
||
105 | |||
106 | public function testParsesUrlencodedRequest() : void |
||
107 | { |
||
108 | $query = '{my query}'; |
||
109 | $variables = ['test' => 1, 'test2' => 2]; |
||
110 | $operation = 'op'; |
||
111 | |||
112 | $post = [ |
||
113 | 'query' => $query, |
||
114 | 'variables' => $variables, |
||
115 | 'operationName' => $operation, |
||
116 | ]; |
||
117 | $parsed = [ |
||
118 | 'raw' => $this->parseRawFormUrlencodedRequest($post), |
||
119 | 'psr' => $this->parsePsrFormUrlEncodedRequest($post), |
||
120 | ]; |
||
121 | |||
122 | foreach ($parsed as $method => $parsedBody) { |
||
123 | self::assertValidOperationParams($parsedBody, $query, null, $variables, $operation, null, $method); |
||
124 | self::assertFalse($parsedBody->isReadOnly(), $method); |
||
125 | } |
||
126 | } |
||
127 | |||
128 | /** |
||
129 | * @param mixed[] $postValue |
||
130 | * |
||
131 | * @return OperationParams|OperationParams[] |
||
132 | */ |
||
133 | private function parseRawFormUrlencodedRequest($postValue) |
||
134 | { |
||
135 | $_SERVER['CONTENT_TYPE'] = 'application/x-www-form-urlencoded'; |
||
136 | $_SERVER['REQUEST_METHOD'] = 'POST'; |
||
137 | $_POST = $postValue; |
||
138 | |||
139 | $helper = new Helper(); |
||
140 | |||
141 | return $helper->parseHttpRequest(static function () { |
||
142 | throw new InvariantViolation("Shouldn't read from php://input for urlencoded request"); |
||
143 | }); |
||
144 | } |
||
145 | |||
146 | /** |
||
147 | * @param mixed[] $postValue |
||
148 | * |
||
149 | * @return OperationParams[]|OperationParams |
||
150 | */ |
||
151 | private function parsePsrFormUrlEncodedRequest($postValue) |
||
152 | { |
||
153 | $psrRequest = new PsrRequestStub(); |
||
154 | $psrRequest->headers['content-type'] = ['application/x-www-form-urlencoded']; |
||
155 | $psrRequest->method = 'POST'; |
||
156 | $psrRequest->parsedBody = $postValue; |
||
157 | |||
158 | $helper = new Helper(); |
||
159 | |||
160 | return $helper->parsePsrRequest($psrRequest); |
||
161 | } |
||
162 | |||
163 | public function testParsesGetRequest() : void |
||
164 | { |
||
165 | $query = '{my query}'; |
||
166 | $variables = ['test' => 1, 'test2' => 2]; |
||
167 | $operation = 'op'; |
||
168 | |||
169 | $get = [ |
||
170 | 'query' => $query, |
||
171 | 'variables' => $variables, |
||
172 | 'operationName' => $operation, |
||
173 | ]; |
||
174 | $parsed = [ |
||
175 | 'raw' => $this->parseRawGetRequest($get), |
||
176 | 'psr' => $this->parsePsrGetRequest($get), |
||
177 | ]; |
||
178 | |||
179 | foreach ($parsed as $method => $parsedBody) { |
||
180 | self::assertValidOperationParams($parsedBody, $query, null, $variables, $operation, null, $method); |
||
181 | self::assertTrue($parsedBody->isReadonly(), $method); |
||
182 | } |
||
183 | } |
||
184 | |||
185 | /** |
||
186 | * @param mixed[] $getValue |
||
187 | * |
||
188 | * @return OperationParams |
||
189 | */ |
||
190 | private function parseRawGetRequest($getValue) |
||
191 | { |
||
192 | $_SERVER['REQUEST_METHOD'] = 'GET'; |
||
193 | $_GET = $getValue; |
||
194 | |||
195 | $helper = new Helper(); |
||
196 | |||
197 | return $helper->parseHttpRequest(static function () { |
||
198 | throw new InvariantViolation("Shouldn't read from php://input for urlencoded request"); |
||
199 | }); |
||
200 | } |
||
201 | |||
202 | /** |
||
203 | * @param mixed[] $getValue |
||
204 | * |
||
205 | * @return OperationParams[]|OperationParams |
||
206 | */ |
||
207 | private function parsePsrGetRequest($getValue) |
||
208 | { |
||
209 | $psrRequest = new PsrRequestStub(); |
||
210 | $psrRequest->method = 'GET'; |
||
211 | $psrRequest->queryParams = $getValue; |
||
212 | |||
213 | $helper = new Helper(); |
||
214 | |||
215 | return $helper->parsePsrRequest($psrRequest); |
||
216 | } |
||
217 | |||
218 | public function testParsesMultipartFormdataRequest() : void |
||
219 | { |
||
220 | $query = '{my query}'; |
||
221 | $variables = ['test' => 1, 'test2' => 2]; |
||
222 | $operation = 'op'; |
||
223 | |||
224 | $post = [ |
||
225 | 'query' => $query, |
||
226 | 'variables' => $variables, |
||
227 | 'operationName' => $operation, |
||
228 | ]; |
||
229 | $parsed = [ |
||
230 | 'raw' => $this->parseRawMultipartFormDataRequest($post), |
||
231 | 'psr' => $this->parsePsrMultipartFormDataRequest($post), |
||
232 | ]; |
||
233 | |||
234 | foreach ($parsed as $method => $parsedBody) { |
||
235 | self::assertValidOperationParams($parsedBody, $query, null, $variables, $operation, null, $method); |
||
236 | self::assertFalse($parsedBody->isReadOnly(), $method); |
||
237 | } |
||
238 | } |
||
239 | |||
240 | /** |
||
241 | * @param mixed[] $postValue |
||
242 | * |
||
243 | * @return OperationParams|OperationParams[] |
||
244 | */ |
||
245 | private function parseRawMultipartFormDataRequest($postValue) |
||
246 | { |
||
247 | $_SERVER['CONTENT_TYPE'] = 'multipart/form-data; boundary=----FormBoundary'; |
||
248 | $_SERVER['REQUEST_METHOD'] = 'POST'; |
||
249 | $_POST = $postValue; |
||
250 | |||
251 | $helper = new Helper(); |
||
252 | |||
253 | return $helper->parseHttpRequest(static function () { |
||
254 | throw new InvariantViolation("Shouldn't read from php://input for multipart/form-data request"); |
||
255 | }); |
||
256 | } |
||
257 | |||
258 | /** |
||
259 | * @param mixed[] $postValue |
||
260 | * |
||
261 | * @return OperationParams|OperationParams[] |
||
262 | */ |
||
263 | private function parsePsrMultipartFormDataRequest($postValue) |
||
264 | { |
||
265 | $psrRequest = new PsrRequestStub(); |
||
266 | $psrRequest->headers['content-type'] = ['multipart/form-data; boundary=----FormBoundary']; |
||
267 | $psrRequest->method = 'POST'; |
||
268 | $psrRequest->parsedBody = $postValue; |
||
269 | |||
270 | $helper = new Helper(); |
||
271 | |||
272 | return $helper->parsePsrRequest($psrRequest); |
||
273 | } |
||
274 | |||
275 | public function testParsesJSONRequest() : void |
||
293 | } |
||
294 | } |
||
295 | |||
296 | public function testParsesParamsAsJSON() : void |
||
297 | { |
||
298 | $query = '{my query}'; |
||
299 | $variables = ['test1' => 1, 'test2' => 2]; |
||
300 | $extensions = ['test3' => 3, 'test4' => 4]; |
||
301 | $operation = 'op'; |
||
302 | |||
303 | $body = [ |
||
316 | } |
||
317 | } |
||
318 | |||
319 | public function testIgnoresInvalidVariablesJson() : void |
||
320 | { |
||
321 | $query = '{my query}'; |
||
322 | $variables = '"some invalid json'; |
||
323 | $operation = 'op'; |
||
324 | |||
325 | $body = [ |
||
326 | 'query' => $query, |
||
327 | 'variables' => $variables, |
||
328 | 'operationName' => $operation, |
||
329 | ]; |
||
330 | $parsed = [ |
||
331 | 'raw' => $this->parseRawRequest('application/json', json_encode($body)), |
||
332 | 'psr' => $this->parsePsrRequest('application/json', json_encode($body)), |
||
333 | ]; |
||
334 | foreach ($parsed as $method => $parsedBody) { |
||
335 | self::assertValidOperationParams($parsedBody, $query, null, $variables, $operation, null, $method); |
||
336 | self::assertFalse($parsedBody->isReadOnly(), $method); |
||
337 | } |
||
338 | } |
||
339 | |||
340 | public function testParsesApolloPersistedQueryJSONRequest() : void |
||
341 | { |
||
342 | $queryId = 'my-query-id'; |
||
343 | $extensions = ['persistedQuery' => ['sha256Hash' => $queryId]]; |
||
344 | $variables = ['test' => 1, 'test2' => 2]; |
||
345 | $operation = 'op'; |
||
346 | |||
347 | $body = [ |
||
348 | 'extensions' => $extensions, |
||
349 | 'variables' => $variables, |
||
350 | 'operationName' => $operation, |
||
351 | ]; |
||
352 | $parsed = [ |
||
353 | 'raw' => $this->parseRawRequest('application/json', json_encode($body)), |
||
354 | 'psr' => $this->parsePsrRequest('application/json', json_encode($body)), |
||
355 | ]; |
||
356 | foreach ($parsed as $method => $parsedBody) { |
||
357 | self::assertValidOperationParams($parsedBody, null, $queryId, $variables, $operation, $extensions, $method); |
||
358 | self::assertFalse($parsedBody->isReadOnly(), $method); |
||
359 | } |
||
360 | } |
||
361 | |||
362 | public function testParsesBatchJSONRequest() : void |
||
363 | { |
||
364 | $body = [ |
||
365 | [ |
||
366 | 'query' => '{my query}', |
||
367 | 'variables' => ['test' => 1, 'test2' => 2], |
||
368 | 'operationName' => 'op', |
||
369 | ], |
||
370 | [ |
||
371 | 'queryId' => 'my-query-id', |
||
372 | 'variables' => ['test' => 1, 'test2' => 2], |
||
373 | 'operationName' => 'op2', |
||
374 | ], |
||
375 | ]; |
||
376 | $parsed = [ |
||
377 | 'raw' => $this->parseRawRequest('application/json', json_encode($body)), |
||
378 | 'psr' => $this->parsePsrRequest('application/json', json_encode($body)), |
||
379 | ]; |
||
380 | foreach ($parsed as $method => $parsedBody) { |
||
381 | self::assertInternalType('array', $parsedBody, $method); |
||
|
|||
382 | self::assertCount(2, $parsedBody, $method); |
||
383 | self::assertValidOperationParams( |
||
384 | $parsedBody[0], |
||
385 | $body[0]['query'], |
||
386 | null, |
||
387 | $body[0]['variables'], |
||
388 | $body[0]['operationName'], |
||
389 | null, |
||
390 | $method |
||
391 | ); |
||
392 | self::assertValidOperationParams( |
||
393 | $parsedBody[1], |
||
394 | null, |
||
395 | $body[1]['queryId'], |
||
396 | $body[1]['variables'], |
||
397 | $body[1]['operationName'], |
||
398 | null, |
||
399 | $method |
||
400 | ); |
||
401 | } |
||
402 | } |
||
403 | |||
404 | public function testFailsParsingInvalidRawJsonRequestRaw() : void |
||
405 | { |
||
406 | $body = 'not really{} a json'; |
||
407 | |||
408 | $this->expectException(RequestError::class); |
||
409 | $this->expectExceptionMessage('Could not parse JSON: Syntax error'); |
||
410 | $this->parseRawRequest('application/json', $body); |
||
411 | } |
||
412 | |||
413 | public function testFailsParsingInvalidRawJsonRequestPsr() : void |
||
414 | { |
||
415 | $body = 'not really{} a json'; |
||
416 | |||
417 | $this->expectException(InvariantViolation::class); |
||
418 | $this->expectExceptionMessage('PSR-7 request is expected to provide parsed body for "application/json" requests but got null'); |
||
419 | $this->parsePsrRequest('application/json', $body); |
||
420 | } |
||
421 | |||
422 | public function testFailsParsingNonPreParsedPsrRequest() : void |
||
432 | ); |
||
433 | } |
||
434 | } |
||
435 | |||
436 | /** |
||
437 | * There is no equivalent for psr request, because it should throw |
||
438 | */ |
||
439 | public function testFailsParsingNonArrayOrObjectJsonRequestRaw() : void |
||
440 | { |
||
441 | $body = '"str"'; |
||
442 | |||
443 | $this->expectException(RequestError::class); |
||
444 | $this->expectExceptionMessage('GraphQL Server expects JSON object or array, but got "str"'); |
||
445 | $this->parseRawRequest('application/json', $body); |
||
446 | } |
||
447 | |||
448 | public function testFailsParsingNonArrayOrObjectJsonRequestPsr() : void |
||
449 | { |
||
450 | $body = '"str"'; |
||
451 | |||
452 | $this->expectException(RequestError::class); |
||
453 | $this->expectExceptionMessage('GraphQL Server expects JSON object or array, but got "str"'); |
||
454 | $this->parsePsrRequest('application/json', $body); |
||
455 | } |
||
456 | |||
457 | public function testFailsParsingInvalidContentTypeRaw() : void |
||
465 | } |
||
466 | |||
467 | public function testFailsParsingInvalidContentTypePsr() : void |
||
468 | { |
||
469 | $contentType = 'not-supported-content-type'; |
||
470 | $body = 'test'; |
||
471 | |||
472 | $this->expectException(RequestError::class); |
||
473 | $this->expectExceptionMessage('Unexpected content type: "not-supported-content-type"'); |
||
474 | $this->parseRawRequest($contentType, $body); |
||
475 | } |
||
476 | |||
477 | public function testFailsWithMissingContentTypeRaw() : void |
||
478 | { |
||
479 | $this->expectException(RequestError::class); |
||
480 | $this->expectExceptionMessage('Missing "Content-Type" header'); |
||
481 | $this->parseRawRequest(null, 'test'); |
||
482 | } |
||
483 | |||
484 | public function testFailsWithMissingContentTypePsr() : void |
||
489 | } |
||
490 | |||
491 | public function testFailsOnMethodsOtherThanPostOrGetRaw() : void |
||
496 | } |
||
497 | |||
498 | public function testFailsOnMethodsOtherThanPostOrGetPsr() : void |
||
503 | } |
||
504 | } |
||
505 |
This function has been deprecated. The supplier of the function has supplied an explanatory message.
The explanatory message should give you some clue as to whether and when the function will be removed and what other function to use instead.