grape 1.7.1 → 2.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +37 -1
- data/CONTRIBUTING.md +1 -1
- data/README.md +30 -25
- data/UPGRADING.md +35 -0
- data/grape.gemspec +3 -6
- data/lib/grape/api.rb +2 -2
- data/lib/grape/content_types.rb +2 -8
- data/lib/grape/dsl/desc.rb +1 -1
- data/lib/grape/dsl/inside_route.rb +11 -11
- data/lib/grape/dsl/request_response.rb +2 -1
- data/lib/grape/dsl/settings.rb +2 -6
- data/lib/grape/endpoint.rb +28 -18
- data/lib/grape/error_formatter/base.rb +1 -1
- data/lib/grape/exceptions/base.rb +2 -2
- data/lib/grape/exceptions/missing_group_type.rb +1 -6
- data/lib/grape/exceptions/unsupported_group_type.rb +1 -6
- data/lib/grape/exceptions/validation_errors.rb +1 -6
- data/lib/grape/extensions/active_support/hash_with_indifferent_access.rb +3 -3
- data/lib/grape/extensions/hash.rb +4 -7
- data/lib/grape/extensions/hashie/mash.rb +3 -3
- data/lib/grape/formatter/serializable_hash.rb +7 -7
- data/lib/grape/http/headers.rb +12 -2
- data/lib/grape/middleware/auth/base.rb +1 -1
- data/lib/grape/middleware/auth/strategies.rb +1 -2
- data/lib/grape/middleware/error.rb +5 -5
- data/lib/grape/middleware/formatter.rb +6 -6
- data/lib/grape/middleware/versioner/header.rb +11 -19
- data/lib/grape/railtie.rb +9 -0
- data/lib/grape/request.rb +8 -2
- data/lib/grape/router/route.rb +1 -3
- data/lib/grape/util/lazy_value.rb +3 -11
- data/lib/grape/util/strict_hash_configuration.rb +3 -4
- data/lib/grape/validations/multiple_attributes_iterator.rb +1 -1
- data/lib/grape/validations/params_scope.rb +8 -2
- data/lib/grape/validations/single_attribute_iterator.rb +3 -1
- data/lib/grape/validations/types/custom_type_coercer.rb +2 -16
- data/lib/grape/validations/validators/base.rb +9 -20
- data/lib/grape/validations/validators/default_validator.rb +2 -20
- data/lib/grape/validations/validators/multiple_params_base.rb +4 -8
- data/lib/grape/validations/validators/values_validator.rb +14 -5
- data/lib/grape/version.rb +1 -1
- data/lib/grape.rb +26 -5
- metadata +13 -253
- data/lib/grape/config.rb +0 -34
- data/lib/grape/extensions/deep_mergeable_hash.rb +0 -21
- data/lib/grape/extensions/deep_symbolize_hash.rb +0 -32
- data/spec/grape/api/custom_validations_spec.rb +0 -256
- data/spec/grape/api/deeply_included_options_spec.rb +0 -56
- data/spec/grape/api/defines_boolean_in_params_spec.rb +0 -38
- data/spec/grape/api/documentation_spec.rb +0 -59
- data/spec/grape/api/inherited_helpers_spec.rb +0 -114
- data/spec/grape/api/instance_spec.rb +0 -103
- data/spec/grape/api/invalid_format_spec.rb +0 -45
- data/spec/grape/api/namespace_parameters_in_route_spec.rb +0 -38
- data/spec/grape/api/nested_helpers_spec.rb +0 -50
- data/spec/grape/api/optional_parameters_in_route_spec.rb +0 -43
- data/spec/grape/api/parameters_modification_spec.rb +0 -41
- data/spec/grape/api/patch_method_helpers_spec.rb +0 -79
- data/spec/grape/api/recognize_path_spec.rb +0 -21
- data/spec/grape/api/required_parameters_in_route_spec.rb +0 -37
- data/spec/grape/api/required_parameters_with_invalid_method_spec.rb +0 -26
- data/spec/grape/api/routes_with_requirements_spec.rb +0 -59
- data/spec/grape/api/shared_helpers_exactly_one_of_spec.rb +0 -41
- data/spec/grape/api/shared_helpers_spec.rb +0 -36
- data/spec/grape/api_remount_spec.rb +0 -473
- data/spec/grape/api_spec.rb +0 -4347
- data/spec/grape/config_spec.rb +0 -17
- data/spec/grape/dsl/callbacks_spec.rb +0 -45
- data/spec/grape/dsl/desc_spec.rb +0 -101
- data/spec/grape/dsl/headers_spec.rb +0 -62
- data/spec/grape/dsl/helpers_spec.rb +0 -100
- data/spec/grape/dsl/inside_route_spec.rb +0 -535
- data/spec/grape/dsl/logger_spec.rb +0 -24
- data/spec/grape/dsl/middleware_spec.rb +0 -60
- data/spec/grape/dsl/parameters_spec.rb +0 -180
- data/spec/grape/dsl/request_response_spec.rb +0 -206
- data/spec/grape/dsl/routing_spec.rb +0 -275
- data/spec/grape/dsl/settings_spec.rb +0 -261
- data/spec/grape/dsl/validations_spec.rb +0 -55
- data/spec/grape/endpoint/declared_spec.rb +0 -846
- data/spec/grape/endpoint_spec.rb +0 -1085
- data/spec/grape/entity_spec.rb +0 -336
- data/spec/grape/exceptions/base_spec.rb +0 -81
- data/spec/grape/exceptions/body_parse_errors_spec.rb +0 -145
- data/spec/grape/exceptions/invalid_accept_header_spec.rb +0 -358
- data/spec/grape/exceptions/invalid_formatter_spec.rb +0 -15
- data/spec/grape/exceptions/invalid_response_spec.rb +0 -11
- data/spec/grape/exceptions/invalid_versioner_option_spec.rb +0 -15
- data/spec/grape/exceptions/missing_group_type_spec.rb +0 -21
- data/spec/grape/exceptions/missing_mime_type_spec.rb +0 -17
- data/spec/grape/exceptions/missing_option_spec.rb +0 -15
- data/spec/grape/exceptions/unknown_options_spec.rb +0 -15
- data/spec/grape/exceptions/unknown_validator_spec.rb +0 -15
- data/spec/grape/exceptions/unsupported_group_type_spec.rb +0 -23
- data/spec/grape/exceptions/validation_errors_spec.rb +0 -92
- data/spec/grape/exceptions/validation_spec.rb +0 -19
- data/spec/grape/extensions/param_builders/hash_spec.rb +0 -83
- data/spec/grape/extensions/param_builders/hash_with_indifferent_access_spec.rb +0 -105
- data/spec/grape/extensions/param_builders/hashie/mash_spec.rb +0 -79
- data/spec/grape/integration/global_namespace_function_spec.rb +0 -29
- data/spec/grape/integration/rack_sendfile_spec.rb +0 -48
- data/spec/grape/integration/rack_spec.rb +0 -51
- data/spec/grape/loading_spec.rb +0 -44
- data/spec/grape/middleware/auth/base_spec.rb +0 -31
- data/spec/grape/middleware/auth/dsl_spec.rb +0 -60
- data/spec/grape/middleware/auth/strategies_spec.rb +0 -120
- data/spec/grape/middleware/base_spec.rb +0 -221
- data/spec/grape/middleware/error_spec.rb +0 -85
- data/spec/grape/middleware/exception_spec.rb +0 -294
- data/spec/grape/middleware/formatter_spec.rb +0 -461
- data/spec/grape/middleware/globals_spec.rb +0 -30
- data/spec/grape/middleware/stack_spec.rb +0 -155
- data/spec/grape/middleware/versioner/accept_version_header_spec.rb +0 -122
- data/spec/grape/middleware/versioner/header_spec.rb +0 -345
- data/spec/grape/middleware/versioner/param_spec.rb +0 -171
- data/spec/grape/middleware/versioner/path_spec.rb +0 -62
- data/spec/grape/middleware/versioner_spec.rb +0 -21
- data/spec/grape/named_api_spec.rb +0 -19
- data/spec/grape/parser_spec.rb +0 -86
- data/spec/grape/path_spec.rb +0 -252
- data/spec/grape/presenters/presenter_spec.rb +0 -71
- data/spec/grape/request_spec.rb +0 -136
- data/spec/grape/util/inheritable_setting_spec.rb +0 -242
- data/spec/grape/util/inheritable_values_spec.rb +0 -79
- data/spec/grape/util/reverse_stackable_values_spec.rb +0 -134
- data/spec/grape/util/stackable_values_spec.rb +0 -128
- data/spec/grape/util/strict_hash_configuration_spec.rb +0 -38
- data/spec/grape/validations/attributes_doc_spec.rb +0 -153
- data/spec/grape/validations/instance_behaivour_spec.rb +0 -43
- data/spec/grape/validations/multiple_attributes_iterator_spec.rb +0 -40
- data/spec/grape/validations/params_scope_spec.rb +0 -1420
- data/spec/grape/validations/single_attribute_iterator_spec.rb +0 -57
- data/spec/grape/validations/types/array_coercer_spec.rb +0 -33
- data/spec/grape/validations/types/primitive_coercer_spec.rb +0 -150
- data/spec/grape/validations/types/set_coercer_spec.rb +0 -32
- data/spec/grape/validations/types_spec.rb +0 -111
- data/spec/grape/validations/validators/all_or_none_spec.rb +0 -162
- data/spec/grape/validations/validators/allow_blank_spec.rb +0 -575
- data/spec/grape/validations/validators/at_least_one_of_spec.rb +0 -205
- data/spec/grape/validations/validators/coerce_spec.rb +0 -1261
- data/spec/grape/validations/validators/default_spec.rb +0 -463
- data/spec/grape/validations/validators/exactly_one_of_spec.rb +0 -233
- data/spec/grape/validations/validators/except_values_spec.rb +0 -192
- data/spec/grape/validations/validators/mutual_exclusion_spec.rb +0 -214
- data/spec/grape/validations/validators/presence_spec.rb +0 -315
- data/spec/grape/validations/validators/regexp_spec.rb +0 -161
- data/spec/grape/validations/validators/same_as_spec.rb +0 -57
- data/spec/grape/validations/validators/values_spec.rb +0 -696
- data/spec/grape/validations/validators/zh-CN.yml +0 -10
- data/spec/grape/validations_spec.rb +0 -2029
- data/spec/integration/eager_load/eager_load_spec.rb +0 -15
- data/spec/integration/multi_json/json_spec.rb +0 -7
- data/spec/integration/multi_xml/xml_spec.rb +0 -7
- data/spec/shared/versioning_examples.rb +0 -215
- data/spec/spec_helper.rb +0 -52
- data/spec/support/basic_auth_encode_helpers.rb +0 -11
- data/spec/support/chunks.rb +0 -14
- data/spec/support/content_type_helpers.rb +0 -15
- data/spec/support/endpoint_faker.rb +0 -25
- data/spec/support/file_streamer.rb +0 -13
- data/spec/support/integer_helpers.rb +0 -13
- data/spec/support/versioned_helpers.rb +0 -55
@@ -1,37 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
describe Grape::Endpoint do
|
4
|
-
subject { Class.new(Grape::API) }
|
5
|
-
|
6
|
-
def app
|
7
|
-
subject
|
8
|
-
end
|
9
|
-
|
10
|
-
before do
|
11
|
-
subject.namespace :api do
|
12
|
-
get ':id' do
|
13
|
-
[params[:id], params[:ext]].compact.join('/')
|
14
|
-
end
|
15
|
-
|
16
|
-
put ':something_id' do
|
17
|
-
params[:something_id]
|
18
|
-
end
|
19
|
-
end
|
20
|
-
end
|
21
|
-
|
22
|
-
context 'get' do
|
23
|
-
it 'responds' do
|
24
|
-
get '/api/foo'
|
25
|
-
expect(last_response.status).to eq 200
|
26
|
-
expect(last_response.body).to eq 'foo'
|
27
|
-
end
|
28
|
-
end
|
29
|
-
|
30
|
-
context 'put' do
|
31
|
-
it 'responds' do
|
32
|
-
put '/api/foo'
|
33
|
-
expect(last_response.status).to eq 200
|
34
|
-
expect(last_response.body).to eq 'foo'
|
35
|
-
end
|
36
|
-
end
|
37
|
-
end
|
@@ -1,26 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
describe Grape::Endpoint do
|
4
|
-
subject { Class.new(Grape::API) }
|
5
|
-
|
6
|
-
def app
|
7
|
-
subject
|
8
|
-
end
|
9
|
-
|
10
|
-
before do
|
11
|
-
subject.namespace do
|
12
|
-
params do
|
13
|
-
requires :id, desc: 'Identifier.'
|
14
|
-
end
|
15
|
-
get ':id' do
|
16
|
-
end
|
17
|
-
end
|
18
|
-
end
|
19
|
-
|
20
|
-
context 'post' do
|
21
|
-
it '405' do
|
22
|
-
post '/something'
|
23
|
-
expect(last_response.status).to eq 405
|
24
|
-
end
|
25
|
-
end
|
26
|
-
end
|
@@ -1,59 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
describe Grape::Endpoint do
|
4
|
-
subject { Class.new(Grape::API) }
|
5
|
-
|
6
|
-
def app
|
7
|
-
subject
|
8
|
-
end
|
9
|
-
|
10
|
-
context 'get' do
|
11
|
-
it 'routes to a namespace param with dots' do
|
12
|
-
subject.namespace ':ns_with_dots', requirements: { ns_with_dots: %r{[^/]+} } do
|
13
|
-
get '/' do
|
14
|
-
params[:ns_with_dots]
|
15
|
-
end
|
16
|
-
end
|
17
|
-
|
18
|
-
get '/test.id.with.dots'
|
19
|
-
expect(last_response.status).to eq 200
|
20
|
-
expect(last_response.body).to eq 'test.id.with.dots'
|
21
|
-
end
|
22
|
-
|
23
|
-
it 'routes to a path with multiple params with dots' do
|
24
|
-
subject.get ':id_with_dots/:another_id_with_dots', requirements: { id_with_dots: %r{[^/]+},
|
25
|
-
another_id_with_dots: %r{[^/]+} } do
|
26
|
-
"#{params[:id_with_dots]}/#{params[:another_id_with_dots]}"
|
27
|
-
end
|
28
|
-
|
29
|
-
get '/test.id/test2.id'
|
30
|
-
expect(last_response.status).to eq 200
|
31
|
-
expect(last_response.body).to eq 'test.id/test2.id'
|
32
|
-
end
|
33
|
-
|
34
|
-
it 'routes to namespace and path params with dots, with overridden requirements' do
|
35
|
-
subject.namespace ':ns_with_dots', requirements: { ns_with_dots: %r{[^/]+} } do
|
36
|
-
get ':another_id_with_dots', requirements: { ns_with_dots: %r{[^/]+},
|
37
|
-
another_id_with_dots: %r{[^/]+} } do
|
38
|
-
"#{params[:ns_with_dots]}/#{params[:another_id_with_dots]}"
|
39
|
-
end
|
40
|
-
end
|
41
|
-
|
42
|
-
get '/test.id/test2.id'
|
43
|
-
expect(last_response.status).to eq 200
|
44
|
-
expect(last_response.body).to eq 'test.id/test2.id'
|
45
|
-
end
|
46
|
-
|
47
|
-
it 'routes to namespace and path params with dots, with merged requirements' do
|
48
|
-
subject.namespace ':ns_with_dots', requirements: { ns_with_dots: %r{[^/]+} } do
|
49
|
-
get ':another_id_with_dots', requirements: { another_id_with_dots: %r{[^/]+} } do
|
50
|
-
"#{params[:ns_with_dots]}/#{params[:another_id_with_dots]}"
|
51
|
-
end
|
52
|
-
end
|
53
|
-
|
54
|
-
get '/test.id/test2.id'
|
55
|
-
expect(last_response.status).to eq 200
|
56
|
-
expect(last_response.body).to eq 'test.id/test2.id'
|
57
|
-
end
|
58
|
-
end
|
59
|
-
end
|
@@ -1,41 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
describe Grape::API::Helpers do
|
4
|
-
let(:app) do
|
5
|
-
Class.new(Grape::API) do
|
6
|
-
helpers Module.new do
|
7
|
-
extend Grape::API::Helpers
|
8
|
-
|
9
|
-
params :drink do
|
10
|
-
optional :beer
|
11
|
-
optional :wine
|
12
|
-
exactly_one_of :beer, :wine
|
13
|
-
end
|
14
|
-
end
|
15
|
-
format :json
|
16
|
-
|
17
|
-
params do
|
18
|
-
requires :orderType, type: String, values: %w[food drink]
|
19
|
-
given orderType: ->(val) { val == 'food' } do
|
20
|
-
optional :pasta
|
21
|
-
optional :pizza
|
22
|
-
exactly_one_of :pasta, :pizza
|
23
|
-
end
|
24
|
-
given orderType: ->(val) { val == 'drink' } do
|
25
|
-
use :drink
|
26
|
-
end
|
27
|
-
end
|
28
|
-
get do
|
29
|
-
declared(params, include_missing: true)
|
30
|
-
end
|
31
|
-
end
|
32
|
-
end
|
33
|
-
|
34
|
-
it 'defines parameters' do
|
35
|
-
get '/', orderType: 'food', pizza: 'mista'
|
36
|
-
expect(last_response.status).to eq 200
|
37
|
-
expect(last_response.body).to eq({ orderType: 'food',
|
38
|
-
pasta: nil, pizza: 'mista',
|
39
|
-
beer: nil, wine: nil }.to_json)
|
40
|
-
end
|
41
|
-
end
|
@@ -1,36 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
describe Grape::API::Helpers do
|
4
|
-
subject do
|
5
|
-
shared_params = Module.new do
|
6
|
-
extend Grape::API::Helpers
|
7
|
-
|
8
|
-
params :pagination do
|
9
|
-
optional :page, type: Integer
|
10
|
-
optional :size, type: Integer
|
11
|
-
end
|
12
|
-
end
|
13
|
-
|
14
|
-
Class.new(Grape::API) do
|
15
|
-
helpers shared_params
|
16
|
-
format :json
|
17
|
-
|
18
|
-
params do
|
19
|
-
use :pagination
|
20
|
-
end
|
21
|
-
get do
|
22
|
-
declared(params, include_missing: true)
|
23
|
-
end
|
24
|
-
end
|
25
|
-
end
|
26
|
-
|
27
|
-
def app
|
28
|
-
subject
|
29
|
-
end
|
30
|
-
|
31
|
-
it 'defines parameters' do
|
32
|
-
get '/'
|
33
|
-
expect(last_response.status).to eq 200
|
34
|
-
expect(last_response.body).to eq({ page: nil, size: nil }.to_json)
|
35
|
-
end
|
36
|
-
end
|
@@ -1,473 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
require 'shared/versioning_examples'
|
4
|
-
|
5
|
-
describe Grape::API do
|
6
|
-
subject(:a_remounted_api) { Class.new(described_class) }
|
7
|
-
|
8
|
-
let(:root_api) { Class.new(described_class) }
|
9
|
-
|
10
|
-
def app
|
11
|
-
root_api
|
12
|
-
end
|
13
|
-
|
14
|
-
describe 'remounting an API' do
|
15
|
-
context 'with a defined route' do
|
16
|
-
before do
|
17
|
-
a_remounted_api.get '/votes' do
|
18
|
-
'10 votes'
|
19
|
-
end
|
20
|
-
end
|
21
|
-
|
22
|
-
context 'when mounting one instance' do
|
23
|
-
before do
|
24
|
-
root_api.mount a_remounted_api
|
25
|
-
end
|
26
|
-
|
27
|
-
it 'can access the endpoint' do
|
28
|
-
get '/votes'
|
29
|
-
expect(last_response.body).to eql '10 votes'
|
30
|
-
end
|
31
|
-
end
|
32
|
-
|
33
|
-
context 'when mounting twice' do
|
34
|
-
before do
|
35
|
-
root_api.mount a_remounted_api => '/posts'
|
36
|
-
root_api.mount a_remounted_api => '/comments'
|
37
|
-
end
|
38
|
-
|
39
|
-
it 'can access the votes in both places' do
|
40
|
-
get '/posts/votes'
|
41
|
-
expect(last_response.body).to eql '10 votes'
|
42
|
-
get '/comments/votes'
|
43
|
-
expect(last_response.body).to eql '10 votes'
|
44
|
-
end
|
45
|
-
end
|
46
|
-
|
47
|
-
context 'when mounting on namespace' do
|
48
|
-
before do
|
49
|
-
stub_const('StaticRefToAPI', a_remounted_api)
|
50
|
-
root_api.namespace 'posts' do
|
51
|
-
mount StaticRefToAPI
|
52
|
-
end
|
53
|
-
|
54
|
-
root_api.namespace 'comments' do
|
55
|
-
mount StaticRefToAPI
|
56
|
-
end
|
57
|
-
end
|
58
|
-
|
59
|
-
it 'can access the votes in both places' do
|
60
|
-
get '/posts/votes'
|
61
|
-
expect(last_response.body).to eql '10 votes'
|
62
|
-
get '/comments/votes'
|
63
|
-
expect(last_response.body).to eql '10 votes'
|
64
|
-
end
|
65
|
-
end
|
66
|
-
end
|
67
|
-
|
68
|
-
describe 'with dynamic configuration' do
|
69
|
-
context 'when mounting an endpoint conditional on a configuration' do
|
70
|
-
subject(:a_remounted_api) do
|
71
|
-
Class.new(described_class) do
|
72
|
-
get 'always' do
|
73
|
-
'success'
|
74
|
-
end
|
75
|
-
|
76
|
-
given configuration[:mount_sometimes] do
|
77
|
-
get 'sometimes' do
|
78
|
-
'sometimes'
|
79
|
-
end
|
80
|
-
end
|
81
|
-
end
|
82
|
-
end
|
83
|
-
|
84
|
-
it 'mounts the endpoints only when configured to do so' do
|
85
|
-
root_api.mount({ a_remounted_api => 'with_conditional' }, with: { mount_sometimes: true })
|
86
|
-
root_api.mount({ a_remounted_api => 'without_conditional' }, with: { mount_sometimes: false })
|
87
|
-
|
88
|
-
get '/with_conditional/always'
|
89
|
-
expect(last_response.body).to eq 'success'
|
90
|
-
|
91
|
-
get '/with_conditional/sometimes'
|
92
|
-
expect(last_response.body).to eq 'sometimes'
|
93
|
-
|
94
|
-
get '/without_conditional/always'
|
95
|
-
expect(last_response.body).to eq 'success'
|
96
|
-
|
97
|
-
get '/without_conditional/sometimes'
|
98
|
-
expect(last_response.status).to eq 404
|
99
|
-
end
|
100
|
-
end
|
101
|
-
|
102
|
-
context 'when using an expression derived from a configuration' do
|
103
|
-
subject(:a_remounted_api) do
|
104
|
-
Class.new(described_class) do
|
105
|
-
get(mounted { "api_name_#{configuration[:api_name]}" }) do
|
106
|
-
'success'
|
107
|
-
end
|
108
|
-
end
|
109
|
-
end
|
110
|
-
|
111
|
-
before do
|
112
|
-
root_api.mount a_remounted_api, with: {
|
113
|
-
api_name: 'a_name'
|
114
|
-
}
|
115
|
-
end
|
116
|
-
|
117
|
-
it 'mounts the endpoint with the name' do
|
118
|
-
get 'api_name_a_name'
|
119
|
-
expect(last_response.body).to eq 'success'
|
120
|
-
end
|
121
|
-
|
122
|
-
it 'does not mount the endpoint with a null name' do
|
123
|
-
get 'api_name_'
|
124
|
-
expect(last_response.body).not_to eq 'success'
|
125
|
-
end
|
126
|
-
|
127
|
-
context 'when the expression lives in a namespace' do
|
128
|
-
subject(:a_remounted_api) do
|
129
|
-
Class.new(described_class) do
|
130
|
-
namespace :base do
|
131
|
-
get(mounted { "api_name_#{configuration[:api_name]}" }) do
|
132
|
-
'success'
|
133
|
-
end
|
134
|
-
end
|
135
|
-
end
|
136
|
-
end
|
137
|
-
|
138
|
-
it 'mounts the endpoint with the name' do
|
139
|
-
get 'base/api_name_a_name'
|
140
|
-
expect(last_response.body).to eq 'success'
|
141
|
-
end
|
142
|
-
|
143
|
-
it 'does not mount the endpoint with a null name' do
|
144
|
-
get 'base/api_name_'
|
145
|
-
expect(last_response.body).not_to eq 'success'
|
146
|
-
end
|
147
|
-
end
|
148
|
-
end
|
149
|
-
|
150
|
-
context 'when executing a standard block within a `mounted` block with all dynamic params' do
|
151
|
-
subject(:a_remounted_api) do
|
152
|
-
Class.new(described_class) do
|
153
|
-
mounted do
|
154
|
-
desc configuration[:description] do
|
155
|
-
headers configuration[:headers]
|
156
|
-
end
|
157
|
-
get configuration[:endpoint] do
|
158
|
-
configuration[:response]
|
159
|
-
end
|
160
|
-
end
|
161
|
-
end
|
162
|
-
end
|
163
|
-
|
164
|
-
let(:api_endpoint) { 'custom_endpoint' }
|
165
|
-
let(:api_response) { 'custom response' }
|
166
|
-
let(:endpoint_description) { 'this is a custom API' }
|
167
|
-
let(:headers) do
|
168
|
-
{
|
169
|
-
'XAuthToken' => {
|
170
|
-
'description' => 'Validates your identity',
|
171
|
-
'required' => true
|
172
|
-
}
|
173
|
-
}
|
174
|
-
end
|
175
|
-
|
176
|
-
it 'mounts the API and obtains the description and headers definition' do
|
177
|
-
root_api.mount a_remounted_api, with: {
|
178
|
-
description: endpoint_description,
|
179
|
-
headers: headers,
|
180
|
-
endpoint: api_endpoint,
|
181
|
-
response: api_response
|
182
|
-
}
|
183
|
-
get api_endpoint
|
184
|
-
expect(last_response.body).to eq api_response
|
185
|
-
expect(a_remounted_api.instances.last.endpoints.first.options[:route_options][:description])
|
186
|
-
.to eq endpoint_description
|
187
|
-
expect(a_remounted_api.instances.last.endpoints.first.options[:route_options][:headers])
|
188
|
-
.to eq headers
|
189
|
-
end
|
190
|
-
end
|
191
|
-
|
192
|
-
context 'when executing a custom block on mount' do
|
193
|
-
subject(:a_remounted_api) do
|
194
|
-
Class.new(described_class) do
|
195
|
-
get 'always' do
|
196
|
-
'success'
|
197
|
-
end
|
198
|
-
|
199
|
-
mounted do
|
200
|
-
configuration[:endpoints].each do |endpoint_name, endpoint_response|
|
201
|
-
get endpoint_name do
|
202
|
-
endpoint_response
|
203
|
-
end
|
204
|
-
end
|
205
|
-
end
|
206
|
-
end
|
207
|
-
end
|
208
|
-
|
209
|
-
it 'mounts the endpoints only when configured to do so' do
|
210
|
-
root_api.mount a_remounted_api, with: { endpoints: { 'api_name' => 'api_response' } }
|
211
|
-
get 'api_name'
|
212
|
-
expect(last_response.body).to eq 'api_response'
|
213
|
-
end
|
214
|
-
end
|
215
|
-
|
216
|
-
context 'when the configuration is part of the arguments of a method' do
|
217
|
-
subject(:a_remounted_api) do
|
218
|
-
Class.new(described_class) do
|
219
|
-
get configuration[:endpoint_name] do
|
220
|
-
'success'
|
221
|
-
end
|
222
|
-
end
|
223
|
-
end
|
224
|
-
|
225
|
-
it 'mounts the endpoint in the location it is configured' do
|
226
|
-
root_api.mount a_remounted_api, with: { endpoint_name: 'some_location' }
|
227
|
-
get '/some_location'
|
228
|
-
expect(last_response.body).to eq 'success'
|
229
|
-
|
230
|
-
get '/different_location'
|
231
|
-
expect(last_response.status).to eq 404
|
232
|
-
|
233
|
-
root_api.mount a_remounted_api, with: { endpoint_name: 'new_location' }
|
234
|
-
get '/new_location'
|
235
|
-
expect(last_response.body).to eq 'success'
|
236
|
-
end
|
237
|
-
|
238
|
-
context 'when the configuration is the value in a key-arg pair' do
|
239
|
-
subject(:a_remounted_api) do
|
240
|
-
Class.new(described_class) do
|
241
|
-
version 'v1', using: :param, parameter: configuration[:version_param]
|
242
|
-
get 'endpoint' do
|
243
|
-
'version 1'
|
244
|
-
end
|
245
|
-
|
246
|
-
version 'v2', using: :param, parameter: configuration[:version_param]
|
247
|
-
get 'endpoint' do
|
248
|
-
'version 2'
|
249
|
-
end
|
250
|
-
end
|
251
|
-
end
|
252
|
-
|
253
|
-
it 'takes the param from the configuration' do
|
254
|
-
root_api.mount a_remounted_api, with: { version_param: 'param_name' }
|
255
|
-
|
256
|
-
get '/endpoint?param_name=v1'
|
257
|
-
expect(last_response.body).to eq 'version 1'
|
258
|
-
|
259
|
-
get '/endpoint?param_name=v2'
|
260
|
-
expect(last_response.body).to eq 'version 2'
|
261
|
-
|
262
|
-
get '/endpoint?wrong_param_name=v2'
|
263
|
-
expect(last_response.body).to eq 'version 1'
|
264
|
-
end
|
265
|
-
end
|
266
|
-
end
|
267
|
-
|
268
|
-
context 'on the DescSCope' do
|
269
|
-
subject(:a_remounted_api) do
|
270
|
-
Class.new(described_class) do
|
271
|
-
desc 'The description of this' do
|
272
|
-
tags ['not_configurable_tag', configuration[:a_configurable_tag]]
|
273
|
-
end
|
274
|
-
get 'location' do
|
275
|
-
'success'
|
276
|
-
end
|
277
|
-
end
|
278
|
-
end
|
279
|
-
|
280
|
-
it 'mounts the endpoint with the appropiate tags' do
|
281
|
-
root_api.mount({ a_remounted_api => 'integer' }, with: { a_configurable_tag: 'a configured tag' })
|
282
|
-
end
|
283
|
-
end
|
284
|
-
|
285
|
-
context 'on the ParamScope' do
|
286
|
-
subject(:a_remounted_api) do
|
287
|
-
Class.new(described_class) do
|
288
|
-
params do
|
289
|
-
requires configuration[:required_param], type: configuration[:required_type]
|
290
|
-
end
|
291
|
-
|
292
|
-
get 'location' do
|
293
|
-
'success'
|
294
|
-
end
|
295
|
-
end
|
296
|
-
end
|
297
|
-
|
298
|
-
it 'mounts the endpoint in the location it is configured' do
|
299
|
-
root_api.mount({ a_remounted_api => 'string' }, with: { required_param: 'param_key', required_type: String })
|
300
|
-
root_api.mount({ a_remounted_api => 'integer' }, with: { required_param: 'param_integer', required_type: Integer })
|
301
|
-
|
302
|
-
get '/string/location', param_key: 'a'
|
303
|
-
expect(last_response.body).to eq 'success'
|
304
|
-
|
305
|
-
get '/string/location', param_integer: 1
|
306
|
-
expect(last_response.status).to eq 400
|
307
|
-
|
308
|
-
get '/integer/location', param_integer: 1
|
309
|
-
expect(last_response.body).to eq 'success'
|
310
|
-
|
311
|
-
get '/integer/location', param_integer: 'a'
|
312
|
-
expect(last_response.status).to eq 400
|
313
|
-
end
|
314
|
-
|
315
|
-
context 'on dynamic checks' do
|
316
|
-
subject(:a_remounted_api) do
|
317
|
-
Class.new(described_class) do
|
318
|
-
params do
|
319
|
-
optional :restricted_values, values: -> { [configuration[:allowed_value], 'always'] }
|
320
|
-
end
|
321
|
-
|
322
|
-
get 'location' do
|
323
|
-
'success'
|
324
|
-
end
|
325
|
-
end
|
326
|
-
end
|
327
|
-
|
328
|
-
it 'can read the configuration on lambdas' do
|
329
|
-
root_api.mount a_remounted_api, with: { allowed_value: 'sometimes' }
|
330
|
-
get '/location', restricted_values: 'always'
|
331
|
-
expect(last_response.body).to eq 'success'
|
332
|
-
get '/location', restricted_values: 'sometimes'
|
333
|
-
expect(last_response.body).to eq 'success'
|
334
|
-
get '/location', restricted_values: 'never'
|
335
|
-
expect(last_response.status).to eq 400
|
336
|
-
end
|
337
|
-
end
|
338
|
-
end
|
339
|
-
|
340
|
-
context 'when the configuration is read within a namespace' do
|
341
|
-
before do
|
342
|
-
a_remounted_api.namespace 'api' do
|
343
|
-
params do
|
344
|
-
requires configuration[:required_param]
|
345
|
-
end
|
346
|
-
get "/#{configuration[:path]}" do
|
347
|
-
'10 votes'
|
348
|
-
end
|
349
|
-
end
|
350
|
-
root_api.mount a_remounted_api, with: { path: 'votes', required_param: 'param_key' }
|
351
|
-
root_api.mount a_remounted_api, with: { path: 'scores', required_param: 'param_key' }
|
352
|
-
end
|
353
|
-
|
354
|
-
it 'will use the dynamic configuration on all routes' do
|
355
|
-
get 'api/votes', param_key: 'a'
|
356
|
-
expect(last_response.body).to eql '10 votes'
|
357
|
-
get 'api/scores', param_key: 'a'
|
358
|
-
expect(last_response.body).to eql '10 votes'
|
359
|
-
get 'api/votes'
|
360
|
-
expect(last_response.status).to eq 400
|
361
|
-
end
|
362
|
-
end
|
363
|
-
|
364
|
-
context 'a very complex configuration example' do
|
365
|
-
before do
|
366
|
-
top_level_api = Class.new(described_class) do
|
367
|
-
remounted_api = Class.new(Grape::API) do
|
368
|
-
get configuration[:endpoint_name] do
|
369
|
-
configuration[:response]
|
370
|
-
end
|
371
|
-
end
|
372
|
-
|
373
|
-
expression_namespace = mounted { configuration[:namespace].to_s * 2 }
|
374
|
-
given(mounted { configuration[:should_mount_expressed] != false }) do
|
375
|
-
namespace expression_namespace do
|
376
|
-
mount remounted_api, with: { endpoint_name: configuration[:endpoint_name], response: configuration[:endpoint_response] }
|
377
|
-
end
|
378
|
-
end
|
379
|
-
end
|
380
|
-
root_api.mount top_level_api, with: configuration_options
|
381
|
-
end
|
382
|
-
|
383
|
-
context 'when the namespace should be mounted' do
|
384
|
-
let(:configuration_options) do
|
385
|
-
{
|
386
|
-
should_mount_expressed: true,
|
387
|
-
namespace: 'bang',
|
388
|
-
endpoint_name: 'james',
|
389
|
-
endpoint_response: 'bond'
|
390
|
-
}
|
391
|
-
end
|
392
|
-
|
393
|
-
it 'gets a response' do
|
394
|
-
get 'bangbang/james'
|
395
|
-
expect(last_response.body).to eq 'bond'
|
396
|
-
end
|
397
|
-
end
|
398
|
-
|
399
|
-
context 'when should be mounted is nil' do
|
400
|
-
let(:configuration_options) do
|
401
|
-
{
|
402
|
-
should_mount_expressed: nil,
|
403
|
-
namespace: 'bang',
|
404
|
-
endpoint_name: 'james',
|
405
|
-
endpoint_response: 'bond'
|
406
|
-
}
|
407
|
-
end
|
408
|
-
|
409
|
-
it 'gets a response' do
|
410
|
-
get 'bangbang/james'
|
411
|
-
expect(last_response.body).to eq 'bond'
|
412
|
-
end
|
413
|
-
end
|
414
|
-
|
415
|
-
context 'when it should not be mounted' do
|
416
|
-
let(:configuration_options) do
|
417
|
-
{
|
418
|
-
should_mount_expressed: false,
|
419
|
-
namespace: 'bang',
|
420
|
-
endpoint_name: 'james',
|
421
|
-
endpoint_response: 'bond'
|
422
|
-
}
|
423
|
-
end
|
424
|
-
|
425
|
-
it 'gets a response' do
|
426
|
-
get 'bangbang/james'
|
427
|
-
expect(last_response.body).not_to eq 'bond'
|
428
|
-
end
|
429
|
-
end
|
430
|
-
end
|
431
|
-
|
432
|
-
context 'when the configuration is read in a helper' do
|
433
|
-
subject(:a_remounted_api) do
|
434
|
-
Class.new(described_class) do
|
435
|
-
helpers do
|
436
|
-
def printed_response
|
437
|
-
configuration[:some_value]
|
438
|
-
end
|
439
|
-
end
|
440
|
-
|
441
|
-
get 'location' do
|
442
|
-
printed_response
|
443
|
-
end
|
444
|
-
end
|
445
|
-
end
|
446
|
-
|
447
|
-
it 'will use the dynamic configuration on all routes' do
|
448
|
-
root_api.mount(a_remounted_api, with: { some_value: 'response value' })
|
449
|
-
|
450
|
-
get '/location'
|
451
|
-
expect(last_response.body).to eq 'response value'
|
452
|
-
end
|
453
|
-
end
|
454
|
-
|
455
|
-
context 'when the configuration is read within the response block' do
|
456
|
-
subject(:a_remounted_api) do
|
457
|
-
Class.new(described_class) do
|
458
|
-
get 'location' do
|
459
|
-
configuration[:some_value]
|
460
|
-
end
|
461
|
-
end
|
462
|
-
end
|
463
|
-
|
464
|
-
it 'will use the dynamic configuration on all routes' do
|
465
|
-
root_api.mount(a_remounted_api, with: { some_value: 'response value' })
|
466
|
-
|
467
|
-
get '/location'
|
468
|
-
expect(last_response.body).to eq 'response value'
|
469
|
-
end
|
470
|
-
end
|
471
|
-
end
|
472
|
-
end
|
473
|
-
end
|