grape-swagger 0.20.3 → 0.21.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/.rubocop_todo.yml +10 -10
- data/.travis.yml +8 -3
- data/CHANGELOG.md +27 -0
- data/Gemfile +2 -0
- data/README.md +111 -12
- data/UPGRADING.md +9 -0
- data/grape-swagger.gemspec +1 -3
- data/lib/grape-swagger.rb +8 -1
- data/lib/grape-swagger/doc_methods/optional_object.rb +14 -2
- data/lib/grape-swagger/doc_methods/parse_params.rb +3 -4
- data/lib/grape-swagger/doc_methods/path_string.rb +4 -3
- data/lib/grape-swagger/endpoint.rb +25 -55
- data/lib/grape-swagger/errors.rb +3 -0
- data/lib/grape-swagger/grape/route.rb +2 -1
- data/lib/grape-swagger/model_parsers.rb +33 -0
- data/lib/grape-swagger/version.rb +1 -1
- data/spec/issues/403_versions_spec.rb +20 -4
- data/spec/lib/model_parsers_spec.rb +102 -0
- data/spec/lib/optional_object_spec.rb +15 -11
- data/spec/lib/path_string_spec.rb +72 -18
- data/spec/lib/produces_consumes_spec.rb +10 -5
- data/spec/spec_helper.rb +4 -2
- data/spec/support/empty_model_parser.rb +20 -0
- data/spec/support/mock_parser.rb +22 -0
- data/spec/support/model_parsers/entity_parser.rb +325 -0
- data/spec/support/{api_swagger_v2_result.rb → model_parsers/mock_parser.rb} +186 -60
- data/spec/support/model_parsers/representable_parser.rb +394 -0
- data/spec/support/the_paths_definitions.rb +7 -3
- data/spec/swagger_v2/api_swagger_v2_definitions-models_spec.rb +5 -4
- data/spec/swagger_v2/api_swagger_v2_detail_spec.rb +3 -3
- data/spec/swagger_v2/api_swagger_v2_extensions_spec.rb +1 -1
- data/spec/swagger_v2/api_swagger_v2_format-content_type_spec.rb +1 -1
- data/spec/swagger_v2/api_swagger_v2_headers_spec.rb +5 -3
- data/spec/swagger_v2/api_swagger_v2_hide_documentation_path_spec.rb +1 -1
- data/spec/swagger_v2/api_swagger_v2_mounted_spec.rb +1 -1
- data/spec/swagger_v2/api_swagger_v2_param_type_body_nested_spec.rb +25 -14
- data/spec/swagger_v2/api_swagger_v2_param_type_body_spec.rb +22 -12
- data/spec/swagger_v2/api_swagger_v2_param_type_spec.rb +30 -18
- data/spec/swagger_v2/api_swagger_v2_request_params_fix_spec.rb +6 -3
- data/spec/swagger_v2/api_swagger_v2_response_spec.rb +13 -40
- data/spec/swagger_v2/api_swagger_v2_spec.rb +4 -2
- data/spec/swagger_v2/api_swagger_v2_type-format_spec.rb +6 -36
- data/spec/swagger_v2/default_api_spec.rb +10 -2
- data/spec/swagger_v2/endpoint_versioned_path_spec.rb +30 -0
- data/spec/swagger_v2/errors_spec.rb +75 -0
- data/spec/swagger_v2/hide_api_spec.rb +22 -4
- data/spec/swagger_v2/mounted_target_class_spec.rb +6 -2
- data/spec/swagger_v2/namespace_tags_prefix_spec.rb +6 -3
- data/spec/swagger_v2/namespace_tags_spec.rb +6 -3
- data/spec/swagger_v2/params_array_spec.rb +4 -2
- data/spec/swagger_v2/params_hash_spec.rb +4 -2
- data/spec/swagger_v2/params_nested_spec.rb +4 -2
- data/spec/swagger_v2/simple_mounted_api_spec.rb +66 -24
- metadata +23 -40
- data/spec/support/the_api_entities.rb +0 -50
- data/spec/swagger_v2/response_model_spec.rb +0 -208
@@ -0,0 +1,394 @@
|
|
1
|
+
require 'representable/json'
|
2
|
+
|
3
|
+
RSpec.shared_context 'representable swagger example' do
|
4
|
+
before :all do
|
5
|
+
module Entities
|
6
|
+
class Something < Representable::Decorator
|
7
|
+
include Representable::JSON
|
8
|
+
|
9
|
+
class << self
|
10
|
+
# Representable doesn't have documentation method, mock this
|
11
|
+
def documentation
|
12
|
+
{
|
13
|
+
id: { type: Integer, desc: 'Identity of Something' },
|
14
|
+
text: { type: String, desc: 'Content of something.' },
|
15
|
+
links: { type: 'link', is_array: true },
|
16
|
+
others: { type: 'text', is_array: false }
|
17
|
+
}
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
property :id, documentation: { type: Integer, desc: 'Identity of Something' }
|
22
|
+
property :text, documentation: { type: String, desc: 'Content of something.' }
|
23
|
+
property :links, documentation: { type: 'link', is_array: true }
|
24
|
+
property :others, documentation: { type: 'text', is_array: false }
|
25
|
+
end
|
26
|
+
|
27
|
+
class EnumValues < Representable::Decorator
|
28
|
+
include Representable::JSON
|
29
|
+
|
30
|
+
property :gender, documentation: { type: 'string', desc: 'Content of something.', values: %w(Male Female) }
|
31
|
+
property :number, documentation: { type: 'integer', desc: 'Content of something.', values: [1, 2] }
|
32
|
+
end
|
33
|
+
|
34
|
+
class AliasedThing < Representable::Decorator
|
35
|
+
include Representable::JSON
|
36
|
+
|
37
|
+
property :something, as: :post, decorator: Entities::Something, documentation: { type: 'Something', desc: 'Reference to something.' }
|
38
|
+
end
|
39
|
+
|
40
|
+
class FourthLevel < Representable::Decorator
|
41
|
+
include Representable::JSON
|
42
|
+
|
43
|
+
property :text, documentation: { type: 'string' }
|
44
|
+
end
|
45
|
+
|
46
|
+
class ThirdLevel < Representable::Decorator
|
47
|
+
include Representable::JSON
|
48
|
+
|
49
|
+
property :parts, decorator: Entities::FourthLevel, documentation: { type: 'FourthLevel' }
|
50
|
+
end
|
51
|
+
|
52
|
+
class SecondLevel < Representable::Decorator
|
53
|
+
include Representable::JSON
|
54
|
+
|
55
|
+
property :parts, decorator: Entities::ThirdLevel, documentation: { type: 'ThirdLevel' }
|
56
|
+
end
|
57
|
+
|
58
|
+
class FirstLevel < Representable::Decorator
|
59
|
+
include Representable::JSON
|
60
|
+
|
61
|
+
property :parts, decorator: Entities::SecondLevel, documentation: { type: 'SecondLevel' }
|
62
|
+
end
|
63
|
+
|
64
|
+
class QueryInputElement < Representable::Decorator
|
65
|
+
include Representable::JSON
|
66
|
+
|
67
|
+
property :key, documentation: {
|
68
|
+
type: String, desc: 'Name of parameter', required: true
|
69
|
+
}
|
70
|
+
property :value, documentation: {
|
71
|
+
type: String, desc: 'Value of parameter', required: true
|
72
|
+
}
|
73
|
+
end
|
74
|
+
|
75
|
+
class QueryInput < Representable::Decorator
|
76
|
+
include Representable::JSON
|
77
|
+
|
78
|
+
property :elements, decorator: Entities::QueryInputElement, documentation: {
|
79
|
+
type: 'QueryInputElement',
|
80
|
+
desc: 'Set of configuration',
|
81
|
+
param_type: 'body',
|
82
|
+
is_array: true,
|
83
|
+
required: true
|
84
|
+
}
|
85
|
+
end
|
86
|
+
|
87
|
+
class ApiError < Representable::Decorator
|
88
|
+
include Representable::JSON
|
89
|
+
|
90
|
+
property :code, documentation: { type: Integer, desc: 'status code' }
|
91
|
+
property :message, documentation: { type: String, desc: 'error message' }
|
92
|
+
end
|
93
|
+
|
94
|
+
class SecondApiError < Representable::Decorator
|
95
|
+
include Representable::JSON
|
96
|
+
|
97
|
+
property :code, documentation: { type: Integer }
|
98
|
+
property :severity, documentation: { type: String }
|
99
|
+
property :message, documentation: { type: String }
|
100
|
+
end
|
101
|
+
|
102
|
+
class ResponseItem < Representable::Decorator
|
103
|
+
include Representable::JSON
|
104
|
+
|
105
|
+
class << self
|
106
|
+
def documentation
|
107
|
+
{
|
108
|
+
id: { type: Integer },
|
109
|
+
name: { type: String }
|
110
|
+
}
|
111
|
+
end
|
112
|
+
end
|
113
|
+
|
114
|
+
property :id, documentation: { type: Integer }
|
115
|
+
property :name, documentation: { type: String }
|
116
|
+
end
|
117
|
+
|
118
|
+
class OtherItem < Representable::Decorator
|
119
|
+
include Representable::JSON
|
120
|
+
|
121
|
+
property :key, documentation: { type: Integer }
|
122
|
+
property :symbol, documentation: { type: String }
|
123
|
+
end
|
124
|
+
|
125
|
+
class UseResponse < Representable::Decorator
|
126
|
+
include Representable::JSON
|
127
|
+
|
128
|
+
class << self
|
129
|
+
def documentation
|
130
|
+
{
|
131
|
+
:description => { type: String },
|
132
|
+
'$responses' => { is_array: true }
|
133
|
+
}
|
134
|
+
end
|
135
|
+
end
|
136
|
+
|
137
|
+
property :description, documentation: { type: String }
|
138
|
+
property :items, as: '$responses', decorator: Entities::ResponseItem, documentation: { is_array: true }
|
139
|
+
end
|
140
|
+
|
141
|
+
class UseItemResponseAsType < Representable::Decorator
|
142
|
+
include Representable::JSON
|
143
|
+
|
144
|
+
property :description, documentation: { type: String }
|
145
|
+
property :responses, documentation: { type: Entities::ResponseItem, is_array: false }
|
146
|
+
end
|
147
|
+
|
148
|
+
class UseAddress < Representable::Decorator
|
149
|
+
include Representable::JSON
|
150
|
+
|
151
|
+
property :street, documentation: { type: String, desc: 'street' }
|
152
|
+
property :postcode, documentation: { type: String, desc: 'postcode' }
|
153
|
+
property :city, documentation: { type: String, desc: 'city' }
|
154
|
+
property :country, documentation: { type: String, desc: 'country' }
|
155
|
+
end
|
156
|
+
|
157
|
+
class UseNestedWithAddress < Representable::Decorator
|
158
|
+
include Representable::JSON
|
159
|
+
|
160
|
+
property :name, documentation: { type: String }
|
161
|
+
property :address, decorator: Entities::UseAddress
|
162
|
+
end
|
163
|
+
|
164
|
+
class TypedDefinition < Representable::Decorator
|
165
|
+
include Representable::JSON
|
166
|
+
|
167
|
+
property :prop_integer, documentation: { type: Integer, desc: 'prop_integer description' }
|
168
|
+
property :prop_long, documentation: { type: Numeric, desc: 'prop_long description' }
|
169
|
+
property :prop_float, documentation: { type: Float, desc: 'prop_float description' }
|
170
|
+
property :prop_double, documentation: { type: BigDecimal, desc: 'prop_double description' }
|
171
|
+
property :prop_string, documentation: { type: String, desc: 'prop_string description' }
|
172
|
+
property :prop_symbol, documentation: { type: Symbol, desc: 'prop_symbol description' }
|
173
|
+
property :prop_date, documentation: { type: Date, desc: 'prop_date description' }
|
174
|
+
property :prop_date_time, documentation: { type: DateTime, desc: 'prop_date_time description' }
|
175
|
+
property :prop_time, documentation: { type: Time, desc: 'prop_time description' }
|
176
|
+
property :prop_password, documentation: { type: 'password', desc: 'prop_password description' }
|
177
|
+
property :prop_email, documentation: { type: 'email', desc: 'prop_email description' }
|
178
|
+
property :prop_boolean, documentation: { type: Virtus::Attribute::Boolean, desc: 'prop_boolean description' }
|
179
|
+
property :prop_file, documentation: { type: File, desc: 'prop_file description' }
|
180
|
+
property :prop_json, documentation: { type: JSON, desc: 'prop_json description' }
|
181
|
+
end
|
182
|
+
|
183
|
+
class RecursiveModel < Representable::Decorator
|
184
|
+
include Representable::JSON
|
185
|
+
|
186
|
+
property :name, documentation: { type: String, desc: 'The name.' }
|
187
|
+
property :children, decorator: self, documentation: { type: 'RecursiveModel', is_array: true, desc: 'The child nodes.' }
|
188
|
+
end
|
189
|
+
end
|
190
|
+
end
|
191
|
+
|
192
|
+
let(:swagger_definitions_models) do
|
193
|
+
{
|
194
|
+
'ApiError' => { 'type' => 'object', 'properties' => { 'code' => { 'description' => 'status code', 'type' => 'integer', 'format' => 'int32' }, 'message' => { 'description' => 'error message', 'type' => 'string' } } },
|
195
|
+
'ResponseItem' => { 'type' => 'object', 'properties' => { 'id' => { 'description' => '', 'type' => 'integer', 'format' => 'int32' }, 'name' => { 'description' => '', 'type' => 'string' } } },
|
196
|
+
'UseResponse' => { 'type' => 'object', 'properties' => { 'description' => { 'description' => '', 'type' => 'string' }, 'items' => { 'type' => 'array', 'items' => { '$ref' => '#/definitions/ResponseItem' }, 'description' => '' } } },
|
197
|
+
'RecursiveModel' => { 'type' => 'object', 'properties' => { 'name' => { 'type' => 'string', 'description' => 'The name.' }, 'children' => { 'type' => 'array', 'items' => { '$ref' => '#/definitions/RecursiveModel' }, 'description' => 'The child nodes.' } } }
|
198
|
+
}
|
199
|
+
end
|
200
|
+
|
201
|
+
let(:swagger_nested_type) do
|
202
|
+
{
|
203
|
+
'ApiError' => { 'type' => 'object', 'properties' => { 'code' => { 'description' => 'status code', 'type' => 'integer', 'format' => 'int32' }, 'message' => { 'description' => 'error message', 'type' => 'string' } }, 'description' => 'This returns something' },
|
204
|
+
'UseItemResponseAsType' => { 'type' => 'object', 'properties' => { 'description' => { 'description' => '', 'type' => 'string' }, 'responses' => { 'description' => '', 'type' => 'ResponseItem' } }, 'description' => 'This returns something' }
|
205
|
+
}
|
206
|
+
end
|
207
|
+
|
208
|
+
let(:swagger_entity_as_response_object) do
|
209
|
+
{
|
210
|
+
'ApiError' => { 'type' => 'object', 'properties' => { 'code' => { 'description' => 'status code', 'type' => 'integer', 'format' => 'int32' }, 'message' => { 'description' => 'error message', 'type' => 'string' } }, 'description' => 'This returns something' },
|
211
|
+
'ResponseItem' => { 'type' => 'object', 'properties' => { 'id' => { 'description' => '', 'type' => 'integer', 'format' => 'int32' }, 'name' => { 'description' => '', 'type' => 'string' } } },
|
212
|
+
'UseResponse' => { 'type' => 'object', 'properties' => { 'description' => { 'description' => '', 'type' => 'string' }, 'items' => { 'type' => 'array', 'items' => { '$ref' => '#/definitions/ResponseItem' }, 'description' => '' } }, 'description' => 'This returns something' }
|
213
|
+
}
|
214
|
+
end
|
215
|
+
|
216
|
+
let(:swagger_params_as_response_object) do
|
217
|
+
{
|
218
|
+
'ApiError' => { 'type' => 'object', 'properties' => { 'code' => { 'description' => 'status code', 'type' => 'integer', 'format' => 'int32' }, 'message' => { 'description' => 'error message', 'type' => 'string' } }, 'description' => 'This returns something' }
|
219
|
+
}
|
220
|
+
end
|
221
|
+
|
222
|
+
let(:swagger_typed_defintion) do
|
223
|
+
{
|
224
|
+
'prop_boolean' => { 'description' => 'prop_boolean description', 'type' => 'boolean' },
|
225
|
+
'prop_date' => { 'description' => 'prop_date description', 'type' => 'string', 'format' => 'date' },
|
226
|
+
'prop_date_time' => { 'description' => 'prop_date_time description', 'type' => 'string', 'format' => 'date-time' },
|
227
|
+
'prop_double' => { 'description' => 'prop_double description', 'type' => 'number', 'format' => 'double' },
|
228
|
+
'prop_email' => { 'description' => 'prop_email description', 'type' => 'string', 'format' => 'email' },
|
229
|
+
'prop_file' => { 'description' => 'prop_file description', 'type' => 'file' },
|
230
|
+
'prop_float' => { 'description' => 'prop_float description', 'type' => 'number', 'format' => 'float' },
|
231
|
+
'prop_integer' => { 'description' => 'prop_integer description', 'type' => 'integer', 'format' => 'int32' },
|
232
|
+
'prop_json' => { 'description' => 'prop_json description', 'type' => 'Representable::JSON' },
|
233
|
+
'prop_long' => { 'description' => 'prop_long description', 'type' => 'integer', 'format' => 'int64' },
|
234
|
+
'prop_password' => { 'description' => 'prop_password description', 'type' => 'string', 'format' => 'password' },
|
235
|
+
'prop_string' => { 'description' => 'prop_string description', 'type' => 'string' },
|
236
|
+
'prop_symbol' => { 'description' => 'prop_symbol description', 'type' => 'string' },
|
237
|
+
'prop_time' => { 'description' => 'prop_time description', 'type' => 'string', 'format' => 'date-time' }
|
238
|
+
}
|
239
|
+
end
|
240
|
+
|
241
|
+
let(:swagger_json) do
|
242
|
+
{
|
243
|
+
'info' => {
|
244
|
+
'title' => 'The API title to be displayed on the API homepage.',
|
245
|
+
'description' => 'A description of the API.',
|
246
|
+
'termsOfServiceUrl' => 'www.The-URL-of-the-terms-and-service.com',
|
247
|
+
'contact' => { 'name' => 'Contact name', 'email' => 'Contact@email.com', 'url' => 'Contact URL' },
|
248
|
+
'license' => { 'name' => 'The name of the license.', 'url' => 'www.The-URL-of-the-license.org' },
|
249
|
+
'version' => '0.0.1'
|
250
|
+
},
|
251
|
+
'swagger' => '2.0',
|
252
|
+
'produces' => ['application/json'],
|
253
|
+
'host' => 'example.org',
|
254
|
+
'basePath' => '/api',
|
255
|
+
'tags' => [
|
256
|
+
{ 'name' => 'other_thing', 'description' => 'Operations about other_things' },
|
257
|
+
{ 'name' => 'thing', 'description' => 'Operations about things' },
|
258
|
+
{ 'name' => 'thing2', 'description' => 'Operations about thing2s' },
|
259
|
+
{ 'name' => 'dummy', 'description' => 'Operations about dummies' }
|
260
|
+
],
|
261
|
+
'paths' => {
|
262
|
+
'/v3/other_thing/{elements}' => {
|
263
|
+
'get' => {
|
264
|
+
'summary' => 'nested route inside namespace',
|
265
|
+
'description' => 'nested route inside namespace',
|
266
|
+
'produces' => ['application/json'],
|
267
|
+
'parameters' => [{ 'in' => 'body', 'name' => 'elements', 'description' => 'Set of configuration', 'type' => 'array', 'items' => { 'type' => 'string' }, 'required' => true }],
|
268
|
+
'responses' => { '200' => { 'description' => 'nested route inside namespace', 'schema' => { '$ref' => '#/definitions/QueryInput' } } },
|
269
|
+
'tags' => ['other_thing'],
|
270
|
+
'operationId' => 'getV3OtherThingElements',
|
271
|
+
'x-amazon-apigateway-auth' => { 'type' => 'none' },
|
272
|
+
'x-amazon-apigateway-integration' => { 'type' => 'aws', 'uri' => 'foo_bar_uri', 'httpMethod' => 'get' }
|
273
|
+
}
|
274
|
+
},
|
275
|
+
'/thing' => {
|
276
|
+
'get' => {
|
277
|
+
'summary' => 'This gets Things.',
|
278
|
+
'description' => 'This gets Things.',
|
279
|
+
'produces' => ['application/json'],
|
280
|
+
'parameters' => [
|
281
|
+
{ 'in' => 'query', 'name' => 'id', 'description' => 'Identity of Something', 'type' => 'integer', 'format' => 'int32', 'required' => false },
|
282
|
+
{ 'in' => 'query', 'name' => 'text', 'description' => 'Content of something.', 'type' => 'string', 'required' => false },
|
283
|
+
{ 'in' => 'formData', 'name' => 'links', 'type' => 'array', 'items' => { 'type' => 'link' }, 'required' => false },
|
284
|
+
{ 'in' => 'query', 'name' => 'others', 'type' => 'text', 'required' => false }
|
285
|
+
],
|
286
|
+
'responses' => { '200' => { 'description' => 'This gets Things.' }, '401' => { 'description' => 'Unauthorized', 'schema' => { '$ref' => '#/definitions/ApiError' } } },
|
287
|
+
'tags' => ['thing'],
|
288
|
+
'operationId' => 'getThing'
|
289
|
+
},
|
290
|
+
'post' => {
|
291
|
+
'summary' => 'This creates Thing.',
|
292
|
+
'description' => 'This creates Thing.',
|
293
|
+
'produces' => ['application/json'],
|
294
|
+
'consumes' => ['application/json'],
|
295
|
+
'parameters' => [
|
296
|
+
{ 'in' => 'formData', 'name' => 'text', 'description' => 'Content of something.', 'type' => 'string', 'required' => true },
|
297
|
+
{ 'in' => 'formData', 'name' => 'links', 'type' => 'array', 'items' => { 'type' => 'string' }, 'required' => true }
|
298
|
+
],
|
299
|
+
'responses' => { '201' => { 'description' => 'This creates Thing.', 'schema' => { '$ref' => '#/definitions/Something' } }, '422' => { 'description' => 'Unprocessible Entity' } },
|
300
|
+
'tags' => ['thing'],
|
301
|
+
'operationId' => 'postThing'
|
302
|
+
}
|
303
|
+
},
|
304
|
+
'/thing/{id}' => {
|
305
|
+
'get' => {
|
306
|
+
'summary' => 'This gets Thing.',
|
307
|
+
'description' => 'This gets Thing.',
|
308
|
+
'produces' => ['application/json'],
|
309
|
+
'parameters' => [{ 'in' => 'path', 'name' => 'id', 'type' => 'integer', 'format' => 'int32', 'required' => true }],
|
310
|
+
'responses' => { '200' => { 'description' => 'getting a single thing' }, '401' => { 'description' => 'Unauthorized' } },
|
311
|
+
'tags' => ['thing'],
|
312
|
+
'operationId' => 'getThingId'
|
313
|
+
},
|
314
|
+
'put' => {
|
315
|
+
'summary' => 'This updates Thing.',
|
316
|
+
'description' => 'This updates Thing.',
|
317
|
+
'produces' => ['application/json'],
|
318
|
+
'consumes' => ['application/json'],
|
319
|
+
'parameters' => [
|
320
|
+
{ 'in' => 'path', 'name' => 'id', 'type' => 'integer', 'format' => 'int32', 'required' => true },
|
321
|
+
{ 'in' => 'formData', 'name' => 'text', 'description' => 'Content of something.', 'type' => 'string', 'required' => false },
|
322
|
+
{ 'in' => 'formData', 'name' => 'links', 'type' => 'array', 'items' => { 'type' => 'string' }, 'required' => false }
|
323
|
+
],
|
324
|
+
'responses' => { '200' => { 'description' => 'This updates Thing.', 'schema' => { '$ref' => '#/definitions/Something' } } },
|
325
|
+
'tags' => ['thing'],
|
326
|
+
'operationId' => 'putThingId'
|
327
|
+
},
|
328
|
+
'delete' => {
|
329
|
+
'summary' => 'This deletes Thing.',
|
330
|
+
'description' => 'This deletes Thing.',
|
331
|
+
'produces' => ['application/json'],
|
332
|
+
'parameters' => [{ 'in' => 'path', 'name' => 'id', 'type' => 'integer', 'format' => 'int32', 'required' => true }],
|
333
|
+
'responses' => { '200' => { 'description' => 'This deletes Thing.', 'schema' => { '$ref' => '#/definitions/Something' } } },
|
334
|
+
'tags' => ['thing'],
|
335
|
+
'operationId' => 'deleteThingId'
|
336
|
+
}
|
337
|
+
},
|
338
|
+
'/thing2' => {
|
339
|
+
'get' => {
|
340
|
+
'summary' => 'This gets Things.',
|
341
|
+
'description' => 'This gets Things.',
|
342
|
+
'produces' => ['application/json'],
|
343
|
+
'responses' => { '200' => { 'description' => 'get Horses', 'schema' => { '$ref' => '#/definitions/Something' } }, '401' => { 'description' => 'HorsesOutError', 'schema' => { '$ref' => '#/definitions/ApiError' } } },
|
344
|
+
'tags' => ['thing2'],
|
345
|
+
'operationId' => 'getThing2'
|
346
|
+
}
|
347
|
+
},
|
348
|
+
'/dummy/{id}' => {
|
349
|
+
'delete' => {
|
350
|
+
'summary' => 'dummy route.',
|
351
|
+
'description' => 'dummy route.',
|
352
|
+
'produces' => ['application/json'],
|
353
|
+
'parameters' => [{ 'in' => 'path', 'name' => 'id', 'type' => 'integer', 'format' => 'int32', 'required' => true }],
|
354
|
+
'responses' => { '204' => { 'description' => 'dummy route.' }, '401' => { 'description' => 'Unauthorized' } },
|
355
|
+
'tags' => ['dummy'],
|
356
|
+
'operationId' => 'deleteDummyId'
|
357
|
+
}
|
358
|
+
}
|
359
|
+
},
|
360
|
+
'definitions' => {
|
361
|
+
'QueryInput' => {
|
362
|
+
'type' => 'object',
|
363
|
+
'properties' => { 'elements' => { 'type' => 'array', 'items' => { '$ref' => '#/definitions/QueryInputElement' }, 'description' => 'Set of configuration' } },
|
364
|
+
'description' => 'nested route inside namespace'
|
365
|
+
},
|
366
|
+
'QueryInputElement' => {
|
367
|
+
'type' => 'object',
|
368
|
+
'properties' => { 'key' => { 'type' => 'string', 'description' => 'Name of parameter' }, 'value' => { 'type' => 'string', 'description' => 'Value of parameter' } }
|
369
|
+
},
|
370
|
+
'ApiError' => {
|
371
|
+
'type' => 'object',
|
372
|
+
'properties' => { 'code' => { 'type' => 'integer', 'format' => 'int32', 'description' => 'status code' }, 'message' => { 'type' => 'string', 'description' => 'error message' } },
|
373
|
+
'description' => 'This gets Things.'
|
374
|
+
},
|
375
|
+
'Something' => {
|
376
|
+
'type' => 'object',
|
377
|
+
'properties' => {
|
378
|
+
'id' => { 'type' => 'integer', 'format' => 'int32', 'description' => 'Identity of Something' },
|
379
|
+
'text' => { 'type' => 'string', 'description' => 'Content of something.' },
|
380
|
+
'links' => { 'type' => 'array', 'items' => { 'description' => '', 'type' => 'link' } },
|
381
|
+
'others' => { 'description' => '', 'type' => 'text' }
|
382
|
+
},
|
383
|
+
'description' => 'This gets Things.'
|
384
|
+
}
|
385
|
+
}
|
386
|
+
}
|
387
|
+
end
|
388
|
+
|
389
|
+
let(:http_verbs) { %w(get post put delete) }
|
390
|
+
end
|
391
|
+
|
392
|
+
def mounted_paths
|
393
|
+
%w( /thing /other_thing /dummy )
|
394
|
+
end
|
@@ -43,7 +43,8 @@ RSpec.shared_context 'the api paths/defs' do
|
|
43
43
|
responses: { 200 => { description: 'get in path /wo entity', schema: { '$ref' => '#/definitions/InBody' } } },
|
44
44
|
tags: ['in_body'],
|
45
45
|
operationId: 'getInBodyKey'
|
46
|
-
}
|
46
|
+
}
|
47
|
+
}
|
47
48
|
}
|
48
49
|
end
|
49
50
|
|
@@ -60,7 +61,8 @@ RSpec.shared_context 'the api paths/defs' do
|
|
60
61
|
responses: { 201 => { description: 'post in body /wo entity', schema: { '$ref' => '#/definitions/InBody' } } },
|
61
62
|
tags: ['in_body'],
|
62
63
|
operationId: 'postInBody'
|
63
|
-
}
|
64
|
+
}
|
65
|
+
}
|
64
66
|
end
|
65
67
|
|
66
68
|
let(:definitions) do
|
@@ -72,7 +74,9 @@ RSpec.shared_context 'the api paths/defs' do
|
|
72
74
|
in_body_2: { type: 'string' },
|
73
75
|
in_body_3: { type: 'string' },
|
74
76
|
key: { type: 'integer', format: 'int32' }
|
75
|
-
}
|
77
|
+
}
|
78
|
+
}
|
79
|
+
}
|
76
80
|
end
|
77
81
|
|
78
82
|
let(:expected_post_defs) do
|
@@ -1,7 +1,7 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
|
3
3
|
describe 'definitions/models' do
|
4
|
-
include_context
|
4
|
+
include_context "#{MODEL_PARSER} swagger example"
|
5
5
|
|
6
6
|
before :all do
|
7
7
|
module TheApi
|
@@ -9,8 +9,9 @@ describe 'definitions/models' do
|
|
9
9
|
format :json
|
10
10
|
|
11
11
|
add_swagger_documentation models: [
|
12
|
-
|
13
|
-
|
12
|
+
::Entities::UseResponse,
|
13
|
+
::Entities::ApiError,
|
14
|
+
::Entities::RecursiveModel
|
14
15
|
]
|
15
16
|
end
|
16
17
|
end
|
@@ -27,6 +28,6 @@ describe 'definitions/models' do
|
|
27
28
|
|
28
29
|
specify do
|
29
30
|
expect(subject).to include 'definitions'
|
30
|
-
expect(subject['definitions']).to include
|
31
|
+
expect(subject['definitions']).to include(swagger_definitions_models)
|
31
32
|
end
|
32
33
|
end
|