grape 1.8.0 → 2.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (210) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +65 -1
  3. data/README.md +377 -334
  4. data/UPGRADING.md +231 -6
  5. data/grape.gemspec +6 -10
  6. data/lib/grape/api/instance.rb +13 -10
  7. data/lib/grape/api.rb +17 -8
  8. data/lib/grape/content_types.rb +0 -2
  9. data/lib/grape/cookies.rb +2 -1
  10. data/lib/grape/dry_types.rb +0 -2
  11. data/lib/grape/dsl/desc.rb +23 -21
  12. data/lib/grape/dsl/headers.rb +1 -1
  13. data/lib/grape/dsl/inside_route.rb +47 -22
  14. data/lib/grape/dsl/parameters.rb +4 -3
  15. data/lib/grape/dsl/routing.rb +20 -4
  16. data/lib/grape/dsl/validations.rb +13 -0
  17. data/lib/grape/endpoint.rb +15 -10
  18. data/lib/grape/{util/env.rb → env.rb} +0 -5
  19. data/lib/grape/error_formatter/txt.rb +11 -10
  20. data/lib/grape/exceptions/base.rb +3 -3
  21. data/lib/grape/exceptions/missing_group_type.rb +1 -1
  22. data/lib/grape/exceptions/unsupported_group_type.rb +1 -1
  23. data/lib/grape/exceptions/validation.rb +0 -2
  24. data/lib/grape/exceptions/validation_array_errors.rb +1 -0
  25. data/lib/grape/exceptions/validation_errors.rb +1 -3
  26. data/lib/grape/extensions/hash.rb +5 -1
  27. data/lib/grape/http/headers.rb +18 -24
  28. data/lib/grape/{util/json.rb → json.rb} +1 -3
  29. data/lib/grape/locale/en.yml +3 -0
  30. data/lib/grape/middleware/auth/base.rb +0 -2
  31. data/lib/grape/middleware/auth/dsl.rb +0 -2
  32. data/lib/grape/middleware/auth/strategies.rb +1 -2
  33. data/lib/grape/middleware/base.rb +0 -2
  34. data/lib/grape/middleware/error.rb +55 -50
  35. data/lib/grape/middleware/formatter.rb +21 -18
  36. data/lib/grape/middleware/globals.rb +1 -3
  37. data/lib/grape/middleware/stack.rb +2 -3
  38. data/lib/grape/middleware/versioner/accept_version_header.rb +0 -2
  39. data/lib/grape/middleware/versioner/header.rb +17 -163
  40. data/lib/grape/middleware/versioner/param.rb +2 -4
  41. data/lib/grape/middleware/versioner/path.rb +1 -3
  42. data/lib/grape/namespace.rb +3 -4
  43. data/lib/grape/path.rb +24 -29
  44. data/lib/grape/railtie.rb +9 -0
  45. data/lib/grape/request.rb +3 -5
  46. data/lib/grape/router/base_route.rb +39 -0
  47. data/lib/grape/router/greedy_route.rb +20 -0
  48. data/lib/grape/router/pattern.rb +39 -30
  49. data/lib/grape/router/route.rb +22 -59
  50. data/lib/grape/router.rb +30 -36
  51. data/lib/grape/util/accept/header.rb +19 -0
  52. data/lib/grape/util/accept_header_handler.rb +105 -0
  53. data/lib/grape/util/base_inheritable.rb +4 -4
  54. data/lib/grape/util/cache.rb +0 -3
  55. data/lib/grape/util/endpoint_configuration.rb +1 -1
  56. data/lib/grape/util/header.rb +13 -0
  57. data/lib/grape/util/inheritable_values.rb +0 -2
  58. data/lib/grape/util/lazy/block.rb +29 -0
  59. data/lib/grape/util/lazy/object.rb +45 -0
  60. data/lib/grape/util/lazy/value.rb +38 -0
  61. data/lib/grape/util/lazy/value_array.rb +21 -0
  62. data/lib/grape/util/lazy/value_enumerable.rb +34 -0
  63. data/lib/grape/util/lazy/value_hash.rb +21 -0
  64. data/lib/grape/util/media_type.rb +70 -0
  65. data/lib/grape/util/reverse_stackable_values.rb +1 -6
  66. data/lib/grape/util/stackable_values.rb +1 -6
  67. data/lib/grape/util/strict_hash_configuration.rb +3 -3
  68. data/lib/grape/validations/attributes_doc.rb +38 -36
  69. data/lib/grape/validations/contract_scope.rb +71 -0
  70. data/lib/grape/validations/params_scope.rb +10 -9
  71. data/lib/grape/validations/types/array_coercer.rb +0 -2
  72. data/lib/grape/validations/types/build_coercer.rb +69 -71
  73. data/lib/grape/validations/types/dry_type_coercer.rb +1 -11
  74. data/lib/grape/validations/types/json.rb +0 -2
  75. data/lib/grape/validations/types/primitive_coercer.rb +0 -2
  76. data/lib/grape/validations/types/set_coercer.rb +0 -3
  77. data/lib/grape/validations/types.rb +0 -3
  78. data/lib/grape/validations/validators/base.rb +2 -1
  79. data/lib/grape/validations/validators/default_validator.rb +5 -1
  80. data/lib/grape/validations/validators/length_validator.rb +42 -0
  81. data/lib/grape/validations/validators/values_validator.rb +8 -3
  82. data/lib/grape/validations.rb +3 -7
  83. data/lib/grape/version.rb +1 -1
  84. data/lib/grape/{util/xml.rb → xml.rb} +1 -1
  85. data/lib/grape.rb +38 -269
  86. metadata +33 -274
  87. data/lib/grape/eager_load.rb +0 -20
  88. data/lib/grape/middleware/versioner/parse_media_type_patch.rb +0 -24
  89. data/lib/grape/router/attribute_translator.rb +0 -63
  90. data/lib/grape/util/lazy_block.rb +0 -27
  91. data/lib/grape/util/lazy_object.rb +0 -43
  92. data/lib/grape/util/lazy_value.rb +0 -91
  93. data/spec/grape/api/custom_validations_spec.rb +0 -213
  94. data/spec/grape/api/deeply_included_options_spec.rb +0 -56
  95. data/spec/grape/api/defines_boolean_in_params_spec.rb +0 -38
  96. data/spec/grape/api/documentation_spec.rb +0 -59
  97. data/spec/grape/api/inherited_helpers_spec.rb +0 -114
  98. data/spec/grape/api/instance_spec.rb +0 -103
  99. data/spec/grape/api/invalid_format_spec.rb +0 -45
  100. data/spec/grape/api/namespace_parameters_in_route_spec.rb +0 -38
  101. data/spec/grape/api/nested_helpers_spec.rb +0 -50
  102. data/spec/grape/api/optional_parameters_in_route_spec.rb +0 -43
  103. data/spec/grape/api/parameters_modification_spec.rb +0 -41
  104. data/spec/grape/api/patch_method_helpers_spec.rb +0 -79
  105. data/spec/grape/api/recognize_path_spec.rb +0 -21
  106. data/spec/grape/api/required_parameters_in_route_spec.rb +0 -37
  107. data/spec/grape/api/required_parameters_with_invalid_method_spec.rb +0 -26
  108. data/spec/grape/api/routes_with_requirements_spec.rb +0 -59
  109. data/spec/grape/api/shared_helpers_exactly_one_of_spec.rb +0 -41
  110. data/spec/grape/api/shared_helpers_spec.rb +0 -36
  111. data/spec/grape/api_remount_spec.rb +0 -509
  112. data/spec/grape/api_spec.rb +0 -4356
  113. data/spec/grape/dsl/callbacks_spec.rb +0 -45
  114. data/spec/grape/dsl/desc_spec.rb +0 -98
  115. data/spec/grape/dsl/headers_spec.rb +0 -62
  116. data/spec/grape/dsl/helpers_spec.rb +0 -100
  117. data/spec/grape/dsl/inside_route_spec.rb +0 -531
  118. data/spec/grape/dsl/logger_spec.rb +0 -24
  119. data/spec/grape/dsl/middleware_spec.rb +0 -60
  120. data/spec/grape/dsl/parameters_spec.rb +0 -180
  121. data/spec/grape/dsl/request_response_spec.rb +0 -225
  122. data/spec/grape/dsl/routing_spec.rb +0 -275
  123. data/spec/grape/dsl/settings_spec.rb +0 -261
  124. data/spec/grape/dsl/validations_spec.rb +0 -55
  125. data/spec/grape/endpoint/declared_spec.rb +0 -846
  126. data/spec/grape/endpoint_spec.rb +0 -1085
  127. data/spec/grape/entity_spec.rb +0 -336
  128. data/spec/grape/exceptions/base_spec.rb +0 -81
  129. data/spec/grape/exceptions/body_parse_errors_spec.rb +0 -185
  130. data/spec/grape/exceptions/invalid_accept_header_spec.rb +0 -358
  131. data/spec/grape/exceptions/invalid_formatter_spec.rb +0 -15
  132. data/spec/grape/exceptions/invalid_response_spec.rb +0 -11
  133. data/spec/grape/exceptions/invalid_versioner_option_spec.rb +0 -15
  134. data/spec/grape/exceptions/missing_group_type_spec.rb +0 -17
  135. data/spec/grape/exceptions/missing_mime_type_spec.rb +0 -17
  136. data/spec/grape/exceptions/missing_option_spec.rb +0 -15
  137. data/spec/grape/exceptions/unknown_options_spec.rb +0 -15
  138. data/spec/grape/exceptions/unknown_validator_spec.rb +0 -15
  139. data/spec/grape/exceptions/unsupported_group_type_spec.rb +0 -19
  140. data/spec/grape/exceptions/validation_errors_spec.rb +0 -92
  141. data/spec/grape/exceptions/validation_spec.rb +0 -19
  142. data/spec/grape/extensions/param_builders/hash_spec.rb +0 -83
  143. data/spec/grape/extensions/param_builders/hash_with_indifferent_access_spec.rb +0 -105
  144. data/spec/grape/extensions/param_builders/hashie/mash_spec.rb +0 -79
  145. data/spec/grape/grape_spec.rb +0 -9
  146. data/spec/grape/integration/global_namespace_function_spec.rb +0 -29
  147. data/spec/grape/integration/rack_sendfile_spec.rb +0 -48
  148. data/spec/grape/integration/rack_spec.rb +0 -51
  149. data/spec/grape/loading_spec.rb +0 -44
  150. data/spec/grape/middleware/auth/base_spec.rb +0 -31
  151. data/spec/grape/middleware/auth/dsl_spec.rb +0 -60
  152. data/spec/grape/middleware/auth/strategies_spec.rb +0 -120
  153. data/spec/grape/middleware/base_spec.rb +0 -221
  154. data/spec/grape/middleware/error_spec.rb +0 -85
  155. data/spec/grape/middleware/exception_spec.rb +0 -294
  156. data/spec/grape/middleware/formatter_spec.rb +0 -461
  157. data/spec/grape/middleware/globals_spec.rb +0 -30
  158. data/spec/grape/middleware/stack_spec.rb +0 -155
  159. data/spec/grape/middleware/versioner/accept_version_header_spec.rb +0 -122
  160. data/spec/grape/middleware/versioner/header_spec.rb +0 -345
  161. data/spec/grape/middleware/versioner/param_spec.rb +0 -171
  162. data/spec/grape/middleware/versioner/path_spec.rb +0 -62
  163. data/spec/grape/middleware/versioner_spec.rb +0 -21
  164. data/spec/grape/named_api_spec.rb +0 -19
  165. data/spec/grape/parser_spec.rb +0 -86
  166. data/spec/grape/path_spec.rb +0 -252
  167. data/spec/grape/presenters/presenter_spec.rb +0 -71
  168. data/spec/grape/request_spec.rb +0 -126
  169. data/spec/grape/util/inheritable_setting_spec.rb +0 -242
  170. data/spec/grape/util/inheritable_values_spec.rb +0 -79
  171. data/spec/grape/util/reverse_stackable_values_spec.rb +0 -134
  172. data/spec/grape/util/stackable_values_spec.rb +0 -128
  173. data/spec/grape/util/strict_hash_configuration_spec.rb +0 -38
  174. data/spec/grape/validations/attributes_doc_spec.rb +0 -153
  175. data/spec/grape/validations/instance_behaivour_spec.rb +0 -43
  176. data/spec/grape/validations/multiple_attributes_iterator_spec.rb +0 -38
  177. data/spec/grape/validations/params_scope_spec.rb +0 -1420
  178. data/spec/grape/validations/single_attribute_iterator_spec.rb +0 -56
  179. data/spec/grape/validations/types/array_coercer_spec.rb +0 -33
  180. data/spec/grape/validations/types/primitive_coercer_spec.rb +0 -150
  181. data/spec/grape/validations/types/set_coercer_spec.rb +0 -32
  182. data/spec/grape/validations/types_spec.rb +0 -111
  183. data/spec/grape/validations/validators/all_or_none_spec.rb +0 -162
  184. data/spec/grape/validations/validators/allow_blank_spec.rb +0 -575
  185. data/spec/grape/validations/validators/at_least_one_of_spec.rb +0 -205
  186. data/spec/grape/validations/validators/base_spec.rb +0 -38
  187. data/spec/grape/validations/validators/coerce_spec.rb +0 -1261
  188. data/spec/grape/validations/validators/default_spec.rb +0 -463
  189. data/spec/grape/validations/validators/exactly_one_of_spec.rb +0 -233
  190. data/spec/grape/validations/validators/except_values_spec.rb +0 -192
  191. data/spec/grape/validations/validators/mutual_exclusion_spec.rb +0 -214
  192. data/spec/grape/validations/validators/presence_spec.rb +0 -315
  193. data/spec/grape/validations/validators/regexp_spec.rb +0 -161
  194. data/spec/grape/validations/validators/same_as_spec.rb +0 -57
  195. data/spec/grape/validations/validators/values_spec.rb +0 -733
  196. data/spec/grape/validations/validators/zh-CN.yml +0 -10
  197. data/spec/grape/validations_spec.rb +0 -2030
  198. data/spec/integration/eager_load/eager_load_spec.rb +0 -15
  199. data/spec/integration/multi_json/json_spec.rb +0 -7
  200. data/spec/integration/multi_xml/xml_spec.rb +0 -7
  201. data/spec/shared/deprecated_class_examples.rb +0 -16
  202. data/spec/shared/versioning_examples.rb +0 -215
  203. data/spec/spec_helper.rb +0 -52
  204. data/spec/support/basic_auth_encode_helpers.rb +0 -11
  205. data/spec/support/chunks.rb +0 -14
  206. data/spec/support/content_type_helpers.rb +0 -15
  207. data/spec/support/endpoint_faker.rb +0 -25
  208. data/spec/support/file_streamer.rb +0 -13
  209. data/spec/support/integer_helpers.rb +0 -13
  210. 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,185 +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 with rescue_from :grape_exceptions handler with block' do
