Skip to content

Commit d5e6f4c

Browse files
authored
Merge pull request #341 from ahx/spec-first-arg
Allow passing the OAD as a first argument of the Middlewares
2 parents b57d5cd + 8c02829 commit d5e6f4c

File tree

5 files changed

+56
-8
lines changed

5 files changed

+56
-8
lines changed

CHANGELOG.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,9 @@
11
# Changelog
22

33
## Unreleased
4-
- 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
54

5+
- Middlewares now accept the OAD as a first positional argument instead of `:spec` inside the options hash.
6+
- 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
67
- `OpenapiFirst::Test::Methods[MyApplication]` returns a Module which adds an `app` method to be used by rack-test alonside the `assert_api_conform` method.
78
- Make default coverage report less verbose
89
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

lib/openapi_first/middlewares/request_validation.rb

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,19 +6,26 @@ module Middlewares
66
# A Rack middleware to validate requests against an OpenAPI API description
77
class RequestValidation
88
# @param app The parent Rack application
9-
# @param options An optional Hash of configuration options to override defaults
9+
# @param spec [String, OpenapiFirst::Definition] Path to the OpenAPI file or an instance of Definition.
10+
# @param options Hash
11+
# :spec [String, OpenapiFirst::Definition] Path to the OpenAPI file or an instance of Definition.
12+
# This will be deprecated. Please use spec argument instead.
1013
# :raise_error A Boolean indicating whether to raise an error if validation fails.
1114
# default: false
1215
# :error_response The Class to use for error responses.
1316
# This can be a Symbol-name of an registered error response (:default, :jsonapi)
1417
# or it can be set to false to disable returning a response.
1518
# default: OpenapiFirst::Plugins::Default::ErrorResponse (Config.default_options.error_response)
16-
def initialize(app, options = {})
19+
def initialize(app, spec = nil, options = {})
1720
@app = app
21+
if spec.is_a?(Hash)
22+
options = spec
23+
spec = options.fetch(:spec)
24+
end
1825
@raise = options.fetch(:raise_error, OpenapiFirst.configuration.request_validation_raise_error)
1926
@error_response_class = error_response_option(options[:error_response])
2027

21-
spec = options.fetch(:spec)
28+
spec ||= options.fetch(:spec)
2229
raise "You have to pass spec: when initializing #{self.class}" unless spec
2330

2431
@definition = spec.is_a?(Definition) ? spec : OpenapiFirst.load(spec)

lib/openapi_first/middlewares/response_validation.rb

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,15 +6,19 @@ module OpenapiFirst
66
module Middlewares
77
# A Rack middleware to validate requests against an OpenAPI API description
88
class ResponseValidation
9-
# @param app The parent Rack application
9+
# @param spec [String, OpenapiFirst::Definition] Path to the OpenAPI file or an instance of Definition
1010
# @param options Hash
11-
# :spec [String, OpenapiFirst::Definition] Path to the OpenAPI file or an instance of Definition
11+
# :spec [String, OpenapiFirst::Definition] Path to the OpenAPI file or an instance of Definition.
12+
# This will be deprecated. Please use spec argument instead.
1213
# :raise_error [Boolean] Whether to raise an error if validation fails. default: true
13-
def initialize(app, options = {})
14+
def initialize(app, spec = nil, options = {})
1415
@app = app
16+
if spec.is_a?(Hash)
17+
options = spec
18+
spec = options.fetch(:spec)
19+
end
1520
@raise = options.fetch(:raise_error, OpenapiFirst.configuration.response_validation_raise_error)
1621

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

2024
@definition = spec.is_a?(Definition) ? spec : OpenapiFirst.load(spec)

spec/middlewares/request_validation_spec.rb

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,22 @@
3232
end
3333
end
3434

35+
context 'when OAD is passed as first argument' do
36+
let(:app) do
37+
Rack::Builder.app do
38+
use(OpenapiFirst::Middlewares::RequestValidation, File.expand_path('../data/petstore-expanded.yaml', __dir__))
39+
run ->(_) {}
40+
end
41+
end
42+
43+
it 'returns 400 is request is invalid' do
44+
header 'Content-Type', 'application/json'
45+
post '/pets', 'not json'
46+
47+
expect(last_response.status).to eq 400
48+
end
49+
end
50+
3551
context 'when parameter is invalid' do
3652
it 'returns 400' do
3753
get '/pets?limit=three'

spec/middlewares/response_validation_spec.rb

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,26 @@
2525
end
2626
let(:response) { Rack::Response.new(response_body, status, headers) }
2727

28+
context 'with path to OAD as first argument' do
29+
let(:response_body) { '2' }
30+
31+
let(:app) do
32+
res = response
33+
definition = spec
34+
Rack::Builder.app do
35+
use Rack::Lint
36+
use OpenapiFirst::Middlewares::ResponseValidation, definition
37+
run ->(_env) { res.finish }
38+
end
39+
end
40+
41+
it 'fails if request is inavlid' do
42+
expect do
43+
get '/pets'
44+
end.to raise_error OpenapiFirst::ResponseInvalidError
45+
end
46+
end
47+
2848
context 'without content-type header' do
2949
let(:headers) do
3050
{ 'X-HEAD' => '/api/next-page' }

0 commit comments

Comments
 (0)