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,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: '格式不正确'