95
- subject { Class.new(Grape::API) }
96
-
97
- before do
98
- subject.rescue_from :grape_exceptions do |e|
99
- rack_response "Custom Error Contents, Original Message: #{e.message}", 400
100
- end
101
-
102
- subject.params do
103
- requires :beer
104
- end
105
-
106
- subject.post '/beer' do
107
- 'beer received'
108
- end
109
- end
110
-
111
- def app
112
- subject
113
- end
114
-
115
- context 'with content_type json' do
116
- it 'returns body parsing error message' do
117
- post '/beer', 'test', 'CONTENT_TYPE' => 'application/json'
118
- expect(last_response.status).to eq 400
119
- expect(last_response.body).to include 'message body does not match declared format'
120
- expect(last_response.body).to include 'Custom Error Contents, Original Message'
121
- end
122
- end
123
-
124
- context 'with content_type xml' do
125
- it 'returns body parsing error message' do
126
- post '/beer', 'test', 'CONTENT_TYPE' => 'application/xml'
127
- expect(last_response.status).to eq 400
128
- expect(last_response.body).to include 'message body does not match declared format'
129
- expect(last_response.body).to include 'Custom Error Contents, Original Message'
130
- end
131
- end
132
- end
133
-
134
- context 'api without a rescue handler' do
135
- subject { Class.new(Grape::API) }
136
-
137
- before do
138
- subject.params do
139
- requires :beer
140
- end
141
- subject.post '/beer' do
142
- 'beer received'
143
- end
144
- end
145
-
146
- def app
147
- subject
148
- end
149
-
150
- context 'and with content_type json' do
151
- it 'can recover from failed body parsing' do
152
- post '/beer', 'test', 'CONTENT_TYPE' => 'application/json'
153
- expect(last_response.status).to eq 400
154
- expect(last_response.body).to include('message body does not match declared format')
155
- expect(last_response.body).to include('application/json')
156
- end
157
- end
158
-
159
- context 'with content_type xml' do
160
- it 'can recover from failed body parsing' do
161
- post '/beer', 'test', 'CONTENT_TYPE' => 'application/xml'
162
- expect(last_response.status).to eq 400
163
- expect(last_response.body).to include('message body does not match declared format')
164
- expect(last_response.body).to include('application/xml')
165
- end
166
- end
167
-
168
- context 'with content_type text' do
169
- it 'can recover from failed body parsing' do
170
- post '/beer', 'test', 'CONTENT_TYPE' => 'text/plain'
171
- expect(last_response.status).to eq 400
172
- expect(last_response.body).to eq('beer is missing')
173
- end
174
- end
175
-
176
- context 'and with no specific content_type' do
177
- it 'can recover from failed body parsing' do
178
- post '/beer', 'test', {}
179
- expect(last_response.status).to eq 400
180
- # plain response with text/html
181
- expect(last_response.body).to eq('beer is missing')
182
- end
183
- end
184
- end
185
- end