Skip to content

Commit

Permalink
strict response validation
Browse files Browse the repository at this point in the history
  • Loading branch information
ota42y committed May 16, 2021
1 parent f009322 commit a5b5fef
Show file tree
Hide file tree
Showing 5 changed files with 52 additions and 2 deletions.
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -160,6 +160,7 @@ Option values and defaults:
|validate_success_only| true | false | Also validate non-2xx responses only. |
|ignore_error| false | false | Validate and ignore result even if validation is error. So always return original data. |
|parse_response_by_content_type| false | false | Parse response body to JSON only if Content-Type header is 'application/json'. When false, this always optimistically parses as JSON without checking for Content-Type header. |
|strict| false | false | Puts the middleware into strict mode, meaning that response code and content type does not defined in the schema will be responded to with a 500 instead of application's status code. |

No boolean option values:

Expand Down
4 changes: 3 additions & 1 deletion lib/committee/middleware/response_validation.rb
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ class ResponseValidation < Base

def initialize(app, options = {})
super
# TODO: show error message for old version
@strict = options[:strict]
@validate_success_only = @schema.validator_option.validate_success_only
end

Expand All @@ -15,7 +17,7 @@ def handle(request)

begin
v = build_schema_validator(request)
v.response_validate(status, headers, response) if v.link_exist? && self.class.validate?(status, validate_success_only)
v.response_validate(status, headers, response, @strict) if v.link_exist? && self.class.validate?(status, validate_success_only)

rescue Committee::InvalidResponse
handle_exception($!, request.env)
Expand Down
1 change: 1 addition & 0 deletions lib/committee/schema_validator/open_api_3.rb
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ def response_validate(status, headers, response, test_method = false)
full_body
end

# TODO: refactoring name
strict = test_method
Committee::SchemaValidator::OpenAPI3::ResponseValidator.
new(@operation_object, validator_option).
Expand Down
39 changes: 38 additions & 1 deletion test/middleware/response_validation_open_api_3_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -228,15 +228,52 @@ def app
end
end

it "strict and invalid status" do
@app = new_response_rack(JSON.generate(CHARACTERS_RESPONSE), {}, {schema: open_api_3_schema, strict: true}, {status: 201})
get "/characters"
assert_equal 500, last_response.status
end

it "strict and invalid status with raise" do
@app = new_response_rack(JSON.generate(CHARACTERS_RESPONSE), {}, {schema: open_api_3_schema, strict: true, raise: true}, {status: 201})

assert_raises(Committee::InvalidResponse) do
get "/characters"
end
end

it "strict and invalid content type" do
@app = new_response_rack("abc",
{},
{schema: open_api_3_schema, strict: true},
{content_type: 'application/text'}
)
get "/characters"
assert_equal 500, last_response.status
end

it "strict and invalid content type with raise" do
@app = new_response_rack("abc",
{},
{schema: open_api_3_schema, strict: true, raise: true},
{content_type: 'application/text'}
)

assert_raises(Committee::InvalidResponse) do
get "/characters"
end
end

private

def new_response_rack(response, headers = {}, options = {}, rack_options = {})
# TODO: delete when 5.0.0 released because default value changed
options[:parse_response_by_content_type] = true if options[:parse_response_by_content_type] == nil

status = rack_options[:status] || 200
content_type = rack_options[:content_type] || "application/json"
headers = {
"Content-Type" => "application/json"
"Content-Type" => content_type
}.merge(headers)
Rack::Builder.new {
use Committee::Middleware::ResponseValidation, options
Expand Down
9 changes: 9 additions & 0 deletions test/schema_validator/open_api_3/response_validator_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,15 @@
assert_kind_of(OpenAPIParser::OpenAPIError, e.original_error)
end

it "raises InvalidResponse when a invalid status code with strict option" do
@status = 201
e = assert_raises(Committee::InvalidResponse) {
call_response_validator(true)
}

assert_kind_of(OpenAPIParser::OpenAPIError, e.original_error)
end

it "passes through a valid response with no Content-Type" do
@headers = {}
call_response_validator
Expand Down

0 comments on commit a5b5fef

Please sign in to comment.