grape 1.5.3 → 1.6.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (142) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +39 -0
  3. data/CONTRIBUTING.md +2 -1
  4. data/README.md +31 -3
  5. data/UPGRADING.md +46 -4
  6. data/grape.gemspec +5 -5
  7. data/lib/grape/api/instance.rb +13 -17
  8. data/lib/grape/api.rb +17 -12
  9. data/lib/grape/cookies.rb +2 -0
  10. data/lib/grape/dsl/desc.rb +3 -5
  11. data/lib/grape/dsl/headers.rb +5 -2
  12. data/lib/grape/dsl/helpers.rb +7 -5
  13. data/lib/grape/dsl/inside_route.rb +17 -8
  14. data/lib/grape/dsl/middleware.rb +4 -4
  15. data/lib/grape/dsl/parameters.rb +3 -3
  16. data/lib/grape/dsl/request_response.rb +9 -6
  17. data/lib/grape/dsl/routing.rb +2 -2
  18. data/lib/grape/dsl/settings.rb +5 -5
  19. data/lib/grape/endpoint.rb +20 -35
  20. data/lib/grape/error_formatter/json.rb +2 -6
  21. data/lib/grape/error_formatter/xml.rb +2 -6
  22. data/lib/grape/exceptions/validation.rb +1 -2
  23. data/lib/grape/formatter/json.rb +1 -0
  24. data/lib/grape/formatter/serializable_hash.rb +2 -1
  25. data/lib/grape/formatter/xml.rb +1 -0
  26. data/lib/grape/middleware/auth/dsl.rb +7 -1
  27. data/lib/grape/middleware/base.rb +3 -1
  28. data/lib/grape/middleware/formatter.rb +4 -4
  29. data/lib/grape/middleware/stack.rb +2 -2
  30. data/lib/grape/middleware/versioner/accept_version_header.rb +3 -5
  31. data/lib/grape/middleware/versioner/header.rb +6 -4
  32. data/lib/grape/middleware/versioner/param.rb +1 -0
  33. data/lib/grape/middleware/versioner/parse_media_type_patch.rb +2 -1
  34. data/lib/grape/middleware/versioner/path.rb +2 -0
  35. data/lib/grape/path.rb +1 -0
  36. data/lib/grape/request.rb +1 -0
  37. data/lib/grape/router/pattern.rb +1 -1
  38. data/lib/grape/router/route.rb +2 -2
  39. data/lib/grape/router.rb +6 -0
  40. data/lib/grape/util/inheritable_setting.rb +1 -3
  41. data/lib/grape/util/lazy_value.rb +3 -2
  42. data/lib/grape/util/strict_hash_configuration.rb +1 -1
  43. data/lib/grape/validations/params_scope.rb +88 -55
  44. data/lib/grape/validations/types/custom_type_coercer.rb +1 -0
  45. data/lib/grape/validations/types/dry_type_coercer.rb +1 -1
  46. data/lib/grape/validations/types/json.rb +2 -1
  47. data/lib/grape/validations/types/primitive_coercer.rb +3 -3
  48. data/lib/grape/validations/validators/all_or_none.rb +8 -5
  49. data/lib/grape/validations/validators/allow_blank.rb +9 -7
  50. data/lib/grape/validations/validators/as.rb +6 -8
  51. data/lib/grape/validations/validators/at_least_one_of.rb +7 -4
  52. data/lib/grape/validations/validators/base.rb +75 -70
  53. data/lib/grape/validations/validators/coerce.rb +63 -79
  54. data/lib/grape/validations/validators/default.rb +37 -34
  55. data/lib/grape/validations/validators/exactly_one_of.rb +9 -6
  56. data/lib/grape/validations/validators/except_values.rb +13 -11
  57. data/lib/grape/validations/validators/multiple_params_base.rb +24 -20
  58. data/lib/grape/validations/validators/mutual_exclusion.rb +8 -5
  59. data/lib/grape/validations/validators/presence.rb +7 -4
  60. data/lib/grape/validations/validators/regexp.rb +8 -5
  61. data/lib/grape/validations/validators/same_as.rb +18 -15
  62. data/lib/grape/validations/validators/values.rb +61 -56
  63. data/lib/grape/validations.rb +6 -0
  64. data/lib/grape/version.rb +1 -1
  65. data/lib/grape.rb +3 -1
  66. data/spec/grape/api/custom_validations_spec.rb +77 -45
  67. data/spec/grape/api/deeply_included_options_spec.rb +3 -3
  68. data/spec/grape/api/defines_boolean_in_params_spec.rb +2 -1
  69. data/spec/grape/api/invalid_format_spec.rb +2 -0
  70. data/spec/grape/api/recognize_path_spec.rb +1 -1
  71. data/spec/grape/api/routes_with_requirements_spec.rb +8 -8
  72. data/spec/grape/api/shared_helpers_exactly_one_of_spec.rb +9 -15
  73. data/spec/grape/api_remount_spec.rb +16 -15
  74. data/spec/grape/api_spec.rb +440 -227
  75. data/spec/grape/dsl/callbacks_spec.rb +2 -1
  76. data/spec/grape/dsl/headers_spec.rb +39 -9
  77. data/spec/grape/dsl/helpers_spec.rb +3 -2
  78. data/spec/grape/dsl/inside_route_spec.rb +6 -4
  79. data/spec/grape/dsl/logger_spec.rb +16 -18
  80. data/spec/grape/dsl/middleware_spec.rb +2 -1
  81. data/spec/grape/dsl/parameters_spec.rb +2 -0
  82. data/spec/grape/dsl/request_response_spec.rb +1 -0
  83. data/spec/grape/dsl/routing_spec.rb +10 -7
  84. data/spec/grape/endpoint/declared_spec.rb +259 -12
  85. data/spec/grape/endpoint_spec.rb +64 -55
  86. data/spec/grape/entity_spec.rb +22 -22
  87. data/spec/grape/exceptions/body_parse_errors_spec.rb +3 -0
  88. data/spec/grape/exceptions/invalid_accept_header_spec.rb +61 -22
  89. data/spec/grape/exceptions/validation_errors_spec.rb +13 -10
  90. data/spec/grape/exceptions/validation_spec.rb +5 -3
  91. data/spec/grape/extensions/param_builders/hash_spec.rb +7 -7
  92. data/spec/grape/extensions/param_builders/hash_with_indifferent_access_spec.rb +8 -8
  93. data/spec/grape/extensions/param_builders/hashie/mash_spec.rb +8 -8
  94. data/spec/grape/integration/rack_sendfile_spec.rb +1 -1
  95. data/spec/grape/loading_spec.rb +8 -8
  96. data/spec/grape/middleware/auth/dsl_spec.rb +15 -6
  97. data/spec/grape/middleware/auth/strategies_spec.rb +60 -20
  98. data/spec/grape/middleware/base_spec.rb +24 -15
  99. data/spec/grape/middleware/error_spec.rb +2 -2
  100. data/spec/grape/middleware/exception_spec.rb +111 -161
  101. data/spec/grape/middleware/formatter_spec.rb +27 -6
  102. data/spec/grape/middleware/globals_spec.rb +7 -4
  103. data/spec/grape/middleware/stack_spec.rb +14 -12
  104. data/spec/grape/middleware/versioner/accept_version_header_spec.rb +2 -1
  105. data/spec/grape/middleware/versioner/header_spec.rb +14 -13
  106. data/spec/grape/middleware/versioner/param_spec.rb +7 -1
  107. data/spec/grape/middleware/versioner/path_spec.rb +5 -1
  108. data/spec/grape/middleware/versioner_spec.rb +1 -1
  109. data/spec/grape/parser_spec.rb +4 -0
  110. data/spec/grape/path_spec.rb +52 -52
  111. data/spec/grape/presenters/presenter_spec.rb +7 -6
  112. data/spec/grape/request_spec.rb +6 -4
  113. data/spec/grape/util/inheritable_setting_spec.rb +7 -7
  114. data/spec/grape/util/inheritable_values_spec.rb +3 -2
  115. data/spec/grape/util/reverse_stackable_values_spec.rb +3 -1
  116. data/spec/grape/util/stackable_values_spec.rb +7 -5
  117. data/spec/grape/validations/instance_behaivour_spec.rb +9 -10
  118. data/spec/grape/validations/multiple_attributes_iterator_spec.rb +1 -0
  119. data/spec/grape/validations/params_scope_spec.rb +46 -10
  120. data/spec/grape/validations/single_attribute_iterator_spec.rb +2 -1
  121. data/spec/grape/validations/types/primitive_coercer_spec.rb +4 -4
  122. data/spec/grape/validations/types_spec.rb +8 -8
  123. data/spec/grape/validations/validators/all_or_none_spec.rb +50 -56
  124. data/spec/grape/validations/validators/allow_blank_spec.rb +136 -140
  125. data/spec/grape/validations/validators/at_least_one_of_spec.rb +50 -56
  126. data/spec/grape/validations/validators/coerce_spec.rb +23 -22
  127. data/spec/grape/validations/validators/default_spec.rb +72 -78
  128. data/spec/grape/validations/validators/exactly_one_of_spec.rb +71 -77
  129. data/spec/grape/validations/validators/except_values_spec.rb +3 -3
  130. data/spec/grape/validations/validators/mutual_exclusion_spec.rb +71 -77
  131. data/spec/grape/validations/validators/presence_spec.rb +16 -1
  132. data/spec/grape/validations/validators/regexp_spec.rb +25 -31
  133. data/spec/grape/validations/validators/same_as_spec.rb +14 -20
  134. data/spec/grape/validations/validators/values_spec.rb +183 -178
  135. data/spec/grape/validations_spec.rb +99 -58
  136. data/spec/integration/eager_load/eager_load_spec.rb +2 -2
  137. data/spec/integration/multi_json/json_spec.rb +1 -1
  138. data/spec/integration/multi_xml/xml_spec.rb +1 -1
  139. data/spec/shared/versioning_examples.rb +12 -9
  140. data/spec/spec_helper.rb +12 -2
  141. data/spec/support/basic_auth_encode_helpers.rb +1 -1
  142. metadata +103 -103
