grape 0.18.0 → 0.19.0
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 +4 -4
- data/CHANGELOG.md +52 -69
- data/Gemfile +3 -3
- data/Gemfile.lock +37 -41
- data/README.md +49 -7
- data/UPGRADING.md +56 -1
- data/gemfiles/rack_edge.gemfile +34 -0
- data/gemfiles/rails_5.gemfile +1 -1
- data/gemfiles/rails_edge.gemfile +34 -0
- data/lib/grape/api.rb +1 -1
- data/lib/grape/dsl/helpers.rb +1 -0
- data/lib/grape/dsl/inside_route.rb +2 -0
- data/lib/grape/dsl/parameters.rb +24 -12
- data/lib/grape/dsl/request_response.rb +2 -3
- data/lib/grape/dsl/routing.rb +4 -0
- data/lib/grape/endpoint.rb +15 -16
- data/lib/grape/error_formatter/base.rb +1 -0
- data/lib/grape/formatter/serializable_hash.rb +2 -2
- data/lib/grape/http/headers.rb +2 -0
- data/lib/grape/middleware/base.rb +3 -4
- data/lib/grape/middleware/error.rb +1 -1
- data/lib/grape/middleware/versioner/path.rb +1 -1
- data/lib/grape/router.rb +37 -21
- data/lib/grape/router/attribute_translator.rb +1 -1
- data/lib/grape/router/pattern.rb +9 -1
- data/lib/grape/router/route.rb +4 -0
- data/lib/grape/validations/params_scope.rb +24 -6
- data/lib/grape/validations/validators/base.rb +1 -2
- data/lib/grape/validations/validators/regexp.rb +2 -1
- data/lib/grape/version.rb +1 -1
- data/pkg/grape-0.17.0.gem +0 -0
- data/spec/grape/api/patch_method_helpers_spec.rb +1 -2
- data/spec/grape/api_spec.rb +87 -21
- data/spec/grape/dsl/desc_spec.rb +2 -4
- data/spec/grape/dsl/inside_route_spec.rb +29 -22
- data/spec/grape/dsl/parameters_spec.rb +15 -1
- data/spec/grape/endpoint_spec.rb +53 -19
- data/spec/grape/middleware/formatter_spec.rb +39 -30
- data/spec/grape/middleware/versioner/param_spec.rb +15 -10
- data/spec/grape/middleware/versioner/path_spec.rb +4 -3
- data/spec/grape/util/inheritable_setting_spec.rb +2 -1
- data/spec/grape/util/strict_hash_configuration_spec.rb +1 -2
- data/spec/grape/validations/params_scope_spec.rb +182 -0
- data/spec/grape/validations/validators/default_spec.rb +1 -3
- data/spec/grape/validations/validators/presence_spec.rb +29 -1
- data/spec/grape/validations/validators/regexp_spec.rb +88 -0
- metadata +5 -3
- data/pkg/grape-0.18.0.gem +0 -0
@@ -585,6 +585,25 @@ describe Grape::Validations::ParamsScope do
|
|
585
585
|
expect(JSON.parse(last_response.body)).to eq('bar' => { 'a' => 'x', 'c' => { 'b' => 'yes' } })
|
586
586
|
end
|
587
587
|
|
588
|
+
it 'includes deeply nested parameters within #declared(params)' do
|
589
|
+
subject.params do
|
590
|
+
requires :arr1, type: Array do
|
591
|
+
requires :hash1, type: Hash do
|
592
|
+
requires :arr2, type: Array do
|
593
|
+
requires :hash2, type: Hash do
|
594
|
+
requires :something, type: String
|
595
|
+
end
|
596
|
+
end
|
597
|
+
end
|
598
|
+
end
|
599
|
+
end
|
600
|
+
subject.get('/nested_deep') { declared(params).to_json }
|
601
|
+
|
602
|
+
get '/nested_deep', arr1: [{ hash1: { arr2: [{ hash2: { something: 'value' } }] } }]
|
603
|
+
expect(last_response.status).to eq(200)
|
604
|
+
expect(JSON.parse(last_response.body)).to eq('arr1' => [{ 'hash1' => { 'arr2' => [{ 'hash2' => { 'something' => 'value' } }] } }])
|
605
|
+
end
|
606
|
+
|
588
607
|
context 'failing fast' do
|
589
608
|
context 'when fail_fast is not defined' do
|
590
609
|
it 'does not stop validation' do
|
@@ -624,4 +643,167 @@ describe Grape::Validations::ParamsScope do
|
|
624
643
|
end
|
625
644
|
end
|
626
645
|
end
|
646
|
+
|
647
|
+
context 'when params have group attributes' do
|
648
|
+
context 'with validations' do
|
649
|
+
before do
|
650
|
+
subject.params do
|
651
|
+
with(allow_blank: false) do
|
652
|
+
requires :id
|
653
|
+
optional :name
|
654
|
+
optional :address, allow_blank: true
|
655
|
+
end
|
656
|
+
end
|
657
|
+
subject.get('test')
|
658
|
+
end
|
659
|
+
|
660
|
+
context 'when data is invalid' do
|
661
|
+
before do
|
662
|
+
get 'test', id: '', name: ''
|
663
|
+
end
|
664
|
+
|
665
|
+
it 'returns a validation error' do
|
666
|
+
expect(last_response.status).to eq(400)
|
667
|
+
end
|
668
|
+
|
669
|
+
it 'applies group validations for every parameter' do
|
670
|
+
expect(last_response.body).to eq('id is empty, name is empty')
|
671
|
+
end
|
672
|
+
end
|
673
|
+
|
674
|
+
context 'when parameter has the same validator as a group' do
|
675
|
+
before do
|
676
|
+
get 'test', id: 'id', address: ''
|
677
|
+
end
|
678
|
+
|
679
|
+
it 'returns a successful response' do
|
680
|
+
expect(last_response.status).to eq(200)
|
681
|
+
end
|
682
|
+
|
683
|
+
it 'prioritizes parameter validation over group validation' do
|
684
|
+
expect(last_response.body).to_not include('address is empty')
|
685
|
+
end
|
686
|
+
end
|
687
|
+
end
|
688
|
+
|
689
|
+
context 'with types' do
|
690
|
+
before do
|
691
|
+
subject.params do
|
692
|
+
with(type: Date) do
|
693
|
+
requires :created_at
|
694
|
+
end
|
695
|
+
end
|
696
|
+
subject.get('test') { params[:created_at] }
|
697
|
+
end
|
698
|
+
|
699
|
+
context 'when invalid date provided' do
|
700
|
+
before do
|
701
|
+
get 'test', created_at: 'not_a_date'
|
702
|
+
end
|
703
|
+
|
704
|
+
it 'responds with HTTP error' do
|
705
|
+
expect(last_response.status).to eq(400)
|
706
|
+
end
|
707
|
+
|
708
|
+
it 'returns a validation error' do
|
709
|
+
expect(last_response.body).to eq('created_at is invalid')
|
710
|
+
end
|
711
|
+
end
|
712
|
+
|
713
|
+
context 'when created_at receives a valid date' do
|
714
|
+
before do
|
715
|
+
get 'test', created_at: '2016-01-01'
|
716
|
+
end
|
717
|
+
|
718
|
+
it 'returns a successful response' do
|
719
|
+
expect(last_response.status).to eq(200)
|
720
|
+
end
|
721
|
+
|
722
|
+
it 'returns a date' do
|
723
|
+
expect(last_response.body).to eq('2016-01-01')
|
724
|
+
end
|
725
|
+
end
|
726
|
+
end
|
727
|
+
|
728
|
+
context 'with several group attributes' do
|
729
|
+
before do
|
730
|
+
subject.params do
|
731
|
+
with(values: [1]) do
|
732
|
+
requires :id, type: Integer
|
733
|
+
end
|
734
|
+
|
735
|
+
with(allow_blank: false) do
|
736
|
+
optional :address, type: String
|
737
|
+
end
|
738
|
+
|
739
|
+
requires :name
|
740
|
+
end
|
741
|
+
subject.get('test')
|
742
|
+
end
|
743
|
+
|
744
|
+
context 'when data is invalid' do
|
745
|
+
before do
|
746
|
+
get 'test', id: 2, address: ''
|
747
|
+
end
|
748
|
+
|
749
|
+
it 'responds with HTTP error' do
|
750
|
+
expect(last_response.status).to eq(400)
|
751
|
+
end
|
752
|
+
|
753
|
+
it 'returns a validation error' do
|
754
|
+
expect(last_response.body).to eq('id does not have a valid value, address is empty, name is missing')
|
755
|
+
end
|
756
|
+
end
|
757
|
+
|
758
|
+
context 'when correct data is provided' do
|
759
|
+
before do
|
760
|
+
get 'test', id: 1, address: 'Some street', name: 'John'
|
761
|
+
end
|
762
|
+
|
763
|
+
it 'returns a successful response' do
|
764
|
+
expect(last_response.status).to eq(200)
|
765
|
+
end
|
766
|
+
end
|
767
|
+
end
|
768
|
+
|
769
|
+
context 'with nested groups' do
|
770
|
+
before do
|
771
|
+
subject.params do
|
772
|
+
with(type: Integer) do
|
773
|
+
requires :id
|
774
|
+
|
775
|
+
with(type: Date) do
|
776
|
+
requires :created_at
|
777
|
+
optional :updated_at
|
778
|
+
end
|
779
|
+
end
|
780
|
+
end
|
781
|
+
subject.get('test')
|
782
|
+
end
|
783
|
+
|
784
|
+
context 'when data is invalid' do
|
785
|
+
before do
|
786
|
+
get 'test', id: 'wrong', created_at: 'not_a_date', updated_at: '2016-01-01'
|
787
|
+
end
|
788
|
+
|
789
|
+
it 'responds with HTTP error' do
|
790
|
+
expect(last_response.status).to eq(400)
|
791
|
+
end
|
792
|
+
|
793
|
+
it 'returns a validation error' do
|
794
|
+
expect(last_response.body).to eq('id is invalid, created_at is invalid')
|
795
|
+
end
|
796
|
+
end
|
797
|
+
|
798
|
+
context 'when correct data is provided' do
|
799
|
+
before do
|
800
|
+
get 'test', id: 1, created_at: '2016-01-01'
|
801
|
+
end
|
802
|
+
|
803
|
+
it 'returns a successful response' do
|
804
|
+
expect(last_response.status).to eq(200)
|
805
|
+
end
|
806
|
+
end
|
807
|
+
end
|
808
|
+
end
|
627
809
|
end
|
@@ -93,9 +93,7 @@ describe Grape::Validations::DefaultValidator do
|
|
93
93
|
params = { some_things:
|
94
94
|
[{ foo: 'one', options: [{ name: 'wat', value: 'nope' }] },
|
95
95
|
{ foo: 'two' },
|
96
|
-
{ foo: 'three', options: [{ name: 'wooop', value: 'yap' }] }
|
97
|
-
]
|
98
|
-
}
|
96
|
+
{ foo: 'three', options: [{ name: 'wooop', value: 'yap' }] }] }
|
99
97
|
get '/nested_optional_array', root: params
|
100
98
|
expect(last_response.status).to eq(200)
|
101
99
|
expect(last_response.body).to eq({ root: params }.to_json)
|
@@ -105,6 +105,34 @@ describe Grape::Validations::PresenceValidator do
|
|
105
105
|
end
|
106
106
|
end
|
107
107
|
|
108
|
+
context 'with multiple parameters per requires' do
|
109
|
+
before do
|
110
|
+
subject.params do
|
111
|
+
requires :one, :two
|
112
|
+
end
|
113
|
+
subject.get '/single-requires' do
|
114
|
+
'Hello'
|
115
|
+
end
|
116
|
+
|
117
|
+
subject.params do
|
118
|
+
requires :one
|
119
|
+
requires :two
|
120
|
+
end
|
121
|
+
subject.get '/multiple-requires' do
|
122
|
+
'Hello'
|
123
|
+
end
|
124
|
+
end
|
125
|
+
it 'validates for all defined params' do
|
126
|
+
get '/single-requires'
|
127
|
+
expect(last_response.status).to eq(400)
|
128
|
+
single_requires_error = last_response.body
|
129
|
+
|
130
|
+
get '/multiple-requires'
|
131
|
+
expect(last_response.status).to eq(400)
|
132
|
+
expect(last_response.body).to eq(single_requires_error)
|
133
|
+
end
|
134
|
+
end
|
135
|
+
|
108
136
|
context 'with required parameters and no type' do
|
109
137
|
before do
|
110
138
|
subject.params do
|
@@ -117,7 +145,7 @@ describe Grape::Validations::PresenceValidator do
|
|
117
145
|
it 'validates name, company' do
|
118
146
|
get '/'
|
119
147
|
expect(last_response.status).to eq(400)
|
120
|
-
expect(last_response.body).to eq('{"error":"name is missing"}')
|
148
|
+
expect(last_response.body).to eq('{"error":"name is missing, company is missing"}')
|
121
149
|
|
122
150
|
get '/', name: 'Bob'
|
123
151
|
expect(last_response.status).to eq(400)
|
@@ -12,6 +12,12 @@ describe Grape::Validations::RegexpValidator do
|
|
12
12
|
end
|
13
13
|
get do
|
14
14
|
end
|
15
|
+
|
16
|
+
params do
|
17
|
+
requires :names, type: { value: Array[String], message: 'can\'t be nil' }, regexp: { value: /^[a-z]+$/, message: 'format is invalid' }
|
18
|
+
end
|
19
|
+
get 'regexp_with_array' do
|
20
|
+
end
|
15
21
|
end
|
16
22
|
|
17
23
|
params do
|
@@ -19,6 +25,20 @@ describe Grape::Validations::RegexpValidator do
|
|
19
25
|
end
|
20
26
|
get do
|
21
27
|
end
|
28
|
+
|
29
|
+
params do
|
30
|
+
requires :names, type: Array[String], regexp: /^[a-z]+$/
|
31
|
+
end
|
32
|
+
get 'regexp_with_array' do
|
33
|
+
end
|
34
|
+
|
35
|
+
params do
|
36
|
+
requires :people, type: Hash do
|
37
|
+
requires :names, type: Array[String], regexp: /^[a-z]+$/
|
38
|
+
end
|
39
|
+
end
|
40
|
+
get 'nested_regexp_with_array' do
|
41
|
+
end
|
22
42
|
end
|
23
43
|
end
|
24
44
|
end
|
@@ -51,6 +71,36 @@ describe Grape::Validations::RegexpValidator do
|
|
51
71
|
get '/custom_message', name: 'bob'
|
52
72
|
expect(last_response.status).to eq(200)
|
53
73
|
end
|
74
|
+
|
75
|
+
context 'regexp with array' do
|
76
|
+
it 'refuses inapppopriate items' do
|
77
|
+
get '/custom_message/regexp_with_array', names: ['invalid name', 'abc']
|
78
|
+
expect(last_response.status).to eq(400)
|
79
|
+
expect(last_response.body).to eq('{"error":"names format is invalid"}')
|
80
|
+
end
|
81
|
+
|
82
|
+
it 'refuses empty items' do
|
83
|
+
get '/custom_message/regexp_with_array', names: ['', 'abc']
|
84
|
+
expect(last_response.status).to eq(400)
|
85
|
+
expect(last_response.body).to eq('{"error":"names format is invalid"}')
|
86
|
+
end
|
87
|
+
|
88
|
+
it 'refuses nil items' do
|
89
|
+
get '/custom_message/regexp_with_array', names: [nil, 'abc']
|
90
|
+
expect(last_response.status).to eq(400)
|
91
|
+
expect(last_response.body).to eq('{"error":"names can\'t be nil"}')
|
92
|
+
end
|
93
|
+
|
94
|
+
it 'accepts valid items' do
|
95
|
+
get '/custom_message/regexp_with_array', names: ['bob']
|
96
|
+
expect(last_response.status).to eq(200)
|
97
|
+
end
|
98
|
+
|
99
|
+
it 'accepts nil instead of array' do
|
100
|
+
get '/custom_message/regexp_with_array', names: nil
|
101
|
+
expect(last_response.status).to eq(200)
|
102
|
+
end
|
103
|
+
end
|
54
104
|
end
|
55
105
|
|
56
106
|
context 'invalid input' do
|
@@ -76,4 +126,42 @@ describe Grape::Validations::RegexpValidator do
|
|
76
126
|
get '/', name: 'bob'
|
77
127
|
expect(last_response.status).to eq(200)
|
78
128
|
end
|
129
|
+
|
130
|
+
context 'regexp with array' do
|
131
|
+
it 'refuses inapppopriate items' do
|
132
|
+
get '/regexp_with_array', names: ['invalid name', 'abc']
|
133
|
+
expect(last_response.status).to eq(400)
|
134
|
+
expect(last_response.body).to eq('{"error":"names is invalid"}')
|
135
|
+
end
|
136
|
+
|
137
|
+
it 'refuses empty items' do
|
138
|
+
get '/regexp_with_array', names: ['', 'abc']
|
139
|
+
expect(last_response.status).to eq(400)
|
140
|
+
expect(last_response.body).to eq('{"error":"names is invalid"}')
|
141
|
+
end
|
142
|
+
|
143
|
+
it 'refuses nil items' do
|
144
|
+
get '/regexp_with_array', names: [nil, 'abc']
|
145
|
+
expect(last_response.status).to eq(400)
|
146
|
+
expect(last_response.body).to eq('{"error":"names is invalid"}')
|
147
|
+
end
|
148
|
+
|
149
|
+
it 'accepts valid items' do
|
150
|
+
get '/regexp_with_array', names: ['bob']
|
151
|
+
expect(last_response.status).to eq(200)
|
152
|
+
end
|
153
|
+
|
154
|
+
it 'accepts nil instead of array' do
|
155
|
+
get '/regexp_with_array', names: nil
|
156
|
+
expect(last_response.status).to eq(200)
|
157
|
+
end
|
158
|
+
end
|
159
|
+
|
160
|
+
context 'nested regexp with array' do
|
161
|
+
it 'refuses inapppopriate' do
|
162
|
+
get '/nested_regexp_with_array', people: 'invalid name'
|
163
|
+
expect(last_response.status).to eq(400)
|
164
|
+
expect(last_response.body).to eq('{"error":"people is invalid, people[names] is missing, people[names] is invalid"}')
|
165
|
+
end
|
166
|
+
end
|
79
167
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: grape
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.19.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Michael Bleigh
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2016-
|
11
|
+
date: 2016-12-19 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rack
|
@@ -157,9 +157,11 @@ files:
|
|
157
157
|
- UPGRADING.md
|
158
158
|
- benchmark/simple.rb
|
159
159
|
- gemfiles/rack_1.5.2.gemfile
|
160
|
+
- gemfiles/rack_edge.gemfile
|
160
161
|
- gemfiles/rails_3.gemfile
|
161
162
|
- gemfiles/rails_4.gemfile
|
162
163
|
- gemfiles/rails_5.gemfile
|
164
|
+
- gemfiles/rails_edge.gemfile
|
163
165
|
- grape.gemspec
|
164
166
|
- grape.png
|
165
167
|
- lib/grape.rb
|
@@ -275,7 +277,7 @@ files:
|
|
275
277
|
- lib/grape/validations/validators/regexp.rb
|
276
278
|
- lib/grape/validations/validators/values.rb
|
277
279
|
- lib/grape/version.rb
|
278
|
-
- pkg/grape-0.
|
280
|
+
- pkg/grape-0.17.0.gem
|
279
281
|
- spec/grape/api/custom_validations_spec.rb
|
280
282
|
- spec/grape/api/deeply_included_options_spec.rb
|
281
283
|
- spec/grape/api/invalid_format_spec.rb
|
data/pkg/grape-0.18.0.gem
DELETED
Binary file
|