mirror of
https://github.com/ditkrg/rswag.git
synced 2026-01-22 22:06:43 +00:00
Validate response headers based on specified header
Add validate_headers step in response validator. Using JSON::Validator with validate header value with swagger header object.
This commit is contained in:
parent
10dd37896f
commit
5cf376891a
@ -13,6 +13,7 @@ module Rswag
|
|||||||
|
|
||||||
def validate!(response)
|
def validate!(response)
|
||||||
validate_code!(response.code)
|
validate_code!(response.code)
|
||||||
|
validate_headers!(response.headers)
|
||||||
validate_body!(response.body)
|
validate_body!(response.body)
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -24,6 +25,20 @@ module Rswag
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def validate_headers!(headers)
|
||||||
|
header_schema = @api_metadata[:response][:headers]
|
||||||
|
return if header_schema.nil?
|
||||||
|
header_schema.each do |header_name, schema|
|
||||||
|
validate_header!(schema, header_name, headers[header_name.to_s])
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def validate_header!(schema, header_name, header_value)
|
||||||
|
JSON::Validator.validate!(schema.merge(@global_metadata), header_value.to_json)
|
||||||
|
rescue JSON::Schema::ValidationError => ex
|
||||||
|
raise UnexpectedResponse, "Expected response headers #{header_name} to match schema: #{ex.message}"
|
||||||
|
end
|
||||||
|
|
||||||
def validate_body!(body)
|
def validate_body!(body)
|
||||||
response_schema = @api_metadata[:response][:schema]
|
response_schema = @api_metadata[:response][:schema]
|
||||||
return if response_schema.nil?
|
return if response_schema.nil?
|
||||||
@ -34,7 +49,7 @@ module Rswag
|
|||||||
.merge(@global_metadata.slice(:definitions))
|
.merge(@global_metadata.slice(:definitions))
|
||||||
JSON::Validator.validate!(validation_schema, body)
|
JSON::Validator.validate!(validation_schema, body)
|
||||||
rescue JSON::Schema::ValidationError => ex
|
rescue JSON::Schema::ValidationError => ex
|
||||||
raise UnexpectedResponse, "Expected response body to match schema: #{ex.message}"
|
raise UnexpectedResponse, "Expected response body to match schema: #{ex.message}"
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@ -66,6 +66,43 @@ module Rswag
|
|||||||
it { expect { call }.to raise_error UnexpectedResponse }
|
it { expect { call }.to raise_error UnexpectedResponse }
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
context "'headers' provided" do
|
||||||
|
before do
|
||||||
|
api_metadata[:response][:headers] = {
|
||||||
|
'X-Rate-Limit-Limit' => {
|
||||||
|
description: 'The number of allowed requests in the current period',
|
||||||
|
type: 'integer'
|
||||||
|
},
|
||||||
|
'X-Rate-Limit-Remaining' => {
|
||||||
|
description: 'The number of remaining requests in the current period',
|
||||||
|
type: 'integer'
|
||||||
|
},
|
||||||
|
'X-Rate-Limit-Reset' => {
|
||||||
|
description: 'The number of seconds left in the current period',
|
||||||
|
type: 'integer'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
end
|
||||||
|
|
||||||
|
context 'response code & body matches' do
|
||||||
|
let(:response) { OpenStruct.new(code: 200, body: '{}', headers: {
|
||||||
|
'X-Rate-Limit-Limit' => 1,
|
||||||
|
'X-Rate-Limit-Remaining' => 1,
|
||||||
|
'X-Rate-Limit-Reset' => 1
|
||||||
|
}) }
|
||||||
|
it { expect { call }.to_not raise_error }
|
||||||
|
end
|
||||||
|
|
||||||
|
context 'response code matches & body does not' do
|
||||||
|
let(:response) { OpenStruct.new(code: 200, body: '{}', headers: {
|
||||||
|
'X-Rate-Limit-Limit' => 'invalid',
|
||||||
|
'X-Rate-Limit-Remaining' => 'invalid',
|
||||||
|
'X-Rate-Limit-Reset' => 'invalid'
|
||||||
|
}) }
|
||||||
|
it { expect { call }.to raise_error UnexpectedResponse }
|
||||||
|
end
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@ -17,6 +17,10 @@ class BlogsController < ApplicationController
|
|||||||
# GET /blogs/1
|
# GET /blogs/1
|
||||||
def show
|
def show
|
||||||
@blog = Blog.find_by_id(params[:id])
|
@blog = Blog.find_by_id(params[:id])
|
||||||
|
|
||||||
|
fresh_when(@blog)
|
||||||
|
return unless stale?(@blog)
|
||||||
|
|
||||||
respond_with @blog, status: :not_found and return unless @blog
|
respond_with @blog, status: :not_found and return unless @blog
|
||||||
respond_with @blog
|
respond_with @blog
|
||||||
end
|
end
|
||||||
|
|||||||
@ -50,6 +50,10 @@ describe 'Blogs API', type: :request, swagger_doc: 'v1/swagger.json' do
|
|||||||
produces 'application/json'
|
produces 'application/json'
|
||||||
|
|
||||||
response '200', 'blog found' do
|
response '200', 'blog found' do
|
||||||
|
header 'ETag', type: :string
|
||||||
|
header 'Last-Modified', type: :string
|
||||||
|
header 'Cache-Control', type: :string
|
||||||
|
|
||||||
schema '$ref' => '#/definitions/blog'
|
schema '$ref' => '#/definitions/blog'
|
||||||
|
|
||||||
response_examples 'application/json' => {
|
response_examples 'application/json' => {
|
||||||
|
|||||||
@ -89,8 +89,26 @@
|
|||||||
"responses": {
|
"responses": {
|
||||||
"200": {
|
"200": {
|
||||||
"description": "blog found",
|
"description": "blog found",
|
||||||
|
"headers": {
|
||||||
|
"ETag": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"Last-Modified": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"Cache-Control": {
|
||||||
|
"type": "string"
|
||||||
|
}
|
||||||
|
},
|
||||||
"schema": {
|
"schema": {
|
||||||
"$ref": "#/definitions/blog"
|
"$ref": "#/definitions/blog"
|
||||||
|
},
|
||||||
|
"examples": {
|
||||||
|
"application/json": {
|
||||||
|
"id": 1,
|
||||||
|
"title": "Hello world!",
|
||||||
|
"content": "Hello world and hello universe. Thank you all very much!!!"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"404": {
|
"404": {
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user