grape 1.7.1 → 2.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (163) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +37 -1
  3. data/CONTRIBUTING.md +1 -1
  4. data/README.md +30 -25
  5. data/UPGRADING.md +35 -0
  6. data/grape.gemspec +3 -6
  7. data/lib/grape/api.rb +2 -2
  8. data/lib/grape/content_types.rb +2 -8
  9. data/lib/grape/dsl/desc.rb +1 -1
  10. data/lib/grape/dsl/inside_route.rb +11 -11
  11. data/lib/grape/dsl/request_response.rb +2 -1
  12. data/lib/grape/dsl/settings.rb +2 -6
  13. data/lib/grape/endpoint.rb +28 -18
  14. data/lib/grape/error_formatter/base.rb +1 -1
  15. data/lib/grape/exceptions/base.rb +2 -2
  16. data/lib/grape/exceptions/missing_group_type.rb +1 -6
  17. data/lib/grape/exceptions/unsupported_group_type.rb +1 -6
  18. data/lib/grape/exceptions/validation_errors.rb +1 -6
  19. data/lib/grape/extensions/active_support/hash_with_indifferent_access.rb +3 -3
  20. data/lib/grape/extensions/hash.rb +4 -7
  21. data/lib/grape/extensions/hashie/mash.rb +3 -3
  22. data/lib/grape/formatter/serializable_hash.rb +7 -7
  23. data/lib/grape/http/headers.rb +12 -2
  24. data/lib/grape/middleware/auth/base.rb +1 -1
  25. data/lib/grape/middleware/auth/strategies.rb +1 -2
  26. data/lib/grape/middleware/error.rb +5 -5
  27. data/lib/grape/middleware/formatter.rb +6 -6
  28. data/lib/grape/middleware/versioner/header.rb +11 -19
  29. data/lib/grape/railtie.rb +9 -0
  30. data/lib/grape/request.rb +8 -2
  31. data/lib/grape/router/route.rb +1 -3
  32. data/lib/grape/util/lazy_value.rb +3 -11
  33. data/lib/grape/util/strict_hash_configuration.rb +3 -4
  34. data/lib/grape/validations/multiple_attributes_iterator.rb +1 -1
  35. data/lib/grape/validations/params_scope.rb +8 -2
  36. data/lib/grape/validations/single_attribute_iterator.rb +3 -1
  37. data/lib/grape/validations/types/custom_type_coercer.rb +2 -16
  38. data/lib/grape/validations/validators/base.rb +9 -20
  39. data/lib/grape/validations/validators/default_validator.rb +2 -20
  40. data/lib/grape/validations/validators/multiple_params_base.rb +4 -8
  41. data/lib/grape/validations/validators/values_validator.rb +14 -5
  42. data/lib/grape/version.rb +1 -1
  43. data/lib/grape.rb +26 -5
  44. metadata +13 -253
  45. data/lib/grape/config.rb +0 -34
  46. data/lib/grape/extensions/deep_mergeable_hash.rb +0 -21
  47. data/lib/grape/extensions/deep_symbolize_hash.rb +0 -32
  48. data/spec/grape/api/custom_validations_spec.rb +0 -256
  49. data/spec/grape/api/deeply_included_options_spec.rb +0 -56
  50. data/spec/grape/api/defines_boolean_in_params_spec.rb +0 -38
  51. data/spec/grape/api/documentation_spec.rb +0 -59
  52. data/spec/grape/api/inherited_helpers_spec.rb +0 -114
  53. data/spec/grape/api/instance_spec.rb +0 -103
  54. data/spec/grape/api/invalid_format_spec.rb +0 -45
  55. data/spec/grape/api/namespace_parameters_in_route_spec.rb +0 -38
  56. data/spec/grape/api/nested_helpers_spec.rb +0 -50
  57. data/spec/grape/api/optional_parameters_in_route_spec.rb +0 -43
  58. data/spec/grape/api/parameters_modification_spec.rb +0 -41
  59. data/spec/grape/api/patch_method_helpers_spec.rb +0 -79
  60. data/spec/grape/api/recognize_path_spec.rb +0 -21
  61. data/spec/grape/api/required_parameters_in_route_spec.rb +0 -37
  62. data/spec/grape/api/required_parameters_with_invalid_method_spec.rb +0 -26
  63. data/spec/grape/api/routes_with_requirements_spec.rb +0 -59
  64. data/spec/grape/api/shared_helpers_exactly_one_of_spec.rb +0 -41
  65. data/spec/grape/api/shared_helpers_spec.rb +0 -36
  66. data/spec/grape/api_remount_spec.rb +0 -473
  67. data/spec/grape/api_spec.rb +0 -4347
  68. data/spec/grape/config_spec.rb +0 -17
  69. data/spec/grape/dsl/callbacks_spec.rb +0 -45
  70. data/spec/grape/dsl/desc_spec.rb +0 -101
  71. data/spec/grape/dsl/headers_spec.rb +0 -62
  72. data/spec/grape/dsl/helpers_spec.rb +0 -100
  73. data/spec/grape/dsl/inside_route_spec.rb +0 -535
  74. data/spec/grape/dsl/logger_spec.rb +0 -24
  75. data/spec/grape/dsl/middleware_spec.rb +0 -60
  76. data/spec/grape/dsl/parameters_spec.rb +0 -180
  77. data/spec/grape/dsl/request_response_spec.rb +0 -206
  78. data/spec/grape/dsl/routing_spec.rb +0 -275
  79. data/spec/grape/dsl/settings_spec.rb +0 -261
  80. data/spec/grape/dsl/validations_spec.rb +0 -55
  81. data/spec/grape/endpoint/declared_spec.rb +0 -846
  82. data/spec/grape/endpoint_spec.rb +0 -1085
  83. data/spec/grape/entity_spec.rb +0 -336
  84. data/spec/grape/exceptions/base_spec.rb +0 -81
  85. data/spec/grape/exceptions/body_parse_errors_spec.rb +0 -145
  86. data/spec/grape/exceptions/invalid_accept_header_spec.rb +0 -358
  87. data/spec/grape/exceptions/invalid_formatter_spec.rb +0 -15
  88. data/spec/grape/exceptions/invalid_response_spec.rb +0 -11
  89. data/spec/grape/exceptions/invalid_versioner_option_spec.rb +0 -15
  90. data/spec/grape/exceptions/missing_group_type_spec.rb +0 -21
  91. data/spec/grape/exceptions/missing_mime_type_spec.rb +0 -17
  92. data/spec/grape/exceptions/missing_option_spec.rb +0 -15
  93. data/spec/grape/exceptions/unknown_options_spec.rb +0 -15
  94. data/spec/grape/exceptions/unknown_validator_spec.rb +0 -15
  95. data/spec/grape/exceptions/unsupported_group_type_spec.rb +0 -23
  96. data/spec/grape/exceptions/validation_errors_spec.rb +0 -92
  97. data/spec/grape/exceptions/validation_spec.rb +0 -19
  98. data/spec/grape/extensions/param_builders/hash_spec.rb +0 -83
  99. data/spec/grape/extensions/param_builders/hash_with_indifferent_access_spec.rb +0 -105
  100. data/spec/grape/extensions/param_builders/hashie/mash_spec.rb +0 -79
  101. data/spec/grape/integration/global_namespace_function_spec.rb +0 -29
  102. data/spec/grape/integration/rack_sendfile_spec.rb +0 -48
  103. data/spec/grape/integration/rack_spec.rb +0 -51
  104. data/spec/grape/loading_spec.rb +0 -44
  105. data/spec/grape/middleware/auth/base_spec.rb +0 -31
  106. data/spec/grape/middleware/auth/dsl_spec.rb +0 -60
  107. data/spec/grape/middleware/auth/strategies_spec.rb +0 -120
  108. data/spec/grape/middleware/base_spec.rb +0 -221
  109. data/spec/grape/middleware/error_spec.rb +0 -85
  110. data/spec/grape/middleware/exception_spec.rb +0 -294
  111. data/spec/grape/middleware/formatter_spec.rb +0 -461
  112. data/spec/grape/middleware/globals_spec.rb +0 -30
  113. data/spec/grape/middleware/stack_spec.rb +0 -155
  114. data/spec/grape/middleware/versioner/accept_version_header_spec.rb +0 -122
  115. data/spec/grape/middleware/versioner/header_spec.rb +0 -345
  116. data/spec/grape/middleware/versioner/param_spec.rb +0 -171
  117. data/spec/grape/middleware/versioner/path_spec.rb +0 -62
  118. data/spec/grape/middleware/versioner_spec.rb +0 -21
  119. data/spec/grape/named_api_spec.rb +0 -19
  120. data/spec/grape/parser_spec.rb +0 -86
  121. data/spec/grape/path_spec.rb +0 -252
  122. data/spec/grape/presenters/presenter_spec.rb +0 -71
  123. data/spec/grape/request_spec.rb +0 -136
  124. data/spec/grape/util/inheritable_setting_spec.rb +0 -242
  125. data/spec/grape/util/inheritable_values_spec.rb +0 -79
  126. data/spec/grape/util/reverse_stackable_values_spec.rb +0 -134
  127. data/spec/grape/util/stackable_values_spec.rb +0 -128
  128. data/spec/grape/util/strict_hash_configuration_spec.rb +0 -38
  129. data/spec/grape/validations/attributes_doc_spec.rb +0 -153
  130. data/spec/grape/validations/instance_behaivour_spec.rb +0 -43
  131. data/spec/grape/validations/multiple_attributes_iterator_spec.rb +0 -40
  132. data/spec/grape/validations/params_scope_spec.rb +0 -1420
  133. data/spec/grape/validations/single_attribute_iterator_spec.rb +0 -57
  134. data/spec/grape/validations/types/array_coercer_spec.rb +0 -33
  135. data/spec/grape/validations/types/primitive_coercer_spec.rb +0 -150
  136. data/spec/grape/validations/types/set_coercer_spec.rb +0 -32
  137. data/spec/grape/validations/types_spec.rb +0 -111
  138. data/spec/grape/validations/validators/all_or_none_spec.rb +0 -162
  139. data/spec/grape/validations/validators/allow_blank_spec.rb +0 -575
  140. data/spec/grape/validations/validators/at_least_one_of_spec.rb +0 -205
  141. data/spec/grape/validations/validators/coerce_spec.rb +0 -1261
  142. data/spec/grape/validations/validators/default_spec.rb +0 -463
  143. data/spec/grape/validations/validators/exactly_one_of_spec.rb +0 -233
  144. data/spec/grape/validations/validators/except_values_spec.rb +0 -192
  145. data/spec/grape/validations/validators/mutual_exclusion_spec.rb +0 -214
  146. data/spec/grape/validations/validators/presence_spec.rb +0 -315
  147. data/spec/grape/validations/validators/regexp_spec.rb +0 -161
  148. data/spec/grape/validations/validators/same_as_spec.rb +0 -57
  149. data/spec/grape/validations/validators/values_spec.rb +0 -696
  150. data/spec/grape/validations/validators/zh-CN.yml +0 -10
  151. data/spec/grape/validations_spec.rb +0 -2029
  152. data/spec/integration/eager_load/eager_load_spec.rb +0 -15
  153. data/spec/integration/multi_json/json_spec.rb +0 -7
  154. data/spec/integration/multi_xml/xml_spec.rb +0 -7
  155. data/spec/shared/versioning_examples.rb +0 -215
  156. data/spec/spec_helper.rb +0 -52
  157. data/spec/support/basic_auth_encode_helpers.rb +0 -11
  158. data/spec/support/chunks.rb +0 -14
  159. data/spec/support/content_type_helpers.rb +0 -15
  160. data/spec/support/endpoint_faker.rb +0 -25
  161. data/spec/support/file_streamer.rb +0 -13
  162. data/spec/support/integer_helpers.rb +0 -13
  163. data/spec/support/versioned_helpers.rb +0 -55
