Skip to content

Commit 74c05d3

Browse files
authored
Merge pull request #113 from pcoliveira/fix-engine-path-resolution
Fix engine path resolution
2 parents 6a1fbf4 + 8456b3f commit 74c05d3

File tree

6 files changed

+73
-17
lines changed

6 files changed

+73
-17
lines changed

lib/rspec/openapi/record_builder.rb

Lines changed: 16 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -69,8 +69,14 @@ def extract_request_attributes(request, example)
6969
raw_path_params = request.path_parameters
7070
path = request.path
7171
if rails?
72-
route = find_rails_route(request)
73-
path = route.path.spec.to_s.delete_suffix('(.:format)')
72+
# Reverse the destructive modification by Rails https://github.com/rails/rails/blob/v6.0.3.4/actionpack/lib/action_dispatch/journey/router.rb#L33-L41
73+
fixed_request = request.dup
74+
fixed_request.path_info = File.join(request.script_name, request.path_info) if request.script_name.present?
75+
76+
route, path = find_rails_route(fixed_request)
77+
raise "No route matched for #{fixed_request.request_method} #{fixed_request.path_info}" if route.nil?
78+
79+
path = path.delete_suffix('(.:format)')
7480
summary ||= route.requirements[:action]
7581
tags ||= [route.requirements[:controller]&.classify].compact
7682
# :controller and :action always exist. :format is added when routes is configured as such.
@@ -102,21 +108,18 @@ def rack_test?(context)
102108
end
103109

104110
# @param [ActionDispatch::Request] request
105-
def find_rails_route(request, app: Rails.application, fix_path: true)
106-
# Reverse the destructive modification by Rails https://github.com/rails/rails/blob/v6.0.3.4/actionpack/lib/action_dispatch/journey/router.rb#L33-L41
107-
if fix_path && !request.script_name.empty?
108-
request = request.dup
109-
request.path_info = File.join(request.script_name, request.path_info)
110-
end
111-
111+
def find_rails_route(request, app: Rails.application, path_prefix: '')
112112
app.routes.router.recognize(request) do |route|
113+
path = route.path.spec.to_s
113114
if route.app.matches?(request)
114-
return find_rails_route(request, app: route.app.app, fix_path: false) if route.app.engine?
115-
116-
return route
115+
if route.app.engine?
116+
route, path = find_rails_route(request, app: route.app.app, path_prefix: path)
117+
next if route.nil?
118+
end
119+
return [route, path_prefix + path]
117120
end
118121
end
119-
raise "No route matched for #{request.request_method} #{request.path_info}"
122+
nil
120123
end
121124

122125
# workaround to get real request parameters

spec/integration_tests/rails_test.rb

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -189,3 +189,12 @@ class EngineTest < ActionDispatch::IntegrationTest
189189
assert_response 200
190190
end
191191
end
192+
193+
class EngineExtraRoutesTest < ActionDispatch::IntegrationTest
194+
openapi!
195+
196+
test 'returns the block content' do
197+
get '/my_engine/test'
198+
assert_response 200
199+
end
200+
end

spec/rails/config/routes.rb

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
Rails.application.routes.draw do
22
mount ::MyEngine::Engine => '/my_engine'
33

4+
get '/my_engine/test' => ->(_env) { [200, { 'Content-Type' => 'text/plain' }, ['ANOTHER TEST']] }
5+
46
defaults format: 'json' do
57
resources :tables, only: [:index, :show, :create, :update, :destroy]
68
resources :images, only: [:index, :show] do

spec/rails/doc/openapi.json

Lines changed: 23 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -720,9 +720,9 @@
720720
}
721721
}
722722
},
723-
"/eng_route": {
723+
"/my_engine/eng_route": {
724724
"get": {
725-
"summary": "GET /eng_route",
725+
"summary": "GET /my_engine/eng_route",
726726
"tags": [
727727

728728
],
@@ -741,6 +741,27 @@
741741
}
742742
}
743743
},
744+
"/my_engine/test": {
745+
"get": {
746+
"summary": "GET /my_engine/test",
747+
"tags": [
748+
749+
],
750+
"responses": {
751+
"200": {
752+
"description": "returns the block content",
753+
"content": {
754+
"text/plain": {
755+
"schema": {
756+
"type": "string"
757+
},
758+
"example": "ANOTHER TEST"
759+
}
760+
}
761+
}
762+
}
763+
}
764+
},
744765
"/images": {
745766
"get": {
746767
"summary": "index",

spec/rails/doc/openapi.yaml

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -488,9 +488,9 @@ paths:
488488
schema:
489489
type: string
490490
example: A TEST
491-
"/eng_route":
491+
"/my_engine/eng_route":
492492
get:
493-
summary: GET /eng_route
493+
summary: GET /my_engine/eng_route
494494
tags: []
495495
responses:
496496
'200':
@@ -526,6 +526,18 @@ paths:
526526
example:
527527
- name: file.png
528528
tags: []
529+
"/my_engine/test":
530+
get:
531+
summary: GET /my_engine/test
532+
tags: []
533+
responses:
534+
'200':
535+
description: returns the block content
536+
content:
537+
text/plain:
538+
schema:
539+
type: string
540+
example: ANOTHER TEST
529541
"/images/upload":
530542
post:
531543
summary: upload

spec/requests/rails_spec.rb

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -197,3 +197,12 @@
197197
end
198198
end
199199
end
200+
201+
RSpec.describe 'Engine extra routes', type: :request do
202+
describe '#test' do
203+
it 'returns the block content' do
204+
get '/my_engine/test'
205+
expect(response.status).to eq(200)
206+
end
207+
end
208+
end

0 commit comments

Comments
 (0)