@@ -2,95 +2,89 @@
2
2
 
3
3
  require 'spec_helper'
4
4
 
5
- describe Grape::Validations::MutualExclusionValidator do
6
- describe '#validate!' do
7
- subject(:validate) { post path, params }
8
-
9
- module ValidationsSpec
10
- module MutualExclusionValidatorSpec
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
5
+ describe Grape::Validations::Validators::MutualExclusionValidator do
6
+ let_it_be(:app) do
7
+ Class.new(Grape::API) do
8
+ rescue_from Grape::Exceptions::ValidationErrors do |e|
9
+ error!(e.errors.transform_keys! { |key| key.join(',') }, 400)
10
+ end
15
11
 
16
- params do
17
- optional :beer
18
- optional :wine
19
- optional :grapefruit
20
- mutually_exclusive :beer, :wine, :grapefruit
21
- end
22
- post do
23
- end
12
+ params do
13
+ optional :beer
14
+ optional :wine
15
+ optional :grapefruit
16
+ mutually_exclusive :beer, :wine, :grapefruit
17
+ end
18
+ post do
19
+ end
24
20
 
25
- params do
26
- optional :beer
27
- optional :wine
28
- optional :grapefruit
29
- optional :other
30
- mutually_exclusive :beer, :wine, :grapefruit
31
- end
32
- post 'mixed-params' do
33
- end
21
+ params do
22
+ optional :beer
23
+ optional :wine
24
+ optional :grapefruit
25
+ optional :other
26
+ mutually_exclusive :beer, :wine, :grapefruit
27
+ end
28
+ post 'mixed-params' do
29
+ end
34
30
 
