diff --git a/Changes b/Changes index 5ec658bb..7ae0f6af 100644 --- a/Changes +++ b/Changes @@ -3,6 +3,7 @@ Revision history for perl distribution JSON-Validator 4.17 Not Released - Add add_default_response() to OpenAPIv2 and OpenAPIv3 - Add base_url() to OpenAPIv2 and OpenAPIv3 + - Fix validating "nullable" for "array" and "object" 4.16 2021-03-24T08:57:46+0900 - Fix handling OpenAPIv2 "responses" $ref when bundling diff --git a/lib/JSON/Validator/Schema/OpenAPIv3.pm b/lib/JSON/Validator/Schema/OpenAPIv3.pm index ccb09ed9..9beed862 100644 --- a/lib/JSON/Validator/Schema/OpenAPIv3.pm +++ b/lib/JSON/Validator/Schema/OpenAPIv3.pm @@ -286,6 +286,11 @@ sub _validate_body { return; } +sub _validate_type_array { + my $self = shift; + return $_[2]->{nullable} && !defined $_[0] ? () : $self->SUPER::_validate_type_array(@_); +} + sub _validate_type_boolean { my $self = shift; return $_[2]->{nullable} && !defined $_[0] ? () : $self->SUPER::_validate_type_boolean(@_); @@ -303,6 +308,7 @@ sub _validate_type_number { sub _validate_type_object { my ($self, $data, $path, $schema) = @_; + return if $schema->{nullable} && !defined $data; return E $path, [object => type => data_type $data] if ref $data ne 'HASH'; return shift->SUPER::_validate_type_object(@_) unless $self->{validate_request} or $self->{validate_response}; diff --git a/t/openapiv3-nullable.t b/t/openapiv3-nullable.t index f064c972..39532bd7 100644 --- a/t/openapiv3-nullable.t +++ b/t/openapiv3-nullable.t @@ -15,6 +15,18 @@ for my $path (qw(/nullable-data /nullable-ref)) { is "@errors", "", "$path - name is undef"; } +for my $extra ({}, undef) { + $body = {exists => 1, value => {extra => $extra, id => 42, name => undef}}; + @errors = $schema->validate_response([get => '/nullable-data'], {body => \&body}); + is "@errors", "", sprintf 'extra %s', $extra ? 'object' : 'null'; +} + +for my $stuff ([], undef) { + $body = {exists => 1, value => {stuff => $stuff, id => 42, name => undef}}; + @errors = $schema->validate_response([get => '/nullable-data'], {body => \&body}); + is "@errors", "", sprintf 'stuff %s', $stuff ? 'array' : 'null'; +} + $schema = JSON::Validator->new->schema('data://main/issue-241.json')->schema; $body = {exists => 1, value => {name => undef}}; @errors = $schema->validate_response([get => '/test'], {body => \&body}); @@ -55,8 +67,10 @@ __DATA__ "WithNullable": { "required": [ "id", "name" ], "properties": { + "extra": { "type": "object", "nullable": true }, "id": { "type": "integer", "format": "int64" }, - "name": { "type": "string", "nullable": true } + "name": { "type": "string", "nullable": true }, + "stuff": { "type": "array", "nullable": true } } }, "WithNullableRef": {