Skip to content

Commit cbb3f7d

Browse files
authored
Merge pull request #345 from kaorukobo/override-path
Allow to override path for schema matching with `env[OpenapiFirst::PATH]`
2 parents 72745a3 + 21f4690 commit cbb3f7d

File tree

4 files changed

+44
-2
lines changed

4 files changed

+44
-2
lines changed

CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22

33
## Unreleased
44

5+
- Allow to override path for schema matching with `env[OpenapiFirst::PATH]` (https://github.com/ahx/openapi_first/pull/345)
6+
57
## 2.6.0
68

79
- Middlewares now accept the OAD as a first positional argument instead of `:spec` inside the options hash.

lib/openapi_first.rb

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,10 @@ module OpenapiFirst
1515

1616
# Key in rack to find instance of Request
1717
REQUEST = 'openapi.request'
18+
19+
# Key in rack to store the alternate path used for schema matching
20+
PATH = 'openapi.path'
21+
1822
FAILURE = :openapi_first_validation_failure
1923

2024
# @return [Configuration]

lib/openapi_first/definition.rb

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ def initialize(contents, filepath = nil)
4545
# @param [Boolean] raise_error Whether to raise an error if validation fails.
4646
# @return [ValidatedRequest] The validated request object.
4747
def validate_request(request, raise_error: false)
48-
route = @router.match(request.request_method, request.path, content_type: request.content_type)
48+
route = @router.match(request.request_method, resolve_path(request), content_type: request.content_type)
4949
if route.error
5050
ValidatedRequest.new(request, error: route.error)
5151
else
@@ -62,7 +62,8 @@ def validate_request(request, raise_error: false)
6262
# @param raise_error [Boolean] Whethir to raise an error if validation fails.
6363
# @return [ValidatedResponse] The validated response object.
6464
def validate_response(rack_request, rack_response, raise_error: false)
65-
route = @router.match(rack_request.request_method, rack_request.path, content_type: rack_request.content_type)
65+
route = @router.match(rack_request.request_method, resolve_path(rack_request),
66+
content_type: rack_request.content_type)
6667
return if route.error # Skip response validation for unknown requests
6768

6869
response_match = route.match_response(status: rack_response.status, content_type: rack_response.content_type)
@@ -76,5 +77,11 @@ def validate_response(rack_request, rack_response, raise_error: false)
7677
raise validated.error.exception(validated) if raise_error && validated.invalid?
7778
end
7879
end
80+
81+
private
82+
83+
def resolve_path(rack_request)
84+
rack_request.env[PATH] || rack_request.path
85+
end
7986
end
8087
end

spec/definition_spec.rb

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -213,6 +213,20 @@ def build_request(path, method: 'GET')
213213
).to be_valid
214214
end
215215
end
216+
217+
context 'with an alternate path used for schema matching' do
218+
let(:request) do
219+
build_request('/prefix/stuff/42').tap do |req|
220+
req.env[OpenapiFirst::PATH] = '/stuff/42'
221+
end
222+
end
223+
224+
it 'returns a valid request' do
225+
validated = definition.validate_request(request)
226+
expect(validated).to be_valid
227+
expect(validated.parsed_path_parameters).to eq({ 'id' => 42 })
228+
end
229+
end
216230
end
217231

218232
describe '#validate_response' do
@@ -296,6 +310,21 @@ def build_request(path, method: 'GET')
296310
end
297311
end
298312
end
313+
314+
context 'with an alternate path used for schema matching' do
315+
let(:request) do
316+
build_request('/prefix/stuff/42').tap do |req|
317+
req.env[OpenapiFirst::PATH] = '/stuff'
318+
end
319+
end
320+
let(:response) { Rack::Response.new(JSON.generate({ 'id' => 42 }), 200, { 'Content-Type' => 'application/json' }) }
321+
322+
it 'returns a valid response' do
323+
validated = definition.validate_response(request, response)
324+
expect(validated).to be_valid
325+
expect(validated.parsed_body).to eq({ 'id' => 42 })
326+
end
327+
end
299328
end
300329

301330
describe '#routes' do

0 commit comments

Comments
 (0)