gitlab-grape-swagger 1.5.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 (166) hide show
  1. checksums.yaml +7 -0
  2. data/.coveralls.yml +1 -0
  3. data/.github/dependabot.yml +20 -0
  4. data/.github/workflows/ci.yml +45 -0
  5. data/.gitignore +44 -0
  6. data/.gitlab-ci.yml +19 -0
  7. data/.rspec +3 -0
  8. data/.rubocop.yml +136 -0
  9. data/.rubocop_todo.yml +60 -0
  10. data/.ruby-gemset +1 -0
  11. data/CHANGELOG.md +671 -0
  12. data/CONTRIBUTING.md +126 -0
  13. data/Dangerfile +3 -0
  14. data/Gemfile +45 -0
  15. data/Gemfile.lock +249 -0
  16. data/LICENSE.txt +20 -0
  17. data/README.md +1772 -0
  18. data/RELEASING.md +82 -0
  19. data/Rakefile +20 -0
  20. data/UPGRADING.md +201 -0
  21. data/example/api/endpoints.rb +131 -0
  22. data/example/api/entities.rb +18 -0
  23. data/example/config.ru +42 -0
  24. data/example/example_requests.postman_collection +146 -0
  25. data/example/splines.png +0 -0
  26. data/example/swagger-example.png +0 -0
  27. data/grape-swagger.gemspec +23 -0
  28. data/lib/grape-swagger/doc_methods/build_model_definition.rb +68 -0
  29. data/lib/grape-swagger/doc_methods/data_type.rb +110 -0
  30. data/lib/grape-swagger/doc_methods/extensions.rb +101 -0
  31. data/lib/grape-swagger/doc_methods/file_params.rb +17 -0
  32. data/lib/grape-swagger/doc_methods/format_data.rb +53 -0
  33. data/lib/grape-swagger/doc_methods/headers.rb +20 -0
  34. data/lib/grape-swagger/doc_methods/move_params.rb +209 -0
  35. data/lib/grape-swagger/doc_methods/operation_id.rb +32 -0
  36. data/lib/grape-swagger/doc_methods/optional_object.rb +30 -0
  37. data/lib/grape-swagger/doc_methods/parse_params.rb +190 -0
  38. data/lib/grape-swagger/doc_methods/path_string.rb +52 -0
  39. data/lib/grape-swagger/doc_methods/produces_consumes.rb +15 -0
  40. data/lib/grape-swagger/doc_methods/status_codes.rb +21 -0
  41. data/lib/grape-swagger/doc_methods/tag_name_description.rb +34 -0
  42. data/lib/grape-swagger/doc_methods/version.rb +20 -0
  43. data/lib/grape-swagger/doc_methods.rb +142 -0
  44. data/lib/grape-swagger/endpoint/params_parser.rb +76 -0
  45. data/lib/grape-swagger/endpoint.rb +476 -0
  46. data/lib/grape-swagger/errors.rb +17 -0
  47. data/lib/grape-swagger/instance.rb +7 -0
  48. data/lib/grape-swagger/model_parsers.rb +42 -0
  49. data/lib/grape-swagger/rake/oapi_tasks.rb +135 -0
  50. data/lib/grape-swagger/version.rb +5 -0
  51. data/lib/grape-swagger.rb +174 -0
  52. data/spec/issues/267_nested_namespaces.rb +55 -0
  53. data/spec/issues/403_versions_spec.rb +124 -0
  54. data/spec/issues/427_entity_as_string_spec.rb +39 -0
  55. data/spec/issues/430_entity_definitions_spec.rb +94 -0
  56. data/spec/issues/532_allow_custom_format_spec.rb +42 -0
  57. data/spec/issues/533_specify_status_code_spec.rb +78 -0
  58. data/spec/issues/537_enum_values_spec.rb +50 -0
  59. data/spec/issues/539_array_post_body_spec.rb +65 -0
  60. data/spec/issues/542_array_of_type_in_post_body_spec.rb +46 -0
  61. data/spec/issues/553_align_array_put_post_params_spec.rb +152 -0
  62. data/spec/issues/572_array_post_body_spec.rb +51 -0
  63. data/spec/issues/579_align_put_post_parameters_spec.rb +185 -0
  64. data/spec/issues/582_file_response_spec.rb +55 -0
  65. data/spec/issues/587_range_parameter_delimited_by_dash_spec.rb +26 -0
  66. data/spec/issues/605_root_route_documentation_spec.rb +23 -0
  67. data/spec/issues/650_params_array_spec.rb +65 -0
  68. data/spec/issues/677_consumes_produces_add_swagger_documentation_options_spec.rb +100 -0
  69. data/spec/issues/680_keep_204_error_schemas_spec.rb +55 -0
  70. data/spec/issues/721_set_default_parameter_location_based_on_consumes_spec.rb +62 -0
  71. data/spec/issues/751_deeply_nested_objects_spec.rb +190 -0
  72. data/spec/issues/776_multiple_presents_spec.rb +59 -0
  73. data/spec/issues/784_extensions_on_params_spec.rb +42 -0
  74. data/spec/issues/809_utf8_routes_spec.rb +55 -0
  75. data/spec/issues/832_array_hash_float_decimal_spec.rb +114 -0
  76. data/spec/issues/847_route_param_options_spec.rb +37 -0
  77. data/spec/issues/873_wildcard_segments_path_parameters_spec.rb +28 -0
  78. data/spec/issues/878_optional_path_segments_spec.rb +29 -0
  79. data/spec/issues/881_handle_file_params_spec.rb +38 -0
  80. data/spec/issues/883_query_array_parameter_spec.rb +46 -0
  81. data/spec/issues/884_dont_document_non_schema_examples_spec.rb +49 -0
  82. data/spec/issues/887_prevent_duplicate_operation_ids_spec.rb +35 -0
  83. data/spec/lib/data_type_spec.rb +111 -0
  84. data/spec/lib/endpoint/params_parser_spec.rb +124 -0
  85. data/spec/lib/endpoint_spec.rb +153 -0
  86. data/spec/lib/extensions_spec.rb +185 -0
  87. data/spec/lib/format_data_spec.rb +115 -0
  88. data/spec/lib/model_parsers_spec.rb +104 -0
  89. data/spec/lib/move_params_spec.rb +444 -0
  90. data/spec/lib/oapi_tasks_spec.rb +163 -0
  91. data/spec/lib/operation_id_spec.rb +55 -0
  92. data/spec/lib/optional_object_spec.rb +47 -0
  93. data/spec/lib/parse_params_spec.rb +68 -0
  94. data/spec/lib/path_string_spec.rb +101 -0
  95. data/spec/lib/produces_consumes_spec.rb +116 -0
  96. data/spec/lib/tag_name_description_spec.rb +80 -0
  97. data/spec/lib/version_spec.rb +28 -0
  98. data/spec/spec_helper.rb +39 -0
  99. data/spec/support/empty_model_parser.rb +23 -0
  100. data/spec/support/grape_version.rb +13 -0
  101. data/spec/support/mock_parser.rb +23 -0
  102. data/spec/support/model_parsers/entity_parser.rb +334 -0
  103. data/spec/support/model_parsers/mock_parser.rb +346 -0
  104. data/spec/support/model_parsers/representable_parser.rb +406 -0
  105. data/spec/support/namespace_tags.rb +93 -0
  106. data/spec/support/the_paths_definitions.rb +109 -0
  107. data/spec/swagger_v2/api_documentation_spec.rb +42 -0
  108. data/spec/swagger_v2/api_swagger_v2_additional_properties_spec.rb +83 -0
  109. data/spec/swagger_v2/api_swagger_v2_body_definitions_spec.rb +48 -0
  110. data/spec/swagger_v2/api_swagger_v2_definitions-models_spec.rb +36 -0
  111. data/spec/swagger_v2/api_swagger_v2_detail_spec.rb +79 -0
  112. data/spec/swagger_v2/api_swagger_v2_extensions_spec.rb +145 -0
  113. data/spec/swagger_v2/api_swagger_v2_format-content_type_spec.rb +137 -0
  114. data/spec/swagger_v2/api_swagger_v2_global_configuration_spec.rb +56 -0
  115. data/spec/swagger_v2/api_swagger_v2_hash_and_array_spec.rb +64 -0
  116. data/spec/swagger_v2/api_swagger_v2_headers_spec.rb +58 -0
  117. data/spec/swagger_v2/api_swagger_v2_hide_documentation_path_spec.rb +57 -0
  118. data/spec/swagger_v2/api_swagger_v2_hide_param_spec.rb +109 -0
  119. data/spec/swagger_v2/api_swagger_v2_ignore_defaults_spec.rb +48 -0
  120. data/spec/swagger_v2/api_swagger_v2_mounted_spec.rb +153 -0
  121. data/spec/swagger_v2/api_swagger_v2_param_type_body_nested_spec.rb +355 -0
  122. data/spec/swagger_v2/api_swagger_v2_param_type_body_spec.rb +217 -0
  123. data/spec/swagger_v2/api_swagger_v2_param_type_spec.rb +247 -0
  124. data/spec/swagger_v2/api_swagger_v2_request_params_fix_spec.rb +80 -0
  125. data/spec/swagger_v2/api_swagger_v2_response_spec.rb +147 -0
  126. data/spec/swagger_v2/api_swagger_v2_response_with_examples_spec.rb +135 -0
  127. data/spec/swagger_v2/api_swagger_v2_response_with_headers_spec.rb +216 -0
  128. data/spec/swagger_v2/api_swagger_v2_response_with_models_spec.rb +53 -0
  129. data/spec/swagger_v2/api_swagger_v2_response_with_root_spec.rb +153 -0
  130. data/spec/swagger_v2/api_swagger_v2_spec.rb +245 -0
  131. data/spec/swagger_v2/api_swagger_v2_status_codes_spec.rb +93 -0
  132. data/spec/swagger_v2/api_swagger_v2_type-format_spec.rb +90 -0
  133. data/spec/swagger_v2/boolean_params_spec.rb +38 -0
  134. data/spec/swagger_v2/default_api_spec.rb +175 -0
  135. data/spec/swagger_v2/deprecated_field_spec.rb +25 -0
  136. data/spec/swagger_v2/description_not_initialized_spec.rb +39 -0
  137. data/spec/swagger_v2/endpoint_versioned_path_spec.rb +130 -0
  138. data/spec/swagger_v2/errors_spec.rb +77 -0
  139. data/spec/swagger_v2/float_api_spec.rb +36 -0
  140. data/spec/swagger_v2/form_params_spec.rb +76 -0
  141. data/spec/swagger_v2/grape-swagger_spec.rb +17 -0
  142. data/spec/swagger_v2/guarded_endpoint_spec.rb +162 -0
  143. data/spec/swagger_v2/hide_api_spec.rb +147 -0
  144. data/spec/swagger_v2/host_spec.rb +43 -0
  145. data/spec/swagger_v2/inheritance_and_discriminator_spec.rb +57 -0
  146. data/spec/swagger_v2/mount_override_api_spec.rb +58 -0
  147. data/spec/swagger_v2/mounted_target_class_spec.rb +76 -0
  148. data/spec/swagger_v2/namespace_tags_prefix_spec.rb +122 -0
  149. data/spec/swagger_v2/namespace_tags_spec.rb +78 -0
  150. data/spec/swagger_v2/namespaced_api_spec.rb +121 -0
  151. data/spec/swagger_v2/nicknamed_api_spec.rb +25 -0
  152. data/spec/swagger_v2/operation_id_api_spec.rb +27 -0
  153. data/spec/swagger_v2/param_multi_type_spec.rb +82 -0
  154. data/spec/swagger_v2/param_type_spec.rb +95 -0
  155. data/spec/swagger_v2/param_values_spec.rb +180 -0
  156. data/spec/swagger_v2/params_array_collection_format_spec.rb +105 -0
  157. data/spec/swagger_v2/params_array_spec.rb +225 -0
  158. data/spec/swagger_v2/params_example_spec.rb +38 -0
  159. data/spec/swagger_v2/params_hash_spec.rb +77 -0
  160. data/spec/swagger_v2/params_nested_spec.rb +92 -0
  161. data/spec/swagger_v2/parent_less_namespace_spec.rb +32 -0
  162. data/spec/swagger_v2/reference_entity_spec.rb +129 -0
  163. data/spec/swagger_v2/security_requirement_spec.rb +46 -0
  164. data/spec/swagger_v2/simple_mounted_api_spec.rb +332 -0
  165. data/spec/version_spec.rb +10 -0
  166. metadata +225 -0