35
- params do
36
- optional :beer
37
- optional :wine
38
- optional :grapefruit
39
- mutually_exclusive :beer, :wine, :grapefruit, message: 'you should not mix beer and wine'
40
- end
41
- post '/custom-message' do
42
- end
31
+ params do
32
+ optional :beer
33
+ optional :wine
34
+ optional :grapefruit
35
+ mutually_exclusive :beer, :wine, :grapefruit, message: 'you should not mix beer and wine'
36
+ end
37
+ post '/custom-message' do
38
+ end
43
39
 
44
- params do
45
- requires :item, type: Hash do
46
- optional :beer
47
- optional :wine
48
- optional :grapefruit
49
- mutually_exclusive :beer, :wine, :grapefruit
50
- end
51
- end
52
- post '/nested-hash' do
53
- end
40
+ params do
41
+ requires :item, type: Hash do
42
+ optional :beer
43
+ optional :wine
44
+ optional :grapefruit
45
+ mutually_exclusive :beer, :wine, :grapefruit
46
+ end
47
+ end
48
+ post '/nested-hash' do
49
+ end
54
50
 
55
- params do
56
- optional :item, type: Hash do
57
- optional :beer
58
- optional :wine
59
- optional :grapefruit
60
- mutually_exclusive :beer, :wine, :grapefruit
61
- end
62
- end
63
- post '/nested-optional-hash' do
64
- end
51
+ params do
52
+ optional :item, type: Hash do
53
+ optional :beer
54
+ optional :wine
55
+ optional :grapefruit
56
+ mutually_exclusive :beer, :wine, :grapefruit
57
+ end
58
+ end
59
+ post '/nested-optional-hash' do
60
+ end
65
61
 
