grape 0.9.0 → 0.10.0
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.
Potentially problematic release.
This version of grape might be problematic. Click here for more details.
- checksums.yaml +4 -4
- data/.rubocop.yml +1 -66
- data/.rubocop_todo.yml +78 -17
- data/.travis.yml +7 -3
- data/Appraisals +7 -0
- data/CHANGELOG.md +24 -0
- data/CONTRIBUTING.md +7 -0
- data/Gemfile +1 -7
- data/Guardfile +1 -1
- data/README.md +560 -94
- data/RELEASING.md +1 -1
- data/Rakefile +10 -11
- data/UPGRADING.md +211 -3
- data/gemfiles/rails_3.gemfile +14 -0
- data/gemfiles/rails_4.gemfile +14 -0
- data/grape.gemspec +10 -9
- data/lib/backports/active_support/deep_dup.rb +49 -0
- data/lib/backports/active_support/duplicable.rb +88 -0
- data/lib/grape.rb +29 -2
- data/lib/grape/api.rb +59 -65
- data/lib/grape/dsl/api.rb +19 -0
- data/lib/grape/dsl/callbacks.rb +6 -4
- data/lib/grape/dsl/configuration.rb +49 -5
- data/lib/grape/dsl/helpers.rb +7 -8
- data/lib/grape/dsl/inside_route.rb +22 -10
- data/lib/grape/dsl/middleware.rb +5 -5
- data/lib/grape/dsl/parameters.rb +6 -2
- data/lib/grape/dsl/request_response.rb +23 -20
- data/lib/grape/dsl/routing.rb +52 -49
- data/lib/grape/dsl/settings.rb +110 -0
- data/lib/grape/dsl/validations.rb +14 -6
- data/lib/grape/endpoint.rb +104 -88
- data/lib/grape/exceptions/base.rb +2 -2
- data/lib/grape/exceptions/incompatible_option_values.rb +1 -1
- data/lib/grape/exceptions/invalid_formatter.rb +1 -1
- data/lib/grape/exceptions/invalid_versioner_option.rb +1 -1
- data/lib/grape/exceptions/invalid_with_option_for_represent.rb +1 -1
- data/lib/grape/exceptions/missing_mime_type.rb +1 -1
- data/lib/grape/exceptions/missing_option.rb +1 -1
- data/lib/grape/exceptions/missing_vendor_option.rb +1 -1
- data/lib/grape/exceptions/unknown_options.rb +1 -1
- data/lib/grape/exceptions/unknown_validator.rb +1 -1
- data/lib/grape/exceptions/validation.rb +1 -1
- data/lib/grape/exceptions/validation_errors.rb +2 -2
- data/lib/grape/formatter/serializable_hash.rb +1 -1
- data/lib/grape/formatter/xml.rb +1 -1
- data/lib/grape/locale/en.yml +2 -0
- data/lib/grape/middleware/auth/dsl.rb +26 -21
- data/lib/grape/middleware/auth/strategies.rb +1 -1
- data/lib/grape/middleware/auth/strategy_info.rb +0 -2
- data/lib/grape/middleware/base.rb +2 -2
- data/lib/grape/middleware/error.rb +1 -1
- data/lib/grape/middleware/formatter.rb +5 -5
- data/lib/grape/middleware/versioner.rb +1 -1
- data/lib/grape/middleware/versioner/header.rb +3 -3
- data/lib/grape/middleware/versioner/param.rb +2 -2
- data/lib/grape/middleware/versioner/path.rb +1 -1
- data/lib/grape/namespace.rb +1 -1
- data/lib/grape/path.rb +9 -3
- data/lib/grape/util/content_types.rb +16 -8
- data/lib/grape/util/inheritable_setting.rb +74 -0
- data/lib/grape/util/inheritable_values.rb +51 -0
- data/lib/grape/util/stackable_values.rb +52 -0
- data/lib/grape/util/strict_hash_configuration.rb +106 -0
- data/lib/grape/validations.rb +0 -220
- data/lib/grape/validations/attributes_iterator.rb +21 -0
- data/lib/grape/validations/params_scope.rb +176 -0
- data/lib/grape/validations/validators/all_or_none.rb +20 -0
- data/lib/grape/validations/validators/allow_blank.rb +30 -0
- data/lib/grape/validations/validators/at_least_one_of.rb +20 -0
- data/lib/grape/validations/validators/base.rb +37 -0
- data/lib/grape/validations/{coerce.rb → validators/coerce.rb} +3 -3
- data/lib/grape/validations/{default.rb → validators/default.rb} +1 -1
- data/lib/grape/validations/validators/exactly_one_of.rb +20 -0
- data/lib/grape/validations/validators/multiple_params_base.rb +26 -0
- data/lib/grape/validations/validators/mutual_exclusion.rb +25 -0
- data/lib/grape/validations/{presence.rb → validators/presence.rb} +2 -2
- data/lib/grape/validations/validators/regexp.rb +12 -0
- data/lib/grape/validations/validators/values.rb +26 -0
- data/lib/grape/version.rb +1 -1
- data/spec/grape/api_spec.rb +522 -343
- data/spec/grape/dsl/callbacks_spec.rb +4 -4
- data/spec/grape/dsl/configuration_spec.rb +48 -9
- data/spec/grape/dsl/helpers_spec.rb +6 -13
- data/spec/grape/dsl/inside_route_spec.rb +43 -4
- data/spec/grape/dsl/middleware_spec.rb +1 -10
- data/spec/grape/dsl/parameters_spec.rb +8 -1
- data/spec/grape/dsl/request_response_spec.rb +16 -22
- data/spec/grape/dsl/routing_spec.rb +21 -5
- data/spec/grape/dsl/settings_spec.rb +219 -0
- data/spec/grape/dsl/validations_spec.rb +8 -11
- data/spec/grape/endpoint_spec.rb +115 -86
- data/spec/grape/entity_spec.rb +33 -33
- data/spec/grape/exceptions/invalid_formatter_spec.rb +3 -5
- data/spec/grape/exceptions/invalid_versioner_option_spec.rb +4 -6
- data/spec/grape/exceptions/missing_mime_type_spec.rb +5 -6
- data/spec/grape/exceptions/missing_option_spec.rb +3 -5
- data/spec/grape/exceptions/unknown_options_spec.rb +3 -5
- data/spec/grape/exceptions/unknown_validator_spec.rb +3 -5
- data/spec/grape/exceptions/validation_errors_spec.rb +5 -5
- data/spec/grape/loading_spec.rb +44 -0
- data/spec/grape/middleware/auth/base_spec.rb +0 -4
- data/spec/grape/middleware/auth/dsl_spec.rb +2 -4
- data/spec/grape/middleware/auth/strategies_spec.rb +5 -6
- data/spec/grape/middleware/exception_spec.rb +8 -10
- data/spec/grape/middleware/formatter_spec.rb +13 -15
- data/spec/grape/middleware/versioner/accept_version_header_spec.rb +10 -10
- data/spec/grape/middleware/versioner/header_spec.rb +25 -25
- data/spec/grape/middleware/versioner/param_spec.rb +15 -17
- data/spec/grape/middleware/versioner/path_spec.rb +1 -2
- data/spec/grape/middleware/versioner_spec.rb +0 -1
- data/spec/grape/path_spec.rb +66 -45
- data/spec/grape/util/inheritable_setting_spec.rb +217 -0
- data/spec/grape/util/inheritable_values_spec.rb +63 -0
- data/spec/grape/util/stackable_values_spec.rb +115 -0
- data/spec/grape/util/strict_hash_configuration_spec.rb +38 -0
- data/spec/grape/validations/attributes_iterator_spec.rb +4 -0
- data/spec/grape/validations/params_scope_spec.rb +57 -0
- data/spec/grape/validations/validators/all_or_none_spec.rb +60 -0
- data/spec/grape/validations/validators/allow_blank_spec.rb +170 -0
- data/spec/grape/validations/{at_least_one_of_spec.rb → validators/at_least_one_of_spec.rb} +7 -3
- data/spec/grape/validations/{coerce_spec.rb → validators/coerce_spec.rb} +8 -11
- data/spec/grape/validations/{default_spec.rb → validators/default_spec.rb} +7 -9
- data/spec/grape/validations/{exactly_one_of_spec.rb → validators/exactly_one_of_spec.rb} +15 -11
- data/spec/grape/validations/{mutual_exclusion_spec.rb → validators/mutual_exclusion_spec.rb} +11 -9
- data/spec/grape/validations/{presence_spec.rb → validators/presence_spec.rb} +30 -30
- data/spec/grape/validations/{regexp_spec.rb → validators/regexp_spec.rb} +2 -4
- data/spec/grape/validations/{values_spec.rb → validators/values_spec.rb} +95 -23
- data/spec/grape/validations/{zh-CN.yml → validators/zh-CN.yml} +0 -0
- data/spec/grape/validations_spec.rb +335 -70
- data/spec/shared/versioning_examples.rb +7 -8
- data/spec/spec_helper.rb +2 -0
- data/spec/support/basic_auth_encode_helpers.rb +1 -1
- data/spec/support/content_type_helpers.rb +1 -1
- data/spec/support/versioned_helpers.rb +3 -3
- metadata +80 -33
- data/lib/grape/util/deep_merge.rb +0 -23
- data/lib/grape/util/hash_stack.rb +0 -120
- data/lib/grape/validations/at_least_one_of.rb +0 -25
- data/lib/grape/validations/exactly_one_of.rb +0 -26
- data/lib/grape/validations/mutual_exclusion.rb +0 -25
- data/lib/grape/validations/regexp.rb +0 -12
- data/lib/grape/validations/values.rb +0 -23
- data/spec/grape/util/hash_stack_spec.rb +0 -132
@@ -0,0 +1,63 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
module Grape
|
3
|
+
module Util
|
4
|
+
describe InheritableValues do
|
5
|
+
let(:parent){ InheritableValues.new }
|
6
|
+
subject { InheritableValues.new(parent) }
|
7
|
+
|
8
|
+
describe '#delete' do
|
9
|
+
it 'deletes a key' do
|
10
|
+
subject[:some_thing] = :new_foo_bar
|
11
|
+
subject.delete :some_thing
|
12
|
+
expect(subject[:some_thing]).to be_nil
|
13
|
+
end
|
14
|
+
|
15
|
+
it 'does not delete parent values' do
|
16
|
+
parent[:some_thing] = :foo
|
17
|
+
subject[:some_thing] = :new_foo_bar
|
18
|
+
subject.delete :some_thing
|
19
|
+
expect(subject[:some_thing]).to eq :foo
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
describe '#[]' do
|
24
|
+
it 'returns a value' do
|
25
|
+
subject[:some_thing] = :foo
|
26
|
+
expect(subject[:some_thing]).to eq :foo
|
27
|
+
end
|
28
|
+
|
29
|
+
it 'returns parent value when no value is set' do
|
30
|
+
parent[:some_thing] = :foo
|
31
|
+
expect(subject[:some_thing]).to eq :foo
|
32
|
+
end
|
33
|
+
|
34
|
+
it 'overwrites parent value with the current one' do
|
35
|
+
parent[:some_thing] = :foo
|
36
|
+
subject[:some_thing] = :foo_bar
|
37
|
+
expect(subject[:some_thing]).to eq :foo_bar
|
38
|
+
end
|
39
|
+
|
40
|
+
it 'parent values are not changed' do
|
41
|
+
parent[:some_thing] = :foo
|
42
|
+
subject[:some_thing] = :foo_bar
|
43
|
+
expect(parent[:some_thing]).to eq :foo
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
describe '#[]=' do
|
48
|
+
it 'sets a value' do
|
49
|
+
subject[:some_thing] = :foo
|
50
|
+
expect(subject[:some_thing]).to eq :foo
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
describe '#to_hash' do
|
55
|
+
it 'returns a Hash representation' do
|
56
|
+
parent[:some_thing] = :foo
|
57
|
+
subject[:some_thing_more] = :foo_bar
|
58
|
+
expect(subject.to_hash).to eq(some_thing: :foo, some_thing_more: :foo_bar)
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
@@ -0,0 +1,115 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
module Grape
|
3
|
+
module Util
|
4
|
+
describe StackableValues do
|
5
|
+
let(:parent){ StackableValues.new }
|
6
|
+
subject { StackableValues.new(parent) }
|
7
|
+
|
8
|
+
describe '#keys' do
|
9
|
+
it 'returns all key' do
|
10
|
+
subject[:some_thing] = :foo_bar
|
11
|
+
subject[:some_thing_else] = :foo_bar
|
12
|
+
expect(subject.keys).to eq [:some_thing, :some_thing_else].sort
|
13
|
+
end
|
14
|
+
|
15
|
+
it 'returns merged keys with parent' do
|
16
|
+
parent[:some_thing] = :foo
|
17
|
+
parent[:some_thing_else] = :foo
|
18
|
+
|
19
|
+
subject[:some_thing] = :foo_bar
|
20
|
+
subject[:some_thing_more] = :foo_bar
|
21
|
+
|
22
|
+
expect(subject.keys).to eq [:some_thing, :some_thing_else, :some_thing_more].sort
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
describe '#delete' do
|
27
|
+
it 'deletes a key' do
|
28
|
+
subject[:some_thing] = :new_foo_bar
|
29
|
+
subject.delete :some_thing
|
30
|
+
expect(subject[:some_thing]).to eq []
|
31
|
+
end
|
32
|
+
|
33
|
+
it 'does not delete parent values' do
|
34
|
+
parent[:some_thing] = :foo
|
35
|
+
subject[:some_thing] = :new_foo_bar
|
36
|
+
subject.delete :some_thing
|
37
|
+
expect(subject[:some_thing]).to eq [:foo]
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
describe '#[]' do
|
42
|
+
it 'returns an array of values' do
|
43
|
+
subject[:some_thing] = :foo
|
44
|
+
expect(subject[:some_thing]).to eq [:foo]
|
45
|
+
end
|
46
|
+
|
47
|
+
it 'returns parent value when no value is set' do
|
48
|
+
parent[:some_thing] = :foo
|
49
|
+
expect(subject[:some_thing]).to eq [:foo]
|
50
|
+
end
|
51
|
+
|
52
|
+
it 'combines parent and actual values' do
|
53
|
+
parent[:some_thing] = :foo
|
54
|
+
subject[:some_thing] = :foo_bar
|
55
|
+
expect(subject[:some_thing]).to eq [:foo, :foo_bar]
|
56
|
+
end
|
57
|
+
|
58
|
+
it 'parent values are not changed' do
|
59
|
+
parent[:some_thing] = :foo
|
60
|
+
subject[:some_thing] = :foo_bar
|
61
|
+
expect(parent[:some_thing]).to eq [:foo]
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
describe '#[]=' do
|
66
|
+
it 'sets a value' do
|
67
|
+
subject[:some_thing] = :foo
|
68
|
+
expect(subject[:some_thing]).to eq [:foo]
|
69
|
+
end
|
70
|
+
|
71
|
+
it 'pushes further values' do
|
72
|
+
subject[:some_thing] = :foo
|
73
|
+
subject[:some_thing] = :bar
|
74
|
+
expect(subject[:some_thing]).to eq [:foo, :bar]
|
75
|
+
end
|
76
|
+
|
77
|
+
it 'can handle array values' do
|
78
|
+
subject[:some_thing] = :foo
|
79
|
+
subject[:some_thing] = [:bar, :more]
|
80
|
+
expect(subject[:some_thing]).to eq [:foo, [:bar, :more]]
|
81
|
+
|
82
|
+
parent[:some_thing_else] = [:foo, :bar]
|
83
|
+
subject[:some_thing_else] = [:some, :bar, :foo]
|
84
|
+
|
85
|
+
expect(subject[:some_thing_else]).to eq [[:foo, :bar], [:some, :bar, :foo]]
|
86
|
+
end
|
87
|
+
end
|
88
|
+
|
89
|
+
describe '#to_hash' do
|
90
|
+
it 'returns a Hash representation' do
|
91
|
+
parent[:some_thing] = :foo
|
92
|
+
subject[:some_thing] = [:bar, :more]
|
93
|
+
subject[:some_thing_more] = :foo_bar
|
94
|
+
expect(subject.to_hash).to eq(some_thing: [:foo, [:bar, :more]], some_thing_more: [:foo_bar])
|
95
|
+
end
|
96
|
+
end
|
97
|
+
|
98
|
+
describe '#clone' do
|
99
|
+
let(:obj_cloned) { subject.clone }
|
100
|
+
it 'copies all values' do
|
101
|
+
parent = StackableValues.new
|
102
|
+
child = StackableValues.new parent
|
103
|
+
grandchild = StackableValues.new child
|
104
|
+
|
105
|
+
parent[:some_thing] = :foo
|
106
|
+
child[:some_thing] = [:bar, :more]
|
107
|
+
grandchild[:some_thing] = :grand_foo_bar
|
108
|
+
grandchild[:some_thing_more] = :foo_bar
|
109
|
+
|
110
|
+
expect(grandchild.clone.to_hash).to eq(some_thing: [:foo, [:bar, :more], :grand_foo_bar], some_thing_more: [:foo_bar])
|
111
|
+
end
|
112
|
+
end
|
113
|
+
end
|
114
|
+
end
|
115
|
+
end
|
@@ -0,0 +1,38 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
module Grape
|
3
|
+
module Util
|
4
|
+
describe 'StrictHashConfiguration' do
|
5
|
+
subject do
|
6
|
+
Class.new do
|
7
|
+
include Grape::Util::StrictHashConfiguration.module(:config1, :config2, config3: [:config4], config5: [config6: [:config7, :config8]])
|
8
|
+
end
|
9
|
+
end
|
10
|
+
|
11
|
+
it 'set nested configs' do
|
12
|
+
subject.configure do
|
13
|
+
config1 'alpha'
|
14
|
+
config2 'beta'
|
15
|
+
|
16
|
+
config3 do
|
17
|
+
config4 'gamma'
|
18
|
+
end
|
19
|
+
|
20
|
+
local_var = 8
|
21
|
+
|
22
|
+
config5 do
|
23
|
+
config6 do
|
24
|
+
config7 7
|
25
|
+
config8 local_var
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
expect(subject.settings).to eq(config1: 'alpha',
|
31
|
+
config2: 'beta',
|
32
|
+
config3: { config4: 'gamma' },
|
33
|
+
config5: { config6: { config7: 7, config8: 8 } }
|
34
|
+
)
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
@@ -0,0 +1,57 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Grape::Validations::ParamsScope do
|
4
|
+
subject do
|
5
|
+
Class.new(Grape::API)
|
6
|
+
end
|
7
|
+
|
8
|
+
def app
|
9
|
+
subject
|
10
|
+
end
|
11
|
+
|
12
|
+
context 'setting description' do
|
13
|
+
[:desc, :description].each do |description_type|
|
14
|
+
it "allows setting #{description_type}" do
|
15
|
+
subject.params do
|
16
|
+
requires :int, type: Integer, description_type => 'My very nice integer'
|
17
|
+
end
|
18
|
+
subject.get '/single' do
|
19
|
+
'int works'
|
20
|
+
end
|
21
|
+
get '/single', int: 420
|
22
|
+
expect(last_response.status).to eq(200)
|
23
|
+
expect(last_response.body).to eq('int works')
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
context 'array without coerce type explicitly given' do
|
29
|
+
it 'sets the type based on first element' do
|
30
|
+
subject.params do
|
31
|
+
requires :periods, type: Array, values: -> { %w(day month) }
|
32
|
+
end
|
33
|
+
subject.get('/required') { 'required works' }
|
34
|
+
|
35
|
+
get '/required', periods: %w(day month)
|
36
|
+
expect(last_response.status).to eq(200)
|
37
|
+
expect(last_response.body).to eq('required works')
|
38
|
+
end
|
39
|
+
|
40
|
+
it 'fails to call API without Array type' do
|
41
|
+
subject.params do
|
42
|
+
requires :periods, type: Array, values: -> { %w(day month) }
|
43
|
+
end
|
44
|
+
subject.get('/required') { 'required works' }
|
45
|
+
|
46
|
+
get '/required', periods: 'day'
|
47
|
+
expect(last_response.status).to eq(400)
|
48
|
+
expect(last_response.body).to eq('periods is invalid')
|
49
|
+
end
|
50
|
+
|
51
|
+
it 'raises exception when values are of different type' do
|
52
|
+
expect do
|
53
|
+
subject.params { requires :numbers, type: Array, values: [1, 'definitely not a number', 3] }
|
54
|
+
end.to raise_error Grape::Exceptions::IncompatibleOptionValues
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
@@ -0,0 +1,60 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Grape::Validations::AllOrNoneOfValidator do
|
4
|
+
describe '#validate!' do
|
5
|
+
let(:scope) do
|
6
|
+
Struct.new(:opts) do
|
7
|
+
def params(arg)
|
8
|
+
arg
|
9
|
+
end
|
10
|
+
|
11
|
+
def required?; end
|
12
|
+
end
|
13
|
+
end
|
14
|
+
let(:all_or_none_params) { [:beer, :wine, :grapefruit] }
|
15
|
+
let(:validator) { described_class.new(all_or_none_params, {}, false, scope.new) }
|
16
|
+
|
17
|
+
context 'when all restricted params are present' do
|
18
|
+
let(:params) { { beer: true, wine: true, grapefruit: true } }
|
19
|
+
|
20
|
+
it 'does not raise a validation exception' do
|
21
|
+
expect(validator.validate!(params)).to eql params
|
22
|
+
end
|
23
|
+
|
24
|
+
context 'mixed with other params' do
|
25
|
+
let(:mixed_params) { params.merge!(other: true, andanother: true) }
|
26
|
+
|
27
|
+
it 'does not raise a validation exception' do
|
28
|
+
expect(validator.validate!(mixed_params)).to eql mixed_params
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
context 'when none of the restricted params is selected' do
|
34
|
+
let(:params) { { somethingelse: true } }
|
35
|
+
|
36
|
+
it 'does not raise a validation exception' do
|
37
|
+
expect(validator.validate!(params)).to eql params
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
context 'when only a subset of restricted params are present' do
|
42
|
+
let(:params) { { beer: true, grapefruit: true } }
|
43
|
+
|
44
|
+
it 'raises a validation exception' do
|
45
|
+
expect do
|
46
|
+
validator.validate! params
|
47
|
+
end.to raise_error(Grape::Exceptions::Validation)
|
48
|
+
end
|
49
|
+
context 'mixed with other params' do
|
50
|
+
let(:mixed_params) { params.merge!(other: true, andanother: true) }
|
51
|
+
|
52
|
+
it 'raise a validation exception' do
|
53
|
+
expect do
|
54
|
+
validator.validate! params
|
55
|
+
end.to raise_error(Grape::Exceptions::Validation)
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
@@ -0,0 +1,170 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Grape::Validations::AllowBlankValidator do
|
4
|
+
module ValidationsSpec
|
5
|
+
module AllowBlankValidatorSpec
|
6
|
+
class API < Grape::API
|
7
|
+
default_format :json
|
8
|
+
|
9
|
+
params do
|
10
|
+
requires :name, allow_blank: false
|
11
|
+
end
|
12
|
+
get
|
13
|
+
|
14
|
+
params do
|
15
|
+
optional :name, allow_blank: false
|
16
|
+
end
|
17
|
+
get '/disallow_blank_optional_param'
|
18
|
+
|
19
|
+
params do
|
20
|
+
requires :name, allow_blank: true
|
21
|
+
end
|
22
|
+
get '/allow_blank'
|
23
|
+
|
24
|
+
params do
|
25
|
+
optional :user, type: Hash do
|
26
|
+
requires :name, allow_blank: false
|
27
|
+
end
|
28
|
+
end
|
29
|
+
get '/disallow_blank_required_param_in_an_optional_group'
|
30
|
+
|
31
|
+
params do
|
32
|
+
optional :user, type: Hash do
|
33
|
+
optional :name, allow_blank: false
|
34
|
+
requires :age
|
35
|
+
end
|
36
|
+
end
|
37
|
+
get '/disallow_blank_optional_param_in_an_optional_group'
|
38
|
+
|
39
|
+
params do
|
40
|
+
requires :user, type: Hash do
|
41
|
+
requires :name, allow_blank: false
|
42
|
+
end
|
43
|
+
end
|
44
|
+
get '/disallow_blank_required_param_in_a_required_group'
|
45
|
+
|
46
|
+
params do
|
47
|
+
requires :user, type: Hash do
|
48
|
+
requires :name, allow_blank: false
|
49
|
+
end
|
50
|
+
end
|
51
|
+
get '/disallow_string_value_in_a_required_hash_group'
|
52
|
+
|
53
|
+
params do
|
54
|
+
requires :user, type: Hash do
|
55
|
+
optional :name, allow_blank: false
|
56
|
+
end
|
57
|
+
end
|
58
|
+
get '/disallow_blank_optional_param_in_a_required_group'
|
59
|
+
|
60
|
+
params do
|
61
|
+
optional :user, type: Hash do
|
62
|
+
optional :name, allow_blank: false
|
63
|
+
end
|
64
|
+
end
|
65
|
+
get '/disallow_string_value_in_an_optional_hash_group'
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
def app
|
71
|
+
ValidationsSpec::AllowBlankValidatorSpec::API
|
72
|
+
end
|
73
|
+
|
74
|
+
context 'invalid input' do
|
75
|
+
it 'refuses empty string' do
|
76
|
+
get '/', name: ''
|
77
|
+
expect(last_response.status).to eq(400)
|
78
|
+
end
|
79
|
+
|
80
|
+
it 'refuses only whitespaces' do
|
81
|
+
get '/', name: ' '
|
82
|
+
expect(last_response.status).to eq(400)
|
83
|
+
|
84
|
+
get '/', name: " \n "
|
85
|
+
expect(last_response.status).to eq(400)
|
86
|
+
|
87
|
+
get '/', name: "\n"
|
88
|
+
expect(last_response.status).to eq(400)
|
89
|
+
end
|
90
|
+
|
91
|
+
it 'refuses nil' do
|
92
|
+
get '/', name: nil
|
93
|
+
expect(last_response.status).to eq(400)
|
94
|
+
end
|
95
|
+
end
|
96
|
+
|
97
|
+
context 'valid input' do
|
98
|
+
it 'accepts valid input' do
|
99
|
+
get '/', name: 'bob'
|
100
|
+
expect(last_response.status).to eq(200)
|
101
|
+
end
|
102
|
+
|
103
|
+
it 'accepts empty input when allow_blank is false' do
|
104
|
+
get '/allow_blank', name: ''
|
105
|
+
expect(last_response.status).to eq(200)
|
106
|
+
end
|
107
|
+
end
|
108
|
+
|
109
|
+
context 'in an optional group' do
|
110
|
+
context 'as a required param' do
|
111
|
+
it 'accepts a missing group, even with a disallwed blank param' do
|
112
|
+
get '/disallow_blank_required_param_in_an_optional_group'
|
113
|
+
expect(last_response.status).to eq(200)
|
114
|
+
end
|
115
|
+
|
116
|
+
it 'refuses a blank value in an existing group' do
|
117
|
+
get '/disallow_blank_required_param_in_an_optional_group', user: { name: '' }
|
118
|
+
expect(last_response.status).to eq(400)
|
119
|
+
end
|
120
|
+
end
|
121
|
+
|
122
|
+
context 'as an optional param' do
|
123
|
+
it 'accepts a missing group, even with a disallwed blank param' do
|
124
|
+
get '/disallow_blank_optional_param_in_an_optional_group'
|
125
|
+
expect(last_response.status).to eq(200)
|
126
|
+
end
|
127
|
+
|
128
|
+
it 'accepts a nested missing optional value' do
|
129
|
+
get '/disallow_blank_optional_param_in_an_optional_group', user: { age: '29' }
|
130
|
+
expect(last_response.status).to eq(200)
|
131
|
+
end
|
132
|
+
|
133
|
+
it 'refuses a blank existing value in an existing scope' do
|
134
|
+
get '/disallow_blank_optional_param_in_an_optional_group', user: { age: '29', name: '' }
|
135
|
+
expect(last_response.status).to eq(400)
|
136
|
+
end
|
137
|
+
end
|
138
|
+
end
|
139
|
+
|
140
|
+
context 'in a required group' do
|
141
|
+
context 'as a required param' do
|
142
|
+
it 'refuses a blank value in a required existing group' do
|
143
|
+
get '/disallow_blank_required_param_in_a_required_group', user: { name: '' }
|
144
|
+
expect(last_response.status).to eq(400)
|
145
|
+
end
|
146
|
+
|
147
|
+
it 'refuses a string value in a required hash group' do
|
148
|
+
get '/disallow_string_value_in_a_required_hash_group', user: ''
|
149
|
+
expect(last_response.status).to eq(400)
|
150
|
+
end
|
151
|
+
end
|
152
|
+
|
153
|
+
context 'as an optional param' do
|
154
|
+
it 'accepts a nested missing value' do
|
155
|
+
get '/disallow_blank_optional_param_in_a_required_group', user: { age: '29' }
|
156
|
+
expect(last_response.status).to eq(200)
|
157
|
+
end
|
158
|
+
|
159
|
+
it 'refuses a blank existing value in an existing scope' do
|
160
|
+
get '/disallow_blank_optional_param_in_a_required_group', user: { age: '29', name: '' }
|
161
|
+
expect(last_response.status).to eq(400)
|
162
|
+
end
|
163
|
+
|
164
|
+
it 'refuses a string value in an optional hash group' do
|
165
|
+
get '/disallow_string_value_in_an_optional_hash_group', user: ''
|
166
|
+
expect(last_response.status).to eq(400)
|
167
|
+
end
|
168
|
+
end
|
169
|
+
end
|
170
|
+
end
|