grape 1.5.3 → 1.7.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (207) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +67 -0
  3. data/CONTRIBUTING.md +2 -1
  4. data/README.md +150 -21
  5. data/UPGRADING.md +61 -4
  6. data/grape.gemspec +5 -5
  7. data/lib/grape/api/instance.rb +14 -18
  8. data/lib/grape/api.rb +17 -12
  9. data/lib/grape/cookies.rb +2 -0
  10. data/lib/grape/dry_types.rb +12 -0
  11. data/lib/grape/dsl/api.rb +0 -2
  12. data/lib/grape/dsl/callbacks.rb +0 -2
  13. data/lib/grape/dsl/configuration.rb +0 -2
  14. data/lib/grape/dsl/desc.rb +2 -19
  15. data/lib/grape/dsl/headers.rb +5 -2
  16. data/lib/grape/dsl/helpers.rb +7 -7
  17. data/lib/grape/dsl/inside_route.rb +43 -30
  18. data/lib/grape/dsl/middleware.rb +4 -6
  19. data/lib/grape/dsl/parameters.rb +8 -10
  20. data/lib/grape/dsl/request_response.rb +9 -8
  21. data/lib/grape/dsl/routing.rb +6 -4
  22. data/lib/grape/dsl/settings.rb +5 -7
  23. data/lib/grape/dsl/validations.rb +0 -15
  24. data/lib/grape/endpoint.rb +20 -35
  25. data/lib/grape/error_formatter/json.rb +9 -7
  26. data/lib/grape/error_formatter/xml.rb +2 -6
  27. data/lib/grape/exceptions/base.rb +2 -2
  28. data/lib/grape/exceptions/missing_group_type.rb +8 -1
  29. data/lib/grape/exceptions/too_many_multipart_files.rb +11 -0
  30. data/lib/grape/exceptions/unsupported_group_type.rb +8 -1
  31. data/lib/grape/exceptions/validation.rb +1 -6
  32. data/lib/grape/formatter/json.rb +1 -0
  33. data/lib/grape/formatter/serializable_hash.rb +2 -1
  34. data/lib/grape/formatter/xml.rb +1 -0
  35. data/lib/grape/locale/en.yml +9 -8
  36. data/lib/grape/middleware/auth/dsl.rb +7 -2
  37. data/lib/grape/middleware/base.rb +3 -1
  38. data/lib/grape/middleware/error.rb +2 -2
  39. data/lib/grape/middleware/formatter.rb +4 -4
  40. data/lib/grape/middleware/stack.rb +2 -2
  41. data/lib/grape/middleware/versioner/accept_version_header.rb +3 -5
  42. data/lib/grape/middleware/versioner/header.rb +6 -4
  43. data/lib/grape/middleware/versioner/param.rb +1 -0
  44. data/lib/grape/middleware/versioner/parse_media_type_patch.rb +2 -1
  45. data/lib/grape/middleware/versioner/path.rb +2 -0
  46. data/lib/grape/path.rb +1 -0
  47. data/lib/grape/request.rb +3 -0
  48. data/lib/grape/router/pattern.rb +1 -1
  49. data/lib/grape/router/route.rb +2 -2
  50. data/lib/grape/router.rb +6 -0
  51. data/lib/grape/util/inheritable_setting.rb +1 -3
  52. data/lib/grape/util/json.rb +2 -0
  53. data/lib/grape/util/lazy_value.rb +3 -2
  54. data/lib/grape/util/strict_hash_configuration.rb +1 -1
  55. data/lib/grape/validations/attributes_doc.rb +58 -0
  56. data/lib/grape/validations/params_scope.rb +137 -78
  57. data/lib/grape/validations/types/array_coercer.rb +0 -2
  58. data/lib/grape/validations/types/custom_type_coercer.rb +1 -0
  59. data/lib/grape/validations/types/dry_type_coercer.rb +4 -8
  60. data/lib/grape/validations/types/json.rb +2 -1
  61. data/lib/grape/validations/types/primitive_coercer.rb +16 -8
  62. data/lib/grape/validations/types/set_coercer.rb +0 -2
  63. data/lib/grape/validations/types.rb +98 -30
  64. data/lib/grape/validations/validators/all_or_none_of_validator.rb +16 -0
  65. data/lib/grape/validations/validators/allow_blank_validator.rb +20 -0
  66. data/lib/grape/validations/validators/as_validator.rb +14 -0
  67. data/lib/grape/validations/validators/at_least_one_of_validator.rb +15 -0
  68. data/lib/grape/validations/validators/base.rb +82 -70
  69. data/lib/grape/validations/validators/coerce_validator.rb +75 -0
  70. data/lib/grape/validations/validators/default_validator.rb +51 -0
  71. data/lib/grape/validations/validators/exactly_one_of_validator.rb +17 -0
  72. data/lib/grape/validations/validators/except_values_validator.rb +24 -0
  73. data/lib/grape/validations/validators/multiple_params_base.rb +24 -20
  74. data/lib/grape/validations/validators/mutual_exclusion_validator.rb +16 -0
  75. data/lib/grape/validations/validators/presence_validator.rb +15 -0
  76. data/lib/grape/validations/validators/regexp_validator.rb +16 -0
  77. data/lib/grape/validations/validators/same_as_validator.rb +29 -0
  78. data/lib/grape/validations/validators/values_validator.rb +88 -0
  79. data/lib/grape/validations.rb +16 -6
  80. data/lib/grape/version.rb +1 -1
  81. data/lib/grape.rb +69 -29
  82. data/spec/grape/api/custom_validations_spec.rb +116 -45
  83. data/spec/grape/api/deeply_included_options_spec.rb +3 -5
  84. data/spec/grape/api/defines_boolean_in_params_spec.rb +2 -3
  85. data/spec/grape/api/documentation_spec.rb +59 -0
  86. data/spec/grape/api/inherited_helpers_spec.rb +0 -2
  87. data/spec/grape/api/instance_spec.rb +0 -1
  88. data/spec/grape/api/invalid_format_spec.rb +2 -2
  89. data/spec/grape/api/namespace_parameters_in_route_spec.rb +0 -2
  90. data/spec/grape/api/nested_helpers_spec.rb +0 -2
  91. data/spec/grape/api/optional_parameters_in_route_spec.rb +0 -2
  92. data/spec/grape/api/parameters_modification_spec.rb +0 -2
  93. data/spec/grape/api/patch_method_helpers_spec.rb +0 -2
  94. data/spec/grape/api/recognize_path_spec.rb +1 -3
  95. data/spec/grape/api/required_parameters_in_route_spec.rb +0 -2
  96. data/spec/grape/api/required_parameters_with_invalid_method_spec.rb +0 -2
  97. data/spec/grape/api/routes_with_requirements_spec.rb +8 -10
  98. data/spec/grape/api/shared_helpers_exactly_one_of_spec.rb +9 -17
  99. data/spec/grape/api/shared_helpers_spec.rb +0 -2
  100. data/spec/grape/api_remount_spec.rb +16 -16
  101. data/spec/grape/api_spec.rb +457 -231
  102. data/spec/grape/config_spec.rb +0 -2
  103. data/spec/grape/dsl/callbacks_spec.rb +2 -3
  104. data/spec/grape/dsl/configuration_spec.rb +0 -2
  105. data/spec/grape/dsl/desc_spec.rb +0 -2
  106. data/spec/grape/dsl/headers_spec.rb +39 -11
  107. data/spec/grape/dsl/helpers_spec.rb +3 -4
  108. data/spec/grape/dsl/inside_route_spec.rb +16 -16
  109. data/spec/grape/dsl/logger_spec.rb +15 -19
  110. data/spec/grape/dsl/middleware_spec.rb +2 -3
  111. data/spec/grape/dsl/parameters_spec.rb +2 -2
  112. data/spec/grape/dsl/request_response_spec.rb +7 -8
  113. data/spec/grape/dsl/routing_spec.rb +11 -10
  114. data/spec/grape/dsl/settings_spec.rb +0 -2
  115. data/spec/grape/dsl/validations_spec.rb +0 -17
  116. data/spec/grape/endpoint/declared_spec.rb +261 -16
  117. data/spec/grape/endpoint_spec.rb +86 -58
  118. data/spec/grape/entity_spec.rb +22 -23
  119. data/spec/grape/exceptions/base_spec.rb +16 -2
  120. data/spec/grape/exceptions/body_parse_errors_spec.rb +3 -2
  121. data/spec/grape/exceptions/invalid_accept_header_spec.rb +61 -24
  122. data/spec/grape/exceptions/invalid_formatter_spec.rb +0 -2
  123. data/spec/grape/exceptions/invalid_response_spec.rb +0 -2
  124. data/spec/grape/exceptions/invalid_versioner_option_spec.rb +1 -3
  125. data/spec/grape/exceptions/missing_group_type_spec.rb +21 -0
  126. data/spec/grape/exceptions/missing_mime_type_spec.rb +0 -2
  127. data/spec/grape/exceptions/missing_option_spec.rb +1 -3
  128. data/spec/grape/exceptions/unknown_options_spec.rb +0 -2
  129. data/spec/grape/exceptions/unknown_validator_spec.rb +0 -2
  130. data/spec/grape/exceptions/unsupported_group_type_spec.rb +23 -0
  131. data/spec/grape/exceptions/validation_errors_spec.rb +13 -11
  132. data/spec/grape/exceptions/validation_spec.rb +5 -5
  133. data/spec/grape/extensions/param_builders/hash_spec.rb +7 -9
  134. data/spec/grape/extensions/param_builders/hash_with_indifferent_access_spec.rb +8 -10
  135. data/spec/grape/extensions/param_builders/hashie/mash_spec.rb +8 -10
  136. data/spec/grape/integration/global_namespace_function_spec.rb +0 -2
  137. data/spec/grape/integration/rack_sendfile_spec.rb +1 -3
  138. data/spec/grape/integration/rack_spec.rb +0 -2
  139. data/spec/grape/loading_spec.rb +8 -10
  140. data/spec/grape/middleware/auth/base_spec.rb +0 -1
  141. data/spec/grape/middleware/auth/dsl_spec.rb +15 -8
  142. data/spec/grape/middleware/auth/strategies_spec.rb +60 -22
  143. data/spec/grape/middleware/base_spec.rb +24 -17
  144. data/spec/grape/middleware/error_spec.rb +8 -3
  145. data/spec/grape/middleware/exception_spec.rb +111 -163
  146. data/spec/grape/middleware/formatter_spec.rb +27 -8
  147. data/spec/grape/middleware/globals_spec.rb +7 -6
  148. data/spec/grape/middleware/stack_spec.rb +14 -14
  149. data/spec/grape/middleware/versioner/accept_version_header_spec.rb +2 -3
  150. data/spec/grape/middleware/versioner/header_spec.rb +30 -15
  151. data/spec/grape/middleware/versioner/param_spec.rb +7 -3
  152. data/spec/grape/middleware/versioner/path_spec.rb +5 -3
  153. data/spec/grape/middleware/versioner_spec.rb +1 -3
  154. data/spec/grape/named_api_spec.rb +0 -2
  155. data/spec/grape/parser_spec.rb +4 -2
  156. data/spec/grape/path_spec.rb +52 -54
  157. data/spec/grape/presenters/presenter_spec.rb +7 -8
  158. data/spec/grape/request_spec.rb +6 -6
  159. data/spec/grape/util/inheritable_setting_spec.rb +7 -8
  160. data/spec/grape/util/inheritable_values_spec.rb +3 -3
  161. data/spec/grape/util/reverse_stackable_values_spec.rb +3 -2
  162. data/spec/grape/util/stackable_values_spec.rb +7 -6
  163. data/spec/grape/util/strict_hash_configuration_spec.rb +0 -1
  164. data/spec/grape/validations/attributes_doc_spec.rb +153 -0
  165. data/spec/grape/validations/attributes_iterator_spec.rb +0 -2
  166. data/spec/grape/validations/instance_behaivour_spec.rb +9 -12
  167. data/spec/grape/validations/multiple_attributes_iterator_spec.rb +1 -2
  168. data/spec/grape/validations/params_scope_spec.rb +361 -96
  169. data/spec/grape/validations/single_attribute_iterator_spec.rb +2 -3
  170. data/spec/grape/validations/types/array_coercer_spec.rb +0 -2
  171. data/spec/grape/validations/types/primitive_coercer_spec.rb +24 -9
  172. data/spec/grape/validations/types/set_coercer_spec.rb +0 -2
  173. data/spec/grape/validations/types_spec.rb +36 -10
  174. data/spec/grape/validations/validators/all_or_none_spec.rb +50 -58
  175. data/spec/grape/validations/validators/allow_blank_spec.rb +135 -141
  176. data/spec/grape/validations/validators/at_least_one_of_spec.rb +50 -58
  177. data/spec/grape/validations/validators/coerce_spec.rb +23 -24
  178. data/spec/grape/validations/validators/default_spec.rb +72 -80
  179. data/spec/grape/validations/validators/exactly_one_of_spec.rb +71 -79
  180. data/spec/grape/validations/validators/except_values_spec.rb +3 -5
  181. data/spec/grape/validations/validators/mutual_exclusion_spec.rb +71 -79
  182. data/spec/grape/validations/validators/presence_spec.rb +16 -3
  183. data/spec/grape/validations/validators/regexp_spec.rb +25 -33
  184. data/spec/grape/validations/validators/same_as_spec.rb +14 -22
  185. data/spec/grape/validations/validators/values_spec.rb +182 -179
  186. data/spec/grape/validations_spec.rb +149 -80
  187. data/spec/integration/eager_load/eager_load_spec.rb +2 -2
  188. data/spec/integration/multi_json/json_spec.rb +1 -3
  189. data/spec/integration/multi_xml/xml_spec.rb +1 -3
  190. data/spec/shared/versioning_examples.rb +12 -9
  191. data/spec/spec_helper.rb +21 -6
  192. data/spec/support/basic_auth_encode_helpers.rb +1 -1
  193. metadata +126 -117
  194. data/lib/grape/validations/validators/all_or_none.rb +0 -15
  195. data/lib/grape/validations/validators/allow_blank.rb +0 -18
  196. data/lib/grape/validations/validators/as.rb +0 -16
  197. data/lib/grape/validations/validators/at_least_one_of.rb +0 -14
  198. data/lib/grape/validations/validators/coerce.rb +0 -91
  199. data/lib/grape/validations/validators/default.rb +0 -48
  200. data/lib/grape/validations/validators/exactly_one_of.rb +0 -16
  201. data/lib/grape/validations/validators/except_values.rb +0 -22
  202. data/lib/grape/validations/validators/mutual_exclusion.rb +0 -15
  203. data/lib/grape/validations/validators/presence.rb +0 -12
  204. data/lib/grape/validations/validators/regexp.rb +0 -13
  205. data/lib/grape/validations/validators/same_as.rb +0 -26
  206. data/lib/grape/validations/validators/values.rb +0 -83
  207. data/spec/support/eager_load.rb +0 -19