66
- params do
67
- requires :items, type: Array do
68
- optional :beer
69
- optional :wine
70
- optional :grapefruit
71
- mutually_exclusive :beer, :wine, :grapefruit
72
- end
73
- end
74
- post '/nested-array' do
75
- end
62
+ params do
63
+ requires :items, type: Array do
64
+ optional :beer
65
+ optional :wine
66
+ optional :grapefruit
67
+ mutually_exclusive :beer, :wine, :grapefruit
68
+ end
69
+ end
70
+ post '/nested-array' do
71
+ end
76
72
 
77
- params do
78
- requires :items, type: Array do
79
- requires :nested_items, type: Array do
80
- optional :beer, :wine, :grapefruit, type: Boolean
81
- mutually_exclusive :beer, :wine, :grapefruit
82
- end
83
- end
84
- end
85
- post '/deeply-nested-array' do
73
+ params do
74
+ requires :items, type: Array do
75
+ requires :nested_items, type: Array do
76
+ optional :beer, :wine, :grapefruit, type: Grape::API::Boolean
77
+ mutually_exclusive :beer, :wine, :grapefruit
86
78
  end
87
79
  end
88
80
  end
81
+ post '/deeply-nested-array' do
82
+ end
89
83
  end
84
+ end
90
85
 
91
- def app
92
- ValidationsSpec::MutualExclusionValidatorSpec::API
93
- end
86
+ describe '#validate!' do
87
+ subject(:validate) { post path, params }
94
88
 
95
89
  context 'when all mutually exclusive params are present' do
96
90
  let(:path) { '/' }
@@ -2,12 +2,13 @@
2
2
 
3
3
  require 'spec_helper'
4
4
 
5
- describe Grape::Validations::PresenceValidator do
5
+ describe Grape::Validations::Validators::PresenceValidator do
6
6
  subject do
7
7
  Class.new(Grape::API) do
8
8
  format :json
9
9
  end
10
10
  end
11
+
11
12
  def app
12
13
  subject
13
14
  end
