Skip to content

Commit e1d130c

Browse files
committed
Allow to override path for schema matching
1 parent b584d00 commit e1d130c

File tree

3 files changed

+42
-2
lines changed

3 files changed

+42
-2
lines changed

lib/openapi_first.rb

Lines changed: 11 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 env that stores the alternative path used for schema matching
20+
RACK_KEY_PATH_TO_MATCH = 'openapi.path_to_match'
21+
1822
FAILURE = :openapi_first_validation_failure
1923

2024
# @return [Configuration]
@@ -31,6 +35,13 @@ def self.configure
3135
ERROR_RESPONSES = {} # rubocop:disable Style/MutableConstant
3236
private_constant :ERROR_RESPONSES
3337

38+
# Retrieve the path used for schema matching.
39+
#
40+
# @param [Rack::Request] rack_request
41+
def self.get_path_to_match(rack_request)
42+
rack_request.env[RACK_KEY_PATH_TO_MATCH] || rack_request.path
43+
end
44+
3445
# Register an error response class
3546
# @param name [Symbol]
3647
# @param klass [Class] A class that includes / implements OpenapiFirst::ErrorResponse

lib/openapi_first/definition.rb

Lines changed: 2 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, OpenapiFirst.get_path_to_match(request), content_type: request.content_type)
4949
if route.error
5050
ValidatedRequest.new(request, error: route.error)
5151
else
@@ -62,7 +62,7 @@ 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, OpenapiFirst.get_path_to_match(rack_request), content_type: rack_request.content_type)
6666
return if route.error # Skip response validation for unknown requests
6767

6868
response_match = route.match_response(status: rack_response.status, content_type: rack_response.content_type)

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) {
219+
build_request('/prefix/stuff/42').tap { |req|
220+
req.env[OpenapiFirst::RACK_KEY_PATH_TO_MATCH] = '/stuff/42'
221+
}
222+
}
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) {
316+
build_request('/prefix/stuff/42').tap { |req|
317+
req.env[OpenapiFirst::RACK_KEY_PATH_TO_MATCH] = '/stuff'
318+
}
319+
}
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)