@@ -1,18 +1,16 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'spec_helper'
4
-
5
3
  describe Grape::Validations::Types::PrimitiveCoercer do
6
- let(:strict) { false }
7
-
8
4
  subject { described_class.new(type, strict) }
9
5
 
6
+ let(:strict) { false }
7
+
10
8
  describe '#call' do
11
9
  context 'BigDecimal' do
12
10
  let(:type) { BigDecimal }
13
11
 
14
12
  it 'coerces to BigDecimal' do
15
- expect(subject.call(5)).to eq(BigDecimal(5))
13
+ expect(subject.call(5)).to eq(BigDecimal('5'))
16
14
  end
17
15
 
18
16
  it 'coerces an empty string to nil' do
@@ -25,13 +23,13 @@ describe Grape::Validations::Types::PrimitiveCoercer do
25
23
 
26
24
  [true, 'true', 1].each do |val|
27
25
  it "coerces '#{val}' to true" do
28
- expect(subject.call(val)).to eq(true)
26
+ expect(subject.call(val)).to be(true)
29
27
  end
30
28
  end
31
29
 
32
30
  [false, 'false', 0].each do |val|
33
31
  it "coerces '#{val}' to false" do
34
- expect(subject.call(val)).to eq(false)
32
+ expect(subject.call(val)).to be(false)
35
33
  end