@@ -20,6 +21,7 @@ describe Grape::Validations::PresenceValidator do
20
21
  end
21
22
  end
22
23
  end
24
+
23
25
  it 'does not validate for any params' do
24
26
  get '/bacons'
25
27
  expect(last_response.status).to eq(200)
@@ -38,15 +40,18 @@ describe Grape::Validations::PresenceValidator do
38
40
  end
39
41
  end
40
42
  end
43
+
41
44
  it 'requires when missing' do
42
45
  get '/requires'
43
46
  expect(last_response.status).to eq(400)
44
47
  expect(last_response.body).to eq('{"error":"email is required, email has no value"}')
45
48
  end
49
+
46
50
  it 'requires when empty' do
47
51
  get '/requires', email: ''
48
52
  expect(last_response.body).to eq('{"error":"email has no value, email format is invalid"}')
49
53
  end
54
+
50
55
  it 'valid when set' do
51
56
  get '/requires', email: 'bob@example.com'
52
57
  expect(last_response.status).to eq(200)
@@ -64,6 +69,7 @@ describe Grape::Validations::PresenceValidator do
64
69
  { ret: params[:id] }
65
70
  end
66
71
  end
72
+
67
73
  it 'validates id' do
68
74
  post '/'
69
75
  expect(last_response.status).to eq(400)
@@ -90,16 +96,19 @@ describe Grape::Validations::PresenceValidator do
90
96
  'Hello'
91
97
  end
92
98
  end
99
+
93
100
  it 'requires when missing' do
94
101
  get '/'
95
102
  expect(last_response.status).to eq(400)
96
103
  expect(last_response.body).to eq('{"error":"email is missing, email is empty"}')
97
104
  end
105
+
98
106
  it 'requires when empty' do
99
107
  get '/', email: ''
100
108
  expect(last_response.status).to eq(400)
101
109
  expect(last_response.body).to eq('{"error":"email is empty, email is invalid"}')
102
110
  end
111
+
103
112
  it 'valid when set' do
104
113
  get '/', email: 'bob@example.com'
105
114
  expect(last_response.status).to eq(200)
@@ -124,6 +133,7 @@ describe Grape::Validations::PresenceValidator do
124
133
  'Hello'
125
134
  end
126
135
  end
136
+
127
137
  it 'validates for all defined params' do
128
138
  get '/single-requires'
129
139
  expect(last_response.status).to eq(400)
@@ -144,6 +154,7 @@ describe Grape::Validations::PresenceValidator do
144
154
  'Hello'
145
155
  end
146
156
  end
157
+
147
158
  it 'validates name, company' do
148
159
  get '/'
149
160
  expect(last_response.status).to eq(400)
@@ -171,6 +182,7 @@ describe Grape::Validations::PresenceValidator do
171
182
  'Nested'
172
183
  end
173
184
  end
185
+
174
186
  it 'validates nested parameters' do
175
187
  get '/nested'
176
188
  expect(last_response.status).to eq(400)
@@ -203,6 +215,7 @@ describe Grape::Validations::PresenceValidator do
203
215
  'Nested triple'
204
216
  end
205
217
  end
218
+
206
219
  it 'validates triple nested parameters' do
207
220
  get '/nested_triple'
208
221
  expect(last_response.status).to eq(400)
@@ -252,6 +265,7 @@ describe Grape::Validations::PresenceValidator do
252
265
  'Hello optional'
253
266
  end
254
267
  end
268
+
255
269
  it 'works with required' do
256
270
  get '/required'
257
271
  expect(last_response.status).to eq(400)
@@ -261,6 +275,7 @@ describe Grape::Validations::PresenceValidator do
261
275
  expect(last_response.status).to eq(200)
262
276
  expect(last_response.body).to eq('Hello required'.to_json)
263
277
  end
278
+
264
279
  it 'works with optional' do
265
280
  get '/optional'
266
281
  expect(last_response.status).to eq(200)
