grape 1.7.1 → 2.0.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.
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,696 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- describe Grape::Validations::Validators::ValuesValidator do
4
- let_it_be(:values_model) do
5
- Class.new do
6
- DEFAULT_VALUES = %w[valid-type1 valid-type2 valid-type3].freeze
7
- DEFAULT_EXCEPTS = %w[invalid-type1 invalid-type2 invalid-type3].freeze
8
-
9
- class << self
10
- def values
11
- @values ||= []
12
- [DEFAULT_VALUES + @values].flatten.uniq
13
- end
14
-
15
- def add_value(value)
16
- @values ||= []
17
- @values << value
18
- end
19
-
20
- def excepts
21
- @excepts ||= []
22
- [DEFAULT_EXCEPTS + @excepts].flatten.uniq
23
- end
24
-
25
- def add_except(except)
26
- @excepts ||= []
27
- @excepts << except
28
- end
29
-
30
- def include?(value)
31
- values.include?(value)
32
- end
33
- end
34
- end
35
- end
36
-
37
- before do
38
- stub_const('ValuesModel', values_model)
39
- end
40
-
41
- let_it_be(:app) do
42
- ValuesModel = values_model
43
- Class.new(Grape::API) do
44
- default_format :json
45
-
46
- resources :custom_message do
47
- params do
48
- requires :type, values: { value: ValuesModel.values, message: 'value does not include in values' }
49
- end
50
- get '/' do
51
- { type: params[:type] }
52
- end
53
-
54
- params do
55
- optional :type, values: { value: -> { ValuesModel.values }, message: 'value does not include in values' }, default: 'valid-type2'
56
- end
57
- get '/lambda' do
58
- { type: params[:type] }
59
- end
60
-
61
- params do
62
- requires :type, values: { except: ValuesModel.excepts, except_message: 'value is on exclusions list', message: 'default exclude message' }
63
- end
64
- get '/exclude/exclude_message'
65
-
66
- params do
67
- requires :type, values: { except: -> { ValuesModel.excepts }, except_message: 'value is on exclusions list' }
68
- end
69
- get '/exclude/lambda/exclude_message'
70
-
71
- params do
72
- requires :type, values: { except: ValuesModel.excepts, message: 'default exclude message' }
73
- end
74
- get '/exclude/fallback_message'
75
- end
76
-
77
- params do
78
- requires :type, values: ValuesModel.values
79
- end
80
- get '/' do
81
- { type: params[:type] }
82
- end
83
-
84
- params do
85
- requires :type, values: []
86
- end
87
- get '/empty'
88
-
89
- params do
90
- optional :type, values: { value: ValuesModel.values }, default: 'valid-type2'
91
- end
92
- get '/default/hash/valid' do
93
- { type: params[:type] }
94
- end
95
-
96
- params do
97
- optional :type, values: ValuesModel.values, default: 'valid-type2'
98
- end
99
- get '/default/valid' do
100
- { type: params[:type] }
101
- end
102
-
103
- params do
104
- optional :type, values: { except: ValuesModel.excepts }, default: 'valid-type2'
105
- end
106
- get '/default/except' do
107
- { type: params[:type] }
108
- end
109
-
110
- params do
111
- optional :type, values: -> { ValuesModel.values }, default: 'valid-type2'
112
- end
113
- get '/lambda' do
114
- { type: params[:type] }
115
- end
116
-
117
- params do
118
- optional :type, type: Integer, values: 1..
119
- end
120
- get '/endless' do
121
- { type: params[:type] }
122
- end
123
-
124
- params do
125
- requires :type, values: ->(v) { ValuesModel.include? v }
126
- end
127
- get '/lambda_val' do
128
- { type: params[:type] }
129
- end
130
-
131
- params do
132
- requires :number, type: Integer, values: ->(v) { v > 0 }
133
- end
134
- get '/lambda_int_val' do
135
- { number: params[:number] }
136
- end
137
-
138
- params do
139
- requires :type, values: -> { [] }
140
- end
141
- get '/empty_lambda'
142
-
143
- params do
144
- optional :type, values: ValuesModel.values, default: -> { ValuesModel.values.sample }
145
- end
146
- get '/default_lambda' do
147
- { type: params[:type] }
148
- end
149
-
150
- params do
151
- optional :type, values: -> { ValuesModel.values }, default: -> { ValuesModel.values.sample }
152
- end
153
- get '/default_and_values_lambda' do
154
- { type: params[:type] }
155
- end
156
-
157
- params do
158
- optional :type, type: Grape::API::Boolean, desc: 'A boolean', values: [true]
159
- end
160
- get '/values/optional_boolean' do
161
- { type: params[:type] }
162
- end
163
-
164
- params do
165
- requires :type, type: Integer, desc: 'An integer', values: [10, 11], default: 10
166
- end
167
- get '/values/coercion' do
168
- { type: params[:type] }
169
- end
170
-
171
- params do
172
- requires :type, type: Array[Integer], desc: 'An integer', values: [10, 11], default: 10
173
- end
174
- get '/values/array_coercion' do
175
- { type: params[:type] }
176
- end
177
-
178
- params do
179
- optional :optional, type: Array do
180
- requires :type, values: %w[a b]
181
- end
182
- end
183
- get '/optional_with_required_values'
184
-
185
- params do
186
- requires :type, values: { except: ValuesModel.excepts }
187
- end
188
- get '/except/exclusive' do
189
- { type: params[:type] }
190
- end
191
-
192
- params do
193
- requires :type, type: String, values: { except: ValuesModel.excepts }
194
- end
195
- get '/except/exclusive/type' do
196
- { type: params[:type] }
197
- end
198
-
199
- params do
200
- requires :type, values: { except: -> { ValuesModel.excepts } }
201
- end
202
- get '/except/exclusive/lambda' do
203
- { type: params[:type] }
204
- end
205
-
206
- params do
207
- requires :type, type: String, values: { except: -> { ValuesModel.excepts } }
208
- end
209
- get '/except/exclusive/lambda/type' do
210
- { type: params[:type] }
211
- end
212
-
213
- params do
214
- requires :type, type: Integer, values: { except: -> { [3, 4, 5] } }
215
- end
216
- get '/except/exclusive/lambda/coercion' do
217
- { type: params[:type] }
218
- end
219
-
220
- params do
221
- requires :type, type: Integer, values: { value: 1..5, except: [3] }
222
- end
223
- get '/mixed/value/except' do
224
- { type: params[:type] }
225
- end
226
-
227
- params do
228
- optional :optional, type: Array[String], values: %w[a b c]
229
- end
230
- put '/optional_with_array_of_string_values'
231
-
232
- params do
233
- requires :type, values: { proc: ->(v) { ValuesModel.include? v } }
234
- end
235
- get '/proc' do
236
- { type: params[:type] }
237
- end
238
-
239
- params do
240
- requires :type, values: { proc: ->(v) { ValuesModel.include? v }, message: 'failed check' }
241
- end
242
- get '/proc/message'
243
-
244
- params do
245
- optional :name, type: String, values: %w[a b], allow_blank: true
246
- end
247
- get '/allow_blank'
248
- end
249
- end
250
-
251
- context 'with a custom validation message' do
252
- it 'allows a valid value for a parameter' do
253
- get('/custom_message', type: 'valid-type1')
254
- expect(last_response.status).to eq 200
255
- expect(last_response.body).to eq({ type: 'valid-type1' }.to_json)
256
- end
257
-
258
- it 'does not allow an invalid value for a parameter' do
259
- get('/custom_message', type: 'invalid-type')
260
- expect(last_response.status).to eq 400
261
- expect(last_response.body).to eq({ error: 'type value does not include in values' }.to_json)
262
- end
263
-
264
- it 'validates against values in a proc' do
265
- ValuesModel.add_value('valid-type4')
266
-
267
- get('/custom_message/lambda', type: 'valid-type4')
268
- expect(last_response.status).to eq 200
269
- expect(last_response.body).to eq({ type: 'valid-type4' }.to_json)
270
- end
271
-
272
- it 'does not allow an invalid value for a parameter using lambda' do
273
- get('/custom_message/lambda', type: 'invalid-type')
274
- expect(last_response.status).to eq 400
275
- expect(last_response.body).to eq({ error: 'type value does not include in values' }.to_json)
276
- end
277
- end
278
-
279
- context 'with a custom exclude validation message' do
280
- it 'does not allow an invalid value for a parameter' do
281
- get('/custom_message/exclude/exclude_message', type: 'invalid-type1')
282
- expect(last_response.status).to eq 400
283
- expect(last_response.body).to eq({ error: 'type value is on exclusions list' }.to_json)
284
- end
285
- end
286
-
287
- context 'with a custom exclude validation message' do
288
- it 'does not allow an invalid value for a parameter' do
289
- get('/custom_message/exclude/lambda/exclude_message', type: 'invalid-type1')
290
- expect(last_response.status).to eq 400
291
- expect(last_response.body).to eq({ error: 'type value is on exclusions list' }.to_json)
292
- end
293
- end
294
-
295
- context 'exclude with a standard custom validation message' do
296
- it 'does not allow an invalid value for a parameter' do
297
- get('/custom_message/exclude/fallback_message', type: 'invalid-type1')
298
- expect(last_response.status).to eq 400
299
- expect(last_response.body).to eq({ error: 'type default exclude message' }.to_json)
300
- end
301
- end
302
-
303
- it 'allows a valid value for a parameter' do
304
- get('/', type: 'valid-type1')
305
- expect(last_response.status).to eq 200
306
- expect(last_response.body).to eq({ type: 'valid-type1' }.to_json)
307
- end
308
-
309
- it 'does not allow an invalid value for a parameter' do
310
- get('/', type: 'invalid-type')
311
- expect(last_response.status).to eq 400
312
- expect(last_response.body).to eq({ error: 'type does not have a valid value' }.to_json)
313
- end
314
-
315
- it 'rejects all values if values is an empty array' do
316
- get('/empty', type: 'invalid-type')
317
- expect(last_response.status).to eq 400
318
- expect(last_response.body).to eq({ error: 'type does not have a valid value' }.to_json)
319
- end
320
-
321
- context 'nil value for a parameter' do
322
- it 'does not allow for root params scope' do
323
- get('/', type: nil)
324
- expect(last_response.status).to eq 400
325
- expect(last_response.body).to eq({ error: 'type does not have a valid value' }.to_json)
326
- end
327
-
328
- it 'allows for a required param in child scope' do
329
- get('/optional_with_required_values')
330
- expect(last_response.status).to eq 200
331
- end
332
-
333
- it 'accepts for an optional param with a list of values' do
334
- put('/optional_with_array_of_string_values', optional: nil)
335
- expect(last_response.status).to eq 200
336
- end
337
- end
338
-
339
- it 'allows a valid default value' do
340
- get('/default/valid')
341
- expect(last_response.status).to eq 200
342
- expect(last_response.body).to eq({ type: 'valid-type2' }.to_json)
343
- end
344
-
345
- it 'allows a default value with except' do
346
- get('/default/except')
347
- expect(last_response.status).to eq 200
348
- expect(last_response.body).to eq({ type: 'valid-type2' }.to_json)
349
- end
350
-
351
- it 'allows a valid default value' do
352
- get('/default/hash/valid')
353
- expect(last_response.status).to eq 200
354
- expect(last_response.body).to eq({ type: 'valid-type2' }.to_json)
355
- end
356
-
357
- it 'allows a proc for values' do
358
- get('/lambda', type: 'valid-type1')
359
- expect(last_response.status).to eq 200
360
- expect(last_response.body).to eq({ type: 'valid-type1' }.to_json)
361
- end
362
-
363
- it 'does not validate updated values without proc' do
364
- ValuesModel.add_value('valid-type4')
365
- get('/', type: 'valid-type4')
366
- expect(last_response.status).to eq 400
367
- expect(last_response.body).to eq({ error: 'type does not have a valid value' }.to_json)
368
- end
369
-
370
- it 'validates against values in a proc' do
371
- ValuesModel.add_value('valid-type4')
372
-
373
- get('/lambda', type: 'valid-type4')
374
- expect(last_response.status).to eq 200
375
- expect(last_response.body).to eq({ type: 'valid-type4' }.to_json)
376
- end
377
-
378
- it 'does not allow an invalid value for a parameter using lambda' do
379
- get('/lambda', type: 'invalid-type')
380
- expect(last_response.status).to eq 400
381
- expect(last_response.body).to eq({ error: 'type does not have a valid value' }.to_json)
382
- end
383
-
384
- it 'validates against values in an endless range', if: ActiveSupport::VERSION::MAJOR >= 6 do
385
- get('/endless', type: 10)
386
- expect(last_response.status).to eq 200
387
- expect(last_response.body).to eq({ type: 10 }.to_json)
388
- end
389
-
390
- it 'does not allow an invalid value for a parameter using an endless range', if: ActiveSupport::VERSION::MAJOR >= 6 do
391
- get('/endless', type: 0)
392
- expect(last_response.status).to eq 400
393
- expect(last_response.body).to eq({ error: 'type does not have a valid value' }.to_json)
394
- end
395
-
396
- it 'does not allow non-numeric string value for int value using lambda' do
397
- get('/lambda_int_val', number: 'foo')
398
- expect(last_response.status).to eq 400
399
- expect(last_response.body).to eq({ error: 'number is invalid, number does not have a valid value' }.to_json)
400
- end
401
-
402
- it 'does not allow nil for int value using lambda' do
403
- get('/lambda_int_val', number: nil)
404
- expect(last_response.status).to eq 400
405
- expect(last_response.body).to eq({ error: 'number does not have a valid value' }.to_json)
406
- end
407
-
408
- it 'allows numeric string for int value using lambda' do
409
- get('/lambda_int_val', number: '3')
410
- expect(last_response.status).to eq 200
411
- expect(last_response.body).to eq({ number: 3 }.to_json)
412
- end
413
-
414
- it 'allows value using lambda' do
415
- get('/lambda_val', type: 'valid-type1')
416
- expect(last_response.status).to eq 200
417
- expect(last_response.body).to eq({ type: 'valid-type1' }.to_json)
418
- end
419
-
420
- it 'does not allow invalid value using lambda' do
421
- get('/lambda_val', type: 'invalid-type')
422
- expect(last_response.status).to eq 400
423
- expect(last_response.body).to eq({ error: 'type does not have a valid value' }.to_json)
424
- end
425
-
426
- it 'validates against an empty array in a proc' do
427
- get('/empty_lambda', type: 'any')
428
- expect(last_response.status).to eq 400
429
- expect(last_response.body).to eq({ error: 'type does not have a valid value' }.to_json)
430
- end
431
-
432
- it 'validates default value from proc' do
433
- get('/default_lambda')
434
- expect(last_response.status).to eq 200
435
- end
436
-
437
- it 'validates default value from proc against values in a proc' do
438
- get('/default_and_values_lambda')
439
- expect(last_response.status).to eq 200
440
- end
441
-
442
- it 'raises IncompatibleOptionValues on an invalid default value from proc' do
443
- subject = Class.new(Grape::API)
444
- expect do
445
- subject.params { optional :type, values: %w[valid-type1 valid-type2 valid-type3], default: "#{ValuesModel.values.sample}_invalid" }
446
- end.to raise_error Grape::Exceptions::IncompatibleOptionValues
447
- end
448
-
449
- it 'raises IncompatibleOptionValues on an invalid default value' do
450
- subject = Class.new(Grape::API)
451
- expect do
452
- subject.params { optional :type, values: %w[valid-type1 valid-type2 valid-type3], default: 'invalid-type' }
453
- end.to raise_error Grape::Exceptions::IncompatibleOptionValues
454
- end
455
-
456
- it 'raises IncompatibleOptionValues when type is incompatible with values array' do
457
- subject = Class.new(Grape::API)
458
- expect do
459
- subject.params { optional :type, values: %w[valid-type1 valid-type2 valid-type3], type: Symbol }
460
- end.to raise_error Grape::Exceptions::IncompatibleOptionValues
461
- end
462
-
463
- context 'boolean values' do
464
- it 'allows a value from the list' do
465
- get('/values/optional_boolean', type: true)
466
-
467
- expect(last_response.status).to eq 200
468
- expect(last_response.body).to eq({ type: true }.to_json)
469
- end
470
-
471
- it 'rejects a value which is not in the list' do
472
- get('/values/optional_boolean', type: false)
473
-
474
- expect(last_response.body).to eq({ error: 'type does not have a valid value' }.to_json)
475
- end
476
- end
477
-
478
- it 'allows values to be a kind of the coerced type not just an instance of it' do
479
- get('/values/coercion', type: 10)
480
- expect(last_response.status).to eq 200
481
- expect(last_response.body).to eq({ type: 10 }.to_json)
482
- end
483
-
484
- it 'allows values to be a kind of the coerced type in an array' do
485
- get('/values/array_coercion', type: [10])
486
- expect(last_response.status).to eq 200
487
- expect(last_response.body).to eq({ type: [10] }.to_json)
488
- end
489
-
490
- it 'raises IncompatibleOptionValues when values contains a value that is not a kind of the type' do
491
- subject = Class.new(Grape::API)
492
- expect do
493
- subject.params { requires :type, values: [10.5, 11], type: Integer }
494
- end.to raise_error Grape::Exceptions::IncompatibleOptionValues
495
- end
496
-
497
- it 'raises IncompatibleOptionValues when except contains a value that is not a kind of the type' do
498
- subject = Class.new(Grape::API)
499
- expect do
500
- subject.params { requires :type, values: { except: [10.5, 11] }, type: Integer }
501
- end.to raise_error Grape::Exceptions::IncompatibleOptionValues
502
- end
503
-
504
- it 'allows a blank value when the allow_blank option is true' do
505
- get 'allow_blank', name: nil
506
- expect(last_response.status).to eq(200)
507
-
508
- get 'allow_blank', name: ''
509
- expect(last_response.status).to eq(200)
510
- end
511
-
512
- context 'with a lambda values' do
513
- subject do
514
- Class.new(Grape::API) do
515
- params do
516
- optional :type, type: String, values: -> { [SecureRandom.uuid] }, default: -> { SecureRandom.uuid }
517
- end
518
- get '/random_values'
519
- end
520
- end
521
-
522
- def app
523
- subject
524
- end
525
-
526
- before do
527
- expect(SecureRandom).to receive(:uuid).and_return('foo').once
528
- end
529
-
530
- it 'only evaluates values dynamically with each request' do
531
- get '/random_values', type: 'foo'
532
- expect(last_response.status).to eq 200
533
- end
534
-
535
- it 'chooses default' do
536
- get '/random_values'
537
- expect(last_response.status).to eq 200
538
- end
539
- end
540
-
541
- context 'with a range of values' do
542
- subject(:app) do
543
- Class.new(Grape::API) do
544
- params do
545
- optional :value, type: Float, values: 0.0..10.0
546
- end
547
- get '/value' do
548
- { value: params[:value] }.to_json
549
- end
550
-
551
- params do
552
- optional :values, type: Array[Float], values: 0.0..10.0
553
- end
554
- get '/values' do
555
- { values: params[:values] }.to_json
556
- end
557
- end
558
- end
559
-
560
- it 'allows a single value inside of the range' do
561
- get('/value', value: 5.2)
562
- expect(last_response.status).to eq 200
563
- expect(last_response.body).to eq({ value: 5.2 }.to_json)
564
- end
565
-
566
- it 'allows an array of values inside of the range' do
567
- get('/values', values: [8.6, 7.5, 3, 0.9])
568
- expect(last_response.status).to eq 200
569
- expect(last_response.body).to eq({ values: [8.6, 7.5, 3.0, 0.9] }.to_json)
570
- end
571
-
572
- it 'rejects a single value outside the range' do
573
- get('/value', value: 'a')
574
- expect(last_response.status).to eq 400
575
- expect(last_response.body).to eq('value is invalid, value does not have a valid value')
576
- end
577
-
578
- it 'rejects an array of values if any of them are outside the range' do
579
- get('/values', values: [8.6, 75, 3, 0.9])
580
- expect(last_response.status).to eq 400
581
- expect(last_response.body).to eq('values does not have a valid value')
582
- end
583
- end
584
-
585
- context 'exclusive excepts' do
586
- it 'allows any other value outside excepts' do
587
- get '/except/exclusive', type: 'value'
588
- expect(last_response.status).to eq 200
589
- expect(last_response.body).to eq({ type: 'value' }.to_json)
590
- end
591
-
592
- it 'allows any other value outside excepts when type is included' do
593
- get '/except/exclusive/type', type: 'value'
594
- expect(last_response.status).to eq 200
595
- expect(last_response.body).to eq({ type: 'value' }.to_json)
596
- end
597
-
598
- it 'rejects values that matches except' do
599
- get '/except/exclusive', type: 'invalid-type1'
600
- expect(last_response.status).to eq 400
601
- expect(last_response.body).to eq({ error: 'type has a value not allowed' }.to_json)
602
- end
603
-
604
- it 'rejects an array of values if any of them matches except' do
605
- get '/except/exclusive', type: %w[valid1 valid2 invalid-type1 valid4]
606
- expect(last_response.status).to eq 400
607
- expect(last_response.body).to eq({ error: 'type has a value not allowed' }.to_json)
608
- end
609
- end
610
-
611
- context 'exclusive excepts with lambda' do
612
- it 'allows any other value outside excepts when type is included' do
613
- get '/except/exclusive/lambda/type', type: 'value'
614
- expect(last_response.status).to eq 200
615
- expect(last_response.body).to eq({ type: 'value' }.to_json)
616
- end
617
-
618
- it 'allows any other value outside excepts' do
619
- get '/except/exclusive/lambda', type: 'value'
620
- expect(last_response.status).to eq 200
621
- expect(last_response.body).to eq({ type: 'value' }.to_json)
622
- end
623
-
624
- it 'rejects values that matches except' do
625
- get '/except/exclusive/lambda', type: 'invalid-type1'
626
- expect(last_response.status).to eq 400
627
- expect(last_response.body).to eq({ error: 'type has a value not allowed' }.to_json)
628
- end
629
- end
630
-
631
- context 'exclusive excepts with lambda and coercion' do
632
- it 'allows any other value outside excepts' do
633
- get '/except/exclusive/lambda/coercion', type: '10010000'
634
- expect(last_response.status).to eq 200
635
- expect(last_response.body).to eq({ type: 10_010_000 }.to_json)
636
- end
637
-
638
- it 'rejects values that matches except' do
639
- get '/except/exclusive/lambda/coercion', type: '3'
640
- expect(last_response.status).to eq 400
641
- expect(last_response.body).to eq({ error: 'type has a value not allowed' }.to_json)
642
- end
643
- end
644
-
645
- context 'with mixed values and excepts' do
646
- it 'allows value, but not in except' do
647
- get '/mixed/value/except', type: 2
648
- expect(last_response.status).to eq 200
649
- expect(last_response.body).to eq({ type: 2 }.to_json)
650
- end
651
-
652
- it 'rejects except' do
653
- get '/mixed/value/except', type: 3
654
- expect(last_response.status).to eq 400
655
- expect(last_response.body).to eq({ error: 'type has a value not allowed' }.to_json)
656
- end
657
-
658
- it 'rejects outside except and outside value' do
659
- get '/mixed/value/except', type: 10
660
- expect(last_response.status).to eq 400
661
- expect(last_response.body).to eq({ error: 'type does not have a valid value' }.to_json)
662
- end
663
- end
664
-
665
- context 'custom validation using proc' do
666
- it 'accepts a single valid value' do
667
- get '/proc', type: 'valid-type1'
668
- expect(last_response.status).to eq 200
669
- expect(last_response.body).to eq({ type: 'valid-type1' }.to_json)
670
- end
671
-
672
- it 'accepts multiple valid values' do
673
- get '/proc', type: %w[valid-type1 valid-type3]
674
- expect(last_response.status).to eq 200
675
- expect(last_response.body).to eq({ type: %w[valid-type1 valid-type3] }.to_json)
676
- end
677
-
678
- it 'rejects a single invalid value' do
679
- get '/proc', type: 'invalid-type1'
680
- expect(last_response.status).to eq 400
681
- expect(last_response.body).to eq({ error: 'type does not have a valid value' }.to_json)
682
- end
683
-
684
- it 'rejects an invalid value among valid ones' do
685
- get '/proc', type: %w[valid-type1 invalid-type1 valid-type3]
686
- expect(last_response.status).to eq 400
687
- expect(last_response.body).to eq({ error: 'type does not have a valid value' }.to_json)
688
- end
689
-
690
- it 'uses supplied message' do
691
- get '/proc/message', type: 'invalid-type1'
692
- expect(last_response.status).to eq 400
693
- expect(last_response.body).to eq({ error: 'type failed check' }.to_json)
694
- end
695
- end
696
- end
@@ -1,10 +0,0 @@
1
- zh-CN:
2
- grape:
3
- errors:
4
- format: ! '%{attributes}%{message}'
5
- attributes:
6
- age: 年龄
7
- messages:
8
- coerce: '格式不正确'
9
- presence: '请填写'
10
- regexp: '格式不正确'