grape 0.14.0 → 0.15.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/CHANGELOG.md +32 -4
- data/Gemfile.lock +13 -13
- data/README.md +290 -12
- data/UPGRADING.md +68 -1
- data/gemfiles/rails_3.gemfile +1 -1
- data/lib/grape.rb +8 -2
- data/lib/grape/api.rb +40 -34
- data/lib/grape/dsl/configuration.rb +2 -115
- data/lib/grape/dsl/desc.rb +101 -0
- data/lib/grape/dsl/headers.rb +16 -0
- data/lib/grape/dsl/helpers.rb +5 -9
- data/lib/grape/dsl/inside_route.rb +3 -11
- data/lib/grape/dsl/logger.rb +20 -0
- data/lib/grape/dsl/parameters.rb +12 -10
- data/lib/grape/dsl/request_response.rb +17 -4
- data/lib/grape/dsl/routing.rb +24 -7
- data/lib/grape/dsl/settings.rb +8 -2
- data/lib/grape/endpoint.rb +30 -26
- data/lib/grape/error_formatter.rb +31 -0
- data/lib/grape/error_formatter/base.rb +0 -28
- data/lib/grape/error_formatter/json.rb +13 -2
- data/lib/grape/error_formatter/txt.rb +3 -1
- data/lib/grape/error_formatter/xml.rb +3 -1
- data/lib/grape/exceptions/base.rb +11 -4
- data/lib/grape/exceptions/incompatible_option_values.rb +1 -1
- data/lib/grape/exceptions/invalid_accept_header.rb +1 -1
- data/lib/grape/exceptions/invalid_formatter.rb +1 -1
- data/lib/grape/exceptions/invalid_message_body.rb +1 -1
- data/lib/grape/exceptions/invalid_version_header.rb +1 -1
- data/lib/grape/exceptions/invalid_versioner_option.rb +1 -1
- data/lib/grape/exceptions/invalid_with_option_for_represent.rb +1 -1
- data/lib/grape/exceptions/method_not_allowed.rb +10 -0
- data/lib/grape/exceptions/missing_group_type.rb +1 -1
- data/lib/grape/exceptions/missing_mime_type.rb +1 -1
- data/lib/grape/exceptions/missing_option.rb +1 -1
- data/lib/grape/exceptions/missing_vendor_option.rb +1 -1
- data/lib/grape/exceptions/unknown_options.rb +1 -1
- data/lib/grape/exceptions/unknown_parameter.rb +1 -1
- data/lib/grape/exceptions/unknown_validator.rb +1 -1
- data/lib/grape/exceptions/unsupported_group_type.rb +1 -1
- data/lib/grape/exceptions/validation.rb +2 -1
- data/lib/grape/formatter.rb +31 -0
- data/lib/grape/middleware/base.rb +28 -2
- data/lib/grape/middleware/error.rb +24 -1
- data/lib/grape/middleware/formatter.rb +4 -3
- data/lib/grape/middleware/versioner/param.rb +13 -2
- data/lib/grape/parser.rb +29 -0
- data/lib/grape/util/sendfile_response.rb +19 -0
- data/lib/grape/util/strict_hash_configuration.rb +1 -1
- data/lib/grape/validations/params_scope.rb +39 -9
- data/lib/grape/validations/types.rb +16 -0
- data/lib/grape/validations/validators/all_or_none.rb +1 -1
- data/lib/grape/validations/validators/allow_blank.rb +2 -2
- data/lib/grape/validations/validators/at_least_one_of.rb +1 -1
- data/lib/grape/validations/validators/base.rb +26 -0
- data/lib/grape/validations/validators/coerce.rb +16 -14
- data/lib/grape/validations/validators/default.rb +1 -1
- data/lib/grape/validations/validators/exactly_one_of.rb +10 -1
- data/lib/grape/validations/validators/mutual_exclusion.rb +1 -1
- data/lib/grape/validations/validators/presence.rb +1 -1
- data/lib/grape/validations/validators/regexp.rb +2 -2
- data/lib/grape/validations/validators/values.rb +2 -2
- data/lib/grape/version.rb +1 -1
- data/spec/grape/api/custom_validations_spec.rb +156 -21
- data/spec/grape/api/namespace_parameters_in_route_spec.rb +38 -0
- data/spec/grape/api/optional_parameters_in_route_spec.rb +43 -0
- data/spec/grape/api/required_parameters_in_route_spec.rb +37 -0
- data/spec/grape/api_spec.rb +118 -60
- data/spec/grape/dsl/configuration_spec.rb +0 -75
- data/spec/grape/dsl/desc_spec.rb +77 -0
- data/spec/grape/dsl/headers_spec.rb +32 -0
- data/spec/grape/dsl/inside_route_spec.rb +0 -18
- data/spec/grape/dsl/logger_spec.rb +26 -0
- data/spec/grape/dsl/parameters_spec.rb +13 -7
- data/spec/grape/dsl/request_response_spec.rb +17 -3
- data/spec/grape/dsl/routing_spec.rb +8 -1
- data/spec/grape/dsl/settings_spec.rb +42 -0
- data/spec/grape/endpoint_spec.rb +60 -9
- data/spec/grape/exceptions/validation_errors_spec.rb +2 -2
- data/spec/grape/exceptions/validation_spec.rb +7 -0
- data/spec/grape/integration/rack_sendfile_spec.rb +44 -0
- data/spec/grape/middleware/base_spec.rb +100 -0
- data/spec/grape/middleware/exception_spec.rb +1 -2
- data/spec/grape/middleware/formatter_spec.rb +12 -2
- data/spec/grape/middleware/versioner/accept_version_header_spec.rb +1 -1
- data/spec/grape/middleware/versioner/header_spec.rb +11 -1
- data/spec/grape/middleware/versioner/param_spec.rb +105 -1
- data/spec/grape/validations/params_scope_spec.rb +77 -0
- data/spec/grape/validations/validators/allow_blank_spec.rb +277 -0
- data/spec/grape/validations/validators/coerce_spec.rb +91 -0
- data/spec/grape/validations/validators/default_spec.rb +6 -0
- data/spec/grape/validations/validators/presence_spec.rb +27 -0
- data/spec/grape/validations/validators/regexp_spec.rb +36 -0
- data/spec/grape/validations/validators/values_spec.rb +44 -0
- data/spec/grape/validations_spec.rb +149 -4
- data/spec/spec_helper.rb +1 -0
- metadata +26 -5
- data/lib/grape/formatter/base.rb +0 -31
- data/lib/grape/parser/base.rb +0 -29
- data/pkg/grape-0.13.0.gem +0 -0
data/spec/grape/endpoint_spec.rb
CHANGED
@@ -10,19 +10,19 @@ describe Grape::Endpoint do
|
|
10
10
|
describe '.before_each' do
|
11
11
|
after { Grape::Endpoint.before_each(nil) }
|
12
12
|
|
13
|
-
it '
|
13
|
+
it 'is settable via block' do
|
14
14
|
block = ->(_endpoint) { 'noop' }
|
15
15
|
Grape::Endpoint.before_each(&block)
|
16
16
|
expect(Grape::Endpoint.before_each.first).to eq(block)
|
17
17
|
end
|
18
18
|
|
19
|
-
it '
|
19
|
+
it 'is settable via reference' do
|
20
20
|
block = ->(_endpoint) { 'noop' }
|
21
21
|
Grape::Endpoint.before_each block
|
22
22
|
expect(Grape::Endpoint.before_each.first).to eq(block)
|
23
23
|
end
|
24
24
|
|
25
|
-
it '
|
25
|
+
it 'is able to override a helper' do
|
26
26
|
subject.get('/') { current_user }
|
27
27
|
expect { get '/' }.to raise_error(NameError)
|
28
28
|
|
@@ -37,7 +37,7 @@ describe Grape::Endpoint do
|
|
37
37
|
expect { get '/' }.to raise_error(NameError)
|
38
38
|
end
|
39
39
|
|
40
|
-
it '
|
40
|
+
it 'is able to stack helper' do
|
41
41
|
subject.get('/') do
|
42
42
|
authenticate_user!
|
43
43
|
current_user
|
@@ -887,13 +887,64 @@ describe Grape::Endpoint do
|
|
887
887
|
expect(last_response.body).to eq('body')
|
888
888
|
end
|
889
889
|
end
|
890
|
+
|
891
|
+
it 'allows adding to response with present' do
|
892
|
+
subject.format :json
|
893
|
+
subject.before { present :before, 'before' }
|
894
|
+
subject.before_validation { present :before_validation, 'before_validation' }
|
895
|
+
subject.after_validation { present :after_validation, 'after_validation' }
|
896
|
+
subject.after { present :after, 'after' }
|
897
|
+
subject.get :all_filters do
|
898
|
+
present :endpoint, 'endpoint'
|
899
|
+
end
|
900
|
+
|
901
|
+
get '/all_filters'
|
902
|
+
json = JSON.parse(last_response.body)
|
903
|
+
expect(json.keys).to match_array %w(before before_validation after_validation endpoint after)
|
904
|
+
end
|
905
|
+
|
906
|
+
context 'when terminating the response with error!' do
|
907
|
+
it 'breaks normal call chain' do
|
908
|
+
called = []
|
909
|
+
subject.before { called << 'before' }
|
910
|
+
subject.before_validation { called << 'before_validation' }
|
911
|
+
subject.after_validation { error! :oops, 500 }
|
912
|
+
subject.after { called << 'after' }
|
913
|
+
subject.get :error_filters do
|
914
|
+
called << 'endpoint'
|
915
|
+
''
|
916
|
+
end
|
917
|
+
|
918
|
+
get '/error_filters'
|
919
|
+
expect(last_response.status).to eql 500
|
920
|
+
expect(called).to match_array %w(before before_validation)
|
921
|
+
end
|
922
|
+
|
923
|
+
it 'allows prior and parent filters of same type to run' do
|
924
|
+
called = []
|
925
|
+
subject.before { called << 'parent' }
|
926
|
+
subject.namespace :parent do
|
927
|
+
before { called << 'prior' }
|
928
|
+
before { error! :oops, 500 }
|
929
|
+
before { called << 'subsequent' }
|
930
|
+
get :hello do
|
931
|
+
called << :endpoint
|
932
|
+
'Hello!'
|
933
|
+
end
|
934
|
+
end
|
935
|
+
|
936
|
+
get '/parent/hello'
|
937
|
+
expect(last_response.status).to eql 500
|
938
|
+
expect(called).to match_array %w(parent prior)
|
939
|
+
end
|
940
|
+
end
|
890
941
|
end
|
891
942
|
|
892
943
|
context 'anchoring' do
|
893
944
|
verbs = %w(post get head delete put options patch)
|
894
945
|
|
895
946
|
verbs.each do |verb|
|
896
|
-
it
|
947
|
+
it "allows for the anchoring option with a #{verb.upcase} method" do
|
897
948
|
subject.send(verb, '/example', anchor: true) do
|
898
949
|
verb
|
899
950
|
end
|
@@ -901,7 +952,7 @@ describe Grape::Endpoint do
|
|
901
952
|
expect(last_response.status).to eql 404
|
902
953
|
end
|
903
954
|
|
904
|
-
it
|
955
|
+
it "anchors paths by default for the #{verb.upcase} method" do
|
905
956
|
subject.send(verb, '/example') do
|
906
957
|
verb
|
907
958
|
end
|
@@ -909,7 +960,7 @@ describe Grape::Endpoint do
|
|
909
960
|
expect(last_response.status).to eql 404
|
910
961
|
end
|
911
962
|
|
912
|
-
it
|
963
|
+
it "responds to /example/and/some/more for the non-anchored #{verb.upcase} method" do
|
913
964
|
subject.send(verb, '/example', anchor: false) do
|
914
965
|
verb
|
915
966
|
end
|
@@ -921,7 +972,7 @@ describe Grape::Endpoint do
|
|
921
972
|
end
|
922
973
|
|
923
974
|
context 'request' do
|
924
|
-
it '
|
975
|
+
it 'is set to the url requested' do
|
925
976
|
subject.get('/url') do
|
926
977
|
request.url
|
927
978
|
end
|
@@ -929,7 +980,7 @@ describe Grape::Endpoint do
|
|
929
980
|
expect(last_response.body).to eq('http://example.org/url')
|
930
981
|
end
|
931
982
|
['v1', :v1].each do |version|
|
932
|
-
it
|
983
|
+
it "should include version #{version}" do
|
933
984
|
subject.version version, using: :path
|
934
985
|
subject.get('/url') do
|
935
986
|
request.url
|
@@ -35,8 +35,8 @@ describe Grape::Exceptions::ValidationErrors do
|
|
35
35
|
|
36
36
|
describe '#full_messages' do
|
37
37
|
context 'with errors' do
|
38
|
-
let(:validation_error_1) { Grape::Exceptions::Validation.new(params: ['id'],
|
39
|
-
let(:validation_error_2) { Grape::Exceptions::Validation.new(params: ['name'],
|
38
|
+
let(:validation_error_1) { Grape::Exceptions::Validation.new(params: ['id'], message: :presence) }
|
39
|
+
let(:validation_error_2) { Grape::Exceptions::Validation.new(params: ['name'], message: :presence) }
|
40
40
|
subject { described_class.new(errors: [validation_error_1, validation_error_2]).full_messages }
|
41
41
|
|
42
42
|
it 'returns an array with each errors full message' do
|
@@ -0,0 +1,44 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Rack::Sendfile do
|
4
|
+
subject do
|
5
|
+
send_file = file_streamer
|
6
|
+
app = Class.new(Grape::API) do
|
7
|
+
use Rack::Sendfile
|
8
|
+
format :json
|
9
|
+
get do
|
10
|
+
file send_file
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
options = {
|
15
|
+
method: 'GET',
|
16
|
+
'HTTP_X_SENDFILE_TYPE' => 'X-Accel-Redirect',
|
17
|
+
'HTTP_X_ACCEL_MAPPING' => '/accel/mapping/=/replaced/'
|
18
|
+
}
|
19
|
+
env = Rack::MockRequest.env_for('/', options)
|
20
|
+
app.call(env)
|
21
|
+
end
|
22
|
+
|
23
|
+
context do
|
24
|
+
let(:file_streamer) do
|
25
|
+
double(:file_streamer, to_path: '/accel/mapping/some/path')
|
26
|
+
end
|
27
|
+
|
28
|
+
it 'contains Sendfile headers' do
|
29
|
+
headers = subject[1]
|
30
|
+
expect(headers).to include('X-Accel-Redirect')
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
context do
|
35
|
+
let(:file_streamer) do
|
36
|
+
double(:file_streamer)
|
37
|
+
end
|
38
|
+
|
39
|
+
it 'not contains Sendfile headers' do
|
40
|
+
headers = subject[1]
|
41
|
+
expect(headers).to_not include('X-Accel-Redirect')
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
@@ -29,6 +29,44 @@ describe Grape::Middleware::Base do
|
|
29
29
|
after { subject.call!({}) }
|
30
30
|
end
|
31
31
|
|
32
|
+
context 'callbacks on error' do
|
33
|
+
let(:blank_app) { ->(_) { fail StandardError } }
|
34
|
+
|
35
|
+
it 'calls #after' do
|
36
|
+
expect(subject).to receive(:after)
|
37
|
+
expect { subject.call({}) }.to raise_error(StandardError)
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
context 'after callback' do
|
42
|
+
before do
|
43
|
+
allow(subject).to receive(:after).and_return([200, {}, 'Hello from after callback'])
|
44
|
+
end
|
45
|
+
|
46
|
+
it 'overwrites application response' do
|
47
|
+
expect(subject.call!({}).last).to eq('Hello from after callback')
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
context 'after callback with errors' do
|
52
|
+
it 'does not overwrite the application response' do
|
53
|
+
expect(subject.call({})).to eq([200, {}, 'Hi there.'])
|
54
|
+
end
|
55
|
+
|
56
|
+
context 'with patched warnings' do
|
57
|
+
before do
|
58
|
+
@warnings = warnings = []
|
59
|
+
allow_any_instance_of(Grape::Middleware::Base).to receive(:warn) { |m| warnings << m }
|
60
|
+
allow(subject).to receive(:after).and_raise(StandardError)
|
61
|
+
end
|
62
|
+
|
63
|
+
it 'does show a warning' do
|
64
|
+
expect { subject.call({}) }.to raise_error(StandardError)
|
65
|
+
expect(@warnings).not_to be_empty
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
32
70
|
it 'is able to access the response' do
|
33
71
|
subject.call({})
|
34
72
|
expect(subject.response).to be_kind_of(Rack::Response)
|
@@ -99,4 +137,66 @@ describe Grape::Middleware::Base do
|
|
99
137
|
end
|
100
138
|
end
|
101
139
|
end
|
140
|
+
|
141
|
+
context 'header' do
|
142
|
+
module HeaderSpec
|
143
|
+
class ExampleWare < Grape::Middleware::Base
|
144
|
+
def before
|
145
|
+
header 'X-Test-Before', 'Hi'
|
146
|
+
end
|
147
|
+
|
148
|
+
def after
|
149
|
+
header 'X-Test-After', 'Bye'
|
150
|
+
nil
|
151
|
+
end
|
152
|
+
end
|
153
|
+
end
|
154
|
+
|
155
|
+
def app
|
156
|
+
Rack::Builder.app do
|
157
|
+
use HeaderSpec::ExampleWare
|
158
|
+
run ->(_) { [200, {}, ['Yeah']] }
|
159
|
+
end
|
160
|
+
end
|
161
|
+
|
162
|
+
it 'is able to set a header' do
|
163
|
+
get '/'
|
164
|
+
expect(last_response.headers['X-Test-Before']).to eq('Hi')
|
165
|
+
expect(last_response.headers['X-Test-After']).to eq('Bye')
|
166
|
+
end
|
167
|
+
end
|
168
|
+
|
169
|
+
context 'header overwrite' do
|
170
|
+
module HeaderOverwritingSpec
|
171
|
+
class ExampleWare < Grape::Middleware::Base
|
172
|
+
def before
|
173
|
+
header 'X-Test-Overwriting', 'Hi'
|
174
|
+
end
|
175
|
+
|
176
|
+
def after
|
177
|
+
header 'X-Test-Overwriting', 'Bye'
|
178
|
+
nil
|
179
|
+
end
|
180
|
+
end
|
181
|
+
|
182
|
+
class API < Grape::API
|
183
|
+
get('/') do
|
184
|
+
header 'X-Test-Overwriting', 'Yeah'
|
185
|
+
'Hello'
|
186
|
+
end
|
187
|
+
end
|
188
|
+
end
|
189
|
+
|
190
|
+
def app
|
191
|
+
Rack::Builder.app do
|
192
|
+
use HeaderOverwritingSpec::ExampleWare
|
193
|
+
run HeaderOverwritingSpec::API.new
|
194
|
+
end
|
195
|
+
end
|
196
|
+
|
197
|
+
it 'overwrites header by after headers' do
|
198
|
+
get '/'
|
199
|
+
expect(last_response.headers['X-Test-Overwriting']).to eq('Bye')
|
200
|
+
end
|
201
|
+
end
|
102
202
|
end
|
@@ -1,5 +1,4 @@
|
|
1
1
|
require 'spec_helper'
|
2
|
-
require 'active_support/core_ext/hash'
|
3
2
|
|
4
3
|
describe Grape::Middleware::Error do
|
5
4
|
# raises a text exception
|
@@ -59,7 +58,7 @@ describe Grape::Middleware::Error do
|
|
59
58
|
use Grape::Middleware::Error
|
60
59
|
run ExceptionSpec::ExceptionApp
|
61
60
|
end
|
62
|
-
expect { get '/' }.to raise_error
|
61
|
+
expect { get '/' }.to raise_error(RuntimeError, 'rain!')
|
63
62
|
end
|
64
63
|
|
65
64
|
context 'with rescue_all set to true' do
|
@@ -50,7 +50,7 @@ describe Grape::Middleware::Formatter do
|
|
50
50
|
context 'error handling' do
|
51
51
|
let(:formatter) { double(:formatter) }
|
52
52
|
before do
|
53
|
-
allow(Grape::Formatter
|
53
|
+
allow(Grape::Formatter).to receive(:formatter_for) { formatter }
|
54
54
|
end
|
55
55
|
|
56
56
|
it 'rescues formatter-specific exceptions' do
|
@@ -66,7 +66,7 @@ describe Grape::Middleware::Formatter do
|
|
66
66
|
|
67
67
|
expect do
|
68
68
|
catch(:error) { subject.call('PATH_INFO' => '/somewhere.xml', 'HTTP_ACCEPT' => 'application/json') }
|
69
|
-
end.to raise_error
|
69
|
+
end.to raise_error(StandardError)
|
70
70
|
end
|
71
71
|
end
|
72
72
|
|
@@ -282,4 +282,14 @@ describe Grape::Middleware::Formatter do
|
|
282
282
|
end
|
283
283
|
end
|
284
284
|
end
|
285
|
+
|
286
|
+
context 'send file' do
|
287
|
+
let(:app) { ->(_env) { [200, {}, @body] } }
|
288
|
+
|
289
|
+
it 'returns Grape::Uril::SendFileReponse' do
|
290
|
+
@body = Grape::Util::FileResponse.new('file')
|
291
|
+
env = { 'PATH_INFO' => '/somewhere', 'HTTP_ACCEPT' => 'application/json' }
|
292
|
+
expect(subject.call(env)).to be_a(Grape::Util::SendfileResponse)
|
293
|
+
end
|
294
|
+
end
|
285
295
|
end
|
@@ -85,7 +85,7 @@ describe Grape::Middleware::Versioner::AcceptVersionHeader do
|
|
85
85
|
end
|
86
86
|
end
|
87
87
|
|
88
|
-
context 'when :strict and :
|
88
|
+
context 'when :strict and cascade: false' do
|
89
89
|
before do
|
90
90
|
@options[:versions] = ['v1']
|
91
91
|
@options[:version_options][:strict] = true
|
@@ -189,7 +189,7 @@ describe Grape::Middleware::Versioner::Header do
|
|
189
189
|
end
|
190
190
|
end
|
191
191
|
|
192
|
-
context 'when :strict and :
|
192
|
+
context 'when :strict and cascade: false' do
|
193
193
|
before do
|
194
194
|
@options[:versions] = ['v1']
|
195
195
|
@options[:version_options][:strict] = true
|
@@ -224,6 +224,16 @@ describe Grape::Middleware::Versioner::Header do
|
|
224
224
|
end
|
225
225
|
end
|
226
226
|
|
227
|
+
it 'fails with 406 Not Acceptable if header contains a single invalid accept' do
|
228
|
+
expect { subject.call('HTTP_ACCEPT' => 'application/json;application/vnd.vendor-v1+json').first }
|
229
|
+
.to raise_exception do |exception|
|
230
|
+
expect(exception).to be_a(Grape::Exceptions::InvalidAcceptHeader)
|
231
|
+
expect(exception.headers).to eql({})
|
232
|
+
expect(exception.status).to eql 406
|
233
|
+
expect(exception.message).to include('API vendor or version not found.')
|
234
|
+
end
|
235
|
+
end
|
236
|
+
|
227
237
|
it 'succeeds if proper header is set' do
|
228
238
|
expect(subject.call('HTTP_ACCEPT' => 'application/vnd.vendor-v1+json').first).to eq(200)
|
229
239
|
end
|
@@ -22,7 +22,7 @@ describe Grape::Middleware::Versioner::Param do
|
|
22
22
|
end
|
23
23
|
|
24
24
|
context 'with specified parameter name' do
|
25
|
-
before { @options = { parameter: 'v' } }
|
25
|
+
before { @options = { version_options: { parameter: 'v' } } }
|
26
26
|
it 'sets the API version based on the custom parameter name' do
|
27
27
|
env = Rack::MockRequest.env_for('/awesome', params: { 'v' => 'v1' })
|
28
28
|
expect(subject.call(env)[1]['api.version']).to eq('v1')
|
@@ -53,4 +53,108 @@ describe Grape::Middleware::Versioner::Param do
|
|
53
53
|
env = Rack::MockRequest.env_for('/awesome', params: {})
|
54
54
|
expect(subject.call(env).first).to eq(200)
|
55
55
|
end
|
56
|
+
|
57
|
+
context 'when there are multiple versions without a custom param' do
|
58
|
+
subject { Class.new(Grape::API) }
|
59
|
+
|
60
|
+
let(:v1_app) do
|
61
|
+
Class.new(Grape::API) do
|
62
|
+
version 'v1', using: :param
|
63
|
+
content_type :v1_test, 'application/vnd.test.a-cool_resource-v1+json'
|
64
|
+
formatter :v1_test, ->(object, _) { object }
|
65
|
+
format :v1_test
|
66
|
+
|
67
|
+
resources :users do
|
68
|
+
get :hello do
|
69
|
+
'one'
|
70
|
+
end
|
71
|
+
end
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
75
|
+
let(:v2_app) do
|
76
|
+
Class.new(Grape::API) do
|
77
|
+
version 'v2', using: :param
|
78
|
+
content_type :v2_test, 'application/vnd.test.a-cool_resource-v2+json'
|
79
|
+
formatter :v2_test, ->(object, _) { object }
|
80
|
+
format :v2_test
|
81
|
+
|
82
|
+
resources :users do
|
83
|
+
get :hello do
|
84
|
+
'two'
|
85
|
+
end
|
86
|
+
end
|
87
|
+
end
|
88
|
+
end
|
89
|
+
|
90
|
+
def app
|
91
|
+
subject.mount v2_app
|
92
|
+
subject.mount v1_app
|
93
|
+
subject
|
94
|
+
end
|
95
|
+
|
96
|
+
it 'responds correctly to a v1 request' do
|
97
|
+
versioned_get '/users/hello', 'v1', using: :param, parameter: :apiver
|
98
|
+
expect(last_response.body).to eq('one')
|
99
|
+
expect(last_response.body).not_to include('API vendor or version not found')
|
100
|
+
end
|
101
|
+
|
102
|
+
it 'responds correctly to a v2 request' do
|
103
|
+
versioned_get '/users/hello', 'v2', using: :param, parameter: :apiver
|
104
|
+
expect(last_response.body).to eq('two')
|
105
|
+
expect(last_response.body).not_to include('API vendor or version not found')
|
106
|
+
end
|
107
|
+
end
|
108
|
+
|
109
|
+
context 'when there are multiple versions with a custom param' do
|
110
|
+
subject { Class.new(Grape::API) }
|
111
|
+
|
112
|
+
let(:v1_app) do
|
113
|
+
Class.new(Grape::API) do
|
114
|
+
version 'v1', using: :param, parameter: 'v'
|
115
|
+
content_type :v1_test, 'application/vnd.test.a-cool_resource-v1+json'
|
116
|
+
formatter :v1_test, ->(object, _) { object }
|
117
|
+
format :v1_test
|
118
|
+
|
119
|
+
resources :users do
|
120
|
+
get :hello do
|
121
|
+
'one'
|
122
|
+
end
|
123
|
+
end
|
124
|
+
end
|
125
|
+
end
|
126
|
+
|
127
|
+
let(:v2_app) do
|
128
|
+
Class.new(Grape::API) do
|
129
|
+
version 'v2', using: :param, parameter: 'v'
|
130
|
+
content_type :v2_test, 'application/vnd.test.a-cool_resource-v2+json'
|
131
|
+
formatter :v2_test, ->(object, _) { object }
|
132
|
+
format :v2_test
|
133
|
+
|
134
|
+
resources :users do
|
135
|
+
get :hello do
|
136
|
+
'two'
|
137
|
+
end
|
138
|
+
end
|
139
|
+
end
|
140
|
+
end
|
141
|
+
|
142
|
+
def app
|
143
|
+
subject.mount v2_app
|
144
|
+
subject.mount v1_app
|
145
|
+
subject
|
146
|
+
end
|
147
|
+
|
148
|
+
it 'responds correctly to a v1 request' do
|
149
|
+
versioned_get '/users/hello', 'v1', using: :param, parameter: 'v'
|
150
|
+
expect(last_response.body).to eq('one')
|
151
|
+
expect(last_response.body).not_to include('API vendor or version not found')
|
152
|
+
end
|
153
|
+
|
154
|
+
it 'responds correctly to a v2 request' do
|
155
|
+
versioned_get '/users/hello', 'v2', using: :param, parameter: 'v'
|
156
|
+
expect(last_response.body).to eq('two')
|
157
|
+
expect(last_response.body).not_to include('API vendor or version not found')
|
158
|
+
end
|
159
|
+
end
|
56
160
|
end
|