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
3 changes: 2 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
# Changelog

## Unreleased
- No longer merge parameter schemas per of the same location (for example "query") in order to fix https://github.com/ahx/openapi_first/issues/320

- Middlewares now accept the OAD as a first positional argument instead of `:spec` inside the options hash.
- No longer merge parameter schemas per of the same location (for example "query") in order to fix https://github.com/ahx/openapi_first/issues/320
- `OpenapiFirst::Test::Methods[MyApplication]` returns a Module which adds an `app` method to be used by rack-test alonside the `assert_api_conform` method.
- Make default coverage report less verbose
The default formatter (TerminalFormatter) no longer prints all un-requested requests by default. You can set `test.coverage_formatter_options = { focused: false }` to get back the old behavior
Expand Down
13 changes: 10 additions & 3 deletions lib/openapi_first/middlewares/request_validation.rb
Original file line number Diff line number Diff line change
Expand Up @@ -6,19 +6,26 @@ module Middlewares
# A Rack middleware to validate requests against an OpenAPI API description
class RequestValidation
# @param app The parent Rack application
# @param options An optional Hash of configuration options to override defaults
# @param spec [String, OpenapiFirst::Definition] Path to the OpenAPI file or an instance of Definition.
# @param options Hash
# :spec [String, OpenapiFirst::Definition] Path to the OpenAPI file or an instance of Definition.
# This will be deprecated. Please use spec argument instead.
# :raise_error A Boolean indicating whether to raise an error if validation fails.
# default: false
# :error_response The Class to use for error responses.
# This can be a Symbol-name of an registered error response (:default, :jsonapi)
# or it can be set to false to disable returning a response.
# default: OpenapiFirst::Plugins::Default::ErrorResponse (Config.default_options.error_response)
def initialize(app, options = {})
def initialize(app, spec = nil, options = {})
@app = app
if spec.is_a?(Hash)
options = spec
spec = options.fetch(:spec)
end
@raise = options.fetch(:raise_error, OpenapiFirst.configuration.request_validation_raise_error)
@error_response_class = error_response_option(options[:error_response])

spec = options.fetch(:spec)
spec ||= options.fetch(:spec)
raise "You have to pass spec: when initializing #{self.class}" unless spec

@definition = spec.is_a?(Definition) ? spec : OpenapiFirst.load(spec)
Expand Down
12 changes: 8 additions & 4 deletions lib/openapi_first/middlewares/response_validation.rb
Original file line number Diff line number Diff line change
Expand Up @@ -6,15 +6,19 @@ module OpenapiFirst
module Middlewares
# A Rack middleware to validate requests against an OpenAPI API description
class ResponseValidation
# @param app The parent Rack application
# @param spec [String, OpenapiFirst::Definition] Path to the OpenAPI file or an instance of Definition
# @param options Hash
# :spec [String, OpenapiFirst::Definition] Path to the OpenAPI file or an instance of Definition
# :spec [String, OpenapiFirst::Definition] Path to the OpenAPI file or an instance of Definition.
# This will be deprecated. Please use spec argument instead.
# :raise_error [Boolean] Whether to raise an error if validation fails. default: true
def initialize(app, options = {})
def initialize(app, spec = nil, options = {})
@app = app
if spec.is_a?(Hash)
options = spec
spec = options.fetch(:spec)
end
@raise = options.fetch(:raise_error, OpenapiFirst.configuration.response_validation_raise_error)

spec = options.fetch(:spec)
raise "You have to pass spec: when initializing #{self.class}" unless spec

@definition = spec.is_a?(Definition) ? spec : OpenapiFirst.load(spec)
Expand Down
16 changes: 16 additions & 0 deletions spec/middlewares/request_validation_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,22 @@
end
end

context 'when OAD is passed as first argument' do
let(:app) do
Rack::Builder.app do
use(OpenapiFirst::Middlewares::RequestValidation, File.expand_path('../data/petstore-expanded.yaml', __dir__))
run ->(_) {}
end
end

it 'returns 400 is request is invalid' do
header 'Content-Type', 'application/json'
post '/pets', 'not json'

expect(last_response.status).to eq 400
end
end

context 'when parameter is invalid' do
it 'returns 400' do
get '/pets?limit=three'
Expand Down
20 changes: 20 additions & 0 deletions spec/middlewares/response_validation_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,26 @@
end
let(:response) { Rack::Response.new(response_body, status, headers) }

context 'with path to OAD as first argument' do
let(:response_body) { '2' }

let(:app) do
res = response
definition = spec
Rack::Builder.app do
use Rack::Lint
use OpenapiFirst::Middlewares::ResponseValidation, definition
run ->(_env) { res.finish }
end
end

it 'fails if request is inavlid' do
expect do
get '/pets'
end.to raise_error OpenapiFirst::ResponseInvalidError
end
end

context 'without content-type header' do
let(:headers) do
{ 'X-HEAD' => '/api/next-page' }
Expand Down