grape 0.6.0 → 0.6.1
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of grape might be problematic. Click here for more details.
- checksums.yaml +8 -8
- data/.rubocop.yml +65 -0
- data/.travis.yml +4 -0
- data/CHANGELOG.md +17 -1
- data/Gemfile +1 -0
- data/README.md +16 -8
- data/RELEASING.md +105 -0
- data/grape.gemspec +1 -1
- data/lib/grape.rb +1 -0
- data/lib/grape/api.rb +88 -54
- data/lib/grape/cookies.rb +4 -6
- data/lib/grape/endpoint.rb +81 -69
- data/lib/grape/error_formatter/base.rb +5 -4
- data/lib/grape/error_formatter/json.rb +3 -3
- data/lib/grape/error_formatter/txt.rb +1 -1
- data/lib/grape/error_formatter/xml.rb +4 -4
- data/lib/grape/exceptions/base.rb +7 -7
- data/lib/grape/exceptions/incompatible_option_values.rb +13 -0
- 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 -4
- 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 +2 -2
- data/lib/grape/exceptions/validation_errors.rb +1 -1
- data/lib/grape/formatter/base.rb +5 -4
- data/lib/grape/formatter/serializable_hash.rb +7 -6
- data/lib/grape/http/request.rb +2 -2
- data/lib/grape/locale/en.yml +2 -0
- data/lib/grape/middleware/auth/base.rb +3 -3
- data/lib/grape/middleware/auth/basic.rb +1 -1
- data/lib/grape/middleware/auth/oauth2.rb +18 -20
- data/lib/grape/middleware/base.rb +1 -1
- data/lib/grape/middleware/error.rb +19 -19
- data/lib/grape/middleware/filter.rb +3 -3
- data/lib/grape/middleware/formatter.rb +29 -23
- data/lib/grape/middleware/versioner.rb +1 -1
- data/lib/grape/middleware/versioner/accept_version_header.rb +8 -6
- data/lib/grape/middleware/versioner/header.rb +16 -14
- data/lib/grape/middleware/versioner/param.rb +7 -7
- data/lib/grape/middleware/versioner/path.rb +7 -9
- data/lib/grape/parser/base.rb +3 -2
- data/lib/grape/path.rb +1 -1
- data/lib/grape/route.rb +6 -4
- data/lib/grape/util/content_types.rb +2 -1
- data/lib/grape/util/deep_merge.rb +5 -5
- data/lib/grape/util/hash_stack.rb +2 -2
- data/lib/grape/validations.rb +34 -30
- data/lib/grape/validations/coerce.rb +6 -5
- data/lib/grape/validations/default.rb +0 -1
- data/lib/grape/validations/presence.rb +1 -1
- data/lib/grape/validations/regexp.rb +2 -2
- data/lib/grape/validations/values.rb +16 -0
- data/lib/grape/version.rb +1 -1
- data/spec/grape/api_spec.rb +229 -210
- data/spec/grape/endpoint_spec.rb +56 -54
- data/spec/grape/entity_spec.rb +31 -33
- data/spec/grape/exceptions/missing_mime_type_spec.rb +3 -9
- data/spec/grape/middleware/auth/basic_spec.rb +8 -8
- data/spec/grape/middleware/auth/digest_spec.rb +5 -5
- data/spec/grape/middleware/auth/oauth2_spec.rb +23 -23
- data/spec/grape/middleware/base_spec.rb +6 -6
- data/spec/grape/middleware/error_spec.rb +11 -15
- data/spec/grape/middleware/exception_spec.rb +45 -25
- data/spec/grape/middleware/formatter_spec.rb +56 -45
- data/spec/grape/middleware/versioner/accept_version_header_spec.rb +25 -25
- data/spec/grape/middleware/versioner/header_spec.rb +54 -54
- data/spec/grape/middleware/versioner/param_spec.rb +17 -18
- data/spec/grape/middleware/versioner/path_spec.rb +6 -6
- data/spec/grape/middleware/versioner_spec.rb +1 -1
- data/spec/grape/util/hash_stack_spec.rb +26 -27
- data/spec/grape/validations/coerce_spec.rb +39 -34
- data/spec/grape/validations/default_spec.rb +12 -13
- data/spec/grape/validations/presence_spec.rb +18 -22
- data/spec/grape/validations/regexp_spec.rb +9 -9
- data/spec/grape/validations/values_spec.rb +64 -0
- data/spec/grape/validations_spec.rb +127 -70
- data/spec/shared/versioning_examples.rb +5 -5
- data/spec/support/basic_auth_encode_helpers.rb +0 -1
- data/spec/support/versioned_helpers.rb +5 -6
- metadata +10 -4
@@ -14,10 +14,10 @@ describe Grape::Validations::PresenceValidator do
|
|
14
14
|
end
|
15
15
|
|
16
16
|
params do
|
17
|
-
requires :id, :
|
17
|
+
requires :id, regexp: /^[0-9]+$/
|
18
18
|
end
|
19
19
|
post do
|
20
|
-
{ :
|
20
|
+
{ ret: params[:id] }
|
21
21
|
end
|
22
22
|
|
23
23
|
params do
|
@@ -58,7 +58,7 @@ describe Grape::Validations::PresenceValidator do
|
|
58
58
|
end
|
59
59
|
|
60
60
|
it 'does not validate for any params' do
|
61
|
-
get
|
61
|
+
get "/bacons"
|
62
62
|
last_response.status.should == 200
|
63
63
|
last_response.body.should == "All the bacon".to_json
|
64
64
|
end
|
@@ -69,74 +69,70 @@ describe Grape::Validations::PresenceValidator do
|
|
69
69
|
last_response.body.should == '{"error":"id is missing"}'
|
70
70
|
|
71
71
|
io = StringIO.new('{"id" : "a56b"}')
|
72
|
-
post '/', {}, 'rack.input' => io,
|
73
|
-
'CONTENT_TYPE' => 'application/json',
|
74
|
-
'CONTENT_LENGTH' => io.length
|
72
|
+
post '/', {}, 'rack.input' => io, 'CONTENT_TYPE' => 'application/json', 'CONTENT_LENGTH' => io.length
|
75
73
|
last_response.body.should == '{"error":"id is invalid"}'
|
76
74
|
last_response.status.should == 400
|
77
75
|
|
78
76
|
io = StringIO.new('{"id" : 56}')
|
79
|
-
post '/', {}, 'rack.input' => io,
|
80
|
-
'CONTENT_TYPE' => 'application/json',
|
81
|
-
'CONTENT_LENGTH' => io.length
|
77
|
+
post '/', {}, 'rack.input' => io, 'CONTENT_TYPE' => 'application/json', 'CONTENT_LENGTH' => io.length
|
82
78
|
last_response.body.should == '{"ret":56}'
|
83
79
|
last_response.status.should == 201
|
84
80
|
end
|
85
81
|
|
86
82
|
it 'validates name, company' do
|
87
|
-
get
|
83
|
+
get '/'
|
88
84
|
last_response.status.should == 400
|
89
85
|
last_response.body.should == '{"error":"name is missing"}'
|
90
86
|
|
91
|
-
get
|
87
|
+
get '/', name: "Bob"
|
92
88
|
last_response.status.should == 400
|
93
89
|
last_response.body.should == '{"error":"company is missing"}'
|
94
90
|
|
95
|
-
get
|
91
|
+
get '/', name: "Bob", company: "TestCorp"
|
96
92
|
last_response.status.should == 200
|
97
93
|
last_response.body.should == "Hello".to_json
|
98
94
|
end
|
99
95
|
|
100
96
|
it 'validates nested parameters' do
|
101
|
-
get
|
97
|
+
get '/nested'
|
102
98
|
last_response.status.should == 400
|
103
99
|
last_response.body.should == '{"error":"user[first_name] is missing"}'
|
104
100
|
|
105
|
-
get
|
101
|
+
get '/nested', user: { first_name: "Billy" }
|
106
102
|
last_response.status.should == 400
|
107
103
|
last_response.body.should == '{"error":"user[last_name] is missing"}'
|
108
104
|
|
109
|
-
get
|
105
|
+
get '/nested', user: { first_name: "Billy", last_name: "Bob" }
|
110
106
|
last_response.status.should == 200
|
111
107
|
last_response.body.should == "Nested".to_json
|
112
108
|
end
|
113
109
|
|
114
110
|
it 'validates triple nested parameters' do
|
115
|
-
get
|
111
|
+
get '/nested_triple'
|
116
112
|
last_response.status.should == 400
|
117
113
|
last_response.body.should == '{"error":"admin[admin_name] is missing, admin[super][user][first_name] is missing"}'
|
118
114
|
|
119
|
-
get
|
115
|
+
get '/nested_triple', user: { first_name: "Billy" }
|
120
116
|
last_response.status.should == 400
|
121
117
|
last_response.body.should == '{"error":"admin[admin_name] is missing, admin[super][user][first_name] is missing"}'
|
122
118
|
|
123
|
-
get
|
119
|
+
get '/nested_triple', admin: { super: { first_name: "Billy" } }
|
124
120
|
last_response.status.should == 400
|
125
121
|
last_response.body.should == '{"error":"admin[admin_name] is missing, admin[super][user][first_name] is missing"}'
|
126
122
|
|
127
|
-
get
|
123
|
+
get '/nested_triple', super: { user: { first_name: "Billy", last_name: "Bob" } }
|
128
124
|
last_response.status.should == 400
|
129
125
|
last_response.body.should == '{"error":"admin[admin_name] is missing, admin[super][user][first_name] is missing"}'
|
130
126
|
|
131
|
-
get
|
127
|
+
get '/nested_triple', admin: { super: { user: { first_name: "Billy" } } }
|
132
128
|
last_response.status.should == 400
|
133
129
|
last_response.body.should == '{"error":"admin[admin_name] is missing, admin[super][user][last_name] is missing"}'
|
134
130
|
|
135
|
-
get
|
131
|
+
get '/nested_triple', admin: { admin_name: 'admin', super: { user: { first_name: "Billy" } } }
|
136
132
|
last_response.status.should == 400
|
137
133
|
last_response.body.should == '{"error":"admin[super][user][last_name] is missing"}'
|
138
134
|
|
139
|
-
get
|
135
|
+
get '/nested_triple', admin: { admin_name: 'admin', super: { user: { first_name: "Billy", last_name: "Bob" } } }
|
140
136
|
last_response.status.should == 200
|
141
137
|
last_response.body.should == "Nested triple".to_json
|
142
138
|
end
|
@@ -5,29 +5,29 @@ describe Grape::Validations::RegexpValidator do
|
|
5
5
|
module RegexpValidatorSpec
|
6
6
|
class API < Grape::API
|
7
7
|
default_format :json
|
8
|
-
|
8
|
+
|
9
9
|
params do
|
10
|
-
requires :name, :
|
10
|
+
requires :name, regexp: /^[a-z]+$/
|
11
11
|
end
|
12
12
|
get do
|
13
|
-
|
13
|
+
|
14
14
|
end
|
15
15
|
end
|
16
16
|
end
|
17
17
|
end
|
18
|
-
|
18
|
+
|
19
19
|
def app
|
20
20
|
ValidationsSpec::RegexpValidatorSpec::API
|
21
21
|
end
|
22
|
-
|
22
|
+
|
23
23
|
it 'refuses invalid input' do
|
24
|
-
get '/', :
|
24
|
+
get '/', name: "invalid name"
|
25
25
|
last_response.status.should == 400
|
26
26
|
end
|
27
|
-
|
27
|
+
|
28
28
|
it 'accepts valid input' do
|
29
|
-
get '/', :
|
29
|
+
get '/', name: "bob"
|
30
30
|
last_response.status.should == 200
|
31
31
|
end
|
32
|
-
|
32
|
+
|
33
33
|
end
|
@@ -0,0 +1,64 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Grape::Validations::ValuesValidator do
|
4
|
+
|
5
|
+
module ValidationsSpec
|
6
|
+
module ValuesValidatorSpec
|
7
|
+
class API < Grape::API
|
8
|
+
default_format :json
|
9
|
+
|
10
|
+
params do
|
11
|
+
requires :type, values: ['valid-type1', 'valid-type2', 'valid-type3']
|
12
|
+
end
|
13
|
+
get '/' do
|
14
|
+
{ type: params[:type] }
|
15
|
+
end
|
16
|
+
|
17
|
+
params do
|
18
|
+
optional :type, values: ['valid-type1', 'valid-type2', 'valid-type3'], default: 'valid-type2'
|
19
|
+
end
|
20
|
+
get '/default/valid' do
|
21
|
+
{ type: params[:type] }
|
22
|
+
end
|
23
|
+
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
def app
|
29
|
+
ValidationsSpec::ValuesValidatorSpec::API
|
30
|
+
end
|
31
|
+
|
32
|
+
it 'allows a valid value for a parameter' do
|
33
|
+
get("/", type: 'valid-type1')
|
34
|
+
last_response.status.should eq 200
|
35
|
+
last_response.body.should eq({ type: "valid-type1" }.to_json)
|
36
|
+
end
|
37
|
+
|
38
|
+
it 'does not allow an invalid value for a parameter' do
|
39
|
+
get("/", type: 'invalid-type')
|
40
|
+
last_response.status.should eq 400
|
41
|
+
last_response.body.should eq({ error: "type does not have a valid value" }.to_json)
|
42
|
+
end
|
43
|
+
|
44
|
+
it 'allows a valid default value' do
|
45
|
+
get("/default/valid")
|
46
|
+
last_response.status.should eq 200
|
47
|
+
last_response.body.should eq({ type: "valid-type2" }.to_json)
|
48
|
+
end
|
49
|
+
|
50
|
+
it 'raises IncompatibleOptionValues on an invalid default value' do
|
51
|
+
subject = Class.new(Grape::API)
|
52
|
+
expect {
|
53
|
+
subject.params { optional :type, values: ['valid-type1', 'valid-type2', 'valid-type3'], default: 'invalid-type' }
|
54
|
+
}.to raise_error Grape::Exceptions::IncompatibleOptionValues
|
55
|
+
end
|
56
|
+
|
57
|
+
it 'raises IncompatibleOptionValues when type is incompatible with values array' do
|
58
|
+
subject = Class.new(Grape::API)
|
59
|
+
expect {
|
60
|
+
subject.params { optional :type, values: ['valid-type1', 'valid-type2', 'valid-type3'], type: Symbol }
|
61
|
+
}.to raise_error Grape::Exceptions::IncompatibleOptionValues
|
62
|
+
end
|
63
|
+
|
64
|
+
end
|
@@ -1,27 +1,39 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
|
3
3
|
describe Grape::Validations do
|
4
|
+
|
4
5
|
subject { Class.new(Grape::API) }
|
5
|
-
|
6
|
+
|
7
|
+
def app
|
8
|
+
subject
|
9
|
+
end
|
6
10
|
|
7
11
|
describe 'params' do
|
8
12
|
context 'optional' do
|
9
13
|
it 'validates when params is present' do
|
10
|
-
subject.params
|
11
|
-
|
14
|
+
subject.params do
|
15
|
+
optional :a_number, regexp: /^[0-9]+$/
|
16
|
+
end
|
17
|
+
subject.get '/optional' do
|
18
|
+
'optional works!'
|
19
|
+
end
|
12
20
|
|
13
|
-
get '/optional',
|
21
|
+
get '/optional', a_number: 'string'
|
14
22
|
last_response.status.should == 400
|
15
23
|
last_response.body.should == 'a_number is invalid'
|
16
24
|
|
17
|
-
get '/optional',
|
25
|
+
get '/optional', a_number: 45
|
18
26
|
last_response.status.should == 200
|
19
27
|
last_response.body.should == 'optional works!'
|
20
28
|
end
|
21
29
|
|
22
30
|
it "doesn't validate when param not present" do
|
23
|
-
subject.params
|
24
|
-
|
31
|
+
subject.params do
|
32
|
+
optional :a_number, regexp: /^[0-9]+$/
|
33
|
+
end
|
34
|
+
subject.get '/optional' do
|
35
|
+
'optional works!'
|
36
|
+
end
|
25
37
|
|
26
38
|
get '/optional'
|
27
39
|
last_response.status.should == 200
|
@@ -29,15 +41,21 @@ describe Grape::Validations do
|
|
29
41
|
end
|
30
42
|
|
31
43
|
it 'adds to declared parameters' do
|
32
|
-
subject.params
|
44
|
+
subject.params do
|
45
|
+
optional :some_param
|
46
|
+
end
|
33
47
|
subject.settings[:declared_params].should == [:some_param]
|
34
48
|
end
|
35
49
|
end
|
36
50
|
|
37
51
|
context 'required' do
|
38
52
|
before do
|
39
|
-
subject.params
|
40
|
-
|
53
|
+
subject.params do
|
54
|
+
requires :key
|
55
|
+
end
|
56
|
+
subject.get '/required' do
|
57
|
+
'required works'
|
58
|
+
end
|
41
59
|
end
|
42
60
|
|
43
61
|
it 'errors when param not present' do
|
@@ -47,25 +65,29 @@ describe Grape::Validations do
|
|
47
65
|
end
|
48
66
|
|
49
67
|
it "doesn't throw a missing param when param is present" do
|
50
|
-
get '/required',
|
68
|
+
get '/required', key: 'cool'
|
51
69
|
last_response.status.should == 200
|
52
70
|
last_response.body.should == 'required works'
|
53
71
|
end
|
54
72
|
|
55
73
|
it 'adds to declared parameters' do
|
56
|
-
subject.params
|
74
|
+
subject.params do
|
75
|
+
requires :some_param
|
76
|
+
end
|
57
77
|
subject.settings[:declared_params].should == [:some_param]
|
58
78
|
end
|
59
79
|
end
|
60
80
|
|
61
81
|
context 'required with a block' do
|
62
82
|
before do
|
63
|
-
subject.params
|
83
|
+
subject.params do
|
64
84
|
requires :items do
|
65
85
|
requires :key
|
66
86
|
end
|
67
|
-
|
68
|
-
subject.get '/required' do
|
87
|
+
end
|
88
|
+
subject.get '/required' do
|
89
|
+
'required works'
|
90
|
+
end
|
69
91
|
end
|
70
92
|
|
71
93
|
it 'errors when param not present' do
|
@@ -75,39 +97,41 @@ describe Grape::Validations do
|
|
75
97
|
end
|
76
98
|
|
77
99
|
it "doesn't throw a missing param when param is present" do
|
78
|
-
get '/required',
|
100
|
+
get '/required', items: [key: 'hello', key: 'world']
|
79
101
|
last_response.status.should == 200
|
80
102
|
last_response.body.should == 'required works'
|
81
103
|
end
|
82
104
|
|
83
105
|
it "doesn't allow more than one parameter" do
|
84
106
|
expect {
|
85
|
-
subject.params
|
107
|
+
subject.params do
|
86
108
|
requires(:items, desc: 'Foo') do
|
87
109
|
requires :key
|
88
110
|
end
|
89
|
-
|
111
|
+
end
|
90
112
|
}.to raise_error ArgumentError
|
91
113
|
end
|
92
114
|
|
93
115
|
it 'adds to declared parameters' do
|
94
|
-
subject.params
|
116
|
+
subject.params do
|
95
117
|
requires :items do
|
96
118
|
requires :key
|
97
119
|
end
|
98
|
-
|
99
|
-
subject.settings[:declared_params].should == [:
|
120
|
+
end
|
121
|
+
subject.settings[:declared_params].should == [items: [:key]]
|
100
122
|
end
|
101
123
|
end
|
102
124
|
|
103
125
|
context 'group' do
|
104
126
|
before do
|
105
|
-
subject.params
|
127
|
+
subject.params do
|
106
128
|
group :items do
|
107
129
|
requires :key
|
108
130
|
end
|
109
|
-
|
110
|
-
subject.get '/required' do
|
131
|
+
end
|
132
|
+
subject.get '/required' do
|
133
|
+
'required works'
|
134
|
+
end
|
111
135
|
end
|
112
136
|
|
113
137
|
it 'errors when param not present' do
|
@@ -117,29 +141,31 @@ describe Grape::Validations do
|
|
117
141
|
end
|
118
142
|
|
119
143
|
it "doesn't throw a missing param when param is present" do
|
120
|
-
get '/required',
|
144
|
+
get '/required', items: [key: 'hello', key: 'world']
|
121
145
|
last_response.status.should == 200
|
122
146
|
last_response.body.should == 'required works'
|
123
147
|
end
|
124
148
|
|
125
149
|
it 'adds to declared parameters' do
|
126
|
-
subject.params
|
150
|
+
subject.params do
|
127
151
|
group :items do
|
128
152
|
requires :key
|
129
153
|
end
|
130
|
-
|
131
|
-
subject.settings[:declared_params].should == [:
|
154
|
+
end
|
155
|
+
subject.settings[:declared_params].should == [items: [:key]]
|
132
156
|
end
|
133
157
|
end
|
134
158
|
|
135
159
|
context 'optional with a block' do
|
136
160
|
before do
|
137
|
-
subject.params
|
161
|
+
subject.params do
|
138
162
|
optional :items do
|
139
163
|
requires :key
|
140
164
|
end
|
141
|
-
|
142
|
-
subject.get '/optional_group' do
|
165
|
+
end
|
166
|
+
subject.get '/optional_group' do
|
167
|
+
'optional group works'
|
168
|
+
end
|
143
169
|
end
|
144
170
|
|
145
171
|
it "doesn't throw a missing param when the group isn't present" do
|
@@ -149,36 +175,36 @@ describe Grape::Validations do
|
|
149
175
|
end
|
150
176
|
|
151
177
|
it "doesn't throw a missing param when both group and param are given" do
|
152
|
-
get '/optional_group',
|
178
|
+
get '/optional_group', items: { key: 'foo' }
|
153
179
|
last_response.status.should == 200
|
154
180
|
last_response.body.should == 'optional group works'
|
155
181
|
end
|
156
182
|
|
157
183
|
it "errors when group is present, but required param is not" do
|
158
|
-
get '/optional_group',
|
184
|
+
get '/optional_group', items: { not_key: 'foo' }
|
159
185
|
last_response.status.should == 400
|
160
186
|
last_response.body.should == 'items[key] is missing'
|
161
187
|
end
|
162
188
|
|
163
189
|
it 'adds to declared parameters' do
|
164
|
-
subject.params
|
190
|
+
subject.params do
|
165
191
|
optional :items do
|
166
192
|
requires :key
|
167
193
|
end
|
168
|
-
|
169
|
-
subject.settings[:declared_params].should == [:
|
194
|
+
end
|
195
|
+
subject.settings[:declared_params].should == [items: [:key]]
|
170
196
|
end
|
171
197
|
end
|
172
198
|
|
173
199
|
context 'nested optional blocks' do
|
174
200
|
before do
|
175
|
-
subject.params
|
201
|
+
subject.params do
|
176
202
|
optional :items do
|
177
203
|
requires :key
|
178
204
|
optional(:optional_subitems) { requires :value }
|
179
205
|
requires(:required_subitems) { requires :value }
|
180
206
|
end
|
181
|
-
|
207
|
+
end
|
182
208
|
subject.get('/nested_optional_group') { 'nested optional group works' }
|
183
209
|
end
|
184
210
|
|
@@ -189,41 +215,46 @@ describe Grape::Validations do
|
|
189
215
|
end
|
190
216
|
|
191
217
|
it 'does internal validations if the outer group is present' do
|
192
|
-
get '/nested_optional_group',
|
218
|
+
get '/nested_optional_group', items: { key: 'foo' }
|
193
219
|
last_response.status.should == 400
|
194
220
|
last_response.body.should == 'items[required_subitems][value] is missing'
|
195
221
|
|
196
|
-
get '/nested_optional_group',
|
222
|
+
get '/nested_optional_group', items: { key: 'foo', required_subitems: { value: 'bar' } }
|
197
223
|
last_response.status.should == 200
|
198
224
|
last_response.body.should == 'nested optional group works'
|
199
225
|
end
|
200
226
|
|
201
227
|
it 'handles deep nesting' do
|
202
|
-
get '/nested_optional_group',
|
228
|
+
get '/nested_optional_group', items: { key: 'foo', required_subitems: { value: 'bar' }, optional_subitems: { not_value: 'baz' } }
|
203
229
|
last_response.status.should == 400
|
204
230
|
last_response.body.should == 'items[optional_subitems][value] is missing'
|
205
231
|
|
206
|
-
get '/nested_optional_group',
|
232
|
+
get '/nested_optional_group', items: { key: 'foo', required_subitems: { value: 'bar' }, optional_subitems: { value: 'baz' } }
|
207
233
|
last_response.status.should == 200
|
208
234
|
last_response.body.should == 'nested optional group works'
|
209
235
|
end
|
210
236
|
|
211
237
|
it 'adds to declared parameters' do
|
212
|
-
subject.params
|
238
|
+
subject.params do
|
213
239
|
optional :items do
|
214
240
|
requires :key
|
215
241
|
optional(:optional_subitems) { requires :value }
|
216
242
|
requires(:required_subitems) { requires :value }
|
217
243
|
end
|
218
|
-
|
219
|
-
subject.settings[:declared_params].should == [:
|
244
|
+
end
|
245
|
+
subject.settings[:declared_params].should == [items: [:key, { optional_subitems: [:value] }, { required_subitems: [:value] }]]
|
220
246
|
end
|
221
247
|
end
|
222
248
|
|
223
249
|
context 'multiple validation errors' do
|
224
250
|
before do
|
225
|
-
subject.params
|
226
|
-
|
251
|
+
subject.params do
|
252
|
+
requires :yolo
|
253
|
+
requires :swag
|
254
|
+
end
|
255
|
+
subject.get '/two_required' do
|
256
|
+
'two required works'
|
257
|
+
end
|
227
258
|
end
|
228
259
|
|
229
260
|
it 'throws the validation errors' do
|
@@ -239,7 +270,7 @@ describe Grape::Validations do
|
|
239
270
|
class Customvalidator < Grape::Validations::Validator
|
240
271
|
def validate_param!(attr_name, params)
|
241
272
|
unless params[attr_name] == 'im custom'
|
242
|
-
raise Grape::Exceptions::Validation, :
|
273
|
+
raise Grape::Exceptions::Validation, param: @scope.full_name(attr_name), message: "is not custom!"
|
243
274
|
end
|
244
275
|
end
|
245
276
|
end
|
@@ -247,16 +278,20 @@ describe Grape::Validations do
|
|
247
278
|
|
248
279
|
context 'when using optional with a custom validator' do
|
249
280
|
before do
|
250
|
-
subject.params
|
251
|
-
|
281
|
+
subject.params do
|
282
|
+
optional :custom, customvalidator: true
|
283
|
+
end
|
284
|
+
subject.get '/optional_custom' do
|
285
|
+
'optional with custom works!'
|
286
|
+
end
|
252
287
|
end
|
253
288
|
|
254
289
|
it 'validates when param is present' do
|
255
|
-
get '/optional_custom', { :
|
290
|
+
get '/optional_custom', { custom: 'im custom' }
|
256
291
|
last_response.status.should == 200
|
257
292
|
last_response.body.should == 'optional with custom works!'
|
258
293
|
|
259
|
-
get '/optional_custom', { :
|
294
|
+
get '/optional_custom', { custom: 'im wrong' }
|
260
295
|
last_response.status.should == 400
|
261
296
|
last_response.body.should == 'custom is not custom!'
|
262
297
|
end
|
@@ -268,9 +303,11 @@ describe Grape::Validations do
|
|
268
303
|
end
|
269
304
|
|
270
305
|
it 'validates with custom validator when param present and incorrect type' do
|
271
|
-
subject.params
|
306
|
+
subject.params do
|
307
|
+
optional :custom, type: String, customvalidator: true
|
308
|
+
end
|
272
309
|
|
273
|
-
get '/optional_custom',
|
310
|
+
get '/optional_custom', custom: 123
|
274
311
|
last_response.status.should == 400
|
275
312
|
last_response.body.should == 'custom is not custom!'
|
276
313
|
end
|
@@ -278,16 +315,20 @@ describe Grape::Validations do
|
|
278
315
|
|
279
316
|
context 'when using requires with a custom validator' do
|
280
317
|
before do
|
281
|
-
subject.params
|
282
|
-
|
318
|
+
subject.params do
|
319
|
+
requires :custom, customvalidator: true
|
320
|
+
end
|
321
|
+
subject.get '/required_custom' do
|
322
|
+
'required with custom works!'
|
323
|
+
end
|
283
324
|
end
|
284
325
|
|
285
326
|
it 'validates when param is present' do
|
286
|
-
get '/required_custom',
|
327
|
+
get '/required_custom', custom: 'im wrong, validate me'
|
287
328
|
last_response.status.should == 400
|
288
329
|
last_response.body.should == 'custom is not custom!'
|
289
330
|
|
290
|
-
get '/required_custom',
|
331
|
+
get '/required_custom', custom: 'im custom'
|
291
332
|
last_response.status.should == 200
|
292
333
|
last_response.body.should == 'required with custom works!'
|
293
334
|
end
|
@@ -300,50 +341,66 @@ describe Grape::Validations do
|
|
300
341
|
|
301
342
|
context 'nested namespaces' do
|
302
343
|
before do
|
303
|
-
subject.params
|
344
|
+
subject.params do
|
345
|
+
requires :custom, customvalidator: true
|
346
|
+
end
|
304
347
|
subject.namespace 'nested' do
|
305
|
-
get 'one' do
|
348
|
+
get 'one' do
|
349
|
+
'validation failed'
|
350
|
+
end
|
306
351
|
namespace 'nested' do
|
307
|
-
get 'two' do
|
352
|
+
get 'two' do
|
353
|
+
'validation failed'
|
354
|
+
end
|
308
355
|
end
|
309
356
|
end
|
310
357
|
subject.namespace 'peer' do
|
311
|
-
get 'one' do
|
358
|
+
get 'one' do
|
359
|
+
'no validation required'
|
360
|
+
end
|
312
361
|
namespace 'nested' do
|
313
|
-
get 'two' do
|
362
|
+
get 'two' do
|
363
|
+
'no validation required'
|
364
|
+
end
|
314
365
|
end
|
315
366
|
end
|
316
367
|
|
317
368
|
subject.namespace 'unrelated' do
|
318
|
-
params
|
319
|
-
|
369
|
+
params do
|
370
|
+
requires :name
|
371
|
+
end
|
372
|
+
get 'one' do
|
373
|
+
'validation required'
|
374
|
+
end
|
320
375
|
|
321
376
|
namespace 'double' do
|
322
|
-
get 'two' do
|
377
|
+
get 'two' do
|
378
|
+
'no validation required'
|
379
|
+
end
|
323
380
|
end
|
324
381
|
end
|
325
382
|
end
|
326
383
|
|
327
384
|
specify 'the parent namespace uses the validator' do
|
328
|
-
get '/nested/one',
|
385
|
+
get '/nested/one', custom: 'im wrong, validate me'
|
329
386
|
last_response.status.should == 400
|
330
387
|
last_response.body.should == 'custom is not custom!'
|
331
388
|
end
|
332
389
|
|
333
390
|
specify 'the nested namesapce inherits the custom validator' do
|
334
|
-
get '/nested/nested/two',
|
391
|
+
get '/nested/nested/two', custom: 'im wrong, validate me'
|
335
392
|
last_response.status.should == 400
|
336
393
|
last_response.body.should == 'custom is not custom!'
|
337
394
|
end
|
338
395
|
|
339
396
|
specify 'peer namesapces does not have the validator' do
|
340
|
-
get '/peer/one',
|
397
|
+
get '/peer/one', custom: 'im not validated'
|
341
398
|
last_response.status.should == 200
|
342
399
|
last_response.body.should == 'no validation required'
|
343
400
|
end
|
344
401
|
|
345
402
|
specify 'namespaces nested in peers should also not have the validator' do
|
346
|
-
get '/peer/nested/two',
|
403
|
+
get '/peer/nested/two', custom: 'im not validated'
|
347
404
|
last_response.status.should == 200
|
348
405
|
last_response.body.should == 'no validation required'
|
349
406
|
end
|