grape 1.1.0 → 1.5.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +278 -44
- data/LICENSE +1 -1
- data/README.md +514 -69
- data/UPGRADING.md +424 -17
- data/grape.gemspec +13 -2
- data/lib/grape.rb +104 -71
- data/lib/grape/api.rb +138 -175
- data/lib/grape/api/helpers.rb +2 -0
- data/lib/grape/api/instance.rb +283 -0
- data/lib/grape/config.rb +34 -0
- data/lib/grape/content_types.rb +34 -0
- data/lib/grape/cookies.rb +2 -0
- data/lib/grape/dsl/api.rb +2 -0
- data/lib/grape/dsl/callbacks.rb +22 -0
- data/lib/grape/dsl/configuration.rb +2 -0
- data/lib/grape/dsl/desc.rb +41 -7
- data/lib/grape/dsl/headers.rb +2 -0
- data/lib/grape/dsl/helpers.rb +5 -2
- data/lib/grape/dsl/inside_route.rb +92 -49
- data/lib/grape/dsl/logger.rb +2 -0
- data/lib/grape/dsl/middleware.rb +9 -0
- data/lib/grape/dsl/parameters.rb +25 -14
- data/lib/grape/dsl/request_response.rb +4 -2
- data/lib/grape/dsl/routing.rb +17 -10
- data/lib/grape/dsl/settings.rb +7 -1
- data/lib/grape/dsl/validations.rb +24 -4
- data/lib/grape/eager_load.rb +20 -0
- data/lib/grape/endpoint.rb +59 -35
- data/lib/grape/error_formatter.rb +4 -2
- 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 +20 -14
- data/lib/grape/exceptions/empty_message_body.rb +11 -0
- 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 +11 -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 +4 -2
- data/lib/grape/exceptions/validation_array_errors.rb +2 -0
- data/lib/grape/exceptions/validation_errors.rb +16 -13
- 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 +50 -18
- data/lib/grape/locale/en.yml +3 -1
- data/lib/grape/middleware/auth/base.rb +7 -7
- 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 +10 -7
- data/lib/grape/middleware/error.rb +21 -16
- data/lib/grape/middleware/filter.rb +2 -0
- data/lib/grape/middleware/formatter.rb +8 -6
- data/lib/grape/middleware/globals.rb +2 -0
- data/lib/grape/middleware/helpers.rb +12 -0
- data/lib/grape/middleware/stack.rb +13 -3
- 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 +10 -8
- data/lib/grape/middleware/versioner/param.rb +3 -1
- data/lib/grape/middleware/versioner/parse_media_type_patch.rb +4 -1
- data/lib/grape/middleware/versioner/path.rb +3 -1
- data/lib/grape/namespace.rb +14 -2
- data/lib/grape/parser.rb +4 -2
- data/lib/grape/parser/json.rb +3 -1
- data/lib/grape/parser/xml.rb +3 -1
- data/lib/grape/path.rb +15 -3
- data/lib/grape/presenters/presenter.rb +2 -0
- data/lib/grape/request.rb +19 -10
- data/lib/grape/router.rb +30 -29
- data/lib/grape/router/attribute_translator.rb +41 -8
- data/lib/grape/router/pattern.rb +20 -16
- data/lib/grape/router/route.rb +14 -28
- data/lib/grape/{serve_file → serve_stream}/file_body.rb +3 -1
- data/lib/grape/{serve_file → serve_stream}/sendfile_response.rb +3 -1
- data/lib/grape/{serve_file/file_response.rb → serve_stream/stream_response.rb} +10 -8
- data/lib/grape/util/base_inheritable.rb +43 -0
- data/lib/grape/util/cache.rb +20 -0
- data/lib/grape/util/endpoint_configuration.rb +8 -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 +7 -25
- data/lib/grape/util/json.rb +2 -0
- data/lib/grape/util/lazy_block.rb +27 -0
- data/lib/grape/util/lazy_object.rb +43 -0
- data/lib/grape/util/lazy_value.rb +98 -0
- data/lib/grape/util/registrable.rb +2 -0
- data/lib/grape/util/reverse_stackable_values.rb +10 -35
- data/lib/grape/util/stackable_values.rb +21 -34
- 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 +16 -6
- data/lib/grape/validations/multiple_attributes_iterator.rb +13 -0
- data/lib/grape/validations/params_scope.rb +51 -30
- data/lib/grape/validations/single_attribute_iterator.rb +24 -0
- data/lib/grape/validations/types.rb +13 -38
- data/lib/grape/validations/types/array_coercer.rb +65 -0
- data/lib/grape/validations/types/build_coercer.rb +47 -49
- data/lib/grape/validations/types/custom_type_coercer.rb +29 -51
- data/lib/grape/validations/types/custom_type_collection_coercer.rb +10 -25
- data/lib/grape/validations/types/dry_type_coercer.rb +76 -0
- data/lib/grape/validations/types/file.rb +22 -18
- data/lib/grape/validations/types/invalid_value.rb +24 -0
- data/lib/grape/validations/types/json.rb +46 -39
- data/lib/grape/validations/types/multiple_type_coercer.rb +14 -33
- data/lib/grape/validations/types/primitive_coercer.rb +67 -0
- data/lib/grape/validations/types/set_coercer.rb +40 -0
- data/lib/grape/validations/types/variant_collection_coercer.rb +5 -13
- data/lib/grape/validations/validator_factory.rb +8 -11
- data/lib/grape/validations/validators/all_or_none.rb +8 -13
- data/lib/grape/validations/validators/allow_blank.rb +3 -1
- data/lib/grape/validations/validators/as.rb +5 -4
- data/lib/grape/validations/validators/at_least_one_of.rb +7 -13
- data/lib/grape/validations/validators/base.rb +20 -16
- data/lib/grape/validations/validators/coerce.rb +46 -29
- data/lib/grape/validations/validators/default.rb +6 -6
- data/lib/grape/validations/validators/exactly_one_of.rb +10 -23
- data/lib/grape/validations/validators/except_values.rb +4 -2
- data/lib/grape/validations/validators/multiple_params_base.rb +17 -10
- data/lib/grape/validations/validators/mutual_exclusion.rb +8 -18
- data/lib/grape/validations/validators/presence.rb +3 -1
- data/lib/grape/validations/validators/regexp.rb +4 -2
- data/lib/grape/validations/validators/same_as.rb +26 -0
- data/lib/grape/validations/validators/values.rb +18 -6
- 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 +39 -0
- data/spec/grape/api/inherited_helpers_spec.rb +2 -0
- data/spec/grape/api/instance_spec.rb +104 -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 +61 -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 +473 -0
- data/spec/grape/api_spec.rb +565 -12
- data/spec/grape/config_spec.rb +19 -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 +42 -16
- 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 +184 -33
- data/spec/grape/dsl/logger_spec.rb +2 -0
- data/spec/grape/dsl/middleware_spec.rb +10 -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 +12 -0
- data/spec/grape/dsl/settings_spec.rb +2 -0
- data/spec/grape/dsl/validations_spec.rb +2 -0
- data/spec/grape/endpoint/declared_spec.rb +601 -0
- data/spec/grape/endpoint_spec.rb +53 -523
- data/spec/grape/entity_spec.rb +9 -1
- data/spec/grape/exceptions/base_spec.rb +67 -0
- 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 +13 -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 +8 -4
- 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 +14 -8
- data/spec/grape/integration/rack_spec.rb +25 -7
- 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 +5 -3
- data/spec/grape/middleware/auth/strategies_spec.rb +3 -1
- data/spec/grape/middleware/base_spec.rb +10 -0
- data/spec/grape/middleware/error_spec.rb +3 -1
- data/spec/grape/middleware/exception_spec.rb +4 -2
- data/spec/grape/middleware/formatter_spec.rb +33 -16
- data/spec/grape/middleware/globals_spec.rb +2 -0
- data/spec/grape/middleware/stack_spec.rb +12 -0
- data/spec/grape/middleware/versioner/accept_version_header_spec.rb +3 -1
- data/spec/grape/middleware/versioner/header_spec.rb +9 -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 +21 -0
- data/spec/grape/parser_spec.rb +7 -5
- data/spec/grape/path_spec.rb +6 -4
- data/spec/grape/presenters/presenter_spec.rb +2 -0
- data/spec/grape/request_spec.rb +26 -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 +5 -3
- data/spec/grape/validations/multiple_attributes_iterator_spec.rb +41 -0
- data/spec/grape/validations/params_scope_spec.rb +213 -9
- data/spec/grape/validations/single_attribute_iterator_spec.rb +58 -0
- data/spec/grape/validations/types/array_coercer_spec.rb +35 -0
- data/spec/grape/validations/types/primitive_coercer_spec.rb +135 -0
- data/spec/grape/validations/types/set_coercer_spec.rb +34 -0
- data/spec/grape/validations/types_spec.rb +9 -36
- data/spec/grape/validations/validators/all_or_none_spec.rb +140 -30
- data/spec/grape/validations/validators/allow_blank_spec.rb +2 -0
- data/spec/grape/validations/validators/at_least_one_of_spec.rb +175 -29
- data/spec/grape/validations/validators/coerce_spec.rb +476 -135
- data/spec/grape/validations/validators/default_spec.rb +172 -0
- data/spec/grape/validations/validators/exactly_one_of_spec.rb +204 -38
- data/spec/grape/validations/validators/except_values_spec.rb +4 -1
- data/spec/grape/validations/validators/mutual_exclusion_spec.rb +186 -27
- 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 +65 -0
- data/spec/grape/validations/validators/values_spec.rb +30 -5
- data/spec/grape/validations_spec.rb +388 -50
- data/spec/integration/eager_load/eager_load_spec.rb +15 -0
- 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 +22 -20
- data/spec/spec_helper.rb +12 -1
- data/spec/support/basic_auth_encode_helpers.rb +2 -0
- data/spec/support/chunks.rb +14 -0
- data/spec/support/content_type_helpers.rb +2 -0
- data/spec/support/eager_load.rb +19 -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 +8 -8
- metadata +86 -48
- data/Appraisals +0 -32
- data/Dangerfile +0 -2
- data/Gemfile +0 -33
- data/Gemfile.lock +0 -231
- data/Guardfile +0 -10
- data/RELEASING.md +0 -111
- data/Rakefile +0 -25
- data/benchmark/simple.rb +0 -27
- data/benchmark/simple_with_type_coercer.rb +0 -22
- data/gemfiles/multi_json.gemfile +0 -35
- data/gemfiles/multi_xml.gemfile +0 -35
- data/gemfiles/rack_1.5.2.gemfile +0 -35
- data/gemfiles/rack_edge.gemfile +0 -35
- data/gemfiles/rails_3.gemfile +0 -36
- data/gemfiles/rails_4.gemfile +0 -35
- data/gemfiles/rails_5.gemfile +0 -35
- data/gemfiles/rails_edge.gemfile +0 -35
- data/lib/grape/extensions/deep_hash_with_indifferent_access.rb +0 -18
- data/lib/grape/util/content_types.rb +0 -26
- data/lib/grape/validations/types/virtus_collection_patch.rb +0 -16
- data/pkg/grape-0.17.0.gem +0 -0
- data/pkg/grape-0.19.0.gem +0 -0
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require 'spec_helper'
|
2
4
|
|
3
5
|
describe Grape::Validations::ExceptValuesValidator do
|
@@ -6,6 +8,7 @@ describe Grape::Validations::ExceptValuesValidator do
|
|
6
8
|
DEFAULT_EXCEPTS = ['invalid-type1', 'invalid-type2', 'invalid-type3'].freeze
|
7
9
|
class << self
|
8
10
|
attr_accessor :excepts
|
11
|
+
|
9
12
|
def excepts
|
10
13
|
@excepts ||= []
|
11
14
|
[DEFAULT_EXCEPTS + @excepts].flatten.uniq
|
@@ -110,7 +113,7 @@ describe Grape::Validations::ExceptValuesValidator do
|
|
110
113
|
optional: { type: Array[Integer], except_values: [10, 11], default: 12 },
|
111
114
|
tests: [
|
112
115
|
{ value: 'invalid-type1', rc: 400, body: { error: 'type is invalid' }.to_json },
|
113
|
-
{ value: 10, rc: 400, body: { error: 'type
|
116
|
+
{ value: 10, rc: 400, body: { error: 'type is invalid' }.to_json },
|
114
117
|
{ value: [10], rc: 400, body: { error: 'type has a value not allowed' }.to_json },
|
115
118
|
{ value: ['3'], rc: 200, body: { type: [3] }.to_json },
|
116
119
|
{ value: [3], rc: 200, body: { type: [3] }.to_json },
|
@@ -1,62 +1,221 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require 'spec_helper'
|
2
4
|
|
3
5
|
describe Grape::Validations::MutualExclusionValidator do
|
4
6
|
describe '#validate!' do
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
7
|
+
subject(:validate) { post path, params }
|
8
|
+
|
9
|
+
module ValidationsSpec
|
10
|
+
module MutualExclusionValidatorSpec
|
11
|
+
class API < Grape::API
|
12
|
+
rescue_from Grape::Exceptions::ValidationErrors do |e|
|
13
|
+
error!(e.errors.transform_keys! { |key| key.join(',') }, 400)
|
14
|
+
end
|
15
|
+
|
16
|
+
params do
|
17
|
+
optional :beer
|
18
|
+
optional :wine
|
19
|
+
optional :grapefruit
|
20
|
+
mutually_exclusive :beer, :wine, :grapefruit
|
21
|
+
end
|
22
|
+
post do
|
23
|
+
end
|
24
|
+
|
25
|
+
params do
|
26
|
+
optional :beer
|
27
|
+
optional :wine
|
28
|
+
optional :grapefruit
|
29
|
+
optional :other
|
30
|
+
mutually_exclusive :beer, :wine, :grapefruit
|
31
|
+
end
|
32
|
+
post 'mixed-params' do
|
33
|
+
end
|
34
|
+
|
35
|
+
params do
|
36
|
+
optional :beer
|
37
|
+
optional :wine
|
38
|
+
optional :grapefruit
|
39
|
+
mutually_exclusive :beer, :wine, :grapefruit, message: 'you should not mix beer and wine'
|
40
|
+
end
|
41
|
+
post '/custom-message' do
|
42
|
+
end
|
43
|
+
|
44
|
+
params do
|
45
|
+
requires :item, type: Hash do
|
46
|
+
optional :beer
|
47
|
+
optional :wine
|
48
|
+
optional :grapefruit
|
49
|
+
mutually_exclusive :beer, :wine, :grapefruit
|
50
|
+
end
|
51
|
+
end
|
52
|
+
post '/nested-hash' do
|
53
|
+
end
|
54
|
+
|
55
|
+
params do
|
56
|
+
optional :item, type: Hash do
|
57
|
+
optional :beer
|
58
|
+
optional :wine
|
59
|
+
optional :grapefruit
|
60
|
+
mutually_exclusive :beer, :wine, :grapefruit
|
61
|
+
end
|
62
|
+
end
|
63
|
+
post '/nested-optional-hash' do
|
64
|
+
end
|
65
|
+
|
66
|
+
params do
|
67
|
+
requires :items, type: Array do
|
68
|
+
optional :beer
|
69
|
+
optional :wine
|
70
|
+
optional :grapefruit
|
71
|
+
mutually_exclusive :beer, :wine, :grapefruit
|
72
|
+
end
|
73
|
+
end
|
74
|
+
post '/nested-array' do
|
75
|
+
end
|
76
|
+
|
77
|
+
params do
|
78
|
+
requires :items, type: Array do
|
79
|
+
requires :nested_items, type: Array do
|
80
|
+
optional :beer, :wine, :grapefruit, type: Boolean
|
81
|
+
mutually_exclusive :beer, :wine, :grapefruit
|
82
|
+
end
|
83
|
+
end
|
84
|
+
end
|
85
|
+
post '/deeply-nested-array' do
|
86
|
+
end
|
9
87
|
end
|
10
88
|
end
|
11
89
|
end
|
12
|
-
|
13
|
-
|
90
|
+
|
91
|
+
def app
|
92
|
+
ValidationsSpec::MutualExclusionValidatorSpec::API
|
93
|
+
end
|
14
94
|
|
15
95
|
context 'when all mutually exclusive params are present' do
|
96
|
+
let(:path) { '/' }
|
16
97
|
let(:params) { { beer: true, wine: true, grapefruit: true } }
|
17
98
|
|
18
|
-
it '
|
19
|
-
|
20
|
-
|
21
|
-
|
99
|
+
it 'returns a validation error' do
|
100
|
+
validate
|
101
|
+
expect(last_response.status).to eq 400
|
102
|
+
expect(JSON.parse(last_response.body)).to eq(
|
103
|
+
'beer,wine,grapefruit' => ['are mutually exclusive']
|
104
|
+
)
|
22
105
|
end
|
23
106
|
|
24
107
|
context 'mixed with other params' do
|
25
|
-
let(:
|
108
|
+
let(:path) { '/mixed-params' }
|
109
|
+
let(:params) { { beer: true, wine: true, grapefruit: true, other: true } }
|
26
110
|
|
27
|
-
it '
|
28
|
-
|
29
|
-
|
30
|
-
|
111
|
+
it 'returns a validation error' do
|
112
|
+
validate
|
113
|
+
expect(last_response.status).to eq 400
|
114
|
+
expect(JSON.parse(last_response.body)).to eq(
|
115
|
+
'beer,wine,grapefruit' => ['are mutually exclusive']
|
116
|
+
)
|
31
117
|
end
|
32
118
|
end
|
33
119
|
end
|
34
120
|
|
35
121
|
context 'when a subset of mutually exclusive params are present' do
|
122
|
+
let(:path) { '/' }
|
36
123
|
let(:params) { { beer: true, grapefruit: true } }
|
37
124
|
|
38
|
-
it '
|
39
|
-
|
40
|
-
|
41
|
-
|
125
|
+
it 'returns a validation error' do
|
126
|
+
validate
|
127
|
+
expect(last_response.status).to eq 400
|
128
|
+
expect(JSON.parse(last_response.body)).to eq(
|
129
|
+
'beer,grapefruit' => ['are mutually exclusive']
|
130
|
+
)
|
42
131
|
end
|
43
132
|
end
|
44
133
|
|
45
|
-
context 'when
|
46
|
-
let(:
|
134
|
+
context 'when custom message is specified' do
|
135
|
+
let(:path) { '/custom-message' }
|
136
|
+
let(:params) { { beer: true, wine: true } }
|
47
137
|
|
48
|
-
it '
|
49
|
-
|
50
|
-
|
51
|
-
|
138
|
+
it 'returns a validation error' do
|
139
|
+
validate
|
140
|
+
expect(last_response.status).to eq 400
|
141
|
+
expect(JSON.parse(last_response.body)).to eq(
|
142
|
+
'beer,wine' => ['you should not mix beer and wine']
|
143
|
+
)
|
52
144
|
end
|
53
145
|
end
|
54
146
|
|
55
147
|
context 'when no mutually exclusive params are present' do
|
148
|
+
let(:path) { '/' }
|
56
149
|
let(:params) { { beer: true, somethingelse: true } }
|
57
150
|
|
58
|
-
it '
|
59
|
-
|
151
|
+
it 'does not return a validation error' do
|
152
|
+
validate
|
153
|
+
expect(last_response.status).to eq 201
|
154
|
+
end
|
155
|
+
end
|
156
|
+
|
157
|
+
context 'when mutually exclusive params are nested inside required hash' do
|
158
|
+
let(:path) { '/nested-hash' }
|
159
|
+
let(:params) { { item: { beer: true, wine: true } } }
|
160
|
+
|
161
|
+
it 'returns a validation error with full names of the params' do
|
162
|
+
validate
|
163
|
+
expect(last_response.status).to eq 400
|
164
|
+
expect(JSON.parse(last_response.body)).to eq(
|
165
|
+
'item[beer],item[wine]' => ['are mutually exclusive']
|
166
|
+
)
|
167
|
+
end
|
168
|
+
end
|
169
|
+
|
170
|
+
context 'when mutually exclusive params are nested inside optional hash' do
|
171
|
+
let(:path) { '/nested-optional-hash' }
|
172
|
+
|
173
|
+
context 'when params are passed' do
|
174
|
+
let(:params) { { item: { beer: true, wine: true } } }
|
175
|
+
|
176
|
+
it 'returns a validation error with full names of the params' do
|
177
|
+
validate
|
178
|
+
expect(last_response.status).to eq 400
|
179
|
+
expect(JSON.parse(last_response.body)).to eq(
|
180
|
+
'item[beer],item[wine]' => ['are mutually exclusive']
|
181
|
+
)
|
182
|
+
end
|
183
|
+
end
|
184
|
+
|
185
|
+
context 'when params are empty' do
|
186
|
+
let(:params) { {} }
|
187
|
+
|
188
|
+
it 'does not return a validation error' do
|
189
|
+
validate
|
190
|
+
expect(last_response.status).to eq 201
|
191
|
+
end
|
192
|
+
end
|
193
|
+
end
|
194
|
+
|
195
|
+
context 'when mutually exclusive params are nested inside array' do
|
196
|
+
let(:path) { '/nested-array' }
|
197
|
+
let(:params) { { items: [{ beer: true, wine: true }, { wine: true, grapefruit: true }] } }
|
198
|
+
|
199
|
+
it 'returns a validation error with full names of the params' do
|
200
|
+
validate
|
201
|
+
expect(last_response.status).to eq 400
|
202
|
+
expect(JSON.parse(last_response.body)).to eq(
|
203
|
+
'items[0][beer],items[0][wine]' => ['are mutually exclusive'],
|
204
|
+
'items[1][wine],items[1][grapefruit]' => ['are mutually exclusive']
|
205
|
+
)
|
206
|
+
end
|
207
|
+
end
|
208
|
+
|
209
|
+
context 'when mutually exclusive params are deeply nested' do
|
210
|
+
let(:path) { '/deeply-nested-array' }
|
211
|
+
let(:params) { { items: [{ nested_items: [{ beer: true, wine: true }] }] } }
|
212
|
+
|
213
|
+
it 'returns a validation error with full names of the params' do
|
214
|
+
validate
|
215
|
+
expect(last_response.status).to eq 400
|
216
|
+
expect(JSON.parse(last_response.body)).to eq(
|
217
|
+
'items[0][nested_items][0][beer],items[0][nested_items][0][wine]' => ['are mutually exclusive']
|
218
|
+
)
|
60
219
|
end
|
61
220
|
end
|
62
221
|
end
|
@@ -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
|
@@ -0,0 +1,65 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'spec_helper'
|
4
|
+
|
5
|
+
describe Grape::Validations::SameAsValidator do
|
6
|
+
module ValidationsSpec
|
7
|
+
module SameAsValidatorSpec
|
8
|
+
class API < Grape::API
|
9
|
+
params do
|
10
|
+
requires :password
|
11
|
+
requires :password_confirmation, same_as: :password
|
12
|
+
end
|
13
|
+
post do
|
14
|
+
end
|
15
|
+
|
16
|
+
params do
|
17
|
+
requires :password
|
18
|
+
requires :password_confirmation, same_as: { value: :password, message: 'not match' }
|
19
|
+
end
|
20
|
+
post '/custom-message' do
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
def app
|
27
|
+
ValidationsSpec::SameAsValidatorSpec::API
|
28
|
+
end
|
29
|
+
|
30
|
+
describe '/' do
|
31
|
+
context 'is the same' do
|
32
|
+
it do
|
33
|
+
post '/', password: '987654', password_confirmation: '987654'
|
34
|
+
expect(last_response.status).to eq(201)
|
35
|
+
expect(last_response.body).to eq('')
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
context 'is not the same' do
|
40
|
+
it do
|
41
|
+
post '/', password: '123456', password_confirmation: 'whatever'
|
42
|
+
expect(last_response.status).to eq(400)
|
43
|
+
expect(last_response.body).to eq('password_confirmation is not the same as password')
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
describe '/custom-message' do
|
49
|
+
context 'is the same' do
|
50
|
+
it do
|
51
|
+
post '/custom-message', password: '987654', password_confirmation: '987654'
|
52
|
+
expect(last_response.status).to eq(201)
|
53
|
+
expect(last_response.body).to eq('')
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
context 'is not the same' do
|
58
|
+
it do
|
59
|
+
post '/custom-message', password: '123456', password_confirmation: 'whatever'
|
60
|
+
expect(last_response.status).to eq(400)
|
61
|
+
expect(last_response.body).to eq('password_confirmation not match')
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
65
|
+
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
|
@@ -312,7 +319,7 @@ describe Grape::Validations::ValuesValidator do
|
|
312
319
|
expect(last_response.status).to eq 200
|
313
320
|
end
|
314
321
|
|
315
|
-
it '
|
322
|
+
it 'accepts for an optional param with a list of values' do
|
316
323
|
put('/optional_with_array_of_string_values', optional: nil)
|
317
324
|
expect(last_response.status).to eq 200
|
318
325
|
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
|