36
34
  end
37
35
 
@@ -66,6 +64,10 @@ describe Grape::Validations::Types::PrimitiveCoercer do
66
64
  it 'coerces an empty string to nil' do
67
65
  expect(subject.call('')).to be_nil
68
66
  end
67
+
68
+ it 'accepts non-nil value' do
69
+ expect(subject.call(42)).to be_a(Integer)
70
+ end
69
71
  end
70
72
 
71
73
  context 'Numeric' do
@@ -74,6 +76,10 @@ describe Grape::Validations::Types::PrimitiveCoercer do
74
76
  it 'coerces an empty string to nil' do
75
77
  expect(subject.call('')).to be_nil
76
78
  end
79
+
80
+ it 'accepts a non-nil value' do
81
+ expect(subject.call(42)).to be_a(Numeric) # in fact Integer
82
+ end
77
83
  end
78
84
 
79
85
  context 'Time' do
@@ -104,6 +110,15 @@ describe Grape::Validations::Types::PrimitiveCoercer do
104
110
  end
105
111
  end
106
112
 
113
+ context 'a type unknown in Dry-types' do
114
+ let(:type) { Complex }
115
+
116
+ it 'raises error on init' do
117
+ expect(DryTypes::Params.constants).not_to include(type.name.to_sym)
118
+ expect { subject }.to raise_error(/type Complex should support coercion/)
119
+ end
120
+ end
121
+
107
122
  context 'the strict mode' do
