grape 1.2.5 → 1.3.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +23 -0
- data/README.md +5 -3
- data/UPGRADING.md +43 -0
- data/grape.gemspec +10 -1
- data/lib/grape.rb +2 -2
- data/lib/grape/api.rb +2 -0
- data/lib/grape/api/helpers.rb +2 -0
- data/lib/grape/api/instance.rb +4 -2
- data/lib/grape/config.rb +2 -0
- data/lib/grape/cookies.rb +2 -0
- data/lib/grape/dsl/api.rb +2 -0
- data/lib/grape/dsl/callbacks.rb +2 -0
- data/lib/grape/dsl/configuration.rb +2 -0
- data/lib/grape/dsl/desc.rb +2 -0
- data/lib/grape/dsl/headers.rb +2 -0
- data/lib/grape/dsl/helpers.rb +3 -1
- data/lib/grape/dsl/inside_route.rb +7 -4
- data/lib/grape/dsl/logger.rb +2 -0
- data/lib/grape/dsl/middleware.rb +2 -0
- data/lib/grape/dsl/parameters.rb +4 -2
- data/lib/grape/dsl/request_response.rb +4 -2
- data/lib/grape/dsl/routing.rb +3 -1
- data/lib/grape/dsl/settings.rb +7 -1
- data/lib/grape/dsl/validations.rb +2 -0
- data/lib/grape/eager_load.rb +2 -0
- data/lib/grape/endpoint.rb +13 -7
- data/lib/grape/error_formatter.rb +3 -1
- data/lib/grape/error_formatter/base.rb +2 -0
- data/lib/grape/error_formatter/json.rb +2 -0
- data/lib/grape/error_formatter/txt.rb +2 -0
- data/lib/grape/error_formatter/xml.rb +2 -0
- data/lib/grape/exceptions/base.rb +11 -9
- data/lib/grape/exceptions/incompatible_option_values.rb +2 -0
- data/lib/grape/exceptions/invalid_accept_header.rb +2 -0
- data/lib/grape/exceptions/invalid_formatter.rb +2 -0
- data/lib/grape/exceptions/invalid_message_body.rb +2 -0
- data/lib/grape/exceptions/invalid_response.rb +2 -0
- data/lib/grape/exceptions/invalid_version_header.rb +2 -0
- data/lib/grape/exceptions/invalid_versioner_option.rb +2 -0
- data/lib/grape/exceptions/invalid_with_option_for_represent.rb +2 -0
- data/lib/grape/exceptions/method_not_allowed.rb +2 -0
- data/lib/grape/exceptions/missing_group_type.rb +2 -0
- data/lib/grape/exceptions/missing_mime_type.rb +2 -0
- data/lib/grape/exceptions/missing_option.rb +2 -0
- data/lib/grape/exceptions/missing_vendor_option.rb +2 -0
- data/lib/grape/exceptions/unknown_options.rb +2 -0
- data/lib/grape/exceptions/unknown_parameter.rb +2 -0
- data/lib/grape/exceptions/unknown_validator.rb +2 -0
- data/lib/grape/exceptions/unsupported_group_type.rb +2 -0
- data/lib/grape/exceptions/validation.rb +3 -1
- data/lib/grape/exceptions/validation_array_errors.rb +2 -0
- data/lib/grape/exceptions/validation_errors.rb +2 -0
- data/lib/grape/extensions/active_support/hash_with_indifferent_access.rb +4 -3
- data/lib/grape/extensions/deep_mergeable_hash.rb +2 -0
- data/lib/grape/extensions/deep_symbolize_hash.rb +2 -0
- data/lib/grape/extensions/hash.rb +2 -0
- data/lib/grape/extensions/hashie/mash.rb +2 -0
- data/lib/grape/formatter.rb +5 -3
- data/lib/grape/formatter/json.rb +2 -0
- data/lib/grape/formatter/serializable_hash.rb +2 -0
- data/lib/grape/formatter/txt.rb +2 -0
- data/lib/grape/formatter/xml.rb +2 -0
- data/lib/grape/http/headers.rb +23 -17
- data/lib/grape/middleware/auth/base.rb +2 -0
- data/lib/grape/middleware/auth/dsl.rb +2 -0
- data/lib/grape/middleware/auth/strategies.rb +2 -0
- data/lib/grape/middleware/auth/strategy_info.rb +2 -0
- data/lib/grape/middleware/base.rb +4 -2
- data/lib/grape/middleware/error.rb +3 -1
- data/lib/grape/middleware/filter.rb +2 -0
- data/lib/grape/middleware/formatter.rb +5 -3
- data/lib/grape/middleware/globals.rb +2 -0
- data/lib/grape/middleware/helpers.rb +2 -0
- data/lib/grape/middleware/stack.rb +2 -0
- data/lib/grape/middleware/versioner.rb +2 -0
- data/lib/grape/middleware/versioner/accept_version_header.rb +2 -0
- data/lib/grape/middleware/versioner/header.rb +2 -0
- data/lib/grape/middleware/versioner/param.rb +3 -1
- data/lib/grape/middleware/versioner/parse_media_type_patch.rb +2 -0
- data/lib/grape/middleware/versioner/path.rb +2 -0
- data/lib/grape/namespace.rb +2 -0
- data/lib/grape/parser.rb +3 -1
- data/lib/grape/parser/json.rb +2 -0
- data/lib/grape/parser/xml.rb +2 -0
- data/lib/grape/path.rb +2 -0
- data/lib/grape/presenters/presenter.rb +2 -0
- data/lib/grape/request.rb +3 -1
- data/lib/grape/router.rb +11 -6
- data/lib/grape/router/attribute_translator.rb +18 -8
- data/lib/grape/router/pattern.rb +6 -3
- data/lib/grape/router/route.rb +7 -2
- data/lib/grape/serve_file/file_body.rb +2 -0
- data/lib/grape/serve_file/file_response.rb +2 -0
- data/lib/grape/serve_file/sendfile_response.rb +2 -0
- data/lib/grape/util/base_inheritable.rb +2 -0
- data/lib/grape/util/content_types.rb +2 -0
- data/lib/grape/util/endpoint_configuration.rb +2 -0
- data/lib/grape/util/env.rb +19 -17
- data/lib/grape/util/inheritable_setting.rb +2 -0
- data/lib/grape/util/inheritable_values.rb +2 -0
- data/lib/grape/util/json.rb +2 -0
- data/lib/grape/util/lazy_block.rb +2 -0
- data/lib/grape/util/lazy_value.rb +2 -0
- data/lib/grape/util/registrable.rb +2 -0
- data/lib/grape/util/reverse_stackable_values.rb +2 -0
- data/lib/grape/util/stackable_values.rb +3 -0
- data/lib/grape/util/strict_hash_configuration.rb +2 -0
- data/lib/grape/util/xml.rb +2 -0
- data/lib/grape/validations.rb +2 -0
- data/lib/grape/validations/attributes_iterator.rb +3 -3
- data/lib/grape/validations/multiple_attributes_iterator.rb +2 -0
- data/lib/grape/validations/params_scope.rb +23 -10
- data/lib/grape/validations/single_attribute_iterator.rb +13 -2
- data/lib/grape/validations/types.rb +7 -30
- data/lib/grape/validations/types/array_coercer.rb +56 -0
- data/lib/grape/validations/types/build_coercer.rb +49 -48
- data/lib/grape/validations/types/custom_type_coercer.rb +15 -49
- data/lib/grape/validations/types/custom_type_collection_coercer.rb +10 -25
- data/lib/grape/validations/types/dry_type_coercer.rb +41 -0
- data/lib/grape/validations/types/file.rb +10 -9
- data/lib/grape/validations/types/json.rb +11 -8
- data/lib/grape/validations/types/multiple_type_coercer.rb +14 -33
- data/lib/grape/validations/types/primitive_coercer.rb +58 -0
- data/lib/grape/validations/types/set_coercer.rb +38 -0
- data/lib/grape/validations/types/variant_collection_coercer.rb +4 -12
- data/lib/grape/validations/validator_factory.rb +2 -0
- data/lib/grape/validations/validators/all_or_none.rb +3 -1
- data/lib/grape/validations/validators/allow_blank.rb +3 -1
- data/lib/grape/validations/validators/as.rb +2 -0
- data/lib/grape/validations/validators/at_least_one_of.rb +3 -1
- data/lib/grape/validations/validators/base.rb +8 -5
- data/lib/grape/validations/validators/coerce.rb +43 -26
- data/lib/grape/validations/validators/default.rb +2 -0
- data/lib/grape/validations/validators/exactly_one_of.rb +3 -1
- data/lib/grape/validations/validators/except_values.rb +3 -1
- data/lib/grape/validations/validators/multiple_params_base.rb +2 -0
- data/lib/grape/validations/validators/mutual_exclusion.rb +3 -1
- data/lib/grape/validations/validators/presence.rb +3 -1
- data/lib/grape/validations/validators/regexp.rb +3 -1
- data/lib/grape/validations/validators/same_as.rb +6 -3
- data/lib/grape/validations/validators/values.rb +17 -5
- data/lib/grape/version.rb +3 -1
- data/spec/grape/api/custom_validations_spec.rb +5 -3
- data/spec/grape/api/deeply_included_options_spec.rb +2 -0
- data/spec/grape/api/defines_boolean_in_params_spec.rb +5 -3
- data/spec/grape/api/inherited_helpers_spec.rb +2 -0
- data/spec/grape/api/instance_spec.rb +54 -0
- data/spec/grape/api/invalid_format_spec.rb +2 -0
- data/spec/grape/api/namespace_parameters_in_route_spec.rb +2 -0
- data/spec/grape/api/nested_helpers_spec.rb +2 -0
- data/spec/grape/api/optional_parameters_in_route_spec.rb +2 -0
- data/spec/grape/api/parameters_modification_spec.rb +3 -1
- data/spec/grape/api/patch_method_helpers_spec.rb +2 -0
- data/spec/grape/api/recognize_path_spec.rb +2 -0
- data/spec/grape/api/required_parameters_in_route_spec.rb +2 -0
- data/spec/grape/api/required_parameters_with_invalid_method_spec.rb +2 -0
- data/spec/grape/api/routes_with_requirements_spec.rb +2 -0
- data/spec/grape/api/shared_helpers_exactly_one_of_spec.rb +2 -0
- data/spec/grape/api/shared_helpers_spec.rb +2 -0
- data/spec/grape/api_remount_spec.rb +2 -0
- data/spec/grape/api_spec.rb +27 -5
- data/spec/grape/config_spec.rb +2 -0
- data/spec/grape/dsl/callbacks_spec.rb +2 -0
- data/spec/grape/dsl/configuration_spec.rb +2 -0
- data/spec/grape/dsl/desc_spec.rb +2 -0
- data/spec/grape/dsl/headers_spec.rb +2 -0
- data/spec/grape/dsl/helpers_spec.rb +4 -2
- data/spec/grape/dsl/inside_route_spec.rb +2 -0
- data/spec/grape/dsl/logger_spec.rb +2 -0
- data/spec/grape/dsl/middleware_spec.rb +2 -0
- data/spec/grape/dsl/parameters_spec.rb +2 -0
- data/spec/grape/dsl/request_response_spec.rb +2 -0
- data/spec/grape/dsl/routing_spec.rb +2 -0
- data/spec/grape/dsl/settings_spec.rb +2 -0
- data/spec/grape/dsl/validations_spec.rb +2 -0
- data/spec/grape/endpoint_spec.rb +3 -1
- data/spec/grape/entity_spec.rb +2 -0
- data/spec/grape/exceptions/base_spec.rb +3 -1
- data/spec/grape/exceptions/body_parse_errors_spec.rb +2 -0
- data/spec/grape/exceptions/invalid_accept_header_spec.rb +2 -0
- data/spec/grape/exceptions/invalid_formatter_spec.rb +2 -0
- data/spec/grape/exceptions/invalid_response_spec.rb +2 -0
- data/spec/grape/exceptions/invalid_versioner_option_spec.rb +2 -0
- data/spec/grape/exceptions/missing_mime_type_spec.rb +2 -0
- data/spec/grape/exceptions/missing_option_spec.rb +2 -0
- data/spec/grape/exceptions/unknown_options_spec.rb +2 -0
- data/spec/grape/exceptions/unknown_validator_spec.rb +2 -0
- data/spec/grape/exceptions/validation_errors_spec.rb +2 -0
- data/spec/grape/exceptions/validation_spec.rb +3 -1
- data/spec/grape/extensions/param_builders/hash_spec.rb +2 -0
- data/spec/grape/extensions/param_builders/hash_with_indifferent_access_spec.rb +2 -0
- data/spec/grape/extensions/param_builders/hashie/mash_spec.rb +2 -0
- data/spec/grape/integration/global_namespace_function_spec.rb +2 -0
- data/spec/grape/integration/rack_sendfile_spec.rb +2 -0
- data/spec/grape/integration/rack_spec.rb +3 -1
- data/spec/grape/loading_spec.rb +2 -0
- data/spec/grape/middleware/auth/base_spec.rb +2 -0
- data/spec/grape/middleware/auth/dsl_spec.rb +2 -0
- data/spec/grape/middleware/auth/strategies_spec.rb +2 -0
- data/spec/grape/middleware/base_spec.rb +2 -0
- data/spec/grape/middleware/error_spec.rb +2 -0
- data/spec/grape/middleware/exception_spec.rb +3 -1
- data/spec/grape/middleware/formatter_spec.rb +17 -10
- data/spec/grape/middleware/globals_spec.rb +2 -0
- data/spec/grape/middleware/stack_spec.rb +2 -0
- data/spec/grape/middleware/versioner/accept_version_header_spec.rb +3 -1
- data/spec/grape/middleware/versioner/header_spec.rb +3 -1
- data/spec/grape/middleware/versioner/param_spec.rb +3 -1
- data/spec/grape/middleware/versioner/path_spec.rb +3 -1
- data/spec/grape/middleware/versioner_spec.rb +2 -0
- data/spec/grape/named_api_spec.rb +2 -0
- data/spec/grape/parser_spec.rb +7 -5
- data/spec/grape/path_spec.rb +2 -0
- data/spec/grape/presenters/presenter_spec.rb +2 -0
- data/spec/grape/request_spec.rb +2 -0
- data/spec/grape/util/inheritable_setting_spec.rb +2 -0
- data/spec/grape/util/inheritable_values_spec.rb +2 -0
- data/spec/grape/util/reverse_stackable_values_spec.rb +2 -0
- data/spec/grape/util/stackable_values_spec.rb +3 -1
- data/spec/grape/util/strict_hash_configuration_spec.rb +2 -0
- data/spec/grape/validations/attributes_iterator_spec.rb +2 -0
- data/spec/grape/validations/instance_behaivour_spec.rb +4 -2
- data/spec/grape/validations/multiple_attributes_iterator_spec.rb +2 -0
- data/spec/grape/validations/params_scope_spec.rb +3 -1
- data/spec/grape/validations/single_attribute_iterator_spec.rb +18 -4
- data/spec/grape/validations/types_spec.rb +8 -35
- data/spec/grape/validations/validators/all_or_none_spec.rb +2 -0
- data/spec/grape/validations/validators/allow_blank_spec.rb +2 -0
- data/spec/grape/validations/validators/at_least_one_of_spec.rb +2 -0
- data/spec/grape/validations/validators/coerce_spec.rb +43 -66
- data/spec/grape/validations/validators/default_spec.rb +2 -0
- data/spec/grape/validations/validators/exactly_one_of_spec.rb +2 -0
- data/spec/grape/validations/validators/except_values_spec.rb +3 -1
- data/spec/grape/validations/validators/mutual_exclusion_spec.rb +2 -0
- data/spec/grape/validations/validators/presence_spec.rb +30 -0
- data/spec/grape/validations/validators/regexp_spec.rb +2 -0
- data/spec/grape/validations/validators/same_as_spec.rb +2 -0
- data/spec/grape/validations/validators/values_spec.rb +29 -4
- data/spec/grape/validations_spec.rb +61 -3
- data/spec/integration/multi_json/json_spec.rb +2 -0
- data/spec/integration/multi_xml/xml_spec.rb +2 -0
- data/spec/shared/versioning_examples.rb +2 -0
- data/spec/spec_helper.rb +15 -0
- data/spec/support/basic_auth_encode_helpers.rb +2 -0
- data/spec/support/content_type_helpers.rb +2 -0
- data/spec/support/endpoint_faker.rb +2 -0
- data/spec/support/file_streamer.rb +2 -0
- data/spec/support/integer_helpers.rb +2 -0
- data/spec/support/versioned_helpers.rb +4 -2
- metadata +119 -111
- data/lib/grape/extensions/deep_hash_with_indifferent_access.rb +0 -18
- data/lib/grape/validations/types/virtus_collection_patch.rb +0 -16
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require 'spec_helper'
|
2
4
|
|
3
5
|
describe Grape::Validations::CoerceValidator do
|
@@ -10,11 +12,13 @@ describe Grape::Validations::CoerceValidator do
|
|
10
12
|
end
|
11
13
|
|
12
14
|
describe 'coerce' do
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
15
|
+
class SecureURIOnly
|
16
|
+
def self.parse(value)
|
17
|
+
URI.parse(value)
|
18
|
+
end
|
19
|
+
|
20
|
+
def self.parsed?(value)
|
21
|
+
value.is_a? URI::HTTPS
|
18
22
|
end
|
19
23
|
end
|
20
24
|
|
@@ -96,6 +100,7 @@ describe Grape::Validations::CoerceValidator do
|
|
96
100
|
|
97
101
|
it 'respects :coerce_with' do
|
98
102
|
get '/', a: 'yup'
|
103
|
+
|
99
104
|
expect(last_response.status).to eq(200)
|
100
105
|
expect(last_response.body).to eq('TrueClass')
|
101
106
|
end
|
@@ -148,25 +153,6 @@ describe Grape::Validations::CoerceValidator do
|
|
148
153
|
expect(last_response.body).to eq('array int works')
|
149
154
|
end
|
150
155
|
|
151
|
-
context 'complex objects' do
|
152
|
-
it 'error on malformed input for complex objects' do
|
153
|
-
subject.params do
|
154
|
-
requires :user, type: CoerceValidatorSpec::User
|
155
|
-
end
|
156
|
-
subject.get '/user' do
|
157
|
-
'complex works'
|
158
|
-
end
|
159
|
-
|
160
|
-
get '/user', user: '32'
|
161
|
-
expect(last_response.status).to eq(400)
|
162
|
-
expect(last_response.body).to eq('user is invalid')
|
163
|
-
|
164
|
-
get '/user', user: { id: 32, name: 'Bob' }
|
165
|
-
expect(last_response.status).to eq(200)
|
166
|
-
expect(last_response.body).to eq('complex works')
|
167
|
-
end
|
168
|
-
end
|
169
|
-
|
170
156
|
context 'coerces' do
|
171
157
|
it 'Integer' do
|
172
158
|
subject.params do
|
@@ -181,6 +167,25 @@ describe Grape::Validations::CoerceValidator do
|
|
181
167
|
expect(last_response.body).to eq(integer_class_name)
|
182
168
|
end
|
183
169
|
|
170
|
+
it 'is a custom type' do
|
171
|
+
subject.params do
|
172
|
+
requires :uri, coerce: SecureURIOnly
|
173
|
+
end
|
174
|
+
subject.get '/secure_uri' do
|
175
|
+
params[:uri].class
|
176
|
+
end
|
177
|
+
|
178
|
+
get 'secure_uri', uri: 'https://www.example.com'
|
179
|
+
|
180
|
+
expect(last_response.status).to eq(200)
|
181
|
+
expect(last_response.body).to eq('URI::HTTPS')
|
182
|
+
|
183
|
+
get 'secure_uri', uri: 'http://www.example.com'
|
184
|
+
|
185
|
+
expect(last_response.status).to eq(400)
|
186
|
+
expect(last_response.body).to eq('uri is invalid')
|
187
|
+
end
|
188
|
+
|
184
189
|
context 'Array' do
|
185
190
|
it 'Array of Integers' do
|
186
191
|
subject.params do
|
@@ -197,7 +202,7 @@ describe Grape::Validations::CoerceValidator do
|
|
197
202
|
|
198
203
|
it 'Array of Bools' do
|
199
204
|
subject.params do
|
200
|
-
requires :arry, coerce: Array[
|
205
|
+
requires :arry, coerce: Array[Grape::API::Boolean]
|
201
206
|
end
|
202
207
|
subject.get '/array' do
|
203
208
|
params[:arry][0].class
|
@@ -208,27 +213,6 @@ describe Grape::Validations::CoerceValidator do
|
|
208
213
|
expect(last_response.body).to eq('TrueClass')
|
209
214
|
end
|
210
215
|
|
211
|
-
it 'Array of Complex' do
|
212
|
-
subject.params do
|
213
|
-
requires :arry, coerce: Array[CoerceValidatorSpec::User]
|
214
|
-
end
|
215
|
-
subject.get '/array' do
|
216
|
-
params[:arry].size
|
217
|
-
end
|
218
|
-
|
219
|
-
get 'array', arry: [31]
|
220
|
-
expect(last_response.status).to eq(400)
|
221
|
-
expect(last_response.body).to eq('arry is invalid')
|
222
|
-
|
223
|
-
get 'array', arry: { id: 31, name: 'Alice' }
|
224
|
-
expect(last_response.status).to eq(400)
|
225
|
-
expect(last_response.body).to eq('arry is invalid')
|
226
|
-
|
227
|
-
get 'array', arry: [{ id: 31, name: 'Alice' }]
|
228
|
-
expect(last_response.status).to eq(200)
|
229
|
-
expect(last_response.body).to eq('1')
|
230
|
-
end
|
231
|
-
|
232
216
|
it 'Array of type implementing parse' do
|
233
217
|
subject.params do
|
234
218
|
requires :uri, type: Array[URI]
|
@@ -253,17 +237,7 @@ describe Grape::Validations::CoerceValidator do
|
|
253
237
|
expect(last_response.body).to eq('Set,URI::HTTP,1')
|
254
238
|
end
|
255
239
|
|
256
|
-
it 'Array of
|
257
|
-
class SecureURIOnly
|
258
|
-
def self.parse(value)
|
259
|
-
URI.parse(value)
|
260
|
-
end
|
261
|
-
|
262
|
-
def self.parsed?(value)
|
263
|
-
value.is_a? URI::HTTPS
|
264
|
-
end
|
265
|
-
end
|
266
|
-
|
240
|
+
it 'Array of a custom type' do
|
267
241
|
subject.params do
|
268
242
|
requires :uri, type: Array[SecureURIOnly]
|
269
243
|
end
|
@@ -295,7 +269,7 @@ describe Grape::Validations::CoerceValidator do
|
|
295
269
|
|
296
270
|
it 'Set of Bools' do
|
297
271
|
subject.params do
|
298
|
-
requires :set, coerce: Set[
|
272
|
+
requires :set, coerce: Set[Grape::API::Boolean]
|
299
273
|
end
|
300
274
|
subject.get '/set' do
|
301
275
|
params[:set].first.class
|
@@ -309,7 +283,7 @@ describe Grape::Validations::CoerceValidator do
|
|
309
283
|
|
310
284
|
it 'Bool' do
|
311
285
|
subject.params do
|
312
|
-
requires :bool, coerce:
|
286
|
+
requires :bool, coerce: Grape::API::Boolean
|
313
287
|
end
|
314
288
|
subject.get '/bool' do
|
315
289
|
params[:bool].class
|
@@ -443,19 +417,19 @@ describe Grape::Validations::CoerceValidator do
|
|
443
417
|
|
444
418
|
it 'parses parameters with Array[String] type' do
|
445
419
|
subject.params do
|
446
|
-
requires :values, type: Array[String], coerce_with: ->(val) { val.split(/\s+/)
|
420
|
+
requires :values, type: Array[String], coerce_with: ->(val) { val.split(/\s+/) }
|
447
421
|
end
|
448
|
-
subject.get '/
|
422
|
+
subject.get '/strings' do
|
449
423
|
params[:values]
|
450
424
|
end
|
451
425
|
|
452
|
-
get '/
|
426
|
+
get '/strings', values: '1 2 3 4'
|
453
427
|
expect(last_response.status).to eq(200)
|
454
428
|
expect(JSON.parse(last_response.body)).to eq(%w[1 2 3 4])
|
455
429
|
|
456
|
-
get '/
|
430
|
+
get '/strings', values: 'a b c d'
|
457
431
|
expect(last_response.status).to eq(200)
|
458
|
-
expect(JSON.parse(last_response.body)).to eq(%w[
|
432
|
+
expect(JSON.parse(last_response.body)).to eq(%w[a b c d])
|
459
433
|
end
|
460
434
|
|
461
435
|
it 'parses parameters with Array[Integer] type' do
|
@@ -914,14 +888,17 @@ describe Grape::Validations::CoerceValidator do
|
|
914
888
|
end
|
915
889
|
|
916
890
|
context 'converter' do
|
917
|
-
it 'does not build
|
891
|
+
it 'does not build a coercer multiple times' do
|
918
892
|
subject.params do
|
919
893
|
requires :something, type: Array[String]
|
920
894
|
end
|
921
895
|
subject.get do
|
922
896
|
end
|
923
897
|
|
924
|
-
expect(
|
898
|
+
expect(Grape::Validations::Types::ArrayCoercer).to(
|
899
|
+
receive(:new).at_most(:once).and_call_original
|
900
|
+
)
|
901
|
+
|
925
902
|
10.times { get '/' }
|
926
903
|
end
|
927
904
|
end
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require 'spec_helper'
|
2
4
|
|
3
5
|
describe Grape::Validations::ExceptValuesValidator do
|
@@ -110,7 +112,7 @@ describe Grape::Validations::ExceptValuesValidator do
|
|
110
112
|
optional: { type: Array[Integer], except_values: [10, 11], default: 12 },
|
111
113
|
tests: [
|
112
114
|
{ value: 'invalid-type1', rc: 400, body: { error: 'type is invalid' }.to_json },
|
113
|
-
{ value: 10, rc: 400, body: { error: 'type
|
115
|
+
{ value: 10, rc: 400, body: { error: 'type is invalid' }.to_json },
|
114
116
|
{ value: [10], rc: 400, body: { error: 'type has a value not allowed' }.to_json },
|
115
117
|
{ value: ['3'], rc: 200, body: { type: [3] }.to_json },
|
116
118
|
{ value: [3], rc: 200, body: { type: [3] }.to_json },
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require 'spec_helper'
|
2
4
|
|
3
5
|
describe Grape::Validations::PresenceValidator do
|
@@ -269,4 +271,32 @@ describe Grape::Validations::PresenceValidator do
|
|
269
271
|
expect(last_response.body).to eq('Hello optional'.to_json)
|
270
272
|
end
|
271
273
|
end
|
274
|
+
|
275
|
+
context 'with a custom type' do
|
276
|
+
it 'does not validate their type when it is missing' do
|
277
|
+
class CustomType
|
278
|
+
def self.parse(value)
|
279
|
+
return if value.blank?
|
280
|
+
|
281
|
+
new
|
282
|
+
end
|
283
|
+
end
|
284
|
+
|
285
|
+
subject.params do
|
286
|
+
requires :custom, type: CustomType
|
287
|
+
end
|
288
|
+
subject.get '/custom' do
|
289
|
+
'custom'
|
290
|
+
end
|
291
|
+
|
292
|
+
get 'custom'
|
293
|
+
|
294
|
+
expect(last_response.status).to eq(400)
|
295
|
+
expect(last_response.body).to eq('{"error":"custom is missing"}')
|
296
|
+
|
297
|
+
get 'custom', custom: 'filled'
|
298
|
+
|
299
|
+
expect(last_response.status).to eq(200)
|
300
|
+
end
|
301
|
+
end
|
272
302
|
end
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require 'spec_helper'
|
2
4
|
|
3
5
|
describe Grape::Validations::ValuesValidator do
|
@@ -222,6 +224,11 @@ describe Grape::Validations::ValuesValidator do
|
|
222
224
|
requires :type, values: { proc: ->(v) { ValuesModel.values.include? v }, message: 'failed check' }
|
223
225
|
end
|
224
226
|
get '/proc/message'
|
227
|
+
|
228
|
+
params do
|
229
|
+
optional :name, type: String, values: %w[a b], allow_blank: true
|
230
|
+
end
|
231
|
+
get '/allow_blank'
|
225
232
|
end
|
226
233
|
end
|
227
234
|
end
|
@@ -431,11 +438,21 @@ describe Grape::Validations::ValuesValidator do
|
|
431
438
|
end.to raise_error Grape::Exceptions::IncompatibleOptionValues
|
432
439
|
end
|
433
440
|
|
434
|
-
|
435
|
-
|
436
|
-
|
437
|
-
|
441
|
+
context 'boolean values' do
|
442
|
+
it 'allows a value from the list' do
|
443
|
+
get('/values/optional_boolean', type: true)
|
444
|
+
|
445
|
+
expect(last_response.status).to eq 200
|
446
|
+
expect(last_response.body).to eq({ type: true }.to_json)
|
447
|
+
end
|
448
|
+
|
449
|
+
it 'rejects a value which is not in the list' do
|
450
|
+
get('/values/optional_boolean', type: false)
|
451
|
+
|
452
|
+
expect(last_response.body).to eq({ error: 'type does not have a valid value' }.to_json)
|
453
|
+
end
|
438
454
|
end
|
455
|
+
|
439
456
|
it 'allows values to be a kind of the coerced type not just an instance of it' do
|
440
457
|
get('/values/coercion', type: 10)
|
441
458
|
expect(last_response.status).to eq 200
|
@@ -462,6 +479,14 @@ describe Grape::Validations::ValuesValidator do
|
|
462
479
|
end.to raise_error Grape::Exceptions::IncompatibleOptionValues
|
463
480
|
end
|
464
481
|
|
482
|
+
it 'allows a blank value when the allow_blank option is true' do
|
483
|
+
get 'allow_blank', name: nil
|
484
|
+
expect(last_response.status).to eq(200)
|
485
|
+
|
486
|
+
get 'allow_blank', name: ''
|
487
|
+
expect(last_response.status).to eq(200)
|
488
|
+
end
|
489
|
+
|
465
490
|
context 'with a lambda values' do
|
466
491
|
subject do
|
467
492
|
Class.new(Grape::API) do
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require 'spec_helper'
|
2
4
|
|
3
5
|
describe Grape::Validations do
|
@@ -120,6 +122,62 @@ describe Grape::Validations do
|
|
120
122
|
end
|
121
123
|
end
|
122
124
|
|
125
|
+
context 'requires with nested params' do
|
126
|
+
before do
|
127
|
+
subject.params do
|
128
|
+
requires :first_level, type: Hash do
|
129
|
+
optional :second_level, type: Array do
|
130
|
+
requires :value, type: Integer
|
131
|
+
optional :name, type: String
|
132
|
+
optional :third_level, type: Array do
|
133
|
+
requires :value, type: Integer
|
134
|
+
optional :name, type: String
|
135
|
+
optional :fourth_level, type: Array do
|
136
|
+
requires :value, type: Integer
|
137
|
+
optional :name, type: String
|
138
|
+
end
|
139
|
+
end
|
140
|
+
end
|
141
|
+
end
|
142
|
+
end
|
143
|
+
subject.put('/required') { 'required works' }
|
144
|
+
end
|
145
|
+
|
146
|
+
let(:request_params) do
|
147
|
+
{
|
148
|
+
first_level: {
|
149
|
+
second_level: [
|
150
|
+
{ value: 1, name: 'Lisa' },
|
151
|
+
{
|
152
|
+
value: 2,
|
153
|
+
name: 'James',
|
154
|
+
third_level: [
|
155
|
+
{ value: 'three', name: 'Sophie' },
|
156
|
+
{
|
157
|
+
value: 4,
|
158
|
+
name: 'Jenny',
|
159
|
+
fourth_level: [
|
160
|
+
{ name: 'Samuel' }, { value: 6, name: 'Jane' }
|
161
|
+
]
|
162
|
+
}
|
163
|
+
]
|
164
|
+
}
|
165
|
+
]
|
166
|
+
}
|
167
|
+
}
|
168
|
+
end
|
169
|
+
|
170
|
+
it 'validates correctly in deep nested params' do
|
171
|
+
put '/required', request_params.to_json, 'CONTENT_TYPE' => 'application/json'
|
172
|
+
|
173
|
+
expect(last_response.status).to eq(400)
|
174
|
+
expect(last_response.body).to eq(
|
175
|
+
'first_level[second_level][1][third_level][0][value] is invalid, ' \
|
176
|
+
'first_level[second_level][1][third_level][1][fourth_level][0][value] is missing'
|
177
|
+
)
|
178
|
+
end
|
179
|
+
end
|
180
|
+
|
123
181
|
context 'requires :all using Grape::Entity documentation' do
|
124
182
|
def define_requires_all
|
125
183
|
documentation = {
|
@@ -436,7 +494,7 @@ describe Grape::Validations do
|
|
436
494
|
class DateRangeValidator < Grape::Validations::Base
|
437
495
|
def validate_param!(attr_name, params)
|
438
496
|
return if params[attr_name][:from] <= params[attr_name][:to]
|
439
|
-
raise Grape::Exceptions::Validation
|
497
|
+
raise Grape::Exceptions::Validation.new(params: [@scope.full_name(attr_name)], message: "'from' must be lower or equal to 'to'")
|
440
498
|
end
|
441
499
|
end
|
442
500
|
end
|
@@ -851,7 +909,7 @@ describe Grape::Validations do
|
|
851
909
|
class Customvalidator < Grape::Validations::Base
|
852
910
|
def validate_param!(attr_name, params)
|
853
911
|
return if params[attr_name] == 'im custom'
|
854
|
-
raise Grape::Exceptions::Validation
|
912
|
+
raise Grape::Exceptions::Validation.new(params: [@scope.full_name(attr_name)], message: 'is not custom!')
|
855
913
|
end
|
856
914
|
end
|
857
915
|
end
|
@@ -999,7 +1057,7 @@ describe Grape::Validations do
|
|
999
1057
|
class CustomvalidatorWithOptions < Grape::Validations::Base
|
1000
1058
|
def validate_param!(attr_name, params)
|
1001
1059
|
return if params[attr_name] == @option[:text]
|
1002
|
-
raise Grape::Exceptions::Validation
|
1060
|
+
raise Grape::Exceptions::Validation.new(params: [@scope.full_name(attr_name)], message: message)
|
1003
1061
|
end
|
1004
1062
|
end
|
1005
1063
|
end
|