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,12 +1,14 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require 'spec_helper'
|
2
4
|
|
3
5
|
describe 'Validator with instance variables' do
|
4
6
|
let(:validator_type) do
|
5
7
|
Class.new(Grape::Validations::Base) do
|
6
8
|
def validate_param!(_attr_name, _params)
|
7
|
-
if @instance_variable
|
8
|
-
raise Grape::Exceptions::Validation
|
9
|
-
|
9
|
+
if instance_variable_defined?(:@instance_variable) && @instance_variable
|
10
|
+
raise Grape::Exceptions::Validation.new(params: ['params'],
|
11
|
+
message: 'This should never happen')
|
10
12
|
end
|
11
13
|
@instance_variable = true
|
12
14
|
end
|
@@ -0,0 +1,41 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'spec_helper'
|
4
|
+
|
5
|
+
describe Grape::Validations::MultipleAttributesIterator do
|
6
|
+
describe '#each' do
|
7
|
+
subject(:iterator) { described_class.new(validator, scope, params) }
|
8
|
+
let(:scope) { Grape::Validations::ParamsScope.new(api: Class.new(Grape::API)) }
|
9
|
+
let(:validator) { double(attrs: %i[first second third]) }
|
10
|
+
|
11
|
+
context 'when params is a hash' do
|
12
|
+
let(:params) do
|
13
|
+
{ first: 'string', second: 'string' }
|
14
|
+
end
|
15
|
+
|
16
|
+
it 'yields the whole params hash and the skipped flag without the list of attrs' do
|
17
|
+
expect { |b| iterator.each(&b) }.to yield_with_args(params, false)
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
context 'when params is an array' do
|
22
|
+
let(:params) do
|
23
|
+
[{ first: 'string1', second: 'string1' }, { first: 'string2', second: 'string2' }]
|
24
|
+
end
|
25
|
+
|
26
|
+
it 'yields each element of the array without the list of attrs' do
|
27
|
+
expect { |b| iterator.each(&b) }.to yield_successive_args([params[0], false], [params[1], false])
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
context 'when params is empty optional placeholder' do
|
32
|
+
let(:params) do
|
33
|
+
[Grape::DSL::Parameters::EmptyOptionalValue, { first: 'string2', second: 'string2' }]
|
34
|
+
end
|
35
|
+
|
36
|
+
it 'yields each element of the array without the list of attrs' do
|
37
|
+
expect { |b| iterator.each(&b) }.to yield_successive_args([Grape::DSL::Parameters::EmptyOptionalValue, true], [params[1], false])
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require 'spec_helper'
|
2
4
|
|
3
5
|
describe Grape::Validations::ParamsScope do
|
@@ -30,7 +32,7 @@ describe Grape::Validations::ParamsScope do
|
|
30
32
|
context 'when the default value is false' do
|
31
33
|
before do
|
32
34
|
subject.params do
|
33
|
-
optional :bool, type:
|
35
|
+
optional :bool, type: Grape::API::Boolean, default: false
|
34
36
|
end
|
35
37
|
subject.get
|
36
38
|
end
|
@@ -121,14 +123,14 @@ describe Grape::Validations::ParamsScope do
|
|
121
123
|
end
|
122
124
|
end
|
123
125
|
|
124
|
-
context 'param
|
126
|
+
context 'param renaming' do
|
125
127
|
it do
|
126
128
|
subject.params do
|
127
129
|
requires :foo, as: :bar
|
128
130
|
optional :super, as: :hiper
|
129
131
|
end
|
130
|
-
subject.get('/
|
131
|
-
get '/
|
132
|
+
subject.get('/renaming') { "#{declared(params)['bar']}-#{declared(params)['hiper']}" }
|
133
|
+
get '/renaming', foo: 'any', super: 'any2'
|
132
134
|
|
133
135
|
expect(last_response.status).to eq(200)
|
134
136
|
expect(last_response.body).to eq('any-any2')
|
@@ -138,8 +140,8 @@ describe Grape::Validations::ParamsScope do
|
|
138
140
|
subject.params do
|
139
141
|
requires :foo, as: :bar, type: String, coerce_with: ->(c) { c.strip }
|
140
142
|
end
|
141
|
-
subject.get('/
|
142
|
-
get '/
|
143
|
+
subject.get('/renaming-coerced') { "#{params['bar']}-#{params['foo']}" }
|
144
|
+
get '/renaming-coerced', foo: ' there we go '
|
143
145
|
|
144
146
|
expect(last_response.status).to eq(200)
|
145
147
|
expect(last_response.body).to eq('there we go-')
|
@@ -149,12 +151,35 @@ describe Grape::Validations::ParamsScope do
|
|
149
151
|
subject.params do
|
150
152
|
requires :foo, as: :bar, allow_blank: false
|
151
153
|
end
|
152
|
-
subject.get('/
|
153
|
-
get '/
|
154
|
+
subject.get('/renaming-not-blank') {}
|
155
|
+
get '/renaming-not-blank', foo: ''
|
154
156
|
|
155
157
|
expect(last_response.status).to eq(400)
|
156
158
|
expect(last_response.body).to eq('foo is empty')
|
157
159
|
end
|
160
|
+
|
161
|
+
it do
|
162
|
+
subject.params do
|
163
|
+
requires :foo, as: :bar, allow_blank: false
|
164
|
+
end
|
165
|
+
subject.get('/renaming-not-blank-with-value') {}
|
166
|
+
get '/renaming-not-blank-with-value', foo: 'any'
|
167
|
+
|
168
|
+
expect(last_response.status).to eq(200)
|
169
|
+
end
|
170
|
+
|
171
|
+
it do
|
172
|
+
subject.params do
|
173
|
+
requires :foo, as: :baz, type: Hash do
|
174
|
+
requires :bar, as: :qux
|
175
|
+
end
|
176
|
+
end
|
177
|
+
subject.get('/nested-renaming') { declared(params).to_json }
|
178
|
+
get '/nested-renaming', foo: { bar: 'any' }
|
179
|
+
|
180
|
+
expect(last_response.status).to eq(200)
|
181
|
+
expect(last_response.body).to eq('{"baz":{"qux":"any"}}')
|
182
|
+
end
|
158
183
|
end
|
159
184
|
|
160
185
|
context 'array without coerce type explicitly given' do
|
@@ -479,7 +504,50 @@ describe Grape::Validations::ParamsScope do
|
|
479
504
|
end.to_not raise_error
|
480
505
|
end
|
481
506
|
|
482
|
-
it '
|
507
|
+
it 'does not raise an error if when using nested given' do
|
508
|
+
expect do
|
509
|
+
subject.params do
|
510
|
+
optional :a, type: Hash do
|
511
|
+
requires :b
|
512
|
+
end
|
513
|
+
given :a do
|
514
|
+
requires :c
|
515
|
+
given :c do
|
516
|
+
requires :d
|
517
|
+
end
|
518
|
+
end
|
519
|
+
end
|
520
|
+
end.to_not raise_error
|
521
|
+
end
|
522
|
+
|
523
|
+
it 'allows nested dependent parameters' do
|
524
|
+
subject.params do
|
525
|
+
optional :a
|
526
|
+
given a: ->(val) { val == 'a' } do
|
527
|
+
optional :b
|
528
|
+
given b: ->(val) { val == 'b' } do
|
529
|
+
optional :c
|
530
|
+
given c: ->(val) { val == 'c' } do
|
531
|
+
requires :d
|
532
|
+
end
|
533
|
+
end
|
534
|
+
end
|
535
|
+
end
|
536
|
+
subject.get('/') { declared(params).to_json }
|
537
|
+
|
538
|
+
get '/'
|
539
|
+
expect(last_response.status).to eq 200
|
540
|
+
|
541
|
+
get '/', a: 'a', b: 'b', c: 'c'
|
542
|
+
expect(last_response.status).to eq 400
|
543
|
+
expect(last_response.body).to eq 'd is missing'
|
544
|
+
|
545
|
+
get '/', a: 'a', b: 'b', c: 'c', d: 'd'
|
546
|
+
expect(last_response.status).to eq 200
|
547
|
+
expect(last_response.body).to eq({ a: 'a', b: 'b', c: 'c', d: 'd' }.to_json)
|
548
|
+
end
|
549
|
+
|
550
|
+
it 'allows renaming of dependent parameters' do
|
483
551
|
subject.params do
|
484
552
|
optional :a
|
485
553
|
given :a do
|
@@ -497,6 +565,34 @@ describe Grape::Validations::ParamsScope do
|
|
497
565
|
expect(body.keys).to_not include('b')
|
498
566
|
end
|
499
567
|
|
568
|
+
it 'allows renaming of dependent on parameter' do
|
569
|
+
subject.params do
|
570
|
+
optional :a, as: :b
|
571
|
+
given b: ->(val) { val == 'x' } do
|
572
|
+
requires :c
|
573
|
+
end
|
574
|
+
end
|
575
|
+
subject.get('/') { declared(params) }
|
576
|
+
|
577
|
+
get '/', a: 'x'
|
578
|
+
expect(last_response.status).to eq 400
|
579
|
+
expect(last_response.body).to eq 'c is missing'
|
580
|
+
|
581
|
+
get '/', a: 'y'
|
582
|
+
expect(last_response.status).to eq 200
|
583
|
+
end
|
584
|
+
|
585
|
+
it 'raises an error if the dependent parameter is not the renamed one' do
|
586
|
+
expect do
|
587
|
+
subject.params do
|
588
|
+
optional :a, as: :b
|
589
|
+
given :a do
|
590
|
+
requires :c
|
591
|
+
end
|
592
|
+
end
|
593
|
+
end.to raise_error(Grape::Exceptions::UnknownParameter)
|
594
|
+
end
|
595
|
+
|
500
596
|
it 'does not validate nested requires when given is false' do
|
501
597
|
subject.params do
|
502
598
|
requires :a, type: String, allow_blank: false, values: %w[x y z]
|
@@ -537,6 +633,32 @@ describe Grape::Validations::ParamsScope do
|
|
537
633
|
expect(last_response.status).to eq(200)
|
538
634
|
end
|
539
635
|
|
636
|
+
it 'detect unmet nested dependency' do
|
637
|
+
subject.params do
|
638
|
+
requires :a, type: String, allow_blank: false, values: %w[x y z]
|
639
|
+
given a: ->(val) { val == 'z' } do
|
640
|
+
requires :inner3, type: Array, allow_blank: false do
|
641
|
+
requires :bar, type: String, allow_blank: false
|
642
|
+
given bar: ->(val) { val == 'b' } do
|
643
|
+
requires :baz, type: Array do
|
644
|
+
optional :baz_category, type: String
|
645
|
+
end
|
646
|
+
end
|
647
|
+
given bar: ->(val) { val == 'c' } do
|
648
|
+
requires :baz, type: Array do
|
649
|
+
requires :baz_category, type: String
|
650
|
+
end
|
651
|
+
end
|
652
|
+
end
|
653
|
+
end
|
654
|
+
end
|
655
|
+
subject.get('/nested-dependency') { declared(params).to_json }
|
656
|
+
|
657
|
+
get '/nested-dependency', a: 'z', inner3: [{ bar: 'c', baz: [{ unrelated: 'nope' }] }]
|
658
|
+
expect(last_response.status).to eq(400)
|
659
|
+
expect(last_response.body).to eq 'inner3[0][baz][0][baz_category] is missing'
|
660
|
+
end
|
661
|
+
|
540
662
|
it 'includes the parameter within #declared(params)' do
|
541
663
|
get '/test', a: true, b: true
|
542
664
|
|
@@ -592,7 +714,53 @@ describe Grape::Validations::ParamsScope do
|
|
592
714
|
end
|
593
715
|
end
|
594
716
|
|
717
|
+
context 'default value in given block' do
|
718
|
+
before do
|
719
|
+
subject.params do
|
720
|
+
optional :a, values: %w[a b]
|
721
|
+
given a: ->(val) { val == 'a' } do
|
722
|
+
optional :b, default: 'default'
|
723
|
+
end
|
724
|
+
end
|
725
|
+
subject.get('/') { params.to_json }
|
726
|
+
end
|
727
|
+
|
728
|
+
context 'when dependency meets' do
|
729
|
+
it 'sets default value for dependent parameter' do
|
730
|
+
get '/', a: 'a'
|
731
|
+
expect(last_response.body).to eq({ a: 'a', b: 'default' }.to_json)
|
732
|
+
end
|
733
|
+
end
|
734
|
+
|
735
|
+
context 'when dependency does not meet' do
|
736
|
+
it 'does not set default value for dependent parameter' do
|
737
|
+
get '/', a: 'b'
|
738
|
+
expect(last_response.body).to eq({ a: 'b' }.to_json)
|
739
|
+
end
|
740
|
+
end
|
741
|
+
end
|
742
|
+
|
595
743
|
context 'when validations are dependent on a parameter within an array param' do
|
744
|
+
before do
|
745
|
+
subject.params do
|
746
|
+
requires :foos, type: Array do
|
747
|
+
optional :foo
|
748
|
+
given :foo do
|
749
|
+
requires :bar
|
750
|
+
end
|
751
|
+
end
|
752
|
+
end
|
753
|
+
subject.get('/test') { 'ok' }
|
754
|
+
end
|
755
|
+
|
756
|
+
it 'should pass none Hash params' do
|
757
|
+
get '/test', foos: ['']
|
758
|
+
expect(last_response.status).to eq(200)
|
759
|
+
expect(last_response.body).to eq('ok')
|
760
|
+
end
|
761
|
+
end
|
762
|
+
|
763
|
+
context 'when validations are dependent on a parameter within an array param within #declared(params).to_json' do
|
596
764
|
before do
|
597
765
|
subject.params do
|
598
766
|
requires :foos, type: Array do
|
@@ -948,4 +1116,40 @@ describe Grape::Validations::ParamsScope do
|
|
948
1116
|
end
|
949
1117
|
end
|
950
1118
|
end
|
1119
|
+
|
1120
|
+
context 'with exactly_one_of validation for optional parameters within an Hash param' do
|
1121
|
+
before do
|
1122
|
+
subject.params do
|
1123
|
+
optional :memo, type: Hash do
|
1124
|
+
optional :text, type: String
|
1125
|
+
optional :custom_body, type: Hash, coerce_with: JSON
|
1126
|
+
exactly_one_of :text, :custom_body
|
1127
|
+
end
|
1128
|
+
end
|
1129
|
+
subject.get('test')
|
1130
|
+
end
|
1131
|
+
|
1132
|
+
context 'when correct data is provided' do
|
1133
|
+
it 'returns a successful response' do
|
1134
|
+
get 'test', memo: {}
|
1135
|
+
expect(last_response.status).to eq(200)
|
1136
|
+
|
1137
|
+
get 'test', memo: { text: 'HOGEHOGE' }
|
1138
|
+
expect(last_response.status).to eq(200)
|
1139
|
+
|
1140
|
+
get 'test', memo: { custom_body: '{ "xxx": "yyy" }' }
|
1141
|
+
expect(last_response.status).to eq(200)
|
1142
|
+
end
|
1143
|
+
end
|
1144
|
+
|
1145
|
+
context 'when invalid data is provided' do
|
1146
|
+
it 'returns a failure response' do
|
1147
|
+
get 'test', memo: { text: 'HOGEHOGE', custom_body: '{ "xxx": "yyy" }' }
|
1148
|
+
expect(last_response.status).to eq(400)
|
1149
|
+
|
1150
|
+
get 'test', memo: '{ "custom_body": "HOGE" }'
|
1151
|
+
expect(last_response.status).to eq(400)
|
1152
|
+
end
|
1153
|
+
end
|
1154
|
+
end
|
951
1155
|
end
|
@@ -0,0 +1,58 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'spec_helper'
|
4
|
+
|
5
|
+
describe Grape::Validations::SingleAttributeIterator do
|
6
|
+
describe '#each' do
|
7
|
+
subject(:iterator) { described_class.new(validator, scope, params) }
|
8
|
+
let(:scope) { Grape::Validations::ParamsScope.new(api: Class.new(Grape::API)) }
|
9
|
+
let(:validator) { double(attrs: %i[first second]) }
|
10
|
+
|
11
|
+
context 'when params is a hash' do
|
12
|
+
let(:params) do
|
13
|
+
{ first: 'string', second: 'string' }
|
14
|
+
end
|
15
|
+
|
16
|
+
it 'yields params and every single attribute from the list' do
|
17
|
+
expect { |b| iterator.each(&b) }
|
18
|
+
.to yield_successive_args([params, :first, false, false], [params, :second, false, false])
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
context 'when params is an array' do
|
23
|
+
let(:params) do
|
24
|
+
[{ first: 'string1', second: 'string1' }, { first: 'string2', second: 'string2' }]
|
25
|
+
end
|
26
|
+
|
27
|
+
it 'yields every single attribute from the list for each of the array elements' do
|
28
|
+
expect { |b| iterator.each(&b) }.to yield_successive_args(
|
29
|
+
[params[0], :first, false, false], [params[0], :second, false, false],
|
30
|
+
[params[1], :first, false, false], [params[1], :second, false, false]
|
31
|
+
)
|
32
|
+
end
|
33
|
+
|
34
|
+
context 'empty values' do
|
35
|
+
let(:params) { [{}, '', 10] }
|
36
|
+
|
37
|
+
it 'marks params with empty values' do
|
38
|
+
expect { |b| iterator.each(&b) }.to yield_successive_args(
|
39
|
+
[params[0], :first, true, false], [params[0], :second, true, false],
|
40
|
+
[params[1], :first, true, false], [params[1], :second, true, false],
|
41
|
+
[params[2], :first, false, false], [params[2], :second, false, false]
|
42
|
+
)
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
context 'when missing optional value' do
|
47
|
+
let(:params) { [Grape::DSL::Parameters::EmptyOptionalValue, 10] }
|
48
|
+
|
49
|
+
it 'marks params with skipped values' do
|
50
|
+
expect { |b| iterator.each(&b) }.to yield_successive_args(
|
51
|
+
[params[0], :first, false, true], [params[0], :second, false, true],
|
52
|
+
[params[1], :first, false, false], [params[1], :second, false, false],
|
53
|
+
)
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'spec_helper'
|
4
|
+
|
5
|
+
describe Grape::Validations::Types::ArrayCoercer do
|
6
|
+
subject { described_class.new(type) }
|
7
|
+
|
8
|
+
describe '#call' do
|
9
|
+
context 'an array of primitives' do
|
10
|
+
let(:type) { Array[String] }
|
11
|
+
|
12
|
+
it 'coerces elements in the array' do
|
13
|
+
expect(subject.call([10, 20])).to eq(%w[10 20])
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
context 'an array of arrays' do
|
18
|
+
let(:type) { Array[Array[Integer]] }
|
19
|
+
|
20
|
+
it 'coerces elements in the nested array' do
|
21
|
+
expect(subject.call([%w[10 20]])).to eq([[10, 20]])
|
22
|
+
expect(subject.call([['10'], ['20']])).to eq([[10], [20]])
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
context 'an array of sets' do
|
27
|
+
let(:type) { Array[Set[Integer]] }
|
28
|
+
|
29
|
+
it 'coerces elements in the nested set' do
|
30
|
+
expect(subject.call([%w[10 20]])).to eq([Set[10, 20]])
|
31
|
+
expect(subject.call([['10'], ['20']])).to eq([Set[10], Set[20]])
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|