108
123
  let(:strict) { true }
109
124
 
@@ -115,7 +130,7 @@ describe Grape::Validations::Types::PrimitiveCoercer do
115
130
  end
116
131
 
117
132
  it 'returns a value as it is when the given value is Boolean' do
118
- expect(subject.call(true)).to eq(true)
133
+ expect(subject.call(true)).to be(true)
119
134
  end
120
135
  end
121
136
 
@@ -127,7 +142,7 @@ describe Grape::Validations::Types::PrimitiveCoercer do
127
142
  end
128
143
 
129
144
  it 'returns a value as it is when the given value is BigDecimal' do
130
- expect(subject.call(BigDecimal(0))).to eq(BigDecimal(0))
145
+ expect(subject.call(BigDecimal('0'))).to eq(BigDecimal('0'))
131
146
  end
132
147
  end
133
148
  end
@@ -1,7 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'spec_helper'
4
-
5
3
  describe Grape::Validations::Types::SetCoercer do
6
4
  subject { described_class.new(type) }
7
5
 
@@ -1,7 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'spec_helper'
4
-
5
3
  describe Grape::Validations::Types do
6
4
  module TypesSpec
7
5
  class FooType
@@ -20,13 +18,13 @@ describe Grape::Validations::Types do
20
18
  Date, DateTime, Time
