Skip to content

Commit c80b016

Browse files
authored
Merge pull request #2612 from alexanderadam/fix/avoid_multiple_mounts_pollution
Avoid multiple mount pollution
2 parents 57408ff + 342b987 commit c80b016

File tree

4 files changed

+47
-33
lines changed

4 files changed

+47
-33
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
* [#2607](https://github.com/ruby-grape/grape/pull/2607): Remove namespace_stackable and namespace_inheritable from public API - [@ericproulx](https://github.com/ericproulx).
2323
* [#2615](https://github.com/ruby-grape/grape/pull/2615): Remove manual toc and tod danger check - [@alexanderadam](https://github.com/alexanderadam).
2424
* Your contribution here.
25+
* [#2612](https://github.com/ruby-grape/grape/pull/2612): Avoid multiple mount pollution - [@alexanderadam](https://github.com/alexanderadam).
2526

2627
#### Fixes
2728

lib/grape/api.rb

Lines changed: 2 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -22,14 +22,13 @@ class << self
2222
attr_accessor :base_instance, :instances
2323

2424
delegate_missing_to :base_instance
25-
def_delegators :base_instance, :new, :configuration
2625

2726
# This is the interface point between Rack and Grape; it accepts a request
2827
# from Rack and ultimately returns an array of three values: the status,
2928
# the headers, and the body. See [the rack specification]
30-
# (http://www.rubydoc.info/github/rack/rack/master/file/SPEC) for more.
29+
# (https://github.com/rack/rack/blob/main/SPEC.rdoc) for more.
3130
# NOTE: This will only be called on an API directly mounted on RACK
32-
def_delegators :instance_for_rack, :call, :compile!
31+
def_delegators :base_instance, :new, :configuration, :call, :compile!
3332

3433
# When inherited, will create a list of all instances (times the API was mounted)
3534
# It will listen to the setup required to mount that endpoint, and replicate it on any new instance
@@ -95,14 +94,6 @@ def replay_setup_on(instance)
9594
end
9695
end
9796

98-
def instance_for_rack
99-
if never_mounted?
100-
base_instance
101-
else
102-
mounted_instances.first
103-
end
104-
end
105-
10697
# Adds a new stage to the set up require to get a Grape::API up and running
10798
def add_setup(step)
10899
@setup << step

spec/grape/api_spec.rb

Lines changed: 0 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1055,28 +1055,6 @@ def to_txt
10551055
end
10561056
end
10571057

1058-
# NOTE: this method is required to preserve the ability of pre-mounting
1059-
# the root API into a namespace, it may be deprecated in the future.
1060-
describe 'instance_for_rack' do
1061-
context 'when the app was not mounted' do
1062-
it 'returns the base_instance' do
1063-
expect(app.__send__(:instance_for_rack)).to eq app.base_instance
1064-
end
1065-
end
1066-
1067-
context 'when the app was mounted' do
1068-
it 'returns the first mounted instance' do
1069-
mounted_app = app
1070-
Class.new(described_class) do
1071-
namespace 'new_namespace' do
1072-
mount mounted_app
1073-
end
1074-
end
1075-
expect(app.__send__(:instance_for_rack)).to eq app.__send__(:mounted_instances).first
1076-
end
1077-
end
1078-
end
1079-
10801058
describe 'filters' do
10811059
it 'adds a before filter' do
10821060
subject.before { @foo = 'first' }

spec/grape/integration/rack_spec.rb

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,4 +71,48 @@
7171
expect(last_response).to be_successful
7272
end
7373
end
74+
75+
# https://github.com/ruby-grape/grape/issues/2576
76+
describe 'when an api is mounted' do
77+
let(:api) do
78+
Class.new(Grape::API) do
79+
format :json
80+
version 'v1', using: :path
81+
82+
resource :system do
83+
get :ping do
84+
{ message: 'pong' }
85+
end
86+
end
87+
end
88+
end
89+
90+
let(:parent_api) do
91+
api_to_mount = api
92+
Class.new(Grape::API) do
93+
format :json
94+
namespace '/api' do
95+
mount api_to_mount
96+
end
97+
end
98+
end
99+
100+
it 'is not polluted with the parent namespace' do
101+
env = Rack::MockRequest.env_for('/v1/api/system/ping', method: 'GET')
102+
response = Rack::MockResponse[*parent_api.call(env)]
103+
104+
expect(response.status).to eq(200)
105+
parsed_body = JSON.parse(response.body)
106+
expect(parsed_body['message']).to eq('pong')
107+
end
108+
109+
it 'can call the api' do
110+
env = Rack::MockRequest.env_for('/v1/system/ping', method: 'GET')
111+
response = Rack::MockResponse[*api.call(env)]
112+
113+
expect(response.status).to eq(200)
114+
parsed_body = JSON.parse(response.body)
115+
expect(parsed_body['message']).to eq('pong')
116+
end
117+
end
74118
end

0 commit comments

Comments
 (0)