Skip to content

Commit

Permalink
Merge pull request #192 from jimcottrell/multipart-encoding-required
Browse files Browse the repository at this point in the history
Allow specifying encoding for optional parts of multipart data
  • Loading branch information
scaytrase authored Mar 23, 2023
2 parents 2f578e3 + 7b6f26b commit e69a504
Show file tree
Hide file tree
Showing 3 changed files with 70 additions and 23 deletions.
10 changes: 1 addition & 9 deletions src/PSR7/Validators/BodyValidator/MultipartValidator.php
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,6 @@
use Psr\Http\Message\UploadedFileInterface;
use Riverline\MultiPartParser\Converters\PSR7;
use Riverline\MultiPartParser\StreamedPart;
use RuntimeException;

use function array_diff_assoc;
use function array_map;
Expand All @@ -39,7 +38,6 @@
use function json_last_error;
use function json_last_error_msg;
use function preg_match;
use function sprintf;
use function str_replace;
use function strpos;
use function strtolower;
Expand Down Expand Up @@ -114,12 +112,6 @@ private function validatePlainBodyMultipart(

foreach ($encodings as $partName => $encoding) {
$parts = $document->getPartsByName($partName); // multiple parts share a name?
if (! $parts) {
throw new RuntimeException(sprintf(
'Specified body part %s is not found',
$partName
));
}
foreach ($parts as $part) {
// 2.1 parts encoding
Expand Down Expand Up @@ -317,7 +309,7 @@ private function validateServerRequestMultipart(

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

$part = $body[$partName];
Expand Down
77 changes: 63 additions & 14 deletions tests/PSR7/Validators/BodyValidator/MultipartValidatorTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
use League\OpenAPIValidation\PSR7\Exception\Validation\InvalidHeaders;
use League\OpenAPIValidation\PSR7\ValidatorBuilder;
use PHPUnit\Framework\TestCase;
use Psr\Http\Message\UploadedFileInterface;

use function filesize;
use function GuzzleHttp\Psr7\parse_request;
Expand Down Expand Up @@ -259,6 +260,23 @@ public function dataProviderMultipartRed(): array
[file content goes there]
------WebKitFormBoundaryWfPNVh4wuWBlyEyQ--
HTTP
,
InvalidBody::class,
],
// missing required part
[
<<<HTTP
POST /multipart/encoding HTTP/1.1
Content-Length: 428
Content-Type: multipart/form-data; boundary=----WebKitFormBoundaryOmz20xyMCkE27rN7
------WebKitFormBoundaryOmz20xyMCkE27rN7
Content-Disposition: form-data; name="description"
Content-Type: text/plain
123
------WebKitFormBoundaryOmz20xyMCkE27rN7--
HTTP
,
InvalidBody::class,
],
Expand Down Expand Up @@ -404,25 +422,56 @@ public function testValidateMultipartRed(string $message, string $expectedExcept
$validator->validate($serverRequest);
}

public function testValidateMultipartServerRequestGreen(): void
/**
* @return mixed[][]
*/
public function dataProviderMultipartServerRequestGreen(): array
{
$specFile = __DIR__ . '/../../../stubs/multipart.yaml';

$imagePath = __DIR__ . '/../../../stubs/image.jpg';
$imageSize = filesize($imagePath);

$serverRequest = (new ServerRequest('post', new Uri('/multipart')))
->withHeader('Content-Type', 'multipart/form-data')
->withParsedBody([
'id' => 'bc8e1430-a963-11e9-a2a3-2a2ae2dbcce4',
'address' => [
'street' => 'Some street',
'city' => 'some city',
return [
// Normal multipart message
[
'post',
'/multipart',
[
'id' => 'bc8e1430-a963-11e9-a2a3-2a2ae2dbcce4',
'address' => [
'street' => 'Some street',
'city' => 'some city',
],
],
[
'profileImage' => new UploadedFile($imagePath, $imageSize, 0),
],
])
->withUploadedFiles([
'profileImage' => new UploadedFile($imagePath, $imageSize, 0),
]);
],
// Missing optional field with defined encoding
[
'post',
'/multipart/encoding',
[],
[
'image' => new UploadedFile($imagePath, $imageSize, 0),
],
],
];
}

/**
* @param string[] $body
* @param array<string, UploadedFileInterface> $files
*
* @dataProvider dataProviderMultipartServerRequestGreen
*/
public function testValidateMultipartServerRequestGreen(string $method, string $uri, array $body = [], array $files = []): void
{
$specFile = __DIR__ . '/../../../stubs/multipart.yaml';

$serverRequest = (new ServerRequest($method, new Uri($uri)))
->withHeader('Content-Type', 'multipart/form-data')
->withParsedBody($body)
->withUploadedFiles($files);

$validator = (new ValidatorBuilder())->fromYamlFile($specFile)->getServerRequestValidator();
$validator->validate($serverRequest);
Expand Down
6 changes: 6 additions & 0 deletions tests/stubs/multipart.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -66,13 +66,19 @@ paths:
multipart/form-data:
schema:
type: object
required:
- image
properties:
image:
type: string
format: binary
description:
type: string
encoding:
image:
contentType: specific/type
description:
contentType: text/plain
responses:
204:
description: good post
Expand Down

0 comments on commit e69a504

Please sign in to comment.