@@ -2,53 +2,47 @@
2
2
 
3
3
  require 'spec_helper'
4
4
 
5
- describe Grape::Validations::RegexpValidator do
6
- module ValidationsSpec
7
- module RegexpValidatorSpec
8
- class API < Grape::API
9
- default_format :json
10
-
11
- resources :custom_message do
12
- params do
13
- requires :name, regexp: { value: /^[a-z]+$/, message: 'format is invalid' }
14
- end
15
- get do
16
- end
17
-
18
- params do
19
- requires :names, type: { value: Array[String], message: 'can\'t be nil' }, regexp: { value: /^[a-z]+$/, message: 'format is invalid' }
20
- end
21
- get 'regexp_with_array' do
22
- end
23
- end
5
+ describe Grape::Validations::Validators::RegexpValidator do
6
+ let_it_be(:app) do
7
+ Class.new(Grape::API) do
8
+ default_format :json
24
9
 
10
+ resources :custom_message do
25
11
  params do
26
- requires :name, regexp: /^[a-z]+$/
12
+ requires :name, regexp: { value: /^[a-z]+$/, message: 'format is invalid' }
27
13
  end
28
14
  get do
29
15
  end
30
16
 
31
17
  params do
32
- requires :names, type: Array[String], regexp: /^[a-z]+$/
18
+ requires :names, type: { value: Array[String], message: 'can\'t be nil' }, regexp: { value: /^[a-z]+$/, message: 'format is invalid' }
33
19
  end
34
20
  get 'regexp_with_array' do
35
21
  end
22
+ end
36
23
 
37
- params do
38
- requires :people, type: Hash do
39
- requires :names, type: Array[String], regexp: /^[a-z]+$/
40
- end
41
- end
42
- get 'nested_regexp_with_array' do
24
+ params do
25
+ requires :name, regexp: /^[a-z]+$/
26
+ end
27
+ get do
28
+ end
29
+
30
+ params do
31
+ requires :names, type: Array[String], regexp: /^[a-z]+$/
32
+ end
33
+ get 'regexp_with_array' do
34
+ end
35
+
36
+ params do
37
+ requires :people, type: Hash do
38
+ requires :names, type: Array[String], regexp: /^[a-z]+$/
43
39
  end
44
40
  end
41
+ get 'nested_regexp_with_array' do
42
+ end
45
43
  end
46
44
  end
47
45
 
48
- def app
49
- ValidationsSpec::RegexpValidatorSpec::API
50
- end
51
-
52
46
  context 'custom validation message' do
53
47
  context 'with invalid input' do
54
48
  it 'refuses inapppopriate' do
@@ -2,31 +2,25 @@
2
2
 
3
3
  require 'spec_helper'
4
4
 
5
- describe Grape::Validations::SameAsValidator do
6
- module ValidationsSpec
7
- module SameAsValidatorSpec
8
- class API < Grape::API
9
- params do
10
- requires :password
11
- requires :password_confirmation, same_as: :password
12
- end
13
- post do
14
- end
5
+ describe Grape::Validations::Validators::SameAsValidator do
6
+ let_it_be(:app) do
7
+ Class.new(Grape::API) do
8
+ params do
9
+ requires :password
10
+ requires :password_confirmation, same_as: :password
11
+ end
12
+ post do
13
+ end
15
14
 
16
- params do
17
- requires :password
18
- requires :password_confirmation, same_as: { value: :password, message: 'not match' }
19
- end
20
- post '/custom-message' do
21
- end
15
+ params do
16
+ requires :password
17
+ requires :password_confirmation, same_as: { value: :password, message: 'not match' }
18
+ end
19
+ post '/custom-message' do
22
20
  end
23
21
  end
24
22
  end
25
23
 
26
- def app
27
- ValidationsSpec::SameAsValidatorSpec::API
28
- end
29
-
30
24
  describe '/' do
31
25
  context 'is the same' do
32
26
  it do