Skip to content

Commit e69a504

Browse files
authored
Merge pull request #192 from jimcottrell/multipart-encoding-required
Allow specifying encoding for optional parts of multipart data
2 parents 2f578e3 + 7b6f26b commit e69a504

File tree

3 files changed

+70
-23
lines changed

3 files changed

+70
-23
lines changed

src/PSR7/Validators/BodyValidator/MultipartValidator.php

Lines changed: 1 addition & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,6 @@
2626
use Psr\Http\Message\UploadedFileInterface;
2727
use Riverline\MultiPartParser\Converters\PSR7;
2828
use Riverline\MultiPartParser\StreamedPart;
29-
use RuntimeException;
3029

3130
use function array_diff_assoc;
3231
use function array_map;
@@ -39,7 +38,6 @@
3938
use function json_last_error;
4039
use function json_last_error_msg;
4140
use function preg_match;
42-
use function sprintf;
4341
use function str_replace;
4442
use function strpos;
4543
use function strtolower;
@@ -114,12 +112,6 @@ private function validatePlainBodyMultipart(
114112

115113
foreach ($encodings as $partName => $encoding) {
116114
$parts = $document->getPartsByName($partName); // multiple parts share a name?
117-
if (! $parts) {
118-
throw new RuntimeException(sprintf(
119-
'Specified body part %s is not found',
120-
$partName
121-
));
122-
}
123115
124116
foreach ($parts as $part) {
125117
// 2.1 parts encoding
@@ -317,7 +309,7 @@ private function validateServerRequestMultipart(
317309

318310
foreach ($encodings as $partName => $encoding) {
319311
if (! isset($body[$partName])) {
320-
throw new RuntimeException(sprintf('Specified body part %s is not found', $partName));
312+
continue;
321313
}
322314

323315
$part = $body[$partName];

tests/PSR7/Validators/BodyValidator/MultipartValidatorTest.php

Lines changed: 63 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
use League\OpenAPIValidation\PSR7\Exception\Validation\InvalidHeaders;
1212
use League\OpenAPIValidation\PSR7\ValidatorBuilder;
1313
use PHPUnit\Framework\TestCase;
14+
use Psr\Http\Message\UploadedFileInterface;
1415

1516
use function filesize;
1617
use function GuzzleHttp\Psr7\parse_request;
@@ -259,6 +260,23 @@ public function dataProviderMultipartRed(): array
259260
[file content goes there]
260261
------WebKitFormBoundaryWfPNVh4wuWBlyEyQ--
261262
HTTP
263+
,
264+
InvalidBody::class,
265+
],
266+
// missing required part
267+
[
268+
<<<HTTP
269+
POST /multipart/encoding HTTP/1.1
270+
Content-Length: 428
271+
Content-Type: multipart/form-data; boundary=----WebKitFormBoundaryOmz20xyMCkE27rN7
272+
273+
------WebKitFormBoundaryOmz20xyMCkE27rN7
274+
Content-Disposition: form-data; name="description"
275+
Content-Type: text/plain
276+
277+
123
278+
------WebKitFormBoundaryOmz20xyMCkE27rN7--
279+
HTTP
262280
,
263281
InvalidBody::class,
264282
],
@@ -404,25 +422,56 @@ public function testValidateMultipartRed(string $message, string $expectedExcept
404422
$validator->validate($serverRequest);
405423
}
406424

407-
public function testValidateMultipartServerRequestGreen(): void
425+
/**
426+
* @return mixed[][]
427+
*/
428+
public function dataProviderMultipartServerRequestGreen(): array
408429
{
409-
$specFile = __DIR__ . '/../../../stubs/multipart.yaml';
410-
411430
$imagePath = __DIR__ . '/../../../stubs/image.jpg';
412431
$imageSize = filesize($imagePath);
413432

414-
$serverRequest = (new ServerRequest('post', new Uri('/multipart')))
415-
->withHeader('Content-Type', 'multipart/form-data')
416-
->withParsedBody([
417-
'id' => 'bc8e1430-a963-11e9-a2a3-2a2ae2dbcce4',
418-
'address' => [
419-
'street' => 'Some street',
420-
'city' => 'some city',
433+
return [
434+
// Normal multipart message
435+
[
436+
'post',
437+
'/multipart',
438+
[
439+
'id' => 'bc8e1430-a963-11e9-a2a3-2a2ae2dbcce4',
440+
'address' => [
441+
'street' => 'Some street',
442+
'city' => 'some city',
443+
],
444+
],
445+
[
446+
'profileImage' => new UploadedFile($imagePath, $imageSize, 0),
421447
],
422-
])
423-
->withUploadedFiles([
424-
'profileImage' => new UploadedFile($imagePath, $imageSize, 0),
425-
]);
448+
],
449+
// Missing optional field with defined encoding
450+
[
451+
'post',
452+
'/multipart/encoding',
453+
[],
454+
[
455+
'image' => new UploadedFile($imagePath, $imageSize, 0),
456+
],
457+
],
458+
];
459+
}
460+
461+
/**
462+
* @param string[] $body
463+
* @param array<string, UploadedFileInterface> $files
464+
*
465+
* @dataProvider dataProviderMultipartServerRequestGreen
466+
*/
467+
public function testValidateMultipartServerRequestGreen(string $method, string $uri, array $body = [], array $files = []): void
468+
{
469+
$specFile = __DIR__ . '/../../../stubs/multipart.yaml';
470+
471+
$serverRequest = (new ServerRequest($method, new Uri($uri)))
472+
->withHeader('Content-Type', 'multipart/form-data')
473+
->withParsedBody($body)
474+
->withUploadedFiles($files);
426475

427476
$validator = (new ValidatorBuilder())->fromYamlFile($specFile)->getServerRequestValidator();
428477
$validator->validate($serverRequest);

tests/stubs/multipart.yaml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,13 +66,19 @@ paths:
6666
multipart/form-data:
6767
schema:
6868
type: object
69+
required:
70+
- image
6971
properties:
7072
image:
7173
type: string
7274
format: binary
75+
description:
76+
type: string
7377
encoding:
7478
image:
7579
contentType: specific/type
80+
description:
81+
contentType: text/plain
7682
responses:
7783
204:
7884
description: good post

0 commit comments

Comments
 (0)