Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 13 additions & 2 deletions lib/JSON/Validator/Schema/OpenAPIv3.pm
Original file line number Diff line number Diff line change
Expand Up @@ -407,8 +407,19 @@ sub _validate_type_object_response {
}

sub _validate_type_string {
my $self = shift;
return $_[1]->{schema}{nullable} && !defined $_[0] ? () : $self->SUPER::_validate_type_string(@_);
my ($self, $val, $state) = @_;

return () if $state->{schema}{nullable} && !defined $val;

if (ref $val eq 'Mojo::Upload') {
return () if
defined $state->{schema}{format} &&
$state->{schema}{format} eq 'binary';

return E $state->{path}, [string => type => data_type $val];
}

return $self->SUPER::_validate_type_string($val, $state);
}

1;
Expand Down
1 change: 1 addition & 0 deletions lib/JSON/Validator/Util.pm
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@ sub data_type {
my $ref = ref $_[0];
my $blessed = blessed $_[0];
return 'object' if $ref eq 'HASH';
return 'file' if $ref eq 'Mojo::Upload';
return lc $ref if $ref and !$blessed;
return 'null' if !defined $_[0];
return 'boolean' if $blessed and ("$_[0]" eq "1" or !"$_[0]");
Expand Down
133 changes: 133 additions & 0 deletions t/openapiv3-file.t
Original file line number Diff line number Diff line change
@@ -0,0 +1,133 @@
use Mojo::Base -strict;
use JSON::Validator::Schema::OpenAPIv3;
use Mojo::File;
use Mojo::Upload;
use Test::Deep;
use Test::More;

my $cwd = Mojo::File->new(__FILE__)->dirname;
my $schema = JSON::Validator::Schema::OpenAPIv3->new;
my ($body, $p, @errors);

subtest 'basic' => sub {
is $schema->specification, 'https://spec.openapis.org/oas/3.0/schema/2019-04-02', 'specification';
is_deeply $schema->coerce, {booleans => 1, numbers => 1, strings => 1}, 'default coercion';

$schema = JSON::Validator->new->schema('data://main/spec.yaml')->schema;
isa_ok $schema, 'JSON::Validator::Schema::OpenAPIv3';

@errors = @{JSON::Validator->new->schema({openapi => '3.0.0', paths => {}})->schema->errors};
is "@errors", '/info: Missing property.', 'invalid schema';

is_deeply(
$schema->routes->to_array,
[
{method => 'post', operation_id => 'submit', path => '/submit'},
{method => 'post', operation_id => 'uploadFile', path => '/upload'},
],
'routes'
);
};

subtest 'validate_request - file string' => sub {
my $file = 'file contents\nmore content';

# Check required works
$body = {exists => 1,value => {image => $file } };
@errors = $schema->validate_request([post => '/upload'], {body => \&body});
is "@errors", "/body/file: Missing property.", 'detects missing file';

$body = {exists => 1,value => {file => $file } };
@errors = $schema->validate_request([post => '/upload'], {body => \&body});
is "@errors", "", 'valid file';
is_deeply $body, {
content_type => 'multipart/form-data',
exists => 1,
in => 'body',
name => 'body',
valid => 1,
value => {file => $file},
}, 'valid file';
};

subtest 'validate_request - file placeholder' => sub {
my $file = Mojo::Upload->new;

# Check required works
$body = {exists => 1,value => {image => $file } };
@errors = $schema->validate_request([post => '/upload'], {body => \&body});
is "@errors", "/body/file: Missing property.", 'detects missing file';

$body = {exists => 1,value => {file => $file } };
@errors = $schema->validate_request([post => '/upload'], {body => \&body});
is "@errors", "", 'valid file';
is_deeply $body, {
content_type => 'multipart/form-data',
exists => 1,
in => 'body',
name => 'body',
valid => 1,
value => {file => $file},
}, 'valid file';
};

subtest 'string in non-file string' => sub {

$body = {exists => 1,value => {name => 'some string' } };
@errors = $schema->validate_request([post => '/submit'], {body => \&body});
is "@errors", "", 'valid file';
is_deeply $body, {
content_type => 'multipart/form-data',
exists => 1,
value => {name => 'some string'},
in => 'body',
name => 'body',
valid => 1,
}, 'valid file';
};

subtest 'file placehodler in non-file string' => sub {
my $file = Mojo::Upload->new;
$body = {exists => 1,value => {name => $file } };
@errors = $schema->validate_request([post => '/submit'], {body => \&body});
is "@errors", "/body/name: Expected string - got file.", 'valid file';
};

done_testing;

sub body {$body}

__DATA__
@@ spec.yaml
openapi: 3.0.0
info:
title: Test body
version: 0.8
paths:
/submit:
post:
operationId: submit
requestBody:
content:
multipart/form-data:
schema:
type: object
required:
- name
properties:
name:
type: string
/upload:
post:
operationId: uploadFile
requestBody:
content:
multipart/form-data:
schema:
type: object
required:
- file
properties:
file:
type: string
format: binary
Loading