Skip to content

Commit c4e94a4

Browse files
committed
Added DateTime/Date/Numeric/Boolean type support allow_blank
1 parent ccc544b commit c4e94a4

File tree

3 files changed

+107
-1
lines changed

3 files changed

+107
-1
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
Next Release
22
============
33

4+
* [#916](https://github.com/intridea/grape/pull/916): Added `DateTime/Date/Numeric/Boolean` type support `allow_blank` - [@u2](https://github.com/u2).
45
* [#871](https://github.com/intridea/grape/pull/871): Fixed `Grape::Middleware::Base#response` - [@galathius](https://github.com/galathius).
56
* [#559](https://github.com/intridea/grape/issues/559): Added support for Rack 1.6.0, which parses requests larger than 128KB - [@myitcv](https://github.com/myitcv).
67
* [#876](https://github.com/intridea/grape/pull/876): Call to `declared(params)` now returns a `Hashie::Mash` - [@rodzyn](https://github.com/rodzyn).

lib/grape/validations/validators/coerce.rb

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,9 +29,12 @@ def _valid_single_type?(klass, val)
2929
# allow nil, to ignore when a parameter is absent
3030
return true if val.nil?
3131
if klass == Virtus::Attribute::Boolean
32-
val.is_a?(TrueClass) || val.is_a?(FalseClass)
32+
val.is_a?(TrueClass) || val.is_a?(FalseClass) || (val.is_a?(String) && val.empty?)
3333
elsif klass == Rack::Multipart::UploadedFile
3434
val.is_a?(Hashie::Mash) && val.key?(:tempfile)
35+
elsif [Virtus::Attribute::DateTime, Virtus::Attribute::Date, Virtus::Attribute::Numeric].any?{ |vclass| vclass >= klass }
36+
return true if val.is_a?(String) && val.empty?
37+
val.is_a?(klass)
3538
else
3639
val.is_a?(klass)
3740
end

spec/grape/validations/validators/allow_blank_spec.rb

Lines changed: 102 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,13 +21,65 @@ class API < Grape::API
2121
end
2222
get '/allow_blank'
2323

24+
params do
25+
requires :val, type: DateTime, allow_blank: true
26+
end
27+
get '/allow_datetime_blank'
28+
29+
params do
30+
requires :val, type: DateTime, allow_blank: false
31+
end
32+
get '/disallow_datetime_blank'
33+
34+
params do
35+
requires :val, type: DateTime
36+
end
37+
get '/default_allow_datetime_blank'
38+
39+
params do
40+
requires :val, type: Date, allow_blank: true
41+
end
42+
get '/allow_date_blank'
43+
44+
params do
45+
requires :val, type: Integer, allow_blank: true
46+
end
47+
get '/allow_integer_blank'
48+
49+
params do
50+
requires :val, type: Float, allow_blank: true
51+
end
52+
get '/allow_float_blank'
53+
54+
params do
55+
requires :val, type: Fixnum, allow_blank: true
56+
end
57+
get '/allow_fixnum_blank'
58+
59+
params do
60+
requires :val, type: Symbol, allow_blank: true
61+
end
62+
get '/allow_symbol_blank'
63+
64+
params do
65+
requires :val, type: Boolean, allow_blank: true
66+
end
67+
get '/allow_boolean_blank'
68+
2469
params do
2570
optional :user, type: Hash do
2671
requires :name, allow_blank: false
2772
end
2873
end
2974
get '/disallow_blank_required_param_in_an_optional_group'
3075

76+
params do
77+
optional :user, type: Hash do
78+
requires :name, type: Date, allow_blank: true
79+
end
80+
end
81+
get '/allow_blank_date_param_in_an_optional_group'
82+
3183
params do
3284
optional :user, type: Hash do
3385
optional :name, allow_blank: false
@@ -75,6 +127,9 @@ def app
75127
it 'refuses empty string' do
76128
get '/', name: ''
77129
expect(last_response.status).to eq(400)
130+
131+
get '/disallow_datetime_blank', val: ''
132+
expect(last_response.status).to eq(400)
78133
end
79134

80135
it 'refuses only whitespaces' do
@@ -104,6 +159,48 @@ def app
104159
get '/allow_blank', name: ''
105160
expect(last_response.status).to eq(200)
106161
end
162+
163+
it 'accepts empty input' do
164+
get '/default_allow_datetime_blank', val: ''
165+
expect(last_response.status).to eq(200)
166+
end
167+
168+
it 'accepts empty when datetime allow_blank' do
169+
get '/allow_datetime_blank', val: ''
170+
expect(last_response.status).to eq(200)
171+
end
172+
173+
it 'accepts empty when date allow_blank' do
174+
get '/allow_date_blank', val: ''
175+
expect(last_response.status).to eq(200)
176+
end
177+
178+
context 'allow_blank when Numeric' do
179+
it 'accepts empty when integer allow_blank' do
180+
get '/allow_integer_blank', val: ''
181+
expect(last_response.status).to eq(200)
182+
end
183+
184+
it 'accepts empty when float allow_blank' do
185+
get '/allow_float_blank', val: ''
186+
expect(last_response.status).to eq(200)
187+
end
188+
189+
it 'accepts empty when fixnum allow_blank' do
190+
get '/allow_fixnum_blank', val: ''
191+
expect(last_response.status).to eq(200)
192+
end
193+
end
194+
195+
it 'accepts empty when symbol allow_blank' do
196+
get '/allow_symbol_blank', val: ''
197+
expect(last_response.status).to eq(200)
198+
end
199+
200+
it 'accepts empty when boolean allow_blank' do
201+
get '/allow_boolean_blank', val: ''
202+
expect(last_response.status).to eq(200)
203+
end
107204
end
108205

109206
context 'in an optional group' do
@@ -113,6 +210,11 @@ def app
113210
expect(last_response.status).to eq(200)
114211
end
115212

213+
it 'accepts a nested missing date value' do
214+
get '/allow_blank_date_param_in_an_optional_group', user: { name: '' }
215+
expect(last_response.status).to eq(200)
216+
end
217+
116218
it 'refuses a blank value in an existing group' do
117219
get '/disallow_blank_required_param_in_an_optional_group', user: { name: '' }
118220
expect(last_response.status).to eq(400)

0 commit comments

Comments
 (0)