21
19
  ].each do |type|
22
20
  it "recognizes #{type} as a primitive" do
23
- expect(described_class.primitive?(type)).to be_truthy
21
+ expect(described_class).to be_primitive(type)
24
22
  end
25
23
  end
26
24
 
27
25
  it 'identifies unknown types' do
28
- expect(described_class.primitive?(Object)).to be_falsy
29
- expect(described_class.primitive?(TypesSpec::FooType)).to be_falsy
26
+ expect(described_class).not_to be_primitive(Object)
27
+ expect(described_class).not_to be_primitive(TypesSpec::FooType)
30
28
  end
31
29
  end
32
30
 
@@ -35,7 +33,7 @@ describe Grape::Validations::Types do
35
33
  Hash, Array, Set
36
34
  ].each do |type|
37
35
  it "recognizes #{type} as a structure" do
38
- expect(described_class.structure?(type)).to be_truthy
36
+ expect(described_class).to be_structure(type)
39
37
  end
40
38
  end
41
39
  end
@@ -45,22 +43,50 @@ describe Grape::Validations::Types do
45
43
  JSON, Array[JSON], File, Rack::Multipart::UploadedFile
46
44
  ].each do |type|
47
45
  it "provides special handling for #{type.inspect}" do
48
- expect(described_class.special?(type)).to be_truthy
46
+ expect(described_class).to be_special(type)
49
47
  end
50
48
  end
51
49
  end
52
50
 
51
+ describe 'special types' do
52
+ subject { described_class::SPECIAL[type] }
53
+
54
+ context 'when JSON' do
55
+ let(:type) { JSON }
56
+
57
+ it { is_expected.to eq(Grape::Validations::Types::Json) }
58
+ end
59
+
60
+ context 'when Array[JSON]' do
61
+ let(:type) { Array[JSON] }
62
+
63
+ it { is_expected.to eq(Grape::Validations::Types::JsonArray) }
64
+ end
65
+
66
+ context 'when File' do
67
+ let(:type) { File }
68
+
69
+ it { is_expected.to eq(Grape::Validations::Types::File) }
70
+ end
71
+
72
+ context 'when Rack::Multipart::UploadedFile' do
73
+ let(:type) { Rack::Multipart::UploadedFile }
74
+
75
+ it { is_expected.to eq(Grape::Validations::Types::File) }
76
+ end
77
+ end
78
+
53
79
  describe '::custom?' do
54
80
  it 'returns false if the type does not respond to :parse' do
55
- expect(described_class.custom?(Object)).to be_falsy
81
+ expect(described_class).not_to be_custom(Object)
56
82
  end
57
83
 
58
84
  it 'returns true if the type responds to :parse with one argument' do
59
- expect(described_class.custom?(TypesSpec::FooType)).to be_truthy
85
+ expect(described_class).to be_custom(TypesSpec::FooType)
60
86
  end
61
87
 
62
88
  it 'returns false if the type\'s #parse method takes other than one argument' do
63
- expect(described_class.custom?(TypesSpec::BarType)).to be_falsy
89
+ expect(described_class).not_to be_custom(TypesSpec::BarType)
64
90
  end
65
91
  end
66
92
 
@@ -1,74 +1,66 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'spec_helper'
4
-
5
- describe Grape::Validations::AllOrNoneOfValidator do
6
- describe '#validate!' do
7
- subject(:validate) { post path, params }
8
-
9
- module ValidationsSpec
10
- module AllOrNoneOfValidatorSpec
11
- class API < Grape::API
12
- rescue_from Grape::Exceptions::ValidationErrors do |e|
13
- error!(e.errors.transform_keys! { |key| key.join(',') }, 400)
14
- end
3
+ describe Grape::Validations::Validators::AllOrNoneOfValidator do
4
+ let_it_be(:app) do
5
+ Class.new(Grape::API) do
6
+ rescue_from Grape::Exceptions::ValidationErrors do |e|
7
+ error!(e.errors.transform_keys! { |key| key.join(',') }, 400)
8
+ end
15
9
 
16
- params do
17
- optional :beer, :wine, type: Boolean
18
- all_or_none_of :beer, :wine
19
- end
20
- post do
21
- end
10
+ params do
11
+ optional :beer, :wine, type: Grape::API::Boolean
12
+ all_or_none_of :beer, :wine
13
+ end
14
+ post do
15
+ end
22
16
 
23
- params do
24
- optional :beer, :wine, :other, type: Boolean
25
- all_or_none_of :beer, :wine
26
- end
27
- post 'mixed-params' do
28
- end
17
+ params do
18
+ optional :beer, :wine, :other, type: Grape::API::Boolean
19
+ all_or_none_of :beer, :wine
20
+ end
21
+ post 'mixed-params' do
22
+ end
29
23
 
