grape 1.5.2 → 1.7.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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +75 -0
- data/CONTRIBUTING.md +2 -1
- data/README.md +152 -21
- data/UPGRADING.md +86 -2
- data/grape.gemspec +5 -5
- data/lib/grape/api/instance.rb +14 -18
- data/lib/grape/api.rb +18 -13
- data/lib/grape/cookies.rb +2 -0
- data/lib/grape/dry_types.rb +12 -0
- data/lib/grape/dsl/api.rb +0 -2
- data/lib/grape/dsl/callbacks.rb +0 -2
- data/lib/grape/dsl/configuration.rb +0 -2
- data/lib/grape/dsl/desc.rb +2 -19
- data/lib/grape/dsl/headers.rb +5 -2
- data/lib/grape/dsl/helpers.rb +7 -7
- data/lib/grape/dsl/inside_route.rb +43 -30
- data/lib/grape/dsl/middleware.rb +4 -6
- data/lib/grape/dsl/parameters.rb +8 -10
- data/lib/grape/dsl/request_response.rb +9 -8
- data/lib/grape/dsl/routing.rb +6 -4
- data/lib/grape/dsl/settings.rb +5 -7
- data/lib/grape/dsl/validations.rb +0 -15
- data/lib/grape/endpoint.rb +21 -36
- data/lib/grape/error_formatter/json.rb +9 -7
- data/lib/grape/error_formatter/xml.rb +2 -6
- data/lib/grape/exceptions/base.rb +2 -2
- data/lib/grape/exceptions/empty_message_body.rb +11 -0
- data/lib/grape/exceptions/missing_group_type.rb +8 -1
- data/lib/grape/exceptions/too_many_multipart_files.rb +11 -0
- data/lib/grape/exceptions/unsupported_group_type.rb +8 -1
- data/lib/grape/exceptions/validation.rb +1 -6
- data/lib/grape/formatter/json.rb +1 -0
- data/lib/grape/formatter/serializable_hash.rb +2 -1
- data/lib/grape/formatter/xml.rb +1 -0
- data/lib/grape/locale/en.yml +9 -8
- data/lib/grape/middleware/auth/dsl.rb +7 -2
- data/lib/grape/middleware/base.rb +3 -1
- data/lib/grape/middleware/error.rb +2 -2
- data/lib/grape/middleware/formatter.rb +4 -4
- data/lib/grape/middleware/stack.rb +2 -2
- data/lib/grape/middleware/versioner/accept_version_header.rb +3 -5
- data/lib/grape/middleware/versioner/header.rb +6 -4
- data/lib/grape/middleware/versioner/param.rb +1 -0
- data/lib/grape/middleware/versioner/parse_media_type_patch.rb +2 -1
- data/lib/grape/middleware/versioner/path.rb +2 -0
- data/lib/grape/parser/json.rb +1 -1
- data/lib/grape/parser/xml.rb +1 -1
- data/lib/grape/path.rb +1 -0
- data/lib/grape/request.rb +5 -0
- data/lib/grape/router/pattern.rb +1 -1
- data/lib/grape/router/route.rb +2 -2
- data/lib/grape/router.rb +6 -0
- data/lib/grape/util/inheritable_setting.rb +1 -3
- data/lib/grape/util/json.rb +2 -0
- data/lib/grape/util/lazy_value.rb +3 -2
- data/lib/grape/util/strict_hash_configuration.rb +1 -1
- data/lib/grape/validations/attributes_doc.rb +58 -0
- data/lib/grape/validations/params_scope.rb +137 -78
- data/lib/grape/validations/types/array_coercer.rb +0 -2
- data/lib/grape/validations/types/custom_type_coercer.rb +1 -2
- data/lib/grape/validations/types/dry_type_coercer.rb +4 -8
- data/lib/grape/validations/types/json.rb +2 -1
- data/lib/grape/validations/types/primitive_coercer.rb +16 -8
- data/lib/grape/validations/types/set_coercer.rb +0 -2
- data/lib/grape/validations/types.rb +98 -30
- data/lib/grape/validations/validators/all_or_none_of_validator.rb +16 -0
- data/lib/grape/validations/validators/allow_blank_validator.rb +20 -0
- data/lib/grape/validations/validators/as_validator.rb +14 -0
- data/lib/grape/validations/validators/at_least_one_of_validator.rb +15 -0
- data/lib/grape/validations/validators/base.rb +82 -70
- data/lib/grape/validations/validators/coerce_validator.rb +75 -0
- data/lib/grape/validations/validators/default_validator.rb +51 -0
- data/lib/grape/validations/validators/exactly_one_of_validator.rb +17 -0
- data/lib/grape/validations/validators/except_values_validator.rb +24 -0
- data/lib/grape/validations/validators/multiple_params_base.rb +24 -20
- data/lib/grape/validations/validators/mutual_exclusion_validator.rb +16 -0
- data/lib/grape/validations/validators/presence_validator.rb +15 -0
- data/lib/grape/validations/validators/regexp_validator.rb +16 -0
- data/lib/grape/validations/validators/same_as_validator.rb +29 -0
- data/lib/grape/validations/validators/values_validator.rb +88 -0
- data/lib/grape/validations.rb +16 -6
- data/lib/grape/version.rb +1 -1
- data/lib/grape.rb +70 -29
- data/spec/grape/api/custom_validations_spec.rb +116 -45
- data/spec/grape/api/deeply_included_options_spec.rb +3 -5
- data/spec/grape/api/defines_boolean_in_params_spec.rb +2 -3
- data/spec/grape/api/documentation_spec.rb +59 -0
- data/spec/grape/api/inherited_helpers_spec.rb +0 -2
- data/spec/grape/api/instance_spec.rb +0 -1
- data/spec/grape/api/invalid_format_spec.rb +2 -2
- data/spec/grape/api/namespace_parameters_in_route_spec.rb +0 -2
- data/spec/grape/api/nested_helpers_spec.rb +0 -2
- data/spec/grape/api/optional_parameters_in_route_spec.rb +0 -2
- data/spec/grape/api/parameters_modification_spec.rb +0 -2
- data/spec/grape/api/patch_method_helpers_spec.rb +0 -2
- data/spec/grape/api/recognize_path_spec.rb +1 -3
- data/spec/grape/api/required_parameters_in_route_spec.rb +0 -2
- data/spec/grape/api/required_parameters_with_invalid_method_spec.rb +0 -2
- data/spec/grape/api/routes_with_requirements_spec.rb +8 -10
- data/spec/grape/api/shared_helpers_exactly_one_of_spec.rb +9 -17
- data/spec/grape/api/shared_helpers_spec.rb +0 -2
- data/spec/grape/api_remount_spec.rb +16 -16
- data/spec/grape/api_spec.rb +527 -224
- data/spec/grape/config_spec.rb +0 -2
- data/spec/grape/dsl/callbacks_spec.rb +2 -3
- data/spec/grape/dsl/configuration_spec.rb +0 -2
- data/spec/grape/dsl/desc_spec.rb +0 -2
- data/spec/grape/dsl/headers_spec.rb +39 -11
- data/spec/grape/dsl/helpers_spec.rb +3 -4
- data/spec/grape/dsl/inside_route_spec.rb +16 -16
- data/spec/grape/dsl/logger_spec.rb +15 -19
- data/spec/grape/dsl/middleware_spec.rb +2 -3
- data/spec/grape/dsl/parameters_spec.rb +2 -2
- data/spec/grape/dsl/request_response_spec.rb +7 -8
- data/spec/grape/dsl/routing_spec.rb +11 -10
- data/spec/grape/dsl/settings_spec.rb +0 -2
- data/spec/grape/dsl/validations_spec.rb +0 -17
- data/spec/grape/endpoint/declared_spec.rb +261 -16
- data/spec/grape/endpoint_spec.rb +98 -57
- data/spec/grape/entity_spec.rb +22 -23
- data/spec/grape/exceptions/base_spec.rb +16 -2
- data/spec/grape/exceptions/body_parse_errors_spec.rb +3 -2
- data/spec/grape/exceptions/invalid_accept_header_spec.rb +61 -24
- data/spec/grape/exceptions/invalid_formatter_spec.rb +0 -2
- data/spec/grape/exceptions/invalid_response_spec.rb +0 -2
- data/spec/grape/exceptions/invalid_versioner_option_spec.rb +1 -3
- data/spec/grape/exceptions/missing_group_type_spec.rb +21 -0
- data/spec/grape/exceptions/missing_mime_type_spec.rb +0 -2
- data/spec/grape/exceptions/missing_option_spec.rb +1 -3
- data/spec/grape/exceptions/unknown_options_spec.rb +0 -2
- data/spec/grape/exceptions/unknown_validator_spec.rb +0 -2
- data/spec/grape/exceptions/unsupported_group_type_spec.rb +23 -0
- data/spec/grape/exceptions/validation_errors_spec.rb +13 -11
- data/spec/grape/exceptions/validation_spec.rb +5 -5
- data/spec/grape/extensions/param_builders/hash_spec.rb +7 -9
- data/spec/grape/extensions/param_builders/hash_with_indifferent_access_spec.rb +8 -10
- data/spec/grape/extensions/param_builders/hashie/mash_spec.rb +8 -10
- data/spec/grape/integration/global_namespace_function_spec.rb +0 -2
- data/spec/grape/integration/rack_sendfile_spec.rb +1 -3
- data/spec/grape/integration/rack_spec.rb +0 -2
- data/spec/grape/loading_spec.rb +8 -10
- data/spec/grape/middleware/auth/base_spec.rb +0 -1
- data/spec/grape/middleware/auth/dsl_spec.rb +15 -8
- data/spec/grape/middleware/auth/strategies_spec.rb +60 -22
- data/spec/grape/middleware/base_spec.rb +24 -17
- data/spec/grape/middleware/error_spec.rb +8 -3
- data/spec/grape/middleware/exception_spec.rb +111 -163
- data/spec/grape/middleware/formatter_spec.rb +27 -8
- data/spec/grape/middleware/globals_spec.rb +7 -6
- data/spec/grape/middleware/stack_spec.rb +14 -14
- data/spec/grape/middleware/versioner/accept_version_header_spec.rb +2 -3
- data/spec/grape/middleware/versioner/header_spec.rb +30 -15
- data/spec/grape/middleware/versioner/param_spec.rb +7 -3
- data/spec/grape/middleware/versioner/path_spec.rb +5 -3
- data/spec/grape/middleware/versioner_spec.rb +1 -3
- data/spec/grape/named_api_spec.rb +0 -2
- data/spec/grape/parser_spec.rb +4 -2
- data/spec/grape/path_spec.rb +52 -54
- data/spec/grape/presenters/presenter_spec.rb +7 -8
- data/spec/grape/request_spec.rb +6 -6
- data/spec/grape/util/inheritable_setting_spec.rb +7 -8
- data/spec/grape/util/inheritable_values_spec.rb +3 -3
- data/spec/grape/util/reverse_stackable_values_spec.rb +3 -2
- data/spec/grape/util/stackable_values_spec.rb +7 -6
- data/spec/grape/util/strict_hash_configuration_spec.rb +0 -1
- data/spec/grape/validations/attributes_doc_spec.rb +153 -0
- data/spec/grape/validations/attributes_iterator_spec.rb +0 -2
- data/spec/grape/validations/instance_behaivour_spec.rb +9 -12
- data/spec/grape/validations/multiple_attributes_iterator_spec.rb +1 -2
- data/spec/grape/validations/params_scope_spec.rb +361 -96
- data/spec/grape/validations/single_attribute_iterator_spec.rb +2 -3
- data/spec/grape/validations/types/array_coercer_spec.rb +0 -2
- data/spec/grape/validations/types/primitive_coercer_spec.rb +24 -9
- data/spec/grape/validations/types/set_coercer_spec.rb +0 -2
- data/spec/grape/validations/types_spec.rb +36 -10
- data/spec/grape/validations/validators/all_or_none_spec.rb +50 -58
- data/spec/grape/validations/validators/allow_blank_spec.rb +135 -141
- data/spec/grape/validations/validators/at_least_one_of_spec.rb +50 -58
- data/spec/grape/validations/validators/coerce_spec.rb +99 -24
- data/spec/grape/validations/validators/default_spec.rb +72 -80
- data/spec/grape/validations/validators/exactly_one_of_spec.rb +71 -79
- data/spec/grape/validations/validators/except_values_spec.rb +3 -5
- data/spec/grape/validations/validators/mutual_exclusion_spec.rb +71 -79
- data/spec/grape/validations/validators/presence_spec.rb +16 -3
- data/spec/grape/validations/validators/regexp_spec.rb +25 -33
- data/spec/grape/validations/validators/same_as_spec.rb +14 -22
- data/spec/grape/validations/validators/values_spec.rb +182 -179
- data/spec/grape/validations_spec.rb +149 -80
- data/spec/integration/eager_load/eager_load_spec.rb +2 -2
- data/spec/integration/multi_json/json_spec.rb +1 -3
- data/spec/integration/multi_xml/xml_spec.rb +1 -3
- data/spec/shared/versioning_examples.rb +12 -9
- data/spec/spec_helper.rb +21 -6
- data/spec/support/basic_auth_encode_helpers.rb +1 -1
- metadata +125 -115
- data/lib/grape/validations/validators/all_or_none.rb +0 -15
- data/lib/grape/validations/validators/allow_blank.rb +0 -18
- data/lib/grape/validations/validators/as.rb +0 -16
- data/lib/grape/validations/validators/at_least_one_of.rb +0 -14
- data/lib/grape/validations/validators/coerce.rb +0 -91
- data/lib/grape/validations/validators/default.rb +0 -48
- data/lib/grape/validations/validators/exactly_one_of.rb +0 -16
- data/lib/grape/validations/validators/except_values.rb +0 -22
- data/lib/grape/validations/validators/mutual_exclusion.rb +0 -15
- data/lib/grape/validations/validators/presence.rb +0 -12
- data/lib/grape/validations/validators/regexp.rb +0 -13
- data/lib/grape/validations/validators/same_as.rb +0 -26
- data/lib/grape/validations/validators/values.rb +0 -83
- data/spec/support/eager_load.rb +0 -19
@@ -1,12 +1,11 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require 'spec_helper'
|
4
|
-
|
5
3
|
describe Grape::Exceptions::InvalidAcceptHeader do
|
6
4
|
shared_examples_for 'a valid request' do
|
7
5
|
it 'does return with status 200' do
|
8
6
|
expect(last_response.status).to eq 200
|
9
7
|
end
|
8
|
+
|
10
9
|
it 'does return the expected result' do
|
11
10
|
expect(last_response.body).to eq('beer received')
|
12
11
|
end
|
@@ -20,6 +19,7 @@ describe Grape::Exceptions::InvalidAcceptHeader do
|
|
20
19
|
it 'does not include the X-Cascade=pass header' do
|
21
20
|
expect(last_response.headers['X-Cascade']).to be_nil
|
22
21
|
end
|
22
|
+
|
23
23
|
it 'does not accept the request' do
|
24
24
|
expect(last_response.status).to eq 406
|
25
25
|
end
|
@@ -28,6 +28,7 @@ describe Grape::Exceptions::InvalidAcceptHeader do
|
|
28
28
|
it 'does not include the X-Cascade=pass header' do
|
29
29
|
expect(last_response.headers['X-Cascade']).to be_nil
|
30
30
|
end
|
31
|
+
|
31
32
|
it 'does show rescue handler processing' do
|
32
33
|
expect(last_response.status).to eq 400
|
33
34
|
expect(last_response.body).to eq('message was processed')
|
@@ -36,6 +37,7 @@ describe Grape::Exceptions::InvalidAcceptHeader do
|
|
36
37
|
|
37
38
|
context 'API with cascade=false and rescue_from :all handler' do
|
38
39
|
subject { Class.new(Grape::API) }
|
40
|
+
|
39
41
|
before do
|
40
42
|
subject.version 'v99', using: :header, vendor: 'vendorname', format: :json, cascade: false
|
41
43
|
subject.rescue_from :all do |e|
|
@@ -52,7 +54,8 @@ describe Grape::Exceptions::InvalidAcceptHeader do
|
|
52
54
|
|
53
55
|
context 'that received a request with correct vendor and version' do
|
54
56
|
before { get '/beer', {}, 'HTTP_ACCEPT' => 'application/vnd.vendorname-v99' }
|
55
|
-
|
57
|
+
|
58
|
+
it_behaves_like 'a valid request'
|
56
59
|
end
|
57
60
|
|
58
61
|
context 'that receives' do
|
@@ -61,13 +64,15 @@ describe Grape::Exceptions::InvalidAcceptHeader do
|
|
61
64
|
get '/beer', {}, 'HTTP_ACCEPT' => 'application/vnd.invalidvendor-v99',
|
62
65
|
'CONTENT_TYPE' => 'application/json'
|
63
66
|
end
|
64
|
-
|
67
|
+
|
68
|
+
it_behaves_like 'a rescued request'
|
65
69
|
end
|
66
70
|
end
|
67
71
|
end
|
68
72
|
|
69
73
|
context 'API with cascade=false and without a rescue handler' do
|
70
74
|
subject { Class.new(Grape::API) }
|
75
|
+
|
71
76
|
before do
|
72
77
|
subject.version 'v99', using: :header, vendor: 'vendorname', format: :json, cascade: false
|
73
78
|
subject.get '/beer' do
|
@@ -81,23 +86,28 @@ describe Grape::Exceptions::InvalidAcceptHeader do
|
|
81
86
|
|
82
87
|
context 'that received a request with correct vendor and version' do
|
83
88
|
before { get '/beer', {}, 'HTTP_ACCEPT' => 'application/vnd.vendorname-v99' }
|
84
|
-
|
89
|
+
|
90
|
+
it_behaves_like 'a valid request'
|
85
91
|
end
|
86
92
|
|
87
93
|
context 'that receives' do
|
88
94
|
context 'an invalid version in the request' do
|
89
95
|
before { get '/beer', {}, 'HTTP_ACCEPT' => 'application/vnd.vendorname-v77' }
|
90
|
-
|
96
|
+
|
97
|
+
it_behaves_like 'a not-cascaded request'
|
91
98
|
end
|
99
|
+
|
92
100
|
context 'an invalid vendor in the request' do
|
93
101
|
before { get '/beer', {}, 'HTTP_ACCEPT' => 'application/vnd.invalidvendor-v99' }
|
94
|
-
|
102
|
+
|
103
|
+
it_behaves_like 'a not-cascaded request'
|
95
104
|
end
|
96
105
|
end
|
97
106
|
end
|
98
107
|
|
99
108
|
context 'API with cascade=false and with rescue_from :all handler and http_codes' do
|
100
109
|
subject { Class.new(Grape::API) }
|
110
|
+
|
101
111
|
before do
|
102
112
|
subject.version 'v99', using: :header, vendor: 'vendorname', format: :json, cascade: false
|
103
113
|
subject.rescue_from :all do |e|
|
@@ -119,7 +129,8 @@ describe Grape::Exceptions::InvalidAcceptHeader do
|
|
119
129
|
|
120
130
|
context 'that received a request with correct vendor and version' do
|
121
131
|
before { get '/beer', {}, 'HTTP_ACCEPT' => 'application/vnd.vendorname-v99' }
|
122
|
-
|
132
|
+
|
133
|
+
it_behaves_like 'a valid request'
|
123
134
|
end
|
124
135
|
|
125
136
|
context 'that receives' do
|
@@ -128,13 +139,15 @@ describe Grape::Exceptions::InvalidAcceptHeader do
|
|
128
139
|
get '/beer', {}, 'HTTP_ACCEPT' => 'application/vnd.invalidvendor-v99',
|
129
140
|
'CONTENT_TYPE' => 'application/json'
|
130
141
|
end
|
131
|
-
|
142
|
+
|
143
|
+
it_behaves_like 'a rescued request'
|
132
144
|
end
|
133
145
|
end
|
134
146
|
end
|
135
147
|
|
136
148
|
context 'API with cascade=false, http_codes but without a rescue handler' do
|
137
149
|
subject { Class.new(Grape::API) }
|
150
|
+
|
138
151
|
before do
|
139
152
|
subject.version 'v99', using: :header, vendor: 'vendorname', format: :json, cascade: false
|
140
153
|
subject.desc 'Get beer' do
|
@@ -153,23 +166,28 @@ describe Grape::Exceptions::InvalidAcceptHeader do
|
|
153
166
|
|
154
167
|
context 'that received a request with correct vendor and version' do
|
155
168
|
before { get '/beer', {}, 'HTTP_ACCEPT' => 'application/vnd.vendorname-v99' }
|
156
|
-
|
169
|
+
|
170
|
+
it_behaves_like 'a valid request'
|
157
171
|
end
|
158
172
|
|
159
173
|
context 'that receives' do
|
160
174
|
context 'an invalid version in the request' do
|
161
175
|
before { get '/beer', {}, 'HTTP_ACCEPT' => 'application/vnd.vendorname-v77' }
|
162
|
-
|
176
|
+
|
177
|
+
it_behaves_like 'a not-cascaded request'
|
163
178
|
end
|
179
|
+
|
164
180
|
context 'an invalid vendor in the request' do
|
165
181
|
before { get '/beer', {}, 'HTTP_ACCEPT' => 'application/vnd.invalidvendor-v99' }
|
166
|
-
|
182
|
+
|
183
|
+
it_behaves_like 'a not-cascaded request'
|
167
184
|
end
|
168
185
|
end
|
169
186
|
end
|
170
187
|
|
171
188
|
context 'API with cascade=true and rescue_from :all handler' do
|
172
189
|
subject { Class.new(Grape::API) }
|
190
|
+
|
173
191
|
before do
|
174
192
|
subject.version 'v99', using: :header, vendor: 'vendorname', format: :json, cascade: true
|
175
193
|
subject.rescue_from :all do |e|
|
@@ -186,7 +204,8 @@ describe Grape::Exceptions::InvalidAcceptHeader do
|
|
186
204
|
|
187
205
|
context 'that received a request with correct vendor and version' do
|
188
206
|
before { get '/beer', {}, 'HTTP_ACCEPT' => 'application/vnd.vendorname-v99' }
|
189
|
-
|
207
|
+
|
208
|
+
it_behaves_like 'a valid request'
|
190
209
|
end
|
191
210
|
|
192
211
|
context 'that receives' do
|
@@ -195,20 +214,24 @@ describe Grape::Exceptions::InvalidAcceptHeader do
|
|
195
214
|
get '/beer', {}, 'HTTP_ACCEPT' => 'application/vnd.vendorname-v77',
|
196
215
|
'CONTENT_TYPE' => 'application/json'
|
197
216
|
end
|
198
|
-
|
217
|
+
|
218
|
+
it_behaves_like 'a cascaded request'
|
199
219
|
end
|
220
|
+
|
200
221
|
context 'an invalid vendor in the request' do
|
201
222
|
before do
|
202
223
|
get '/beer', {}, 'HTTP_ACCEPT' => 'application/vnd.invalidvendor-v99',
|
203
224
|
'CONTENT_TYPE' => 'application/json'
|
204
225
|
end
|
205
|
-
|
226
|
+
|
227
|
+
it_behaves_like 'a cascaded request'
|
206
228
|
end
|
207
229
|
end
|
208
230
|
end
|
209
231
|
|
210
232
|
context 'API with cascade=true and without a rescue handler' do
|
211
233
|
subject { Class.new(Grape::API) }
|
234
|
+
|
212
235
|
before do
|
213
236
|
subject.version 'v99', using: :header, vendor: 'vendorname', format: :json, cascade: true
|
214
237
|
subject.get '/beer' do
|
@@ -222,23 +245,28 @@ describe Grape::Exceptions::InvalidAcceptHeader do
|
|
222
245
|
|
223
246
|
context 'that received a request with correct vendor and version' do
|
224
247
|
before { get '/beer', {}, 'HTTP_ACCEPT' => 'application/vnd.vendorname-v99' }
|
225
|
-
|
248
|
+
|
249
|
+
it_behaves_like 'a valid request'
|
226
250
|
end
|
227
251
|
|
228
252
|
context 'that receives' do
|
229
253
|
context 'an invalid version in the request' do
|
230
254
|
before { get '/beer', {}, 'HTTP_ACCEPT' => 'application/vnd.vendorname-v77' }
|
231
|
-
|
255
|
+
|
256
|
+
it_behaves_like 'a cascaded request'
|
232
257
|
end
|
258
|
+
|
233
259
|
context 'an invalid vendor in the request' do
|
234
260
|
before { get '/beer', {}, 'HTTP_ACCEPT' => 'application/vnd.invalidvendor-v99' }
|
235
|
-
|
261
|
+
|
262
|
+
it_behaves_like 'a cascaded request'
|
236
263
|
end
|
237
264
|
end
|
238
265
|
end
|
239
266
|
|
240
267
|
context 'API with cascade=true and with rescue_from :all handler and http_codes' do
|
241
268
|
subject { Class.new(Grape::API) }
|
269
|
+
|
242
270
|
before do
|
243
271
|
subject.version 'v99', using: :header, vendor: 'vendorname', format: :json, cascade: true
|
244
272
|
subject.rescue_from :all do |e|
|
@@ -260,7 +288,8 @@ describe Grape::Exceptions::InvalidAcceptHeader do
|
|
260
288
|
|
261
289
|
context 'that received a request with correct vendor and version' do
|
262
290
|
before { get '/beer', {}, 'HTTP_ACCEPT' => 'application/vnd.vendorname-v99' }
|
263
|
-
|
291
|
+
|
292
|
+
it_behaves_like 'a valid request'
|
264
293
|
end
|
265
294
|
|
266
295
|
context 'that receives' do
|
@@ -269,20 +298,24 @@ describe Grape::Exceptions::InvalidAcceptHeader do
|
|
269
298
|
get '/beer', {}, 'HTTP_ACCEPT' => 'application/vnd.vendorname-v77',
|
270
299
|
'CONTENT_TYPE' => 'application/json'
|
271
300
|
end
|
272
|
-
|
301
|
+
|
302
|
+
it_behaves_like 'a cascaded request'
|
273
303
|
end
|
304
|
+
|
274
305
|
context 'an invalid vendor in the request' do
|
275
306
|
before do
|
276
307
|
get '/beer', {}, 'HTTP_ACCEPT' => 'application/vnd.invalidvendor-v99',
|
277
308
|
'CONTENT_TYPE' => 'application/json'
|
278
309
|
end
|
279
|
-
|
310
|
+
|
311
|
+
it_behaves_like 'a cascaded request'
|
280
312
|
end
|
281
313
|
end
|
282
314
|
end
|
283
315
|
|
284
316
|
context 'API with cascade=true, http_codes but without a rescue handler' do
|
285
317
|
subject { Class.new(Grape::API) }
|
318
|
+
|
286
319
|
before do
|
287
320
|
subject.version 'v99', using: :header, vendor: 'vendorname', format: :json, cascade: true
|
288
321
|
subject.desc 'Get beer' do
|
@@ -301,17 +334,21 @@ describe Grape::Exceptions::InvalidAcceptHeader do
|
|
301
334
|
|
302
335
|
context 'that received a request with correct vendor and version' do
|
303
336
|
before { get '/beer', {}, 'HTTP_ACCEPT' => 'application/vnd.vendorname-v99' }
|
304
|
-
|
337
|
+
|
338
|
+
it_behaves_like 'a valid request'
|
305
339
|
end
|
306
340
|
|
307
341
|
context 'that receives' do
|
308
342
|
context 'an invalid version in the request' do
|
309
343
|
before { get '/beer', {}, 'HTTP_ACCEPT' => 'application/vnd.vendorname-v77' }
|
310
|
-
|
344
|
+
|
345
|
+
it_behaves_like 'a cascaded request'
|
311
346
|
end
|
347
|
+
|
312
348
|
context 'an invalid vendor in the request' do
|
313
349
|
before { get '/beer', {}, 'HTTP_ACCEPT' => 'application/vnd.invalidvendor-v99' }
|
314
|
-
|
350
|
+
|
351
|
+
it_behaves_like 'a cascaded request'
|
315
352
|
end
|
316
353
|
end
|
317
354
|
end
|
@@ -1,7 +1,5 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require 'spec_helper'
|
4
|
-
|
5
3
|
describe Grape::Exceptions::InvalidVersionerOption do
|
6
4
|
describe '#message' do
|
7
5
|
let(:error) do
|
@@ -10,7 +8,7 @@ describe Grape::Exceptions::InvalidVersionerOption do
|
|
10
8
|
|
11
9
|
it 'contains the problem in the message' do
|
12
10
|
expect(error.message).to include(
|
13
|
-
'
|
11
|
+
'unknown :using for versioner: headers'
|
14
12
|
)
|
15
13
|
end
|
16
14
|
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
RSpec.describe Grape::Exceptions::MissingGroupType do
|
4
|
+
describe '#message' do
|
5
|
+
subject { described_class.new.message }
|
6
|
+
|
7
|
+
it { is_expected.to include 'group type is required' }
|
8
|
+
end
|
9
|
+
|
10
|
+
describe 'deprecated Grape::Exceptions::MissingGroupTypeError' do
|
11
|
+
subject { Grape::Exceptions::MissingGroupTypeError.new }
|
12
|
+
|
13
|
+
it 'puts a deprecation warning' do
|
14
|
+
expect(Warning).to receive(:warn) do |message|
|
15
|
+
expect(message).to include('`Grape::Exceptions::MissingGroupTypeError` is deprecated')
|
16
|
+
end
|
17
|
+
|
18
|
+
subject
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
@@ -1,7 +1,5 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require 'spec_helper'
|
4
|
-
|
5
3
|
describe Grape::Exceptions::MissingOption do
|
6
4
|
describe '#message' do
|
7
5
|
let(:error) do
|
@@ -10,7 +8,7 @@ describe Grape::Exceptions::MissingOption do
|
|
10
8
|
|
11
9
|
it 'contains the problem in the message' do
|
12
10
|
expect(error.message).to include(
|
13
|
-
'
|
11
|
+
'you must specify :path options'
|
14
12
|
)
|
15
13
|
end
|
16
14
|
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
RSpec.describe Grape::Exceptions::UnsupportedGroupType do
|
4
|
+
subject { described_class.new }
|
5
|
+
|
6
|
+
describe '#message' do
|
7
|
+
subject { described_class.new.message }
|
8
|
+
|
9
|
+
it { is_expected.to include 'group type must be Array, Hash, JSON or Array[JSON]' }
|
10
|
+
end
|
11
|
+
|
12
|
+
describe 'deprecated Grape::Exceptions::UnsupportedGroupTypeError' do
|
13
|
+
subject { Grape::Exceptions::UnsupportedGroupTypeError.new }
|
14
|
+
|
15
|
+
it 'puts a deprecation warning' do
|
16
|
+
expect(Warning).to receive(:warn) do |message|
|
17
|
+
expect(message).to include('`Grape::Exceptions::UnsupportedGroupTypeError` is deprecated')
|
18
|
+
end
|
19
|
+
|
20
|
+
subject
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
@@ -1,34 +1,34 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require 'spec_helper'
|
4
3
|
require 'ostruct'
|
5
4
|
|
6
5
|
describe Grape::Exceptions::ValidationErrors do
|
7
6
|
let(:validation_message) { 'FooBar is invalid' }
|
8
|
-
let(:validation_error) {
|
7
|
+
let(:validation_error) { instance_double Grape::Exceptions::Validation, params: [validation_message], message: '' }
|
9
8
|
|
10
9
|
context 'initialize' do
|
10
|
+
subject do
|
11
|
+
described_class.new(errors: [validation_error], headers: headers)
|
12
|
+
end
|
13
|
+
|
11
14
|
let(:headers) do
|
12
15
|
{
|
13
16
|
'A-Header-Key' => 'A-Header-Value'
|
14
17
|
}
|
15
18
|
end
|
16
19
|
|
17
|
-
|
18
|
-
described_class.new(errors: [validation_error], headers: headers)
|
19
|
-
end
|
20
|
-
|
21
|
-
it 'should assign headers through base class' do
|
20
|
+
it 'assigns headers through base class' do
|
22
21
|
expect(subject.headers).to eq(headers)
|
23
22
|
end
|
24
23
|
end
|
25
24
|
|
26
25
|
context 'message' do
|
27
26
|
context 'is not repeated' do
|
27
|
+
subject(:message) { error.message.split(',').map(&:strip) }
|
28
|
+
|
28
29
|
let(:error) do
|
29
30
|
described_class.new(errors: [validation_error, validation_error])
|
30
31
|
end
|
31
|
-
subject(:message) { error.message.split(',').map(&:strip) }
|
32
32
|
|
33
33
|
it { expect(message).to include validation_message }
|
34
34
|
it { expect(message.size).to eq 1 }
|
@@ -37,9 +37,10 @@ describe Grape::Exceptions::ValidationErrors do
|
|
37
37
|
|
38
38
|
describe '#full_messages' do
|
39
39
|
context 'with errors' do
|
40
|
+
subject { described_class.new(errors: [validation_error_1, validation_error_2]).full_messages }
|
41
|
+
|
40
42
|
let(:validation_error_1) { Grape::Exceptions::Validation.new(params: ['id'], message: :presence) }
|
41
43
|
let(:validation_error_2) { Grape::Exceptions::Validation.new(params: ['name'], message: :presence) }
|
42
|
-
subject { described_class.new(errors: [validation_error_1, validation_error_2]).full_messages }
|
43
44
|
|
44
45
|
it 'returns an array with each errors full message' do
|
45
46
|
expect(subject).to contain_exactly('id is missing', 'name is missing')
|
@@ -47,9 +48,10 @@ describe Grape::Exceptions::ValidationErrors do
|
|
47
48
|
end
|
48
49
|
|
49
50
|
context 'when attributes is an array of symbols' do
|
50
|
-
let(:validation_error) { Grape::Exceptions::Validation.new(params: [:admin_field], message: 'Can not set admin-only field') }
|
51
51
|
subject { described_class.new(errors: [validation_error]).full_messages }
|
52
52
|
|
53
|
+
let(:validation_error) { Grape::Exceptions::Validation.new(params: [:admin_field], message: 'Can not set admin-only field') }
|
54
|
+
|
53
55
|
it 'returns an array with an error full message' do
|
54
56
|
expect(subject.first).to eq('admin_field Can not set admin-only field')
|
55
57
|
end
|
@@ -65,7 +67,7 @@ describe Grape::Exceptions::ValidationErrors do
|
|
65
67
|
|
66
68
|
it 'can return structured json with separate fields' do
|
67
69
|
subject.format :json
|
68
|
-
subject.rescue_from
|
70
|
+
subject.rescue_from described_class do |e|
|
69
71
|
error!(e, 400)
|
70
72
|
end
|
71
73
|
subject.params do
|
@@ -1,19 +1,19 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require 'spec_helper'
|
4
|
-
|
5
3
|
describe Grape::Exceptions::Validation do
|
6
4
|
it 'fails when params are missing' do
|
7
|
-
expect {
|
5
|
+
expect { described_class.new(message: 'presence') }.to raise_error(ArgumentError, /missing keyword:.+?params/)
|
8
6
|
end
|
7
|
+
|
9
8
|
context 'when message is a symbol' do
|
10
9
|
it 'stores message_key' do
|
11
|
-
expect(
|
10
|
+
expect(described_class.new(params: ['id'], message: :presence).message_key).to eq(:presence)
|
12
11
|
end
|
13
12
|
end
|
13
|
+
|
14
14
|
context 'when message is a String' do
|
15
15
|
it 'does not store the message_key' do
|
16
|
-
expect(
|
16
|
+
expect(described_class.new(params: ['id'], message: 'presence').message_key).to be_nil
|
17
17
|
end
|
18
18
|
end
|
19
19
|
end
|
@@ -1,7 +1,5 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require 'spec_helper'
|
4
|
-
|
5
3
|
describe Grape::Extensions::Hash::ParamBuilder do
|
6
4
|
subject { Class.new(Grape::API) }
|
7
5
|
|
@@ -10,10 +8,10 @@ describe Grape::Extensions::Hash::ParamBuilder do
|
|
10
8
|
end
|
11
9
|
|
12
10
|
describe 'in an endpoint' do
|
13
|
-
|
11
|
+
describe '#params' do
|
14
12
|
before do
|
15
13
|
subject.params do
|
16
|
-
build_with Grape::Extensions::Hash::ParamBuilder
|
14
|
+
build_with Grape::Extensions::Hash::ParamBuilder # rubocop:disable RSpec/DescribedClass
|
17
15
|
end
|
18
16
|
|
19
17
|
subject.get do
|
@@ -21,7 +19,7 @@ describe Grape::Extensions::Hash::ParamBuilder do
|
|
21
19
|
end
|
22
20
|
end
|
23
21
|
|
24
|
-
it '
|
22
|
+
it 'is of type Hash' do
|
25
23
|
get '/'
|
26
24
|
expect(last_response.status).to eq(200)
|
27
25
|
expect(last_response.body).to eq('Hash')
|
@@ -31,17 +29,17 @@ describe Grape::Extensions::Hash::ParamBuilder do
|
|
31
29
|
|
32
30
|
describe 'in an api' do
|
33
31
|
before do
|
34
|
-
subject.send(:include, Grape::Extensions::Hash::ParamBuilder)
|
32
|
+
subject.send(:include, Grape::Extensions::Hash::ParamBuilder) # rubocop:disable RSpec/DescribedClass
|
35
33
|
end
|
36
34
|
|
37
|
-
|
35
|
+
describe '#params' do
|
38
36
|
before do
|
39
37
|
subject.get do
|
40
38
|
params.class
|
41
39
|
end
|
42
40
|
end
|
43
41
|
|
44
|
-
it '
|
42
|
+
it 'is Hash' do
|
45
43
|
get '/'
|
46
44
|
expect(last_response.status).to eq(200)
|
47
45
|
expect(last_response.body).to eq('Hash')
|
@@ -69,7 +67,7 @@ describe Grape::Extensions::Hash::ParamBuilder do
|
|
69
67
|
|
70
68
|
it 'symbolizes the params' do
|
71
69
|
subject.params do
|
72
|
-
build_with Grape::Extensions::Hash::ParamBuilder
|
70
|
+
build_with Grape::Extensions::Hash::ParamBuilder # rubocop:disable RSpec/DescribedClass
|
73
71
|
requires :a, type: String
|
74
72
|
end
|
75
73
|
|
@@ -1,7 +1,5 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require 'spec_helper'
|
4
|
-
|
5
3
|
describe Grape::Extensions::ActiveSupport::HashWithIndifferentAccess::ParamBuilder do
|
6
4
|
subject { Class.new(Grape::API) }
|
7
5
|
|
@@ -10,10 +8,10 @@ describe Grape::Extensions::ActiveSupport::HashWithIndifferentAccess::ParamBuild
|
|
10
8
|
end
|
11
9
|
|
12
10
|
describe 'in an endpoint' do
|
13
|
-
|
11
|
+
describe '#params' do
|
14
12
|
before do
|
15
13
|
subject.params do
|
16
|
-
build_with Grape::Extensions::ActiveSupport::HashWithIndifferentAccess::ParamBuilder
|
14
|
+
build_with Grape::Extensions::ActiveSupport::HashWithIndifferentAccess::ParamBuilder # rubocop:disable RSpec/DescribedClass
|
17
15
|
end
|
18
16
|
|
19
17
|
subject.get do
|
@@ -21,7 +19,7 @@ describe Grape::Extensions::ActiveSupport::HashWithIndifferentAccess::ParamBuild
|
|
21
19
|
end
|
22
20
|
end
|
23
21
|
|
24
|
-
it '
|
22
|
+
it 'is of type Hash' do
|
25
23
|
get '/'
|
26
24
|
expect(last_response.status).to eq(200)
|
27
25
|
expect(last_response.body).to eq('ActiveSupport::HashWithIndifferentAccess')
|
@@ -31,10 +29,10 @@ describe Grape::Extensions::ActiveSupport::HashWithIndifferentAccess::ParamBuild
|
|
31
29
|
|
32
30
|
describe 'in an api' do
|
33
31
|
before do
|
34
|
-
subject.send(:include, Grape::Extensions::ActiveSupport::HashWithIndifferentAccess::ParamBuilder)
|
32
|
+
subject.send(:include, Grape::Extensions::ActiveSupport::HashWithIndifferentAccess::ParamBuilder) # rubocop:disable RSpec/DescribedClass
|
35
33
|
end
|
36
34
|
|
37
|
-
|
35
|
+
describe '#params' do
|
38
36
|
before do
|
39
37
|
subject.get do
|
40
38
|
params.class
|
@@ -49,7 +47,7 @@ describe Grape::Extensions::ActiveSupport::HashWithIndifferentAccess::ParamBuild
|
|
49
47
|
|
50
48
|
it 'parses sub hash params' do
|
51
49
|
subject.params do
|
52
|
-
build_with Grape::Extensions::ActiveSupport::HashWithIndifferentAccess::ParamBuilder
|
50
|
+
build_with Grape::Extensions::ActiveSupport::HashWithIndifferentAccess::ParamBuilder # rubocop:disable RSpec/DescribedClass
|
53
51
|
|
54
52
|
optional :a, type: Hash do
|
55
53
|
optional :b, type: Hash do
|
@@ -70,7 +68,7 @@ describe Grape::Extensions::ActiveSupport::HashWithIndifferentAccess::ParamBuild
|
|
70
68
|
|
71
69
|
it 'params are indifferent to symbol or string keys' do
|
72
70
|
subject.params do
|
73
|
-
build_with Grape::Extensions::ActiveSupport::HashWithIndifferentAccess::ParamBuilder
|
71
|
+
build_with Grape::Extensions::ActiveSupport::HashWithIndifferentAccess::ParamBuilder # rubocop:disable RSpec/DescribedClass
|
74
72
|
optional :a, type: Hash do
|
75
73
|
optional :b, type: Hash do
|
76
74
|
optional :c, type: String
|
@@ -90,7 +88,7 @@ describe Grape::Extensions::ActiveSupport::HashWithIndifferentAccess::ParamBuild
|
|
90
88
|
|
91
89
|
it 'responds to string keys' do
|
92
90
|
subject.params do
|
93
|
-
build_with Grape::Extensions::ActiveSupport::HashWithIndifferentAccess::ParamBuilder
|
91
|
+
build_with Grape::Extensions::ActiveSupport::HashWithIndifferentAccess::ParamBuilder # rubocop:disable RSpec/DescribedClass
|
94
92
|
requires :a, type: String
|
95
93
|
end
|
96
94
|
|