@@ -0,0 +1,355 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'spec_helper'
4
+
5
+ describe 'moving body/formData Params to definitions' do
6
+ include_context "#{MODEL_PARSER} swagger example"
7
+
8
+ before :all do
9
+ module TheApi
10
+ class NestedBodyParamTypeApi < Grape::API
11
+ namespace :simple_nested_params do
12
+ desc 'post in body with nested parameters',
13
+ detail: 'more details description',
14
+ success: Entities::UseNestedWithAddress
15
+ params do
16
+ optional :contact, type: Hash, documentation: { additional_properties: true } do
17
+ requires :name, type: String, documentation: { desc: 'name', in: 'body' }
18
+ optional :addresses, type: Array do
19
+ requires :street, type: String, documentation: { desc: 'street', in: 'body' }
20
+ requires :postcode, type: String, documentation: { desc: 'postcode', in: 'body' }
21
+ requires :city, type: String, documentation: { desc: 'city', in: 'body' }
22
+ optional :country, type: String, documentation: { desc: 'country', in: 'body' }
23
+ end
24
+ end
25
+ end
26
+
27
+ post '/in_body' do
28
+ { 'declared_params' => declared(params) }
29
+ end
30
+
31
+ desc 'put in body with nested parameters',
32
+ detail: 'more details description',
33
+ success: Entities::UseNestedWithAddress
34
+ params do
35
+ requires :id, type: Integer
36
+ optional :name, type: String, documentation: { desc: 'name', in: 'body' }
37
+ optional :address, type: Hash do
38
+ optional :street, type: String, documentation: { desc: 'street', in: 'body' }
39
+ optional :postcode, type: String, documentation: { desc: 'postcode', in: 'formData' }
40
+ optional :city, type: String, documentation: { desc: 'city', in: 'body' }
41
+ optional :country, type: String, documentation: { desc: 'country', in: 'body' }
42
+ end
43
+ end
44
+
45
+ put '/in_body/:id' do
46
+ { 'declared_params' => declared(params) }
47
+ end
48
+ end
49
+
50
+ namespace :multiple_nested_params do
51
+ desc 'put in body with multiple nested parameters',
52
+ success: Entities::UseNestedWithAddress
53
+ params do
54
+ optional :contact, type: Hash do
55
+ requires :name, type: String, documentation: { desc: 'name', in: 'body' }
56
+ optional :addresses, type: Array do
57
+ optional :street, type: String, documentation: { desc: 'street', in: 'body' }
58
+ requires :postcode, type: Integer, documentation: { desc: 'postcode', in: 'formData' }
59
+ optional :city, type: String, documentation: { desc: 'city', in: 'body' }
60
+ optional :country, type: String, documentation: { desc: 'country', in: 'body' }
61
+ end
62
+ optional :delivery_address, type: Hash do
63
+ optional :street, type: String, documentation: { desc: 'street', in: 'body' }
64
+ optional :postcode, type: String, documentation: { desc: 'postcode', in: 'formData' }
65
+ optional :city, type: String, documentation: { desc: 'city', in: 'body' }
66
+ optional :country, type: String, documentation: { desc: 'country', in: 'body' }
67
+ end
68
+ end
69
+ end
70
+
71
+ post '/in_body' do
72
+ { 'declared_params' => declared(params) }
73
+ end
74
+
75
+ desc 'put in body with multiple nested parameters',
76
+ success: Entities::UseNestedWithAddress
77
+ params do
78
+ requires :id, type: Integer
79
+ optional :name, type: String, documentation: { desc: 'name', in: 'body' }
80
+ optional :address, type: Hash do
81
+ optional :street, type: String, documentation: { desc: 'street', in: 'body' }
82
+ requires :postcode, type: String, documentation: { desc: 'postcode', in: 'formData' }
83
+ optional :city, type: String, documentation: { desc: 'city', in: 'body' }
84
+ optional :country, type: String, documentation: { desc: 'country', in: 'body' }
85
+ end
86
+ optional :delivery_address, type: Hash do
87
+ optional :street, type: String, documentation: { desc: 'street', in: 'body' }
88
+ optional :postcode, type: String, documentation: { desc: 'postcode', in: 'formData' }
89
+ optional :city, type: String, documentation: { desc: 'city', in: 'body' }
90
+ optional :country, type: String, documentation: { desc: 'country', in: 'body' }
91
+ end
92
+ end
93
+
94
+ put '/in_body/:id' do
95
+ { 'declared_params' => declared(params) }
96
+ end
97
+ end
98
+
99
+ namespace :nested_params_array do
100
+ desc 'post in body with array of nested parameters',
101
+ detail: 'more details description',
102
+ success: Entities::UseNestedWithAddress
103
+ params do
104
+ optional :contacts, type: Array, documentation: { additional_properties: false } do
105
+ requires :name, type: String, documentation: { desc: 'name', in: 'body' }
106
+ optional :addresses, type: Array do
107
+ requires :street, type: String, documentation: { desc: 'street', in: 'body' }
108
+ requires :postcode, type: String, documentation: { desc: 'postcode', in: 'body' }
109
+ requires :city, type: String, documentation: { desc: 'city', in: 'body' }
110
+ optional :country, type: String, documentation: { desc: 'country', in: 'body' }
111
+ end
112
+ end
113
+ end
114
+
115
+ post '/in_body' do
116
+ { 'declared_params' => declared(params) }
117
+ end
118
+ end
119
+
120
+ add_swagger_documentation
121
+ end
122
+ end
123
+ end
124
+
125
+ def app
126
+ TheApi::NestedBodyParamTypeApi
127
+ end
128
+
129
+ describe 'nested body parameters given' do
130
+ subject do
131
+ get '/swagger_doc/simple_nested_params'
132
+ JSON.parse(last_response.body)
133
+ end
134
+
135
+ describe 'POST' do
136
+ specify do
137
+ expect(subject['paths']['/simple_nested_params/in_body']['post']['parameters']).to eql(
138
+ [
139
+ { 'name' => 'postSimpleNestedParamsInBody', 'in' => 'body', 'required' => true, 'schema' => { '$ref' => '#/definitions/postSimpleNestedParamsInBody' } }
140
+ ]
141
+ )
142
+ end
143
+
144
+ specify do
145
+ expect(subject['definitions']['postSimpleNestedParamsInBody']).to eql(
146
+ 'type' => 'object',
147
+ 'properties' => {
148
+ 'contact' => {
149
+ 'type' => 'object',
150
+ 'additionalProperties' => true,
151
+ 'properties' => {
152
+ 'name' => { 'type' => 'string', 'description' => 'name' },
153
+ 'addresses' => {
154
+ 'type' => 'array',
155
+ 'items' => {
156
+ 'type' => 'object',
157
+ 'properties' => {
158
+ 'street' => { 'type' => 'string', 'description' => 'street' },
159
+ 'postcode' => { 'type' => 'string', 'description' => 'postcode' },
160
+ 'city' => { 'type' => 'string', 'description' => 'city' },
161
+ 'country' => { 'type' => 'string', 'description' => 'country' }
162
+ },
163
+ 'required' => %w[street postcode city]
164
+ }
165
+ }
166
+ },
167
+ 'required' => %w[name]
168
+ }
169
+ },
170
+ 'description' => 'post in body with nested parameters'
171
+ )
172
+ end
173
+ end
174
+
175
+ describe 'PUT' do
176
+ specify do
177
+ expect(subject['paths']['/simple_nested_params/in_body/{id}']['put']['parameters']).to eql(
178
+ [
179
+ { 'in' => 'path', 'name' => 'id', 'type' => 'integer', 'format' => 'int32', 'required' => true },
180
+ { 'name' => 'putSimpleNestedParamsInBodyId', 'in' => 'body', 'required' => true, 'schema' => { '$ref' => '#/definitions/putSimpleNestedParamsInBodyId' } }
181
+ ]
182
+ )
183
+ end
184
+
185
+ specify do
186
+ expect(subject['definitions']['putSimpleNestedParamsInBodyId']).to eql(
187
+ 'type' => 'object',
188
+ 'properties' => {
189
+ 'name' => { 'type' => 'string', 'description' => 'name' },
190
+ 'address' => {
191
+ 'type' => 'object',
192
+ 'properties' => {
193
+ 'street' => { 'type' => 'string', 'description' => 'street' },
194
+ 'postcode' => { 'type' => 'string', 'description' => 'postcode' },
195
+ 'city' => { 'type' => 'string', 'description' => 'city' },
196
+ 'country' => { 'type' => 'string', 'description' => 'country' }
197
+ }
198
+ }
199
+ },
200
+ 'description' => 'put in body with nested parameters'
201
+ )
202
+ end
203
+ end
204
+ end
205
+
206
+ describe 'multiple nested body parameters given' do
207
+ subject do
208
+ get '/swagger_doc/multiple_nested_params'
209
+ JSON.parse(last_response.body)
210
+ end
211
+
212
+ describe 'POST' do
213
+ specify do
214
+ expect(subject['paths']['/multiple_nested_params/in_body']['post']['parameters']).to eql(
215
+ [
216
+ {
217
+ 'name' => 'postMultipleNestedParamsInBody',
218
+ 'in' => 'body',
219
+ 'required' => true,
220
+ 'schema' => { '$ref' => '#/definitions/postMultipleNestedParamsInBody' }
221
+ }
222
+ ]
223
+ )
224
+ end
225
+
226
+ specify do
227
+ expect(subject['definitions']['postMultipleNestedParamsInBody']).to eql(
228
+ 'type' => 'object',
229
+ 'properties' => {
230
+ 'contact' => {
231
+ 'type' => 'object',
232
+ 'properties' => {
233
+ 'name' => { 'type' => 'string', 'description' => 'name' },
234
+ 'addresses' => {
235
+ 'type' => 'array',
236
+ 'items' => {
237
+ 'type' => 'object',
238
+ 'properties' => {
239
+ 'street' => { 'type' => 'string', 'description' => 'street' },
240
+ 'postcode' => { 'type' => 'integer', 'format' => 'int32', 'description' => 'postcode' },
241
+ 'city' => { 'type' => 'string', 'description' => 'city' },
242
+ 'country' => { 'type' => 'string', 'description' => 'country' }
243
+ },
244
+ 'required' => ['postcode']
245
+ }
246
+ },
247
+ 'delivery_address' => {
248
+ 'type' => 'object',
249
+ 'properties' => {
250
+ 'street' => { 'type' => 'string', 'description' => 'street' },
251
+ 'postcode' => { 'type' => 'string', 'description' => 'postcode' },
252
+ 'city' => { 'type' => 'string', 'description' => 'city' },
253
+ 'country' => { 'type' => 'string', 'description' => 'country' }
254
+ }
255
+ }
256
+ },
257
+ 'required' => %w[name]
258
+ }
259
+ },
260
+ 'description' => 'put in body with multiple nested parameters'
261
+ )
262
+ end
263
+ end
264
+
265
+ describe 'PUT' do
266
+ specify do
267
+ expect(subject['paths']['/multiple_nested_params/in_body/{id}']['put']['parameters']).to eql(
268
+ [
269
+ { 'in' => 'path', 'name' => 'id', 'type' => 'integer', 'format' => 'int32', 'required' => true },
270
+ { 'name' => 'putMultipleNestedParamsInBodyId', 'in' => 'body', 'required' => true, 'schema' => { '$ref' => '#/definitions/putMultipleNestedParamsInBodyId' } }
271
+ ]
272
+ )
273
+ end
274
+
275
+ specify do
276
+ expect(subject['definitions']['putMultipleNestedParamsInBodyId']).to eql(
277
+ 'type' => 'object',
278
+ 'properties' => {
279
+ 'name' => { 'type' => 'string', 'description' => 'name' },
280
+ 'address' => {
281
+ 'type' => 'object',
282
+ 'properties' => {
283
+ 'street' => { 'type' => 'string', 'description' => 'street' },
284
+ 'postcode' => { 'type' => 'string', 'description' => 'postcode' },
285
+ 'city' => { 'type' => 'string', 'description' => 'city' },
286
+ 'country' => { 'type' => 'string', 'description' => 'country' }
287
+ },
288
+ 'required' => ['postcode']
289
+ },
290
+ 'delivery_address' => {
291
+ 'type' => 'object',
292
+ 'properties' => {
293
+ 'street' => { 'type' => 'string', 'description' => 'street' },
294
+ 'postcode' => { 'type' => 'string', 'description' => 'postcode' },
295
+ 'city' => { 'type' => 'string', 'description' => 'city' },
296
+ 'country' => { 'type' => 'string', 'description' => 'country' }
297
+ }
298
+ }
299
+ },
300
+ 'description' => 'put in body with multiple nested parameters'
301
+ )
302
+ end
303
+ end
304
+ end
305
+
306
+ describe 'array of nested body parameters given' do
307
+ subject do
308
+ get '/swagger_doc/nested_params_array'
309
+ JSON.parse(last_response.body)
310
+ end
311
+
312
+ describe 'POST' do
313
+ specify do
314
+ expect(subject['paths']['/nested_params_array/in_body']['post']['parameters']).to eql(
315
+ [
316
+ { 'name' => 'postNestedParamsArrayInBody', 'in' => 'body', 'required' => true, 'schema' => { '$ref' => '#/definitions/postNestedParamsArrayInBody' } }
317
+ ]
318
+ )
319
+ end
320
+
321
+ specify do
322
+ expect(subject['definitions']['postNestedParamsArrayInBody']).to eql(
323
+ 'type' => 'object',
324
+ 'properties' => {
325
+ 'contacts' => {
326
+ 'type' => 'array',
327
+ 'items' => {
328
+ 'type' => 'object',
329
+ 'additionalProperties' => false,
330
+ 'properties' => {
331
+ 'name' => { 'type' => 'string', 'description' => 'name' },
332
+ 'addresses' => {
333
+ 'type' => 'array',
334
+ 'items' => {
335
+ 'type' => 'object',
336
+ 'properties' => {
337
+ 'street' => { 'type' => 'string', 'description' => 'street' },
338
+ 'postcode' => { 'type' => 'string', 'description' => 'postcode' },
339
+ 'city' => { 'type' => 'string', 'description' => 'city' },
340
+ 'country' => { 'type' => 'string', 'description' => 'country' }
341
+ },
342
+ 'required' => %w[street postcode city]
343
+ }
344
+ }
345
+ },
346
+ 'required' => %w[name]
347
+ }
348
+ }
349
+ },
350
+ 'description' => 'post in body with array of nested parameters'
351
+ )
352
+ end
353
+ end
354
+ end
355
+ end
@@ -0,0 +1,217 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'spec_helper'
4
+
5
+ describe 'setting of param type, such as `query`, `path`, `formData`, `body`, `header`' do
6
+ include_context "#{MODEL_PARSER} swagger example"
7
+
8
+ before :all do
9
+ module TheApi
10
+ class BodyParamTypeApi < Grape::API
11
+ namespace :wo_entities do
12
+ desc 'post in body /wo entity'
13
+ params do
14
+ requires :in_body_1, type: Integer, documentation: { desc: 'in_body_1', param_type: 'body' }
15
+ optional :in_body_2, type: String, documentation: { desc: 'in_body_2', param_type: 'body' }
16
+ optional :in_body_3, type: String, documentation: { desc: 'in_body_3', param_type: 'body' }
17
+ end
18
+
19
+ post '/in_body' do
20
+ { 'declared_params' => declared(params) }
21
+ end
22
+
23
+ desc 'put in body /wo entity'
24
+ params do
25
+ requires :key, type: Integer
26
+ optional :in_body_1, type: Integer, documentation: { desc: 'in_body_1', param_type: 'body' }
27
+ optional :in_body_2, type: String, documentation: { desc: 'in_body_2', param_type: 'body' }
28
+ optional :in_body_3, type: String, documentation: { desc: 'in_body_3', param_type: 'body' }
29
+ end
30
+
31
+ put '/in_body/:key' do
32
+ { 'declared_params' => declared(params) }
33
+ end
34
+ end
35
+
36
+ namespace :with_entities do
37
+ desc 'post in body with entity',
38
+ success: ::Entities::ResponseItem
39
+ params do
40
+ requires :name, type: String, documentation: { desc: 'name', param_type: 'body' }
41
+ end
42
+
43
+ post '/in_body' do
44
+ { 'declared_params' => declared(params) }
45
+ end
46
+
47
+ desc 'put in body with entity',
48
+ success: ::Entities::ResponseItem
49
+ params do
50
+ requires :id, type: Integer
51
+ optional :name, type: String, documentation: { desc: 'name', param_type: 'body' }
52
+ end
53
+
54
+ put '/in_body/:id' do
55
+ { 'declared_params' => declared(params) }
56
+ end
57
+ end
58
+
59
+ namespace :with_entity_param do
60
+ desc 'put in body with entity parameter'
61
+ params do
62
+ optional :data, type: ::Entities::NestedModule::ApiResponse, documentation: { desc: 'request data' }
63
+ end
64
+
65
+ post do
66
+ { 'declared_params' => declared(params) }
67
+ end
68
+ end
69
+
70
+ add_swagger_documentation
71
+ end
72
+ end
73
+ end
74
+
75
+ def app
76
+ TheApi::BodyParamTypeApi
77
+ end
78
+
79
+ describe 'no entity given' do
80
+ subject do
81
+ get '/swagger_doc/wo_entities'
82
+ JSON.parse(last_response.body)
83
+ end
84
+
85
+ specify do
86
+ expect(subject['paths']['/wo_entities/in_body']['post']['parameters']).to eql(
87
+ [
88
+ { 'name' => 'postWoEntitiesInBody', 'in' => 'body', 'required' => true, 'schema' => { '$ref' => '#/definitions/postWoEntitiesInBody' } }
89
+ ]
90
+ )
91
+ end
92
+
93
+ specify do
94
+ expect(subject['definitions']['postWoEntitiesInBody']).to eql(
95
+ 'description' => 'post in body /wo entity',
96
+ 'type' => 'object',
97
+ 'properties' => {
98
+ 'in_body_1' => { 'type' => 'integer', 'format' => 'int32', 'description' => 'in_body_1' },
99
+ 'in_body_2' => { 'type' => 'string', 'description' => 'in_body_2' },
100
+ 'in_body_3' => { 'type' => 'string', 'description' => 'in_body_3' }
101
+ },
102
+ 'required' => ['in_body_1']
103
+ )
104
+ end
105
+
106
+ specify do
107
+ expect(subject['paths']['/wo_entities/in_body/{key}']['put']['parameters']).to eql(
108
+ [
109
+ { 'in' => 'path', 'name' => 'key', 'type' => 'integer', 'format' => 'int32', 'required' => true },
110
+ { 'name' => 'putWoEntitiesInBodyKey', 'in' => 'body', 'required' => true, 'schema' => { '$ref' => '#/definitions/putWoEntitiesInBodyKey' } }
111
+ ]
112
+ )
113
+ end
114
+
115
+ specify do
116
+ expect(subject['definitions']['putWoEntitiesInBodyKey']).to eql(
117
+ 'description' => 'put in body /wo entity',
118
+ 'type' => 'object',
119
+ 'properties' => {
120
+ 'in_body_1' => { 'type' => 'integer', 'format' => 'int32', 'description' => 'in_body_1' },
121
+ 'in_body_2' => { 'type' => 'string', 'description' => 'in_body_2' },
122
+ 'in_body_3' => { 'type' => 'string', 'description' => 'in_body_3' }
123
+ }
124
+ )
125
+ end
126
+ end
127
+
128
+ describe 'entity given' do
129
+ subject do
130
+ get '/swagger_doc/with_entities'
131
+ JSON.parse(last_response.body)
132
+ end
133
+
134
+ specify do
135
+ expect(subject['paths']['/with_entities/in_body']['post']['parameters']).to eql(
136
+ [
137
+ { 'name' => 'postWithEntitiesInBody', 'in' => 'body', 'required' => true, 'schema' => { '$ref' => '#/definitions/postWithEntitiesInBody' } }
138
+ ]
139
+ )
140
+ end
141
+
142
+ specify do
143
+ expect(subject['definitions']['postWithEntitiesInBody']).to eql(
144
+ 'type' => 'object',
145
+ 'properties' => {
146
+ 'name' => { 'type' => 'string', 'description' => 'name' }
147
+ },
148
+ 'required' => ['name'],
149
+ 'description' => 'post in body with entity'
150
+ )
151
+ end
152
+
153
+ specify do
154
+ expect(subject['paths']['/with_entities/in_body/{id}']['put']['parameters']).to eql(
155
+ [
156
+ { 'in' => 'path', 'name' => 'id', 'type' => 'integer', 'format' => 'int32', 'required' => true },
157
+ { 'name' => 'putWithEntitiesInBodyId', 'in' => 'body', 'required' => true, 'schema' => { '$ref' => '#/definitions/putWithEntitiesInBodyId' } }
158
+ ]
159
+ )
160
+ end
161
+
162
+ specify do
163
+ expect(subject['definitions']['putWithEntitiesInBodyId']).to eql(
164
+ 'type' => 'object',
165
+ 'properties' => {
166
+ 'name' => { 'type' => 'string', 'description' => 'name' }
167
+ },
168
+ 'description' => 'put in body with entity'
169
+ )
170
+ end
171
+ end
172
+
173
+ describe 'complex entity given' do
174
+ let(:request_parameters_definition) do
175
+ [
176
+ {
177
+ 'name' => 'postWithEntityParam',
178
+ 'in' => 'body',
179
+ 'required' => true,
180
+ 'schema' => {
181
+ '$ref' => '#/definitions/postWithEntityParam'
182
+ }
183
+ }
184
+ ]
185
+ end
186
+
187
+ let(:request_body_parameters_definition) do
188
+ {
189
+ 'type' => 'object',
190
+ 'properties' => {
191
+ 'data' => {
192
+ '$ref' => '#/definitions/NestedModule_ApiResponse',
193
+ 'description' => 'request data'
194
+ }
195
+ },
196
+ 'description' => 'put in body with entity parameter'
197
+ }
198
+ end
199
+
200
+ subject do
201
+ get '/swagger_doc/with_entity_param'
202
+ JSON.parse(last_response.body)
203
+ end
204
+
205
+ specify do
206
+ expect(subject['paths']['/with_entity_param']['post']['parameters']).to eql(request_parameters_definition)
207
+ end
208
+
209
+ specify do
210
+ expect(subject['definitions']['NestedModule_ApiResponse']).not_to be_nil
211
+ end
212
+
213
+ specify do
214
+ expect(subject['definitions']['postWithEntityParam']).to eql(request_body_parameters_definition)
215
+ end
216
+ end
217
+ end