30
- params do
31
- optional :beer, :wine, type: Boolean
32
- all_or_none_of :beer, :wine, message: 'choose all or none'
33
- end
34
- post '/custom-message' do
35
- end
24
+ params do
25
+ optional :beer, :wine, type: Grape::API::Boolean
26
+ all_or_none_of :beer, :wine, message: 'choose all or none'
27
+ end
28
+ post '/custom-message' do
29
+ end
36
30
 
37
- params do
38
- requires :item, type: Hash do
39
- optional :beer, :wine, type: Boolean
40
- all_or_none_of :beer, :wine
41
- end
42
- end
43
- post '/nested-hash' do
44
- end
31
+ params do
32
+ requires :item, type: Hash do
33
+ optional :beer, :wine, type: Grape::API::Boolean
34
+ all_or_none_of :beer, :wine
35
+ end
36
+ end
37
+ post '/nested-hash' do
38
+ end
45
39
 
46
- params do
47
- requires :items, type: Array do
48
- optional :beer, :wine, type: Boolean
49
- all_or_none_of :beer, :wine
50
- end
51
- end
52
- post '/nested-array' do
53
- end
40
+ params do
41
+ requires :items, type: Array do
42
+ optional :beer, :wine, type: Grape::API::Boolean
43
+ all_or_none_of :beer, :wine
44
+ end
45
+ end
46
+ post '/nested-array' do
47
+ end
54
48
 
55
- params do
56
- requires :items, type: Array do
57
- requires :nested_items, type: Array do
58
- optional :beer, :wine, type: Boolean
59
- all_or_none_of :beer, :wine
60
- end
61
- end
62
- end
63
- post '/deeply-nested-array' do
49
+ params do
50
+ requires :items, type: Array do
51
+ requires :nested_items, type: Array do
52
+ optional :beer, :wine, type: Grape::API::Boolean
53
+ all_or_none_of :beer, :wine
64
54
  end
65
55
  end
66
56
  end
57
+ post '/deeply-nested-array' do
58
+ end
67
59
  end
60
+ end
68
61
 
69
- def app
70
- ValidationsSpec::AllOrNoneOfValidatorSpec::API
71
- end
62
+ describe '#validate!' do
63
+ subject(:validate) { post path, params }
72
64
 
73
65
  context 'when all restricted params are present' do
74
66
  let(:path) { '/' }
@@ -1,25 +1,138 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'spec_helper'
3
+ describe Grape::Validations::Validators::AllowBlankValidator do
4
+ let_it_be(:app) do
5
+ Class.new(Grape::API) do
6
+ default_format :json
4
7
 
5
- describe Grape::Validations::AllowBlankValidator do
6
- module ValidationsSpec
7
- module AllowBlankValidatorSpec
8
- class API < Grape::API
9
- default_format :json
8
+ params do
9
+ requires :name, allow_blank: false
10
+ end
11
+ get '/disallow_blank'
10
12
 
11
- params do
13
+ params do
14
+ optional :name, type: String, allow_blank: false
15
+ end
16
+ get '/opt_disallow_string_blank'
17
+
18
+ params do
19
+ optional :name, allow_blank: false
20
+ end
21
+ get '/disallow_blank_optional_param'
22
+
23
+ params do
24
+ requires :name, allow_blank: true
25
+ end
26
+ get '/allow_blank'
27
+
28
+ params do
29
+ requires :val, type: DateTime, allow_blank: true
30
+ end
31
+ get '/allow_datetime_blank'
32
+
33
+ params do
34
+ requires :val, type: DateTime, allow_blank: false
35
+ end
36
+ get '/disallow_datetime_blank'
37
+
38
+ params do
39
+ requires :val, type: DateTime
40
+ end
41
+ get '/default_allow_datetime_blank'
42
+
43
+ params do
44
+ requires :val, type: Date, allow_blank: true
45
+ end
46
+ get '/allow_date_blank'
47
+
48
+ params do
49
+ requires :val, type: Integer, allow_blank: true
50
+ end
51
+ get '/allow_integer_blank'
52
+
53
+ params do
54
+ requires :val, type: Float, allow_blank: true
55
+ end
56
+ get '/allow_float_blank'
57
+
58
+ params do
59
+ requires :val, type: Integer, allow_blank: true
60
+ end
61
+ get '/allow_integer_blank'
62
+
63
+ params do
64
+ requires :val, type: Symbol, allow_blank: true
65
+ end
66
+ get '/allow_symbol_blank'
67
+
68
+ params do
69
+ requires :val, type: Grape::API::Boolean, allow_blank: true
70
+ end
71
+ get '/allow_boolean_blank'
72
+
73
+ params do
74
+ requires :val, type: Grape::API::Boolean, allow_blank: false
75
+ end
76
+ get '/disallow_boolean_blank'
77
+
78
+ params do
79
+ optional :user, type: Hash do
80
+ requires :name, allow_blank: false
81
+ end
82
+ end
83
+ get '/disallow_blank_required_param_in_an_optional_group'
84
+
85
+ params do
86
+ optional :user, type: Hash do
87
+ requires :name, type: Date, allow_blank: true
88
+ end
89
+ end
90
+ get '/allow_blank_date_param_in_an_optional_group'
91
+
92
+ params do
93
+ optional :user, type: Hash do
94
+ optional :name, allow_blank: false
95
+ requires :age
96
+ end
97
+ end
98
+ get '/disallow_blank_optional_param_in_an_optional_group'
99
+
100
+ params do
101
+ requires :user, type: Hash do
12
102
  requires :name, allow_blank: false
