grape 0.10.1 → 0.11.0
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of grape might be problematic. Click here for more details.
- checksums.yaml +4 -4
- data/.gitignore +1 -0
- data/.rspec +1 -1
- data/CHANGELOG.md +18 -0
- data/Gemfile +1 -1
- data/README.md +124 -9
- data/UPGRADING.md +66 -0
- data/gemfiles/rails_3.gemfile +1 -1
- data/gemfiles/rails_4.gemfile +1 -1
- data/lib/grape.rb +4 -0
- data/lib/grape/api.rb +1 -5
- data/lib/grape/dsl/inside_route.rb +2 -1
- data/lib/grape/dsl/parameters.rb +20 -9
- data/lib/grape/dsl/routing.rb +11 -1
- data/lib/grape/error_formatter/base.rb +1 -1
- data/lib/grape/exceptions/invalid_accept_header.rb +10 -0
- data/lib/grape/exceptions/invalid_message_body.rb +10 -0
- data/lib/grape/exceptions/missing_group_type.rb +10 -0
- data/lib/grape/exceptions/unsupported_group_type.rb +10 -0
- data/lib/grape/http/request.rb +1 -0
- data/lib/grape/locale/en.yml +11 -0
- data/lib/grape/middleware/base.rb +1 -1
- data/lib/grape/middleware/formatter.rb +2 -0
- data/lib/grape/middleware/versioner/header.rb +14 -11
- data/lib/grape/parser/json.rb +3 -0
- data/lib/grape/parser/xml.rb +3 -0
- data/lib/grape/validations/params_scope.rb +20 -4
- data/lib/grape/validations/validators/coerce.rb +4 -1
- data/lib/grape/validations/validators/values.rb +1 -1
- data/lib/grape/version.rb +1 -1
- data/spec/grape/api_spec.rb +3 -3
- data/spec/grape/dsl/parameters_spec.rb +11 -11
- data/spec/grape/dsl/routing_spec.rb +13 -4
- data/spec/grape/endpoint_spec.rb +2 -2
- data/spec/grape/exceptions/body_parse_errors_spec.rb +105 -0
- data/spec/grape/exceptions/invalid_accept_header_spec.rb +330 -0
- data/spec/grape/integration/rack_spec.rb +32 -0
- data/spec/grape/middleware/base_spec.rb +20 -0
- data/spec/grape/middleware/versioner/header_spec.rb +74 -96
- data/spec/grape/validations/params_scope_spec.rb +124 -0
- data/spec/grape/validations/validators/allow_blank_spec.rb +102 -0
- data/spec/grape/validations/validators/values_spec.rb +45 -1
- data/spec/grape/validations_spec.rb +54 -16
- data/spec/shared/versioning_examples.rb +32 -0
- metadata +61 -51
@@ -0,0 +1,330 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Grape::Exceptions::InvalidAcceptHeader do
|
4
|
+
shared_examples_for 'a valid request' do
|
5
|
+
it 'does return with status 200' do
|
6
|
+
expect(last_response.status).to eq 200
|
7
|
+
end
|
8
|
+
it 'does return the expected result' do
|
9
|
+
expect(last_response.body).to eq('beer received')
|
10
|
+
end
|
11
|
+
end
|
12
|
+
shared_examples_for 'a cascaded request' do
|
13
|
+
it 'does not find a matching route' do
|
14
|
+
expect(last_response.status).to eq 404
|
15
|
+
end
|
16
|
+
end
|
17
|
+
shared_examples_for 'a not-cascaded request' do
|
18
|
+
it 'does not include the X-Cascade=pass header' do
|
19
|
+
expect(last_response.headers['X-Cascade']).to be_nil
|
20
|
+
end
|
21
|
+
it 'does not accept the request' do
|
22
|
+
expect(last_response.status).to eq 406
|
23
|
+
end
|
24
|
+
end
|
25
|
+
shared_examples_for 'a rescued request' do
|
26
|
+
it 'does not include the X-Cascade=pass header' do
|
27
|
+
expect(last_response.headers['X-Cascade']).to be_nil
|
28
|
+
end
|
29
|
+
it 'does show rescue handler processing' do
|
30
|
+
expect(last_response.status).to eq 400
|
31
|
+
expect(last_response.body).to eq('message was processed')
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
context 'API with cascade=false and rescue_from :all handler' do
|
36
|
+
subject { Class.new(Grape::API) }
|
37
|
+
before {
|
38
|
+
subject.version 'v99', using: :header, vendor: 'vendorname', format: :json, cascade: false
|
39
|
+
subject.rescue_from :all do |e|
|
40
|
+
rack_response 'message was processed', 400, e[:headers]
|
41
|
+
end
|
42
|
+
subject.get '/beer' do
|
43
|
+
'beer received'
|
44
|
+
end
|
45
|
+
}
|
46
|
+
|
47
|
+
def app
|
48
|
+
subject
|
49
|
+
end
|
50
|
+
|
51
|
+
context 'that received a request with correct vendor and version' do
|
52
|
+
before { get '/beer', {}, 'HTTP_ACCEPT' => 'application/vnd.vendorname-v99' }
|
53
|
+
it_should_behave_like 'a valid request'
|
54
|
+
end
|
55
|
+
|
56
|
+
context 'that receives' do
|
57
|
+
context 'an invalid version in the request' do
|
58
|
+
before {
|
59
|
+
get '/beer', {}, 'HTTP_ACCEPT' => 'application/vnd.vendorname-v77',
|
60
|
+
'CONTENT_TYPE' => 'application/json'
|
61
|
+
}
|
62
|
+
it_should_behave_like 'a rescued request'
|
63
|
+
end
|
64
|
+
context 'an invalid vendor in the request' do
|
65
|
+
before {
|
66
|
+
get '/beer', {}, 'HTTP_ACCEPT' => 'application/vnd.invalidvendor-v99',
|
67
|
+
'CONTENT_TYPE' => 'application/json'
|
68
|
+
}
|
69
|
+
it_should_behave_like 'a rescued request'
|
70
|
+
end
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
context 'API with cascade=false and without a rescue handler' do
|
75
|
+
subject { Class.new(Grape::API) }
|
76
|
+
before {
|
77
|
+
subject.version 'v99', using: :header, vendor: 'vendorname', format: :json, cascade: false
|
78
|
+
subject.get '/beer' do
|
79
|
+
'beer received'
|
80
|
+
end
|
81
|
+
}
|
82
|
+
|
83
|
+
def app
|
84
|
+
subject
|
85
|
+
end
|
86
|
+
|
87
|
+
context 'that received a request with correct vendor and version' do
|
88
|
+
before { get '/beer', {}, 'HTTP_ACCEPT' => 'application/vnd.vendorname-v99' }
|
89
|
+
it_should_behave_like 'a valid request'
|
90
|
+
end
|
91
|
+
|
92
|
+
context 'that receives' do
|
93
|
+
context 'an invalid version in the request' do
|
94
|
+
before { get '/beer', {}, 'HTTP_ACCEPT' => 'application/vnd.vendorname-v77' }
|
95
|
+
it_should_behave_like 'a not-cascaded request'
|
96
|
+
end
|
97
|
+
context 'an invalid vendor in the request' do
|
98
|
+
before { get '/beer', {}, 'HTTP_ACCEPT' => 'application/vnd.invalidvendor-v99' }
|
99
|
+
it_should_behave_like 'a not-cascaded request'
|
100
|
+
end
|
101
|
+
end
|
102
|
+
end
|
103
|
+
|
104
|
+
context 'API with cascade=false and with rescue_from :all handler and http_codes' do
|
105
|
+
subject { Class.new(Grape::API) }
|
106
|
+
before {
|
107
|
+
subject.version 'v99', using: :header, vendor: 'vendorname', format: :json, cascade: false
|
108
|
+
subject.rescue_from :all do |e|
|
109
|
+
rack_response 'message was processed', 400, e[:headers]
|
110
|
+
end
|
111
|
+
subject.desc 'Get beer' do
|
112
|
+
failure [[400, 'Bad Request'], [401, 'Unauthorized'], [403, 'Forbidden'],
|
113
|
+
[404, 'Resource not found'], [406, 'API vendor or version not found'],
|
114
|
+
[500, 'Internal processing error']]
|
115
|
+
end
|
116
|
+
subject.get '/beer' do
|
117
|
+
'beer received'
|
118
|
+
end
|
119
|
+
}
|
120
|
+
|
121
|
+
def app
|
122
|
+
subject
|
123
|
+
end
|
124
|
+
|
125
|
+
context 'that received a request with correct vendor and version' do
|
126
|
+
before { get '/beer', {}, 'HTTP_ACCEPT' => 'application/vnd.vendorname-v99' }
|
127
|
+
it_should_behave_like 'a valid request'
|
128
|
+
end
|
129
|
+
|
130
|
+
context 'that receives' do
|
131
|
+
context 'an invalid version in the request' do
|
132
|
+
before {
|
133
|
+
get '/beer', {}, 'HTTP_ACCEPT' => 'application/vnd.vendorname-v77',
|
134
|
+
'CONTENT_TYPE' => 'application/json'
|
135
|
+
}
|
136
|
+
it_should_behave_like 'a rescued request'
|
137
|
+
end
|
138
|
+
context 'an invalid vendor in the request' do
|
139
|
+
before {
|
140
|
+
get '/beer', {}, 'HTTP_ACCEPT' => 'application/vnd.invalidvendor-v99',
|
141
|
+
'CONTENT_TYPE' => 'application/json'
|
142
|
+
}
|
143
|
+
it_should_behave_like 'a rescued request'
|
144
|
+
end
|
145
|
+
end
|
146
|
+
end
|
147
|
+
|
148
|
+
context 'API with cascade=false, http_codes but without a rescue handler' do
|
149
|
+
subject { Class.new(Grape::API) }
|
150
|
+
before {
|
151
|
+
subject.version 'v99', using: :header, vendor: 'vendorname', format: :json, cascade: false
|
152
|
+
subject.desc 'Get beer' do
|
153
|
+
failure [[400, 'Bad Request'], [401, 'Unauthorized'], [403, 'Forbidden'],
|
154
|
+
[404, 'Resource not found'], [406, 'API vendor or version not found'],
|
155
|
+
[500, 'Internal processing error']]
|
156
|
+
end
|
157
|
+
subject.get '/beer' do
|
158
|
+
'beer received'
|
159
|
+
end
|
160
|
+
}
|
161
|
+
|
162
|
+
def app
|
163
|
+
subject
|
164
|
+
end
|
165
|
+
|
166
|
+
context 'that received a request with correct vendor and version' do
|
167
|
+
before { get '/beer', {}, 'HTTP_ACCEPT' => 'application/vnd.vendorname-v99' }
|
168
|
+
it_should_behave_like 'a valid request'
|
169
|
+
end
|
170
|
+
|
171
|
+
context 'that receives' do
|
172
|
+
context 'an invalid version in the request' do
|
173
|
+
before { get '/beer', {}, 'HTTP_ACCEPT' => 'application/vnd.vendorname-v77' }
|
174
|
+
it_should_behave_like 'a not-cascaded request'
|
175
|
+
end
|
176
|
+
context 'an invalid vendor in the request' do
|
177
|
+
before { get '/beer', {}, 'HTTP_ACCEPT' => 'application/vnd.invalidvendor-v99' }
|
178
|
+
it_should_behave_like 'a not-cascaded request'
|
179
|
+
end
|
180
|
+
end
|
181
|
+
end
|
182
|
+
|
183
|
+
context 'API with cascade=true and rescue_from :all handler' do
|
184
|
+
subject { Class.new(Grape::API) }
|
185
|
+
before {
|
186
|
+
subject.version 'v99', using: :header, vendor: 'vendorname', format: :json, cascade: true
|
187
|
+
subject.rescue_from :all do |e|
|
188
|
+
rack_response 'message was processed', 400, e[:headers]
|
189
|
+
end
|
190
|
+
subject.get '/beer' do
|
191
|
+
'beer received'
|
192
|
+
end
|
193
|
+
}
|
194
|
+
|
195
|
+
def app
|
196
|
+
subject
|
197
|
+
end
|
198
|
+
|
199
|
+
context 'that received a request with correct vendor and version' do
|
200
|
+
before { get '/beer', {}, 'HTTP_ACCEPT' => 'application/vnd.vendorname-v99' }
|
201
|
+
it_should_behave_like 'a valid request'
|
202
|
+
end
|
203
|
+
|
204
|
+
context 'that receives' do
|
205
|
+
context 'an invalid version in the request' do
|
206
|
+
before {
|
207
|
+
get '/beer', {}, 'HTTP_ACCEPT' => 'application/vnd.vendorname-v77',
|
208
|
+
'CONTENT_TYPE' => 'application/json'
|
209
|
+
}
|
210
|
+
it_should_behave_like 'a cascaded request'
|
211
|
+
end
|
212
|
+
context 'an invalid vendor in the request' do
|
213
|
+
before {
|
214
|
+
get '/beer', {}, 'HTTP_ACCEPT' => 'application/vnd.invalidvendor-v99',
|
215
|
+
'CONTENT_TYPE' => 'application/json'
|
216
|
+
}
|
217
|
+
it_should_behave_like 'a cascaded request'
|
218
|
+
end
|
219
|
+
end
|
220
|
+
end
|
221
|
+
|
222
|
+
context 'API with cascade=true and without a rescue handler' do
|
223
|
+
subject { Class.new(Grape::API) }
|
224
|
+
before {
|
225
|
+
subject.version 'v99', using: :header, vendor: 'vendorname', format: :json, cascade: true
|
226
|
+
subject.get '/beer' do
|
227
|
+
'beer received'
|
228
|
+
end
|
229
|
+
}
|
230
|
+
|
231
|
+
def app
|
232
|
+
subject
|
233
|
+
end
|
234
|
+
|
235
|
+
context 'that received a request with correct vendor and version' do
|
236
|
+
before { get '/beer', {}, 'HTTP_ACCEPT' => 'application/vnd.vendorname-v99' }
|
237
|
+
it_should_behave_like 'a valid request'
|
238
|
+
end
|
239
|
+
|
240
|
+
context 'that receives' do
|
241
|
+
context 'an invalid version in the request' do
|
242
|
+
before { get '/beer', {}, 'HTTP_ACCEPT' => 'application/vnd.vendorname-v77' }
|
243
|
+
it_should_behave_like 'a cascaded request'
|
244
|
+
end
|
245
|
+
context 'an invalid vendor in the request' do
|
246
|
+
before { get '/beer', {}, 'HTTP_ACCEPT' => 'application/vnd.invalidvendor-v99' }
|
247
|
+
it_should_behave_like 'a cascaded request'
|
248
|
+
end
|
249
|
+
end
|
250
|
+
end
|
251
|
+
|
252
|
+
context 'API with cascade=true and with rescue_from :all handler and http_codes' do
|
253
|
+
subject { Class.new(Grape::API) }
|
254
|
+
before {
|
255
|
+
subject.version 'v99', using: :header, vendor: 'vendorname', format: :json, cascade: true
|
256
|
+
subject.rescue_from :all do |e|
|
257
|
+
rack_response 'message was processed', 400, e[:headers]
|
258
|
+
end
|
259
|
+
subject.desc 'Get beer' do
|
260
|
+
failure [[400, 'Bad Request'], [401, 'Unauthorized'], [403, 'Forbidden'],
|
261
|
+
[404, 'Resource not found'], [406, 'API vendor or version not found'],
|
262
|
+
[500, 'Internal processing error']]
|
263
|
+
end
|
264
|
+
subject.get '/beer' do
|
265
|
+
'beer received'
|
266
|
+
end
|
267
|
+
}
|
268
|
+
|
269
|
+
def app
|
270
|
+
subject
|
271
|
+
end
|
272
|
+
|
273
|
+
context 'that received a request with correct vendor and version' do
|
274
|
+
before { get '/beer', {}, 'HTTP_ACCEPT' => 'application/vnd.vendorname-v99' }
|
275
|
+
it_should_behave_like 'a valid request'
|
276
|
+
end
|
277
|
+
|
278
|
+
context 'that receives' do
|
279
|
+
context 'an invalid version in the request' do
|
280
|
+
before {
|
281
|
+
get '/beer', {}, 'HTTP_ACCEPT' => 'application/vnd.vendorname-v77',
|
282
|
+
'CONTENT_TYPE' => 'application/json'
|
283
|
+
}
|
284
|
+
it_should_behave_like 'a cascaded request'
|
285
|
+
end
|
286
|
+
context 'an invalid vendor in the request' do
|
287
|
+
before {
|
288
|
+
get '/beer', {}, 'HTTP_ACCEPT' => 'application/vnd.invalidvendor-v99',
|
289
|
+
'CONTENT_TYPE' => 'application/json'
|
290
|
+
}
|
291
|
+
it_should_behave_like 'a cascaded request'
|
292
|
+
end
|
293
|
+
end
|
294
|
+
end
|
295
|
+
|
296
|
+
context 'API with cascade=true, http_codes but without a rescue handler' do
|
297
|
+
subject { Class.new(Grape::API) }
|
298
|
+
before {
|
299
|
+
subject.version 'v99', using: :header, vendor: 'vendorname', format: :json, cascade: true
|
300
|
+
subject.desc 'Get beer' do
|
301
|
+
failure [[400, 'Bad Request'], [401, 'Unauthorized'], [403, 'Forbidden'],
|
302
|
+
[404, 'Resource not found'], [406, 'API vendor or version not found'],
|
303
|
+
[500, 'Internal processing error']]
|
304
|
+
end
|
305
|
+
subject.get '/beer' do
|
306
|
+
'beer received'
|
307
|
+
end
|
308
|
+
}
|
309
|
+
|
310
|
+
def app
|
311
|
+
subject
|
312
|
+
end
|
313
|
+
|
314
|
+
context 'that received a request with correct vendor and version' do
|
315
|
+
before { get '/beer', {}, 'HTTP_ACCEPT' => 'application/vnd.vendorname-v99' }
|
316
|
+
it_should_behave_like 'a valid request'
|
317
|
+
end
|
318
|
+
|
319
|
+
context 'that receives' do
|
320
|
+
context 'an invalid version in the request' do
|
321
|
+
before { get '/beer', {}, 'HTTP_ACCEPT' => 'application/vnd.vendorname-v77' }
|
322
|
+
it_should_behave_like 'a cascaded request'
|
323
|
+
end
|
324
|
+
context 'an invalid vendor in the request' do
|
325
|
+
before { get '/beer', {}, 'HTTP_ACCEPT' => 'application/vnd.invalidvendor-v99' }
|
326
|
+
it_should_behave_like 'a cascaded request'
|
327
|
+
end
|
328
|
+
end
|
329
|
+
end
|
330
|
+
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Rack do
|
4
|
+
it 'correctly populates params from a Tempfile' do
|
5
|
+
input = Tempfile.new 'rubbish'
|
6
|
+
begin
|
7
|
+
app = Class.new(Grape::API) do
|
8
|
+
format :json
|
9
|
+
post do
|
10
|
+
{ params_keys: params.keys }
|
11
|
+
end
|
12
|
+
end
|
13
|
+
input.write({ test: '123' * 10_000 }.to_json)
|
14
|
+
input.rewind
|
15
|
+
options = {
|
16
|
+
input: input,
|
17
|
+
method: 'POST',
|
18
|
+
'CONTENT_TYPE' => 'application/json'
|
19
|
+
}
|
20
|
+
env = Rack::MockRequest.env_for('/', options)
|
21
|
+
|
22
|
+
# requires Rack 1.6.0 to pass
|
23
|
+
# can't check explicitly version of Rack because of https://github.com/rack/rack/issues/773
|
24
|
+
pending 'Rack 1.6.0 is required' unless ::Rack.const_defined?(:TempfileReaper) || RUBY_PLATFORM == 'java'
|
25
|
+
|
26
|
+
expect(JSON.parse(app.call(env)[2].body.first)['params_keys']).to match_array('test')
|
27
|
+
ensure
|
28
|
+
input.close
|
29
|
+
input.unlink
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
@@ -34,6 +34,26 @@ describe Grape::Middleware::Base do
|
|
34
34
|
expect(subject.response).to be_kind_of(Rack::Response)
|
35
35
|
end
|
36
36
|
|
37
|
+
describe '#response' do
|
38
|
+
subject { Grape::Middleware::Base.new(response) }
|
39
|
+
let(:response) { lambda { |_| [204, { abc: 1 }, 'test'] } }
|
40
|
+
|
41
|
+
it 'status' do
|
42
|
+
subject.call({})
|
43
|
+
expect(subject.response.status).to eq(204)
|
44
|
+
end
|
45
|
+
|
46
|
+
it 'body' do
|
47
|
+
subject.call({})
|
48
|
+
expect(subject.response.body).to eq(['test'])
|
49
|
+
end
|
50
|
+
|
51
|
+
it 'header' do
|
52
|
+
subject.call({})
|
53
|
+
expect(subject.response.header).to have_key(:abc)
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
37
57
|
context 'options' do
|
38
58
|
it 'persists options passed at initialization' do
|
39
59
|
expect(Grape::Middleware::Base.new(blank_app, abc: true).options[:abc]).to be true
|
@@ -84,14 +84,13 @@ describe Grape::Middleware::Versioner::Header do
|
|
84
84
|
end
|
85
85
|
|
86
86
|
it 'fails with 406 Not Acceptable if vendor is invalid' do
|
87
|
-
expect
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
)
|
87
|
+
expect { subject.call('HTTP_ACCEPT' => 'application/vnd.othervendor+json').last }
|
88
|
+
.to raise_exception do |exception|
|
89
|
+
expect(exception).to be_a(Grape::Exceptions::InvalidAcceptHeader)
|
90
|
+
expect(exception.headers).to eql('X-Cascade' => 'pass')
|
91
|
+
expect(exception.status).to eql 406
|
92
|
+
expect(exception.message).to include 'API vendor or version not found'
|
93
|
+
end
|
95
94
|
end
|
96
95
|
|
97
96
|
context 'when version is set' do
|
@@ -112,14 +111,13 @@ describe Grape::Middleware::Versioner::Header do
|
|
112
111
|
end
|
113
112
|
|
114
113
|
it 'fails with 406 Not Acceptable if vendor is invalid' do
|
115
|
-
expect
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
)
|
114
|
+
expect { subject.call('HTTP_ACCEPT' => 'application/vnd.othervendor-v1+json').last }
|
115
|
+
.to raise_exception do |exception|
|
116
|
+
expect(exception).to be_a(Grape::Exceptions::InvalidAcceptHeader)
|
117
|
+
expect(exception.headers).to eql('X-Cascade' => 'pass')
|
118
|
+
expect(exception.status).to eql 406
|
119
|
+
expect(exception.message).to include('API vendor or version not found')
|
120
|
+
end
|
123
121
|
end
|
124
122
|
end
|
125
123
|
end
|
@@ -142,14 +140,12 @@ describe Grape::Middleware::Versioner::Header do
|
|
142
140
|
end
|
143
141
|
|
144
142
|
it 'fails with 406 Not Acceptable if version is invalid' do
|
145
|
-
expect do
|
146
|
-
|
147
|
-
|
148
|
-
|
149
|
-
|
150
|
-
|
151
|
-
message: 'API vendor or version not found.'
|
152
|
-
)
|
143
|
+
expect { subject.call('HTTP_ACCEPT' => 'application/vnd.vendor-v2+json').last }.to raise_exception do |exception|
|
144
|
+
expect(exception).to be_a(Grape::Exceptions::InvalidAcceptHeader)
|
145
|
+
expect(exception.headers).to eql('X-Cascade' => 'pass')
|
146
|
+
expect(exception.status).to eql 406
|
147
|
+
expect(exception.message).to include('API vendor or version not found')
|
148
|
+
end
|
153
149
|
end
|
154
150
|
end
|
155
151
|
|
@@ -171,47 +167,39 @@ describe Grape::Middleware::Versioner::Header do
|
|
171
167
|
end
|
172
168
|
|
173
169
|
it 'fails with 406 Not Acceptable if header is not set' do
|
174
|
-
expect do
|
175
|
-
|
176
|
-
|
177
|
-
|
178
|
-
|
179
|
-
|
180
|
-
message: 'Accept header must be set.'
|
181
|
-
)
|
170
|
+
expect { subject.call({}).last }.to raise_exception do |exception|
|
171
|
+
expect(exception).to be_a(Grape::Exceptions::InvalidAcceptHeader)
|
172
|
+
expect(exception.headers).to eql('X-Cascade' => 'pass')
|
173
|
+
expect(exception.status).to eql 406
|
174
|
+
expect(exception.message).to include('Accept header must be set.')
|
175
|
+
end
|
182
176
|
end
|
183
177
|
|
184
178
|
it 'fails with 406 Not Acceptable if header is empty' do
|
185
|
-
expect do
|
186
|
-
|
187
|
-
|
188
|
-
|
189
|
-
|
190
|
-
|
191
|
-
message: 'Accept header must be set.'
|
192
|
-
)
|
179
|
+
expect { subject.call('HTTP_ACCEPT' => '').last }.to raise_exception do |exception|
|
180
|
+
expect(exception).to be_a(Grape::Exceptions::InvalidAcceptHeader)
|
181
|
+
expect(exception.headers).to eql('X-Cascade' => 'pass')
|
182
|
+
expect(exception.status).to eql 406
|
183
|
+
expect(exception.message).to include('Accept header must be set.')
|
184
|
+
end
|
193
185
|
end
|
194
186
|
|
195
187
|
it 'fails with 406 Not Acceptable if type is a range' do
|
196
|
-
expect do
|
197
|
-
|
198
|
-
|
199
|
-
|
200
|
-
|
201
|
-
|
202
|
-
message: 'Accept header must not contain ranges ("*").'
|
203
|
-
)
|
188
|
+
expect { subject.call('HTTP_ACCEPT' => '*/*').last }.to raise_exception do |exception|
|
189
|
+
expect(exception).to be_a(Grape::Exceptions::InvalidAcceptHeader)
|
190
|
+
expect(exception.headers).to eql('X-Cascade' => 'pass')
|
191
|
+
expect(exception.status).to eql 406
|
192
|
+
expect(exception.message).to include('Accept header must not contain ranges ("*").')
|
193
|
+
end
|
204
194
|
end
|
205
195
|
|
206
196
|
it 'fails with 406 Not Acceptable if subtype is a range' do
|
207
|
-
expect do
|
208
|
-
|
209
|
-
|
210
|
-
|
211
|
-
|
212
|
-
|
213
|
-
message: 'Accept header must not contain ranges ("*").'
|
214
|
-
)
|
197
|
+
expect { subject.call('HTTP_ACCEPT' => 'application/*').last }.to raise_exception do |exception|
|
198
|
+
expect(exception).to be_a(Grape::Exceptions::InvalidAcceptHeader)
|
199
|
+
expect(exception.headers).to eql('X-Cascade' => 'pass')
|
200
|
+
expect(exception.status).to eql 406
|
201
|
+
expect(exception.message).to include('Accept header must not contain ranges ("*").')
|
202
|
+
end
|
215
203
|
end
|
216
204
|
|
217
205
|
it 'succeeds if proper header is set' do
|
@@ -227,47 +215,39 @@ describe Grape::Middleware::Versioner::Header do
|
|
227
215
|
end
|
228
216
|
|
229
217
|
it 'fails with 406 Not Acceptable if header is not set' do
|
230
|
-
expect do
|
231
|
-
|
232
|
-
|
233
|
-
|
234
|
-
|
235
|
-
|
236
|
-
message: 'Accept header must be set.'
|
237
|
-
)
|
218
|
+
expect { subject.call({}).last }.to raise_exception do |exception|
|
219
|
+
expect(exception).to be_a(Grape::Exceptions::InvalidAcceptHeader)
|
220
|
+
expect(exception.headers).to eql({})
|
221
|
+
expect(exception.status).to eql 406
|
222
|
+
expect(exception.message).to include('Accept header must be set.')
|
223
|
+
end
|
238
224
|
end
|
239
225
|
|
240
226
|
it 'fails with 406 Not Acceptable if header is empty' do
|
241
|
-
expect do
|
242
|
-
|
243
|
-
|
244
|
-
|
245
|
-
|
246
|
-
|
247
|
-
message: 'Accept header must be set.'
|
248
|
-
)
|
227
|
+
expect { subject.call('HTTP_ACCEPT' => '').last }.to raise_exception do |exception|
|
228
|
+
expect(exception).to be_a(Grape::Exceptions::InvalidAcceptHeader)
|
229
|
+
expect(exception.headers).to eql({})
|
230
|
+
expect(exception.status).to eql 406
|
231
|
+
expect(exception.message).to include('Accept header must be set.')
|
232
|
+
end
|
249
233
|
end
|
250
234
|
|
251
235
|
it 'fails with 406 Not Acceptable if type is a range' do
|
252
|
-
expect do
|
253
|
-
|
254
|
-
|
255
|
-
|
256
|
-
|
257
|
-
|
258
|
-
message: 'Accept header must not contain ranges ("*").'
|
259
|
-
)
|
236
|
+
expect { subject.call('HTTP_ACCEPT' => '*/*').last }.to raise_exception do |exception|
|
237
|
+
expect(exception).to be_a(Grape::Exceptions::InvalidAcceptHeader)
|
238
|
+
expect(exception.headers).to eql({})
|
239
|
+
expect(exception.status).to eql 406
|
240
|
+
expect(exception.message).to include('Accept header must not contain ranges ("*").')
|
241
|
+
end
|
260
242
|
end
|
261
243
|
|
262
244
|
it 'fails with 406 Not Acceptable if subtype is a range' do
|
263
|
-
expect do
|
264
|
-
|
265
|
-
|
266
|
-
|
267
|
-
|
268
|
-
|
269
|
-
message: 'Accept header must not contain ranges ("*").'
|
270
|
-
)
|
245
|
+
expect { subject.call('HTTP_ACCEPT' => 'application/*').last }.to raise_exception do |exception|
|
246
|
+
expect(exception).to be_a(Grape::Exceptions::InvalidAcceptHeader)
|
247
|
+
expect(exception.headers).to eql({})
|
248
|
+
expect(exception.status).to eql 406
|
249
|
+
expect(exception.message).to include('Accept header must not contain ranges ("*").')
|
250
|
+
end
|
271
251
|
end
|
272
252
|
|
273
253
|
it 'succeeds if proper header is set' do
|
@@ -289,14 +269,12 @@ describe Grape::Middleware::Versioner::Header do
|
|
289
269
|
end
|
290
270
|
|
291
271
|
it 'fails with another version' do
|
292
|
-
expect do
|
293
|
-
|
294
|
-
|
295
|
-
|
296
|
-
|
297
|
-
|
298
|
-
message: 'API vendor or version not found.'
|
299
|
-
)
|
272
|
+
expect { subject.call('HTTP_ACCEPT' => 'application/vnd.vendor-v3+json') }.to raise_exception do |exception|
|
273
|
+
expect(exception).to be_a(Grape::Exceptions::InvalidAcceptHeader)
|
274
|
+
expect(exception.headers).to eql('X-Cascade' => 'pass')
|
275
|
+
expect(exception.status).to eql 406
|
276
|
+
expect(exception.message).to include('API vendor or version not found')
|
277
|
+
end
|
300
278
|
end
|
301
279
|
end
|
302
280
|
end
|