Skip to content

Commit 89591f2

Browse files
committed
Merge pull request #886 from jrichter1/required_params_type
Make the type in group of required params required (#722)
2 parents f3fe0eb + 2e64114 commit 89591f2

File tree

12 files changed

+143
-20
lines changed

12 files changed

+143
-20
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ Next Release
77
* [#879](https://github.com/intridea/grape/pull/879): The `route_info` value is no longer included in `params` Hash - [@rodzyn](https://github.com/rodzyn).
88
* [#881](https://github.com/intridea/grape/issues/881): Fixed `Grape::Validations::ValuesValidator` support for `Range` type - [@ajvondrak](https://github.com/ajvondrak).
99
* [#901](https://github.com/intridea/grape/pull/901): Fix: callbacks defined in a version block are only called for the routes defined in that block - [@kushkella](https://github.com/kushkella).
10+
* [#886](https://github.com/intridea/grape/pull/886): Group of parameters made to require an explicit type of Hash or Array - [@jrichter1](https://github.com/jrichter1).
1011
* Your contribution here.
1112

1213
0.10.1 (12/28/2014)

UPGRADING.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,14 @@ Callbacks defined in a version block are only called for the routes defined in t
2626

2727
See [#901](https://github.com/intridea/grape/pull/901) for more information.
2828

29+
30+
#### Make type of group of parameters required
31+
32+
Groups of parameters now require their type to be set explicitly as Array or Hash.
33+
Not setting the type now results in MissingGroupTypeError, unsupported type will raise UnsupportedTypeError.
34+
35+
See [#886](https://github.com/intridea/grape/pull/886) for more information.
36+
2937
### Upgrading to >= 0.10.1
3038

3139
#### Changes to `declared(params, include_missing: false)`

lib/grape.rb

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,8 @@ module Exceptions
5555
autoload :UnknownOptions, 'grape/exceptions/unknown_options'
5656
autoload :InvalidWithOptionForRepresent, 'grape/exceptions/invalid_with_option_for_represent'
5757
autoload :IncompatibleOptionValues, 'grape/exceptions/incompatible_option_values'
58+
autoload :MissingGroupTypeError, 'grape/exceptions/missing_group_type'
59+
autoload :UnsupportedGroupTypeError, 'grape/exceptions/unsupported_group_type'
5860
end
5961

6062
module ErrorFormatter

lib/grape/dsl/parameters.rb

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,13 @@ def optional(*attrs, &block)
3838
orig_attrs = attrs.clone
3939

4040
opts = attrs.last.is_a?(Hash) ? attrs.pop : {}
41+
type = opts[:type]
42+
43+
# check type for optional parameter group
44+
if attrs && block_given?
45+
fail Grape::Exceptions::MissingGroupTypeError.new if type.nil?
46+
fail Grape::Exceptions::UnsupportedGroupTypeError.new unless [Array, Hash].include?(type)
47+
end
4148

4249
validate_attributes(attrs, opts, &block)
4350

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
# encoding: utf-8
2+
module Grape
3+
module Exceptions
4+
class MissingGroupTypeError < Base
5+
def initialize
6+
super(message: compose_message('missing_group_type'))
7+
end
8+
end
9+
end
10+
end
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
# encoding: utf-8
2+
module Grape
3+
module Exceptions
4+
class UnsupportedGroupTypeError < Base
5+
def initialize
6+
super(message: compose_message('unsupported_group_type'))
7+
end
8+
end
9+
end
10+
end

lib/grape/locale/en.yml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,4 +33,6 @@ en:
3333
at_least_one: 'are missing, at least one parameter must be provided'
3434
exactly_one: 'are missing, exactly one parameter must be provided'
3535
all_or_none: 'provide all or none of parameters'
36+
missing_group_type: 'group type is required'
37+
unsupported_group_type: 'group type must be Array or Hash'
3638

lib/grape/validations/params_scope.rb

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,13 @@ def validate_attributes(attrs, opts, &block)
7171
end
7272

7373
def new_scope(attrs, optional = false, &block)
74+
# if required params are grouped and no type or unsupported type is provided, raise an error
75+
type = attrs[1] ? attrs[1][:type] : nil
76+
if attrs.first && !optional
77+
fail Grape::Exceptions::MissingGroupTypeError.new if type.nil?
78+
fail Grape::Exceptions::UnsupportedGroupTypeError.new unless [Array, Hash].include?(type)
79+
end
80+
7481
opts = attrs[1] || { type: Array }
7582
ParamsScope.new(api: @api, element: attrs.first, parent: self, optional: optional, type: opts[:type], &block)
7683
end

spec/grape/api_spec.rb

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2166,11 +2166,11 @@ def static
21662166
it 'groups nested params and prevents overwriting of params with same name in different groups' do
21672167
subject.desc 'method'
21682168
subject.params do
2169-
group :group1 do
2169+
group :group1, type: Array do
21702170
optional :param1, desc: 'group1 param1 desc'
21712171
requires :param2, desc: 'group1 param2 desc'
21722172
end
2173-
group :group2 do
2173+
group :group2, type: Array do
21742174
optional :param1, desc: 'group2 param1 desc'
21752175
requires :param2, desc: 'group2 param2 desc'
21762176
end
@@ -2190,7 +2190,7 @@ def static
21902190
subject.desc 'nesting'
21912191
subject.params do
21922192
requires :root_param, desc: 'root param'
2193-
group :nested do
2193+
group :nested, type: Array do
21942194
requires :nested_param, desc: 'nested param'
21952195
end
21962196
end

spec/grape/validations/params_scope_spec.rb

Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -102,4 +102,80 @@ def app
102102
end
103103
end
104104
end
105+
106+
context 'parameters in group' do
107+
it 'errors when no type is provided' do
108+
expect do
109+
subject.params do
110+
group :a do
111+
requires :b
112+
end
113+
end
114+
end.to raise_error Grape::Exceptions::MissingGroupTypeError
115+
116+
expect do
117+
subject.params do
118+
optional :a do
119+
requires :b
120+
end
121+
end
122+
end.to raise_error Grape::Exceptions::MissingGroupTypeError
123+
end
124+
125+
it 'allows Hash as type' do
126+
subject.params do
127+
group :a, type: Hash do
128+
requires :b
129+
end
130+
end
131+
subject.get('/group') { 'group works' }
132+
get '/group', a: { b: true }
133+
expect(last_response.status).to eq(200)
134+
expect(last_response.body).to eq('group works')
135+
136+
subject.params do
137+
optional :a, type: Hash do
138+
requires :b
139+
end
140+
end
141+
get '/optional_type_hash'
142+
end
143+
144+
it 'allows Array as type' do
145+
subject.params do
146+
group :a, type: Array do
147+
requires :b
148+
end
149+
end
150+
subject.get('/group') { 'group works' }
151+
get '/group', a: [{ b: true }]
152+
expect(last_response.status).to eq(200)
153+
expect(last_response.body).to eq('group works')
154+
155+
subject.params do
156+
optional :a, type: Array do
157+
requires :b
158+
end
159+
end
160+
get '/optional_type_array'
161+
end
162+
163+
it 'errors with an unsupported type' do
164+
expect do
165+
subject.params do
166+
group :a, type: Set do
167+
requires :b
168+
end
169+
end
170+
end.to raise_error Grape::Exceptions::UnsupportedGroupTypeError
171+
172+
expect do
173+
subject.params do
174+
optional :a, type: Set do
175+
requires :b
176+
end
177+
end
178+
end.to raise_error Grape::Exceptions::UnsupportedGroupTypeError
179+
end
180+
end
105181
end

0 commit comments

Comments
 (0)