From 10082d455d0dc23387c9fc68c91edf1850db0aef Mon Sep 17 00:00:00 2001 From: Pedro Oliveira Date: Thu, 4 May 2023 21:18:10 +0100 Subject: [PATCH 1/4] Add test to replicate issue #56 --- spec/integration_tests/rails_test.rb | 9 +++++++++ spec/rails/config/routes.rb | 2 ++ spec/rails/doc/openapi.json | 21 +++++++++++++++++++++ spec/rails/doc/openapi.yaml | 12 ++++++++++++ spec/requests/rails_spec.rb | 9 +++++++++ 5 files changed, 53 insertions(+) diff --git a/spec/integration_tests/rails_test.rb b/spec/integration_tests/rails_test.rb index da0a723d..cc1dce30 100644 --- a/spec/integration_tests/rails_test.rb +++ b/spec/integration_tests/rails_test.rb @@ -160,3 +160,12 @@ class EngineTest < ActionDispatch::IntegrationTest assert_response 200 end end + +class EngineExtraRoutesTest < ActionDispatch::IntegrationTest + openapi! + + test 'returns the block content' do + get '/my_engine/test' + assert_response 200 + end +end diff --git a/spec/rails/config/routes.rb b/spec/rails/config/routes.rb index 5d76adf4..7f129d99 100644 --- a/spec/rails/config/routes.rb +++ b/spec/rails/config/routes.rb @@ -1,6 +1,8 @@ Rails.application.routes.draw do mount ::MyEngine::Engine => '/my_engine' + get '/my_engine/test' => ->(_env) { [200, { 'Content-Type' => 'text/plain' }, ['ANOTHER TEST']] } + defaults format: 'json' do resources :tables, only: [:index, :show, :create, :update, :destroy] resources :images, only: [:index, :show] diff --git a/spec/rails/doc/openapi.json b/spec/rails/doc/openapi.json index 9f87dab8..bf93832f 100644 --- a/spec/rails/doc/openapi.json +++ b/spec/rails/doc/openapi.json @@ -753,6 +753,27 @@ } } }, + "/my_engine/test": { + "get": { + "summary": "GET /my_engine/test", + "tags": [ + + ], + "responses": { + "200": { + "description": "returns the block content", + "content": { + "text/plain": { + "schema": { + "type": "string" + }, + "example": "ANOTHER TEST" + } + } + } + } + } + }, "/images": { "get": { "summary": "index", diff --git a/spec/rails/doc/openapi.yaml b/spec/rails/doc/openapi.yaml index 0139283f..363c9cb7 100644 --- a/spec/rails/doc/openapi.yaml +++ b/spec/rails/doc/openapi.yaml @@ -533,3 +533,15 @@ paths: example: - name: file.png tags: [] + "/my_engine/test": + get: + summary: GET /my_engine/test + tags: [] + responses: + '200': + description: returns the block content + content: + text/plain: + schema: + type: string + example: ANOTHER TEST diff --git a/spec/requests/rails_spec.rb b/spec/requests/rails_spec.rb index febdce15..5d56bb78 100644 --- a/spec/requests/rails_spec.rb +++ b/spec/requests/rails_spec.rb @@ -144,3 +144,12 @@ end end end + +RSpec.describe 'Engine extra routes', type: :request do + describe '#test' do + it 'returns the block content' do + get '/my_engine/test' + expect(response.status).to eq(200) + end + end +end From 6b6b9e0d0852792afa2fb3b3a5e373c32c6120f8 Mon Sep 17 00:00:00 2001 From: Pedro Oliveira Date: Thu, 4 May 2023 23:09:01 +0100 Subject: [PATCH 2/4] fix path resolution --- lib/rspec/openapi/record_builder.rb | 9 ++++++--- spec/rails/doc/openapi.json | 6 +++--- spec/rails/doc/openapi.yaml | 4 ++-- 3 files changed, 11 insertions(+), 8 deletions(-) diff --git a/lib/rspec/openapi/record_builder.rb b/lib/rspec/openapi/record_builder.rb index 26e02b57..c8927b6e 100644 --- a/lib/rspec/openapi/record_builder.rb +++ b/lib/rspec/openapi/record_builder.rb @@ -108,12 +108,15 @@ def find_rails_route(request, app: Rails.application, fix_path: true) app.routes.router.recognize(request) do |route| if route.app.matches?(request) - return find_rails_route(request, app: route.app.app, fix_path: false) if route.app.engine? - + if route.app.engine? + route = find_rails_route(request, app: route.app.app, fix_path: false) + next if route.nil? + end return route end end - raise "No route matched for #{request.request_method} #{request.path_info}" + raise "No route matched for #{request.request_method} #{request.path_info}" if fix_path + nil end # workaround to get real request parameters diff --git a/spec/rails/doc/openapi.json b/spec/rails/doc/openapi.json index bf93832f..4fa23f26 100644 --- a/spec/rails/doc/openapi.json +++ b/spec/rails/doc/openapi.json @@ -732,9 +732,9 @@ } } }, - "/eng_route": { + "/my_engine/eng_route": { "get": { - "summary": "GET /eng_route", + "summary": "GET /my_engine/eng_route", "tags": [ ], @@ -820,4 +820,4 @@ } } } -} \ No newline at end of file +} diff --git a/spec/rails/doc/openapi.yaml b/spec/rails/doc/openapi.yaml index 363c9cb7..5218adb5 100644 --- a/spec/rails/doc/openapi.yaml +++ b/spec/rails/doc/openapi.yaml @@ -495,9 +495,9 @@ paths: schema: type: string example: A TEST - "/eng_route": + "/my_engine/eng_route": get: - summary: GET /eng_route + summary: GET /my_engine/eng_route tags: [] responses: '200': From 288b7c39d247728fc558fa607b21bb5a5e909b62 Mon Sep 17 00:00:00 2001 From: Pedro Oliveira Date: Fri, 5 May 2023 09:53:15 +0100 Subject: [PATCH 3/4] fix engine path --- lib/rspec/openapi/record_builder.rb | 26 ++++++++++++++------------ 1 file changed, 14 insertions(+), 12 deletions(-) diff --git a/lib/rspec/openapi/record_builder.rb b/lib/rspec/openapi/record_builder.rb index c8927b6e..013b3043 100644 --- a/lib/rspec/openapi/record_builder.rb +++ b/lib/rspec/openapi/record_builder.rb @@ -66,8 +66,16 @@ def extract_request_attributes(request, example) raw_path_params = request.path_parameters path = request.path if rails? - route = find_rails_route(request) - path = route.path.spec.to_s.delete_suffix('(.:format)') + # 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 + fixed_request = request.dup + if request.script_name.present? + fixed_request.path_info = File.join(request.script_name, request.path_info) + end + + route, path = find_rails_route(fixed_request) + raise "No route matched for #{fixed_request.request_method} #{fixed_request.path_info}" if route.nil? + + path = path.delete_suffix('(.:format)') summary ||= route.requirements[:action] tags ||= [route.requirements[:controller]&.classify].compact # :controller and :action always exist. :format is added when routes is configured as such. @@ -99,23 +107,17 @@ def rack_test?(context) end # @param [ActionDispatch::Request] request - def find_rails_route(request, app: Rails.application, fix_path: true) - # 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 - if fix_path && !request.script_name.empty? - request = request.dup - request.path_info = File.join(request.script_name, request.path_info) - end - + def find_rails_route(request, app: Rails.application, path_prefix: "") app.routes.router.recognize(request) do |route| + path = route.path.spec.to_s if route.app.matches?(request) if route.app.engine? - route = find_rails_route(request, app: route.app.app, fix_path: false) + route, path = find_rails_route(request, app: route.app.app, path_prefix: path) next if route.nil? end - return route + return [route, path_prefix + path] end end - raise "No route matched for #{request.request_method} #{request.path_info}" if fix_path nil end From 8456b3fc84c8be35de0ba56a756c93c870ef6343 Mon Sep 17 00:00:00 2001 From: Pedro Oliveira Date: Wed, 16 Aug 2023 09:19:03 +0100 Subject: [PATCH 4/4] fix linter warnings --- lib/rspec/openapi/record_builder.rb | 6 ++---- spec/rails/doc/openapi.json | 2 +- 2 files changed, 3 insertions(+), 5 deletions(-) diff --git a/lib/rspec/openapi/record_builder.rb b/lib/rspec/openapi/record_builder.rb index 3541367b..8d3f1962 100644 --- a/lib/rspec/openapi/record_builder.rb +++ b/lib/rspec/openapi/record_builder.rb @@ -71,9 +71,7 @@ def extract_request_attributes(request, example) if rails? # 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 fixed_request = request.dup - if request.script_name.present? - fixed_request.path_info = File.join(request.script_name, request.path_info) - end + fixed_request.path_info = File.join(request.script_name, request.path_info) if request.script_name.present? route, path = find_rails_route(fixed_request) raise "No route matched for #{fixed_request.request_method} #{fixed_request.path_info}" if route.nil? @@ -110,7 +108,7 @@ def rack_test?(context) end # @param [ActionDispatch::Request] request - def find_rails_route(request, app: Rails.application, path_prefix: "") + def find_rails_route(request, app: Rails.application, path_prefix: '') app.routes.router.recognize(request) do |route| path = route.path.spec.to_s if route.app.matches?(request) diff --git a/spec/rails/doc/openapi.json b/spec/rails/doc/openapi.json index 65b27841..07f98407 100644 --- a/spec/rails/doc/openapi.json +++ b/spec/rails/doc/openapi.json @@ -1015,4 +1015,4 @@ } } } -} +} \ No newline at end of file