@@ -1,336 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require 'grape_entity'
4
-
5
- describe Grape::Entity do
6
- subject { Class.new(Grape::API) }
7
-
8
- def app
9
- subject
10
- end
11
-
12
- describe '#present' do
13
- it 'sets the object as the body if no options are provided' do
14
- inner_body = nil
15
- subject.get '/example' do
16
- present(abc: 'def')
17
- inner_body = body
18
- end
19
- get '/example'
20
- expect(inner_body).to eql(abc: 'def')
21
- end
22
-
23
- it 'calls through to the provided entity class if one is given' do
24
- entity_mock = Object.new
25
- allow(entity_mock).to receive(:represent)
26
-
27
- subject.get '/example' do
28
- present Object.new, with: entity_mock
29
- end
30
- get '/example'
31
- end
32
-
33
- it 'pulls a representation from the class options if it exists' do
34
- entity = Class.new(described_class)
35
- allow(entity).to receive(:represent).and_return('Hiya')
36
-
37
- subject.represent Object, with: entity
38
- subject.get '/example' do
39
- present Object.new
40
- end
41
- get '/example'
42
- expect(last_response.body).to eq('Hiya')
43
- end
44
-
45
- it 'pulls a representation from the class options if the presented object is a collection of objects' do
46
- entity = Class.new(described_class)
47
- allow(entity).to receive(:represent).and_return('Hiya')
48
-
49
- module EntitySpec
50
- class TestObject
51
- end
52
-
53
- class FakeCollection
54
- def first
55
- TestObject.new
56
- end
57
- end
58
- end
59
-
60
- subject.represent EntitySpec::TestObject, with: entity
61
- subject.get '/example' do
62
- present [EntitySpec::TestObject.new]
63
- end
64
-
65
- subject.get '/example2' do
66
- present EntitySpec::FakeCollection.new
67
- end
68
-
69
- get '/example'
70
- expect(last_response.body).to eq('Hiya')
71
-
72
- get '/example2'
73
- expect(last_response.body).to eq('Hiya')
74
- end
75
-
76
- it 'pulls a representation from the class ancestor if it exists' do
77
- entity = Class.new(described_class)
78
- allow(entity).to receive(:represent).and_return('Hiya')
79
-
80
- subclass = Class.new(Object)
81
-
82
- subject.represent Object, with: entity
83
- subject.get '/example' do
84
- present subclass.new
85
- end
86
- get '/example'
87
- expect(last_response.body).to eq('Hiya')
88
- end
89
-
90
- it 'automatically uses Klass::Entity if that exists' do
91
- some_model = Class.new
92
- entity = Class.new(described_class)
93
- allow(entity).to receive(:represent).and_return('Auto-detect!')
94
-
95
- some_model.const_set :Entity, entity
96
-
97
- subject.get '/example' do
98
- present some_model.new
99
- end
100
- get '/example'
101
- expect(last_response.body).to eq('Auto-detect!')
102
- end
103
-
104
- it 'automatically uses Klass::Entity based on the first object in the collection being presented' do
105
- some_model = Class.new
106
- entity = Class.new(described_class)
107
- allow(entity).to receive(:represent).and_return('Auto-detect!')
108
-
109
- some_model.const_set :Entity, entity
110
-
111
- subject.get '/example' do
112
- present [some_model.new]
113
- end
114
- get '/example'
115
- expect(last_response.body).to eq('Auto-detect!')
116
- end
117
-
118
- it 'does not run autodetection for Entity when explicitly provided' do
119
- entity = Class.new(described_class)
120
- some_array = []
121
-
122
- subject.get '/example' do
123
- present some_array, with: entity
124
- end
125
-
126
- expect(some_array).not_to receive(:first)
127
- get '/example'
128
- end
129
-
130
- it 'does not use #first method on ActiveRecord::Relation to prevent needless sql query' do
131
- entity = Class.new(described_class)
132
- some_relation = Class.new
133
- some_model = Class.new
134
-
135
- allow(entity).to receive(:represent).and_return('Auto-detect!')
136
- allow(some_relation).to receive(:first)
137
- allow(some_relation).to receive(:klass).and_return(some_model)
138
-
139
- some_model.const_set :Entity, entity
140
-
141
- subject.get '/example' do
142
- present some_relation
143
- end
144
-
145
- expect(some_relation).not_to receive(:first)
146
- get '/example'
147
- expect(last_response.body).to eq('Auto-detect!')
148
- end
149
-
150
- it 'autodetection does not use Entity if it is not a presenter' do
151
- some_model = Class.new
152
- entity = Class.new
153
-
154
- some_model.class.const_set :Entity, entity
155
-
156
- subject.get '/example' do
157
- present some_model
158
- end
159
- get '/example'
160
- expect(entity).not_to receive(:represent)
161
- end
162
-
163
- it 'adds a root key to the output if one is given' do
164
- inner_body = nil
165
- subject.get '/example' do
166
- present({ abc: 'def' }, root: :root)
167
- inner_body = body
168
- end
169
- get '/example'
170
- expect(inner_body).to eql(root: { abc: 'def' })
171
- end
172
-
173
- %i[json serializable_hash].each do |format|
174
- it "presents with #{format}" do
175
- entity = Class.new(described_class)
176
- entity.root 'examples', 'example'
177
- entity.expose :id
178
-
179
- subject.format format
180
- subject.get '/example' do
181
- c = Class.new do
182
- attr_reader :id
183
-
184
- def initialize(id)
185
- @id = id
186
- end
187
- end
188
- present c.new(1), with: entity
189
- end
190
-
191
- get '/example'
192
- expect(last_response.status).to eq(200)
193
- expect(last_response.body).to eq('{"example":{"id":1}}')
194
- end
195
-
196
- it "presents with #{format} collection" do
197
- entity = Class.new(described_class)
198
- entity.root 'examples', 'example'
199
- entity.expose :id
200
-
201
- subject.format format
202
- subject.get '/examples' do
203
- c = Class.new do
204
- attr_reader :id
205
-
206
- def initialize(id)
207
- @id = id
208
- end
209
- end
210
- examples = [c.new(1), c.new(2)]
211
- present examples, with: entity
212
- end
213
-
214
- get '/examples'
215
- expect(last_response.status).to eq(200)
216
- expect(last_response.body).to eq('{"examples":[{"id":1},{"id":2}]}')
217
- end
218
- end
219
-
220
- it 'presents with xml' do
221
- entity = Class.new(described_class)
222
- entity.root 'examples', 'example'
223
- entity.expose :name
224
-
225
- subject.format :xml
226
-
227
- subject.get '/example' do
228
- c = Class.new do
229
- attr_reader :name
230
-
231
- def initialize(args)
232
- @name = args[:name] || 'no name set'
233
- end
234
- end
235
- present c.new(name: 'johnnyiller'), with: entity
236
- end
237
- get '/example'
238
- expect(last_response.status).to eq(200)
239
- expect(last_response.headers['Content-type']).to eq('application/xml')
240
- expect(last_response.body).to eq <<~XML
241
- <?xml version="1.0" encoding="UTF-8"?>
242
- <hash>
243
- <example>
244
- <name>johnnyiller</name>
245
- </example>
246
- </hash>
247
- XML
248
- end
249
-
250
- it 'presents with json' do
251
- entity = Class.new(described_class)
252
- entity.root 'examples', 'example'
253
- entity.expose :name
254
-
255
- subject.format :json
256
-
257
- subject.get '/example' do
258
- c = Class.new do
259
- attr_reader :name
260
-
261
- def initialize(args)
262
- @name = args[:name] || 'no name set'
263
- end
264
- end
265
- present c.new(name: 'johnnyiller'), with: entity
266
- end
267
- get '/example'
268
- expect(last_response.status).to eq(200)
269
- expect(last_response.headers['Content-type']).to eq('application/json')
270
- expect(last_response.body).to eq('{"example":{"name":"johnnyiller"}}')
271
- end
272
-
273
- it 'presents with jsonp utilising Rack::JSONP' do
274
- # Include JSONP middleware
275
- subject.use Rack::JSONP
276
-
277
- entity = Class.new(described_class)
278
- entity.root 'examples', 'example'
279
- entity.expose :name
280
-
281
- # Rack::JSONP expects a standard JSON response in UTF-8 format
282
- subject.format :json
283
- subject.formatter :json, lambda { |object, _|
284
- object.to_json.encode('utf-8')
285
- }
286
-
287
- subject.get '/example' do
288
- c = Class.new do
289
- attr_reader :name
290
-
291
- def initialize(args)
292
- @name = args[:name] || 'no name set'
293
- end
294
- end
295
-
296
- present c.new(name: 'johnnyiller'), with: entity
297
- end
298
-
299
- get '/example?callback=abcDef'
300
- expect(last_response.status).to eq(200)
301
- expect(last_response.headers['Content-type']).to eq('application/javascript')
302
- expect(last_response.body).to include 'abcDef({"example":{"name":"johnnyiller"}})'
303
- end
304
-
305
- context 'present with multiple entities' do
306
- it 'present with multiple entities using optional symbol' do
307
- user = Class.new do
308
- attr_reader :name
309
-
310
- def initialize(args)
311
- @name = args[:name] || 'no name set'
312
- end
313
- end
314
- user1 = user.new(name: 'user1')
315
- user2 = user.new(name: 'user2')
316
-
317
- entity = Class.new(described_class)
318
- entity.expose :name
319
-
320
- subject.format :json
321
- subject.get '/example' do
322
- present :page, 1
323
- present :user1, user1, with: entity
324
- present :user2, user2, with: entity
325
- end
326
- get '/example'
327
- expect_response_json = {
328
- 'page' => 1,
329
- 'user1' => { 'name' => 'user1' },
330
- 'user2' => { 'name' => 'user2' }
331
- }
332
- expect(JSON(last_response.body)).to eq(expect_response_json)
333
- end
334
- end
335
- end
336
- end
@@ -1,81 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- describe Grape::Exceptions::Base do
4
- describe '#to_s' do
5
- subject { described_class.new(message: message).to_s }
6
-
7
- let(:message) { 'a_message' }
8
-
9
- it { is_expected.to eq(message) }
10
- end
11
-
12
- describe '#message' do
13
- subject { described_class.new(message: message).message }
14
-
15
- let(:message) { 'a_message' }
16
-
17
- it { is_expected.to eq(message) }
18
- end
19
-
20
- describe '#compose_message' do
21
- subject { described_class.new.send(:compose_message, key, **attributes) }
22
-
23
- let(:key) { :invalid_formatter }
24
- let(:attributes) { { klass: String, to_format: 'xml' } }
25
-
26
- after do
27
- I18n.enforce_available_locales = true
28
- I18n.available_locales = %i[en]
29
- I18n.locale = :en
30
- I18n.default_locale = :en
31
- I18n.reload!
32
- end
33
-
34
- context 'when I18n enforces available locales' do
35
- before { I18n.enforce_available_locales = true }
36
-
37
- context 'when the fallback locale is available' do
38
- before do
39
- I18n.available_locales = %i[de en]
40
- I18n.default_locale = :de
41
- end
42
-
43
- it 'returns the translated message' do
44
- expect(subject).to eq('cannot convert String to xml')
45
- end
46
- end
47
-
48
- context 'when the fallback locale is not available' do
49
- before do
50
- I18n.available_locales = %i[de jp]
51
- I18n.locale = :de
52
- I18n.default_locale = :de
53
- end
54
-
55
- it 'returns the translation string' do
56
- expect(subject).to eq("grape.errors.messages.#{key}")
57
- end
58
- end
59
- end
60
-
61
- context 'when I18n does not enforce available locales' do
62
- before { I18n.enforce_available_locales = false }
63
-
64
- context 'when the fallback locale is available' do
65
- before { I18n.available_locales = %i[de en] }
66
-
67
- it 'returns the translated message' do
68
- expect(subject).to eq('cannot convert String to xml')
69
- end
70
- end
71
-
72
- context 'when the fallback locale is not available' do
73
- before { I18n.available_locales = %i[de jp] }
74
-
75
- it 'returns the translated message' do
76
- expect(subject).to eq('cannot convert String to xml')
77
- end
78
- end
79
- end
80
- end
81
- end
@@ -1,145 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- describe Grape::Exceptions::ValidationErrors do
4
- context 'api with rescue_from :all handler' do
5
- subject { Class.new(Grape::API) }
6
-
7
- before do
8
- subject.rescue_from :all do |_e|
9
- rack_response 'message was processed', 400
10
- end
11
- subject.params do
12
- requires :beer
13
- end
14
- subject.post '/beer' do
15
- 'beer received'
16
- end
17
- end
18
-
19
- def app
20
- subject
21
- end
22
-
23
- context 'with content_type json' do
24
- it 'can recover from failed body parsing' do
25
- post '/beer', 'test', 'CONTENT_TYPE' => 'application/json'
26
- expect(last_response.status).to eq 400
27
- expect(last_response.body).to eq('message was processed')
28
- end
29
- end
30
-
31
- context 'with content_type xml' do
32
- it 'can recover from failed body parsing' do
33
- post '/beer', 'test', 'CONTENT_TYPE' => 'application/xml'
34
- expect(last_response.status).to eq 400
35
- expect(last_response.body).to eq('message was processed')
36
- end
37
- end
38
-
39
- context 'with content_type text' do
40
- it 'can recover from failed body parsing' do
41
- post '/beer', 'test', 'CONTENT_TYPE' => 'text/plain'
42
- expect(last_response.status).to eq 400
43
- expect(last_response.body).to eq('message was processed')
44
- end
45
- end
46
-
47
- context 'with no specific content_type' do
48
- it 'can recover from failed body parsing' do
49
- post '/beer', 'test', {}
50
- expect(last_response.status).to eq 400
51
- expect(last_response.body).to eq('message was processed')
52
- end
53
- end
54
- end
55
-
56
- context 'api with rescue_from :grape_exceptions handler' do
57
- subject { Class.new(Grape::API) }
58
-
59
- before do
60
- subject.rescue_from :all do |_e|
61
- rack_response 'message was processed', 400
62
- end
63
- subject.rescue_from :grape_exceptions
64
-
65
- subject.params do
66
- requires :beer
67
- end
68
- subject.post '/beer' do
69
- 'beer received'
70
- end
71
- end
72
-
73
- def app
74
- subject
75
- end
76
-
77
- context 'with content_type json' do
78
- it 'returns body parsing error message' do
79
- post '/beer', 'test', 'CONTENT_TYPE' => 'application/json'
80
- expect(last_response.status).to eq 400
81
- expect(last_response.body).to include 'message body does not match declared format'
82
- end
83
- end
84
-
85
- context 'with content_type xml' do
86
- it 'returns body parsing error message' do
87
- post '/beer', 'test', 'CONTENT_TYPE' => 'application/xml'
88
- expect(last_response.status).to eq 400
89
- expect(last_response.body).to include 'message body does not match declared format'
90
- end
91
- end
92
- end
93
-
94
- context 'api without a rescue handler' do
95
- subject { Class.new(Grape::API) }
96
-
97
- before do
98
- subject.params do
99
- requires :beer
100
- end
101
- subject.post '/beer' do
102
- 'beer received'
103
- end
104
- end
105
-
106
- def app
107
- subject
108
- end
109
-
110
- context 'and with content_type json' do
111
- it 'can recover from failed body parsing' do
112
- post '/beer', 'test', 'CONTENT_TYPE' => 'application/json'
113
- expect(last_response.status).to eq 400
114
- expect(last_response.body).to include('message body does not match declared format')
115
- expect(last_response.body).to include('application/json')
116
- end
117
- end
118
-
119
- context 'with content_type xml' do
120
- it 'can recover from failed body parsing' do
121
- post '/beer', 'test', 'CONTENT_TYPE' => 'application/xml'
122
- expect(last_response.status).to eq 400
123
- expect(last_response.body).to include('message body does not match declared format')
124
- expect(last_response.body).to include('application/xml')
125
- end
126
- end
127
-
128
- context 'with content_type text' do
129
- it 'can recover from failed body parsing' do
130
- post '/beer', 'test', 'CONTENT_TYPE' => 'text/plain'
131
- expect(last_response.status).to eq 400
132
- expect(last_response.body).to eq('beer is missing')
133
- end
134
- end
135
-
136
- context 'and with no specific content_type' do
137
- it 'can recover from failed body parsing' do
138
- post '/beer', 'test', {}
139
- expect(last_response.status).to eq 400
140
- # plain response with text/html
141
- expect(last_response.body).to eq('beer is missing')
142
- end
143
- end
144
- end
145
- end