diff --git a/lib/JSON/Validator/Schema/OpenAPIv3.pm b/lib/JSON/Validator/Schema/OpenAPIv3.pm index e92a0d99..190cfaad 100644 --- a/lib/JSON/Validator/Schema/OpenAPIv3.pm +++ b/lib/JSON/Validator/Schema/OpenAPIv3.pm @@ -32,8 +32,9 @@ sub add_default_response { for my $route ($self->routes->each) { my $op = $self->get([paths => @$route{qw(path method)}]); for my $status (@{$params->{status}}) { - $op->{responses}{$status}{description} //= $params->{description}; + next if $self->get(['paths', @$route{qw(path method)}, 'responses', $status]); $op->{responses}{$status}{content}{'application/json'} //= {schema => $ref}; + $op->{responses}{$status}{description} //= $params->{description}; } } diff --git a/t/openapiv3-basic.t b/t/openapiv3-basic.t index cdf956b8..4bd2d4a6 100644 --- a/t/openapiv3-basic.t +++ b/t/openapiv3-basic.t @@ -30,15 +30,15 @@ subtest 'basic' => sub { }; subtest base_url => sub { - is $schema->base_url, 'http://petstore.swagger.io/v1', 'get'; - is $schema->base_url('https://api.example.com:8080/api'), $schema, 'set url'; - is $schema->get('/servers/0/url'), 'https://api.example.com:8080/api', 'servers changed'; + is $schema->base_url, 'http://petstore.swagger.io/v1', 'get'; + is $schema->base_url('https://api.example.com:8080/api'), $schema, 'set url'; + is $schema->get('/servers/0/url'), 'https://api.example.com:8080/api', 'servers changed'; - is $schema->base_url(Mojo::URL->new('//api2.example.com')), $schema, 'set without scheme'; - is $schema->get('/servers/0/url'), 'https://api2.example.com', 'servers changed'; + is $schema->base_url(Mojo::URL->new('//api2.example.com')), $schema, 'set without scheme'; + is $schema->get('/servers/0/url'), 'https://api2.example.com', 'servers changed'; - is $schema->base_url(Mojo::URL->new('/v1')), $schema, 'set path'; - is $schema->base_url->to_string, 'https://api2.example.com/v1', 'get'; + is $schema->base_url(Mojo::URL->new('/v1')), $schema, 'set path'; + is $schema->base_url->to_string, 'https://api2.example.com/v1', 'get'; }; subtest 'parameters_for_request' => sub { @@ -143,8 +143,8 @@ subtest 'validate_response - content_type' => sub { }; subtest add_default_response => sub { - $schema = JSON::Validator->new->schema($cwd->child(qw(spec v3-petstore.json)))->schema; - ok !$schema->get('/components/schemas/DefaultResponse'), 'default response missing'; + my $schema = JSON::Validator->new->schema($cwd->child(qw(spec v3-petstore.json)))->schema; + ok !$schema->get('/components/schemas/DefaultResponse'), 'default response missing'; ok !$schema->get([paths => '/petss', 'get', 'responses', '400']), 'default response missing for 400'; $schema->add_default_response; ok $schema->get('/components/schemas/DefaultResponse'), 'default response added'; @@ -157,10 +157,20 @@ subtest add_default_response => sub { is_deeply $schema->errors, [], 'errors'; }; +subtest 'add_default_response do not overwrite $ref' => sub { + my $schema = JSON::Validator->new->schema($cwd->child(qw(spec v3-default-response-extra.yaml)))->schema; + $schema->add_default_response; + is $schema->get([qw(paths /item/{id} get summary)]), 'get a single item', 'summary'; + is $schema->get([qw(paths /item/{id} get responses 200 content application/json schema type)]), 'object', + 'responses 200'; + is $schema->get([qw(paths /item/{id} get responses 404 description)]), 'Custom 404', 'responses 404'; + is $schema->get([qw(paths /item/{id} get responses 500 description)]), 'Custom 500', 'responses 500'; +}; + subtest 'v3.1.x' => sub { my $schema = JSON::Validator->new->schema({openapi => '3.1.0', paths => {}})->schema; - is $schema->specification, 'https://spec.openapis.org/oas/3.1/schema/2021-05-20', 'specification'; - is join(', ', @{$schema->errors}), '/info: Missing property.', 'errors'; + is $schema->specification, 'https://spec.openapis.org/oas/3.1/schema/2021-05-20', 'specification'; + is join(', ', @{$schema->errors}), '/info: Missing property.', 'errors'; }; subtest 'coerce defaults' => sub { diff --git a/t/spec/v3-default-response-extra.yaml b/t/spec/v3-default-response-extra.yaml new file mode 100644 index 00000000..c74d586c --- /dev/null +++ b/t/spec/v3-default-response-extra.yaml @@ -0,0 +1,50 @@ +openapi: 3.0.0 +info: + title: v3-default-response-extra + version: 0.0.1 +components: + schemas: + base: + type: object + required: [status, reason] + properties: + status: + type: integer + reason: + type: string + not_found: + type: object + allOf: + - $ref: '#/components/schemas/base' + exception: + type: object + allOf: + - $ref: '#/components/schemas/base' + responses: + '404': + description: Custom 404 + content: + application/json: + schema: + $ref: '#/components/schemas/not_found' +paths: + /item/{id}: + get: + summary: get a single item + description: get a single item from the database + x-mojo-name: item + responses: + '200': + description: OK + content: + application/json: + schema: + $ref: '#/components/schemas/base' + '404': + $ref: '#/components/responses/404' + '500': + description: Custom 500 + content: + application/json: + schema: + $ref: '#/components/schemas/exception'