Skip to content

Commit b59999d

Browse files
committed
Merge pull request #936 from dm1try/fix_weird_behaviour_with_optional_groups
fix weird behaviour for optional groups with default params
2 parents 9d3200e + 80ddb63 commit b59999d

File tree

3 files changed

+116
-22
lines changed

3 files changed

+116
-22
lines changed

CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,10 @@
11
0.11.1 (Next)
22
=============
33

4+
#### Fixes
5+
6+
* [#936](https://github.com/intridea/grape/pull/936): Fixed default params processing for optional groups - [@dm1try](https://github.com/dm1try).
7+
48
* Your contribution here.
59

610
0.11.0 (2/23/2015)

lib/grape/validations/validators/default.rb

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,12 +11,12 @@ def validate_param!(attr_name, params)
1111
end
1212

1313
def validate!(params)
14+
return unless @scope.should_validate?(params)
15+
1416
attrs = AttributesIterator.new(self, @scope, params)
15-
parent_element = @scope.element
1617
attrs.each do |resource_params, attr_name|
1718
if resource_params[attr_name].nil?
1819
validate_param!(attr_name, resource_params)
19-
params[parent_element] = resource_params if parent_element && params[parent_element].nil?
2020
end
2121
end
2222
end

spec/grape/validations/validators/default_spec.rb

Lines changed: 110 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -40,20 +40,6 @@ class API < Grape::API
4040
{ random_number: params[:random], non_random_number: params[:non_random_number] }
4141
end
4242

43-
params do
44-
# NOTE: The :foo parameter could be made required with json body
45-
# params, and then an empty hash would be valid. With query parameters
46-
# it must be optional if it isn't provided at all, as otherwise
47-
# the validaton for the Hash itself fails because there is no such
48-
# thing as an empty hash.
49-
optional :foo, type: Hash do
50-
optional :bar, default: 'foo-bar'
51-
end
52-
end
53-
get '/group' do
54-
{ foo_bar: params[:foo][:bar] }
55-
end
56-
5743
params do
5844
optional :array, type: Array do
5945
requires :name
@@ -107,15 +93,119 @@ def app
10793
expect(before['random_number']).not_to eq(after['random_number'])
10894
end
10995

110-
it 'set default values for optional grouped params' do
111-
get('/group')
112-
expect(last_response.status).to eq(200)
113-
expect(last_response.body).to eq({ foo_bar: 'foo-bar' }.to_json)
114-
end
115-
11696
it 'sets default values for grouped arrays' do
11797
get('/array?array[][name]=name&array[][name]=name2&array[][with_default]=bar2')
11898
expect(last_response.status).to eq(200)
11999
expect(last_response.body).to eq({ array: [{ name: 'name', with_default: 'default' }, { name: 'name2', with_default: 'bar2' }] }.to_json)
120100
end
101+
102+
context 'optional group with defaults' do
103+
subject do
104+
Class.new(Grape::API) do
105+
default_format :json
106+
end
107+
end
108+
109+
def app
110+
subject
111+
end
112+
113+
context 'optional array without default value includes optional param with default value' do
114+
before do
115+
subject.params do
116+
optional :optional_array, type: Array do
117+
optional :foo_in_optional_array, default: 'bar'
118+
end
119+
end
120+
subject.post '/optional_array' do
121+
{ optional_array: params[:optional_array] }
122+
end
123+
end
124+
125+
it 'returns nil for optional array if param is not provided' do
126+
post '/optional_array'
127+
expect(last_response.status).to eq(201)
128+
expect(last_response.body).to eq({ optional_array: nil }.to_json)
129+
end
130+
end
131+
132+
context 'optional array with default value includes optional param with default value' do
133+
before do
134+
subject.params do
135+
optional :optional_array_with_default, type: Array, default: [] do
136+
optional :foo_in_optional_array, default: 'bar'
137+
end
138+
end
139+
subject.post '/optional_array_with_default' do
140+
{ optional_array_with_default: params[:optional_array_with_default] }
141+
end
142+
end
143+
144+
it 'sets default value for optional array if param is not provided' do
145+
post '/optional_array_with_default'
146+
expect(last_response.status).to eq(201)
147+
expect(last_response.body).to eq({ optional_array_with_default: [] }.to_json)
148+
end
149+
end
150+
151+
context 'optional hash without default value includes optional param with default value' do
152+
before do
153+
subject.params do
154+
optional :optional_hash_without_default, type: Hash do
155+
optional :foo_in_optional_hash, default: 'bar'
156+
end
157+
end
158+
subject.post '/optional_hash_without_default' do
159+
{ optional_hash_without_default: params[:optional_hash_without_default] }
160+
end
161+
end
162+
163+
it 'returns nil for optional hash if param is not provided' do
164+
post '/optional_hash_without_default'
165+
expect(last_response.status).to eq(201)
166+
expect(last_response.body).to eq({ optional_hash_without_default: nil }.to_json)
167+
end
168+
end
169+
170+
context 'optional hash with default value includes optional param with default value' do
171+
before do
172+
subject.params do
173+
optional :optional_hash_with_default, type: Hash, default: {} do
174+
optional :foo_in_optional_hash, default: 'bar'
175+
end
176+
end
177+
subject.post '/optional_hash_with_default_empty_hash' do
178+
{ optional_hash_with_default: params[:optional_hash_with_default] }
179+
end
180+
181+
subject.params do
182+
optional :optional_hash_with_default, type: Hash, default: { foo_in_optional_hash: 'parent_default' } do
183+
optional :some_param
184+
optional :foo_in_optional_hash, default: 'own_default'
185+
end
186+
end
187+
subject.post '/optional_hash_with_default_inner_params' do
188+
{ foo_in_optional_hash: params[:optional_hash_with_default][:foo_in_optional_hash] }
189+
end
190+
end
191+
192+
it 'sets default value for optional hash if param is not provided' do
193+
post '/optional_hash_with_default_empty_hash'
194+
expect(last_response.status).to eq(201)
195+
expect(last_response.body).to eq({ optional_hash_with_default: {} }.to_json)
196+
end
197+
198+
it 'sets default value from parent defaults for inner param if parent param is not provided' do
199+
post '/optional_hash_with_default_inner_params'
200+
expect(last_response.status).to eq(201)
201+
expect(last_response.body).to eq({ foo_in_optional_hash: 'parent_default' }.to_json)
202+
end
203+
204+
it 'sets own default value for inner param if parent param is provided' do
205+
post '/optional_hash_with_default_inner_params', optional_hash_with_default: { some_param: 'param' }
206+
expect(last_response.status).to eq(201)
207+
expect(last_response.body).to eq({ foo_in_optional_hash: 'own_default' }.to_json)
208+
end
209+
end
210+
end
121211
end

0 commit comments

Comments
 (0)