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.
Files changed (163) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +37 -1
  3. data/CONTRIBUTING.md +1 -1
  4. data/README.md +30 -25
  5. data/UPGRADING.md +35 -0
  6. data/grape.gemspec +3 -6
  7. data/lib/grape/api.rb +2 -2
  8. data/lib/grape/content_types.rb +2 -8
  9. data/lib/grape/dsl/desc.rb +1 -1
  10. data/lib/grape/dsl/inside_route.rb +11 -11
  11. data/lib/grape/dsl/request_response.rb +2 -1
  12. data/lib/grape/dsl/settings.rb +2 -6
  13. data/lib/grape/endpoint.rb +28 -18
  14. data/lib/grape/error_formatter/base.rb +1 -1
  15. data/lib/grape/exceptions/base.rb +2 -2
  16. data/lib/grape/exceptions/missing_group_type.rb +1 -6
  17. data/lib/grape/exceptions/unsupported_group_type.rb +1 -6
  18. data/lib/grape/exceptions/validation_errors.rb +1 -6
  19. data/lib/grape/extensions/active_support/hash_with_indifferent_access.rb +3 -3
  20. data/lib/grape/extensions/hash.rb +4 -7
  21. data/lib/grape/extensions/hashie/mash.rb +3 -3
  22. data/lib/grape/formatter/serializable_hash.rb +7 -7
  23. data/lib/grape/http/headers.rb +12 -2
  24. data/lib/grape/middleware/auth/base.rb +1 -1
  25. data/lib/grape/middleware/auth/strategies.rb +1 -2
  26. data/lib/grape/middleware/error.rb +5 -5
  27. data/lib/grape/middleware/formatter.rb +6 -6
  28. data/lib/grape/middleware/versioner/header.rb +11 -19
  29. data/lib/grape/railtie.rb +9 -0
  30. data/lib/grape/request.rb +8 -2
  31. data/lib/grape/router/route.rb +1 -3
  32. data/lib/grape/util/lazy_value.rb +3 -11
  33. data/lib/grape/util/strict_hash_configuration.rb +3 -4
  34. data/lib/grape/validations/multiple_attributes_iterator.rb +1 -1
  35. data/lib/grape/validations/params_scope.rb +8 -2
  36. data/lib/grape/validations/single_attribute_iterator.rb +3 -1
  37. data/lib/grape/validations/types/custom_type_coercer.rb +2 -16
  38. data/lib/grape/validations/validators/base.rb +9 -20
  39. data/lib/grape/validations/validators/default_validator.rb +2 -20
  40. data/lib/grape/validations/validators/multiple_params_base.rb +4 -8
  41. data/lib/grape/validations/validators/values_validator.rb +14 -5
  42. data/lib/grape/version.rb +1 -1
  43. data/lib/grape.rb +26 -5
  44. metadata +13 -253
  45. data/lib/grape/config.rb +0 -34
  46. data/lib/grape/extensions/deep_mergeable_hash.rb +0 -21
  47. data/lib/grape/extensions/deep_symbolize_hash.rb +0 -32
  48. data/spec/grape/api/custom_validations_spec.rb +0 -256
  49. data/spec/grape/api/deeply_included_options_spec.rb +0 -56
  50. data/spec/grape/api/defines_boolean_in_params_spec.rb +0 -38
  51. data/spec/grape/api/documentation_spec.rb +0 -59
  52. data/spec/grape/api/inherited_helpers_spec.rb +0 -114
  53. data/spec/grape/api/instance_spec.rb +0 -103
  54. data/spec/grape/api/invalid_format_spec.rb +0 -45
  55. data/spec/grape/api/namespace_parameters_in_route_spec.rb +0 -38
  56. data/spec/grape/api/nested_helpers_spec.rb +0 -50
  57. data/spec/grape/api/optional_parameters_in_route_spec.rb +0 -43
  58. data/spec/grape/api/parameters_modification_spec.rb +0 -41
  59. data/spec/grape/api/patch_method_helpers_spec.rb +0 -79
  60. data/spec/grape/api/recognize_path_spec.rb +0 -21
  61. data/spec/grape/api/required_parameters_in_route_spec.rb +0 -37
  62. data/spec/grape/api/required_parameters_with_invalid_method_spec.rb +0 -26
  63. data/spec/grape/api/routes_with_requirements_spec.rb +0 -59
  64. data/spec/grape/api/shared_helpers_exactly_one_of_spec.rb +0 -41
  65. data/spec/grape/api/shared_helpers_spec.rb +0 -36
  66. data/spec/grape/api_remount_spec.rb +0 -473
  67. data/spec/grape/api_spec.rb +0 -4347
  68. data/spec/grape/config_spec.rb +0 -17
  69. data/spec/grape/dsl/callbacks_spec.rb +0 -45
  70. data/spec/grape/dsl/desc_spec.rb +0 -101
  71. data/spec/grape/dsl/headers_spec.rb +0 -62
  72. data/spec/grape/dsl/helpers_spec.rb +0 -100
  73. data/spec/grape/dsl/inside_route_spec.rb +0 -535
  74. data/spec/grape/dsl/logger_spec.rb +0 -24
  75. data/spec/grape/dsl/middleware_spec.rb +0 -60
  76. data/spec/grape/dsl/parameters_spec.rb +0 -180
  77. data/spec/grape/dsl/request_response_spec.rb +0 -206
  78. data/spec/grape/dsl/routing_spec.rb +0 -275
  79. data/spec/grape/dsl/settings_spec.rb +0 -261
  80. data/spec/grape/dsl/validations_spec.rb +0 -55
  81. data/spec/grape/endpoint/declared_spec.rb +0 -846
  82. data/spec/grape/endpoint_spec.rb +0 -1085
  83. data/spec/grape/entity_spec.rb +0 -336
  84. data/spec/grape/exceptions/base_spec.rb +0 -81
  85. data/spec/grape/exceptions/body_parse_errors_spec.rb +0 -145
  86. data/spec/grape/exceptions/invalid_accept_header_spec.rb +0 -358
  87. data/spec/grape/exceptions/invalid_formatter_spec.rb +0 -15
  88. data/spec/grape/exceptions/invalid_response_spec.rb +0 -11
  89. data/spec/grape/exceptions/invalid_versioner_option_spec.rb +0 -15
  90. data/spec/grape/exceptions/missing_group_type_spec.rb +0 -21
  91. data/spec/grape/exceptions/missing_mime_type_spec.rb +0 -17
  92. data/spec/grape/exceptions/missing_option_spec.rb +0 -15
  93. data/spec/grape/exceptions/unknown_options_spec.rb +0 -15
  94. data/spec/grape/exceptions/unknown_validator_spec.rb +0 -15
  95. data/spec/grape/exceptions/unsupported_group_type_spec.rb +0 -23
  96. data/spec/grape/exceptions/validation_errors_spec.rb +0 -92
  97. data/spec/grape/exceptions/validation_spec.rb +0 -19
  98. data/spec/grape/extensions/param_builders/hash_spec.rb +0 -83
  99. data/spec/grape/extensions/param_builders/hash_with_indifferent_access_spec.rb +0 -105
  100. data/spec/grape/extensions/param_builders/hashie/mash_spec.rb +0 -79
  101. data/spec/grape/integration/global_namespace_function_spec.rb +0 -29
  102. data/spec/grape/integration/rack_sendfile_spec.rb +0 -48
  103. data/spec/grape/integration/rack_spec.rb +0 -51
  104. data/spec/grape/loading_spec.rb +0 -44
  105. data/spec/grape/middleware/auth/base_spec.rb +0 -31
  106. data/spec/grape/middleware/auth/dsl_spec.rb +0 -60
  107. data/spec/grape/middleware/auth/strategies_spec.rb +0 -120
  108. data/spec/grape/middleware/base_spec.rb +0 -221
  109. data/spec/grape/middleware/error_spec.rb +0 -85
  110. data/spec/grape/middleware/exception_spec.rb +0 -294
  111. data/spec/grape/middleware/formatter_spec.rb +0 -461
  112. data/spec/grape/middleware/globals_spec.rb +0 -30
  113. data/spec/grape/middleware/stack_spec.rb +0 -155
  114. data/spec/grape/middleware/versioner/accept_version_header_spec.rb +0 -122
  115. data/spec/grape/middleware/versioner/header_spec.rb +0 -345
  116. data/spec/grape/middleware/versioner/param_spec.rb +0 -171
  117. data/spec/grape/middleware/versioner/path_spec.rb +0 -62
  118. data/spec/grape/middleware/versioner_spec.rb +0 -21
  119. data/spec/grape/named_api_spec.rb +0 -19
  120. data/spec/grape/parser_spec.rb +0 -86
  121. data/spec/grape/path_spec.rb +0 -252
  122. data/spec/grape/presenters/presenter_spec.rb +0 -71
  123. data/spec/grape/request_spec.rb +0 -136
  124. data/spec/grape/util/inheritable_setting_spec.rb +0 -242
  125. data/spec/grape/util/inheritable_values_spec.rb +0 -79
  126. data/spec/grape/util/reverse_stackable_values_spec.rb +0 -134
  127. data/spec/grape/util/stackable_values_spec.rb +0 -128
  128. data/spec/grape/util/strict_hash_configuration_spec.rb +0 -38
  129. data/spec/grape/validations/attributes_doc_spec.rb +0 -153
  130. data/spec/grape/validations/instance_behaivour_spec.rb +0 -43
  131. data/spec/grape/validations/multiple_attributes_iterator_spec.rb +0 -40
  132. data/spec/grape/validations/params_scope_spec.rb +0 -1420
  133. data/spec/grape/validations/single_attribute_iterator_spec.rb +0 -57
  134. data/spec/grape/validations/types/array_coercer_spec.rb +0 -33
  135. data/spec/grape/validations/types/primitive_coercer_spec.rb +0 -150
  136. data/spec/grape/validations/types/set_coercer_spec.rb +0 -32
  137. data/spec/grape/validations/types_spec.rb +0 -111
  138. data/spec/grape/validations/validators/all_or_none_spec.rb +0 -162
  139. data/spec/grape/validations/validators/allow_blank_spec.rb +0 -575
  140. data/spec/grape/validations/validators/at_least_one_of_spec.rb +0 -205
  141. data/spec/grape/validations/validators/coerce_spec.rb +0 -1261
  142. data/spec/grape/validations/validators/default_spec.rb +0 -463
  143. data/spec/grape/validations/validators/exactly_one_of_spec.rb +0 -233
  144. data/spec/grape/validations/validators/except_values_spec.rb +0 -192
  145. data/spec/grape/validations/validators/mutual_exclusion_spec.rb +0 -214
  146. data/spec/grape/validations/validators/presence_spec.rb +0 -315
  147. data/spec/grape/validations/validators/regexp_spec.rb +0 -161
  148. data/spec/grape/validations/validators/same_as_spec.rb +0 -57
  149. data/spec/grape/validations/validators/values_spec.rb +0 -696
  150. data/spec/grape/validations/validators/zh-CN.yml +0 -10
  151. data/spec/grape/validations_spec.rb +0 -2029
  152. data/spec/integration/eager_load/eager_load_spec.rb +0 -15
  153. data/spec/integration/multi_json/json_spec.rb +0 -7
  154. data/spec/integration/multi_xml/xml_spec.rb +0 -7
  155. data/spec/shared/versioning_examples.rb +0 -215
  156. data/spec/spec_helper.rb +0 -52
  157. data/spec/support/basic_auth_encode_helpers.rb +0 -11
  158. data/spec/support/chunks.rb +0 -14
  159. data/spec/support/content_type_helpers.rb +0 -15
  160. data/spec/support/endpoint_faker.rb +0 -25
  161. data/spec/support/file_streamer.rb +0 -13
  162. data/spec/support/integer_helpers.rb +0 -13
  163. 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