13
103
  end
14
- get '/disallow_blank'
104
+ end
105
+ get '/disallow_blank_required_param_in_a_required_group'
15
106
 
107
+ params do
108
+ requires :user, type: Hash do
109
+ requires :name, allow_blank: false
110
+ end
111
+ end
112
+ get '/disallow_string_value_in_a_required_hash_group'
113
+
114
+ params do
115
+ requires :user, type: Hash do
116
+ optional :name, allow_blank: false
117
+ end
118
+ end
119
+ get '/disallow_blank_optional_param_in_a_required_group'
120
+
121
+ params do
122
+ optional :user, type: Hash do
123
+ optional :name, allow_blank: false
124
+ end
125
+ end
126
+ get '/disallow_string_value_in_an_optional_hash_group'
127
+
128
+ resources :custom_message do
16
129
  params do
17
- optional :name, type: String, allow_blank: false
130
+ requires :name, allow_blank: { value: false, message: 'has no value' }
18
131
  end
19
- get '/opt_disallow_string_blank'
132
+ get
20
133
 
21
134
  params do
22
- optional :name, allow_blank: false
135
+ optional :name, allow_blank: { value: false, message: 'has no value' }
23
136
  end
24
137
  get '/disallow_blank_optional_param'
25
138
 
@@ -34,7 +147,7 @@ describe Grape::Validations::AllowBlankValidator do
34
147
  get '/allow_datetime_blank'
35
148
 
36
149
  params do
37
- requires :val, type: DateTime, allow_blank: false
150
+ requires :val, type: DateTime, allow_blank: { value: false, message: 'has no value' }
38
151
  end
39
152
  get '/disallow_datetime_blank'
40
153
 
@@ -69,18 +182,18 @@ describe Grape::Validations::AllowBlankValidator do
69
182
  get '/allow_symbol_blank'
70
183
 
71
184
  params do
72
- requires :val, type: Boolean, allow_blank: true
185
+ requires :val, type: Grape::API::Boolean, allow_blank: true
73
186
  end
74
187
  get '/allow_boolean_blank'
75
188
 
76
189
  params do
77
- requires :val, type: Boolean, allow_blank: false
190
+ requires :val, type: Grape::API::Boolean, allow_blank: { value: false, message: 'has no value' }
78
191
  end
79
192
  get '/disallow_boolean_blank'
80
193
 
81
194
  params do
82
195
  optional :user, type: Hash do
83
- requires :name, allow_blank: false
196
+ requires :name, allow_blank: { value: false, message: 'has no value' }
84
197
  end
85
198
  end
86
199
  get '/disallow_blank_required_param_in_an_optional_group'
@@ -94,7 +207,7 @@ describe Grape::Validations::AllowBlankValidator do
94
207
 
95
208
  params do
96
209
  optional :user, type: Hash do
97
- optional :name, allow_blank: false
210
+ optional :name, allow_blank: { value: false, message: 'has no value' }
98
211
  requires :age
99
212
  end
100
213
  end
@@ -102,156 +215,35 @@ describe Grape::Validations::AllowBlankValidator do
102
215
 
103
216
  params do
104
217
  requires :user, type: Hash do
105
- requires :name, allow_blank: false
218
+ requires :name, allow_blank: { value: false, message: 'has no value' }
106
219
  end
107
220
  end
108
221
  get '/disallow_blank_required_param_in_a_required_group'
109
222
 
110
223
  params do
111
224
  requires :user, type: Hash do
112
- requires :name, allow_blank: false
225
+ requires :name, allow_blank: { value: false, message: 'has no value' }
113
226
  end
114
227
  end
115
228
  get '/disallow_string_value_in_a_required_hash_group'
116
229
 
117
230
  params do
118
231
  requires :user, type: Hash do
119
- optional :name, allow_blank: false
232
+ optional :name, allow_blank: { value: false, message: 'has no value' }
120
233
  end
121
234
  end
122
235
  get '/disallow_blank_optional_param_in_a_required_group'
123
236
 
124
237
  params do
125
238
  optional :user, type: Hash do
126
- optional :name, allow_blank: false
127
- end
128
- end
129
- get '/disallow_string_value_in_an_optional_hash_group'
130
-
131
- resources :custom_message do
132
- params do
133
- requires :name, allow_blank: { value: false, message: 'has no value' }
134
- end
135
- get
136
-
137
- params do
138
239
  optional :name, allow_blank: { value: false, message: 'has no value' }
139
240
  end
140
- get '/disallow_blank_optional_param'
141
-
142
- params do
143
- requires :name, allow_blank: true
144
- end
145
- get '/allow_blank'
146
-
147
- params do
148
- requires :val, type: DateTime, allow_blank: true
149
- end
150
- get '/allow_datetime_blank'
151
-
152
- params do
153
- requires :val, type: DateTime, allow_blank: { value: false, message: 'has no value' }
154
- end
155
- get '/disallow_datetime_blank'
156
-
157
- params do
158
- requires :val, type: DateTime
159
- end
160
- get '/default_allow_datetime_blank'
161
-
162
- params do
163
- requires :val, type: Date, allow_blank: true
164
- end
165
- get '/allow_date_blank'
166
-
167
- params do
168
- requires :val, type: Integer, allow_blank: true
169
- end
170
- get '/allow_integer_blank'
171
-
172
- params do
173
- requires :val, type: Float, allow_blank: true
174
- end
175
- get '/allow_float_blank'
176
-
177
- params do
178
- requires :val, type: Integer, allow_blank: true
179
- end
180
- get '/allow_integer_blank'
181
-
182
- params do
183
- requires :val, type: Symbol, allow_blank: true
184
- end
185
- get '/allow_symbol_blank'
186
-
187
- params do
188
- requires :val, type: Boolean, allow_blank: true
189
- end
190
- get '/allow_boolean_blank'
191
-
192
- params do
193
- requires :val, type: Boolean, allow_blank: { value: false, message: 'has no value' }
194
- end
195
- get '/disallow_boolean_blank'
196
-
197
- params do
198
- optional :user, type: Hash do
199
- requires :name, allow_blank: { value: false, message: 'has no value' }
200
- end
201
- end
202
- get '/disallow_blank_required_param_in_an_optional_group'
203
-
204
- params do
205
- optional :user, type: Hash do
206
- requires :name, type: Date, allow_blank: true
207
- end
208
- end
209
- get '/allow_blank_date_param_in_an_optional_group'
210
-
211
- params do
212
- optional :user, type: Hash do
213
- optional :name, allow_blank: { value: false, message: 'has no value' }
214
- requires :age
215
- end
216
- end
217
- get '/disallow_blank_optional_param_in_an_optional_group'
218
-
219
- params do
220
- requires :user, type: Hash do
221
- requires :name, allow_blank: { value: false, message: 'has no value' }
222
- end
223
- end
224
- get '/disallow_blank_required_param_in_a_required_group'
225
-
226
- params do
227
- requires :user, type: Hash do
228
- requires :name, allow_blank: { value: false, message: 'has no value' }
229
- end
230
- end
231
- get '/disallow_string_value_in_a_required_hash_group'
232
-
233
- params do
234
- requires :user, type: Hash do
235
- optional :name, allow_blank: { value: false, message: 'has no value' }
236
- end
237
- end
238
- get '/disallow_blank_optional_param_in_a_required_group'
239
-
240
- params do
241
- optional :user, type: Hash do
242
- optional :name, allow_blank: { value: false, message: 'has no value' }
243
- end
244
- end
245
- get '/disallow_string_value_in_an_optional_hash_group'
246
241
  end
242
+ get '/disallow_string_value_in_an_optional_hash_group'
247
243
  end
248
244
  end
249
245
  end
250
246
 
251
- def app
252
- ValidationsSpec::AllowBlankValidatorSpec::API
253
- end
254
-
255
247
  context 'invalid input' do
256
248
  it 'refuses empty string' do
257
249
  get '/disallow_blank', name: ''
@@ -289,10 +281,12 @@ describe Grape::Validations::AllowBlankValidator do
289
281
  get '/custom_message', name: ''
290
282
  expect(last_response.body).to eq('{"error":"name has no value"}')
291
283
  end
284
+
292
285
  it 'refuses empty string for an optional param' do
293
286
  get '/custom_message/disallow_blank_optional_param', name: ''
294
287
  expect(last_response.body).to eq('{"error":"name has no value"}')
295
288
  end
289
+
296
290
  it 'refuses only whitespaces' do
297
291
  get '/custom_message', name: ' '
298
292
  expect(last_response.body).to eq('{"error":"name has no value"}')