grape-swagger 0.21.0 → 0.22.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.yml +1 -0
- data/.rubocop_todo.yml +1 -1
- data/CHANGELOG.md +24 -2
- data/Gemfile +5 -0
- data/README.md +105 -3
- data/example/api/endpoints.rb +16 -16
- data/lib/grape-swagger.rb +0 -1
- data/lib/grape-swagger/doc_methods.rb +1 -0
- data/lib/grape-swagger/doc_methods/data_type.rb +15 -3
- data/lib/grape-swagger/doc_methods/extensions.rb +16 -12
- data/lib/grape-swagger/doc_methods/move_params.rb +139 -94
- data/lib/grape-swagger/doc_methods/parse_params.rb +9 -7
- data/lib/grape-swagger/endpoint.rb +36 -17
- data/lib/grape-swagger/version.rb +1 -1
- data/spec/lib/data_type_spec.rb +24 -0
- data/spec/lib/endpoint_spec.rb +13 -0
- data/spec/lib/move_params_spec.rb +124 -116
- data/spec/support/model_parsers/entity_parser.rb +8 -2
- data/spec/support/model_parsers/mock_parser.rb +10 -0
- data/spec/support/model_parsers/representable_parser.rb +7 -0
- data/spec/support/the_paths_definitions.rb +1 -2
- data/spec/swagger_v2/api_swagger_v2_definitions-models_spec.rb +2 -1
- data/spec/swagger_v2/api_swagger_v2_detail_spec.rb +1 -1
- data/spec/swagger_v2/api_swagger_v2_extensions_spec.rb +22 -1
- data/spec/swagger_v2/api_swagger_v2_global_configuration_spec.rb +4 -1
- data/spec/swagger_v2/api_swagger_v2_hash_and_array_spec.rb +60 -0
- data/spec/swagger_v2/api_swagger_v2_headers_spec.rb +14 -9
- data/spec/swagger_v2/api_swagger_v2_hide_param_spec.rb +90 -0
- data/spec/swagger_v2/api_swagger_v2_param_type_body_nested_spec.rb +185 -110
- data/spec/swagger_v2/api_swagger_v2_param_type_body_spec.rb +11 -13
- data/spec/swagger_v2/api_swagger_v2_response_spec.rb +5 -5
- data/spec/swagger_v2/endpoint_versioned_path_spec.rb +19 -18
- data/spec/swagger_v2/namespaced_api_spec.rb +20 -0
- data/spec/swagger_v2/param_multi_type_spec.rb +73 -0
- data/spec/swagger_v2/param_type_spec.rb +54 -27
- data/spec/swagger_v2/params_array_spec.rb +96 -6
- data/spec/swagger_v2/params_nested_spec.rb +2 -2
- metadata +9 -3
@@ -116,6 +116,11 @@ RSpec.shared_context 'entity swagger example' do
|
|
116
116
|
expose :name, documentation: { type: String, desc: 'The name.' }
|
117
117
|
expose :children, using: self, documentation: { type: 'RecursiveModel', is_array: true, desc: 'The child nodes.' }
|
118
118
|
end
|
119
|
+
|
120
|
+
class DocumentedHashAndArrayModel < Grape::Entity
|
121
|
+
expose :raw_hash, documentation: { type: Hash, desc: 'Example Hash.', documentation: { in: 'body' } }
|
122
|
+
expose :raw_array, documentation: { type: Array, desc: 'Example Array', documentation: { in: 'body' } }
|
123
|
+
end
|
119
124
|
end
|
120
125
|
end
|
121
126
|
|
@@ -124,7 +129,8 @@ RSpec.shared_context 'entity swagger example' do
|
|
124
129
|
'ApiError' => { 'type' => 'object', 'properties' => { 'code' => { 'type' => 'integer', 'format' => 'int32', 'description' => 'status code' }, 'message' => { 'type' => 'string', 'description' => 'error message' } } },
|
125
130
|
'ResponseItem' => { 'type' => 'object', 'properties' => { 'id' => { 'type' => 'integer', 'format' => 'int32' }, 'name' => { 'type' => 'string' } } },
|
126
131
|
'UseResponse' => { 'type' => 'object', 'properties' => { 'description' => { 'type' => 'string' }, '$responses' => { 'type' => 'array', 'items' => { '$ref' => '#/definitions/ResponseItem' } } } },
|
127
|
-
'RecursiveModel' => { 'type' => 'object', 'properties' => { 'name' => { 'type' => 'string', 'description' => 'The name.' }, 'children' => { 'type' => 'array', 'items' => { '$ref' => '#/definitions/RecursiveModel' }, 'description' => 'The child nodes.' } } }
|
132
|
+
'RecursiveModel' => { 'type' => 'object', 'properties' => { 'name' => { 'type' => 'string', 'description' => 'The name.' }, 'children' => { 'type' => 'array', 'items' => { '$ref' => '#/definitions/RecursiveModel' }, 'description' => 'The child nodes.' } } },
|
133
|
+
'DocumentedHashAndArrayModel' => { 'type' => 'object', 'properties' => { 'raw_hash' => { 'type' => 'object', 'description' => 'Example Hash.' }, 'raw_array' => { 'type' => 'array', 'description' => 'Example Array' } } }
|
128
134
|
}
|
129
135
|
end
|
130
136
|
|
@@ -308,7 +314,7 @@ RSpec.shared_context 'entity swagger example' do
|
|
308
314
|
'properties' => {
|
309
315
|
'id' => { 'type' => 'integer', 'format' => 'int32', 'description' => 'Identity of Something' },
|
310
316
|
'text' => { 'type' => 'string', 'description' => 'Content of something.' },
|
311
|
-
'links' => { 'type' => 'link' },
|
317
|
+
'links' => { 'type' => 'array', 'items' => { 'type' => 'link' } },
|
312
318
|
'others' => { 'type' => 'text' }
|
313
319
|
},
|
314
320
|
'description' => 'This gets Things.'
|
@@ -52,6 +52,7 @@ RSpec.shared_context 'mock swagger example' do
|
|
52
52
|
class ApiError < OpenStruct; end
|
53
53
|
class SecondApiError < OpenStruct; end
|
54
54
|
class RecursiveModel < OpenStruct; end
|
55
|
+
class DocumentedHashAndArrayModel < OpenStruct; end
|
55
56
|
end
|
56
57
|
end
|
57
58
|
|
@@ -83,6 +84,15 @@ RSpec.shared_context 'mock swagger example' do
|
|
83
84
|
'description' => "it's a mock"
|
84
85
|
}
|
85
86
|
}
|
87
|
+
},
|
88
|
+
'DocumentedHashAndArrayModel' => {
|
89
|
+
'type' => 'object',
|
90
|
+
'properties' => {
|
91
|
+
'mock_data' => {
|
92
|
+
'type' => 'string',
|
93
|
+
'description' => "it's a mock"
|
94
|
+
}
|
95
|
+
}
|
86
96
|
}
|
87
97
|
}
|
88
98
|
end
|
@@ -186,6 +186,13 @@ RSpec.shared_context 'representable swagger example' do
|
|
186
186
|
property :name, documentation: { type: String, desc: 'The name.' }
|
187
187
|
property :children, decorator: self, documentation: { type: 'RecursiveModel', is_array: true, desc: 'The child nodes.' }
|
188
188
|
end
|
189
|
+
|
190
|
+
class DocumentedHashAndArrayModel < Representable::Decorator
|
191
|
+
include Representable::JSON
|
192
|
+
|
193
|
+
property :raw_hash, documentation: { type: Hash, desc: 'Example Hash.' }
|
194
|
+
property :raw_array, documentation: { type: Array, desc: 'Example Array' }
|
195
|
+
end
|
189
196
|
end
|
190
197
|
end
|
191
198
|
|
@@ -97,8 +97,7 @@ RSpec.shared_context 'the api paths/defs' do
|
|
97
97
|
properties: {
|
98
98
|
in_body_1: { type: 'integer', format: 'int32', description: 'in_body_1' },
|
99
99
|
in_body_2: { type: 'string', description: 'in_body_2' },
|
100
|
-
in_body_3: { type: 'string', description: 'in_body_3' }
|
101
|
-
key: { type: 'integer', format: 'int32', readOnly: true }
|
100
|
+
in_body_3: { type: 'string', description: 'in_body_3' }
|
102
101
|
},
|
103
102
|
required: [:in_body_1]
|
104
103
|
}
|
@@ -144,7 +144,7 @@ describe 'details' do
|
|
144
144
|
specify do
|
145
145
|
expect(subject['paths']['/use_gfm_rc_detail']['get']).to include('description')
|
146
146
|
expect(subject['paths']['/use_gfm_rc_detail']['get']['description']).to eql(
|
147
|
-
"<h1>This returns something</h1>\n\n<p># Burgers in Heaven</p>\n\n<blockquote>\n<p>A burger doesn't come for free</p>\n</blockquote>\n\n<p>If you want to reserve a burger in heaven, you have to do\nsome crazy stuff on earth.</p>\n<pre class=\"highlight plaintext\"><code>def do_good\nputs 'help people'\nend\n</code></pre>\n
|
147
|
+
"<h1>This returns something</h1>\n\n<p># Burgers in Heaven</p>\n\n<blockquote>\n<p>A burger doesn't come for free</p>\n</blockquote>\n\n<p>If you want to reserve a burger in heaven, you have to do\nsome crazy stuff on earth.</p>\n<pre class=\"highlight plaintext\"><code>def do_good\nputs 'help people'\nend\n</code></pre>\n<ul>\n<li><em>Will go to Heaven:</em> Probably</li>\n<li><em>Will go to Hell:</em> Probably not</li>\n</ul>"
|
148
148
|
)
|
149
149
|
end
|
150
150
|
end
|
@@ -1,6 +1,6 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
|
3
|
-
describe '
|
3
|
+
describe 'extensions' do
|
4
4
|
include_context "#{MODEL_PARSER} swagger example"
|
5
5
|
|
6
6
|
before :all do
|
@@ -40,6 +40,14 @@ describe 'extension' do
|
|
40
40
|
|
41
41
|
route_setting :x_def, [{ for: 422, other: 'stuff' }, { for: 200, some: 'stuff' }]
|
42
42
|
|
43
|
+
desc 'This returns something with extension on definition level',
|
44
|
+
success: Entities::OtherItem
|
45
|
+
get '/non_existend_status_definitions_extension' do
|
46
|
+
{ 'declared_params' => declared(params) }
|
47
|
+
end
|
48
|
+
|
49
|
+
route_setting :x_def, [{ for: 422, other: 'stuff' }, { for: 200, some: 'stuff' }]
|
50
|
+
|
43
51
|
desc 'This returns something with extension on definition level',
|
44
52
|
success: Entities::OtherItem,
|
45
53
|
failure: [{ code: 422, message: 'NotFound', model: Entities::SecondApiError }]
|
@@ -106,4 +114,17 @@ describe 'extension' do
|
|
106
114
|
expect(subject['definitions']['SecondApiError']['x-other']).to eql 'stuff'
|
107
115
|
end
|
108
116
|
end
|
117
|
+
|
118
|
+
describe 'extension on definition level' do
|
119
|
+
subject do
|
120
|
+
get '/swagger_doc/non_existend_status_definitions_extension'
|
121
|
+
JSON.parse(last_response.body)
|
122
|
+
end
|
123
|
+
|
124
|
+
specify do
|
125
|
+
expect(subject['definitions'].length).to eql 1
|
126
|
+
expect(subject['definitions']['OtherItem']).to include 'x-some'
|
127
|
+
expect(subject['definitions']['OtherItem']['x-some']).to eql 'stuff'
|
128
|
+
end
|
129
|
+
end
|
109
130
|
end
|
@@ -23,7 +23,8 @@ describe 'global configuration stuff' do
|
|
23
23
|
base_path: -> { 'somewhere/over/the/rainbow' },
|
24
24
|
mount_path: 'documentation',
|
25
25
|
add_base_path: true,
|
26
|
-
add_version: true
|
26
|
+
add_version: true,
|
27
|
+
security_definitions: { api_key: { foo: 'bar' } }
|
27
28
|
end
|
28
29
|
end
|
29
30
|
end
|
@@ -44,6 +45,8 @@ describe 'global configuration stuff' do
|
|
44
45
|
expect(subject['basePath']).to eql 'somewhere/over/the/rainbow'
|
45
46
|
expect(subject['paths'].keys.first).to eql '/somewhere/over/the/rainbow/v3/configuration'
|
46
47
|
expect(subject['schemes']).to eql ['https']
|
48
|
+
expect(subject['securityDefinitions'].keys).to include('api_key')
|
49
|
+
expect(subject['securityDefinitions']['api_key']).to include('foo' => 'bar')
|
47
50
|
end
|
48
51
|
end
|
49
52
|
end
|
@@ -0,0 +1,60 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe 'document hash and array' do
|
4
|
+
include_context "#{MODEL_PARSER} swagger example"
|
5
|
+
|
6
|
+
before :all do
|
7
|
+
module TheApi
|
8
|
+
class TestApi < Grape::API
|
9
|
+
format :json
|
10
|
+
|
11
|
+
documentation = ::Entities::DocumentedHashAndArrayModel.documentation if ::Entities::DocumentedHashAndArrayModel.respond_to?(:documentation)
|
12
|
+
|
13
|
+
desc 'This returns something'
|
14
|
+
namespace :arbitrary do
|
15
|
+
params do
|
16
|
+
requires :id, type: Integer
|
17
|
+
end
|
18
|
+
route_param :id do
|
19
|
+
desc 'Timeless treasure'
|
20
|
+
params do
|
21
|
+
requires :body, using: documentation unless documentation.nil?
|
22
|
+
requires :raw_hash, type: Hash, documentation: { param_type: 'body' } if documentation.nil?
|
23
|
+
requires :raw_array, type: Array, documentation: { param_type: 'body' } if documentation.nil?
|
24
|
+
end
|
25
|
+
put '/id_and_hash' do
|
26
|
+
{}
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
add_swagger_documentation
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
def app
|
37
|
+
TheApi::TestApi
|
38
|
+
end
|
39
|
+
|
40
|
+
subject do
|
41
|
+
get '/swagger_doc'
|
42
|
+
JSON.parse(last_response.body)
|
43
|
+
end
|
44
|
+
describe 'generated request definition' do
|
45
|
+
it 'has hash' do
|
46
|
+
expect(subject['definitions'].keys).to include('putArbitraryIdIdAndHash')
|
47
|
+
expect(subject['definitions']['putArbitraryIdIdAndHash']['properties'].keys).to include('raw_hash')
|
48
|
+
end
|
49
|
+
|
50
|
+
it 'has array' do
|
51
|
+
expect(subject['definitions'].keys).to include('putArbitraryIdIdAndHash')
|
52
|
+
expect(subject['definitions']['putArbitraryIdIdAndHash']['properties'].keys).to include('raw_array')
|
53
|
+
end
|
54
|
+
|
55
|
+
it 'does not have the path parameter' do
|
56
|
+
expect(subject['definitions'].keys).to include('putArbitraryIdIdAndHash')
|
57
|
+
expect(subject['definitions']['putArbitraryIdIdAndHash']).to_not include('id')
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
@@ -18,6 +18,9 @@ describe 'headers' do
|
|
18
18
|
},
|
19
19
|
|
20
20
|
entity: Entities::UseResponse
|
21
|
+
params do
|
22
|
+
optional :param_x, type: String, desc: 'This is a parameter', documentation: { param_type: 'query' }
|
23
|
+
end
|
21
24
|
get '/use_headers' do
|
22
25
|
{ 'declared_params' => declared(params) }
|
23
26
|
end
|
@@ -37,15 +40,17 @@ describe 'headers' do
|
|
37
40
|
end
|
38
41
|
|
39
42
|
specify do
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
]
|
43
|
+
parameters = subject['paths']['/use_headers']['get']['parameters']
|
44
|
+
expect(parameters).to include(
|
45
|
+
'in' => 'header',
|
46
|
+
'name' => 'X-Rate-Limit-Limit',
|
47
|
+
'description' => 'The number of allowed requests in the current period',
|
48
|
+
'type' => 'integer',
|
49
|
+
'format' => 'int32',
|
50
|
+
'required' => false
|
49
51
|
)
|
52
|
+
expect(parameters.size).to eq(2)
|
53
|
+
expect(parameters.first['in']).to eq('header')
|
54
|
+
expect(parameters.last['in']).to eq('query')
|
50
55
|
end
|
51
56
|
end
|
@@ -0,0 +1,90 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe 'hidden flag enables a single endpoint parameter to be excluded from the documentation' do
|
4
|
+
include_context "#{MODEL_PARSER} swagger example"
|
5
|
+
before :all do
|
6
|
+
module TheApi
|
7
|
+
class HideParamsApi < Grape::API
|
8
|
+
namespace :flat_params_endpoint do
|
9
|
+
desc 'This is a endpoint with a flat parameter hierarchy'
|
10
|
+
params do
|
11
|
+
requires :name, type: String, documentation: { desc: 'name' }
|
12
|
+
optional :favourite_color, type: String, documentation: { desc: 'I should not be anywhere', hidden: true }
|
13
|
+
optional :proc_param, type: String, documentation: { desc: 'I should not be anywhere', hidden: -> { true } }
|
14
|
+
end
|
15
|
+
|
16
|
+
post do
|
17
|
+
{ 'declared_params' => declared(params) }
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
namespace :nested_params_endpoint do
|
22
|
+
desc 'This is a endpoint with a nested parameter hierarchy'
|
23
|
+
params do
|
24
|
+
optional :name, type: String, documentation: { desc: 'name' }
|
25
|
+
optional :hidden_attribute, type: Hash do
|
26
|
+
optional :favourite_color, type: String, documentation: { desc: 'I should not be anywhere', hidden: true }
|
27
|
+
end
|
28
|
+
|
29
|
+
optional :attributes, type: Hash do
|
30
|
+
optional :attribute_1, type: String, documentation: { desc: 'Attribute one' }
|
31
|
+
optional :hidden_attribute, type: String, documentation: { desc: 'I should not be anywhere', hidden: true }
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
post do
|
36
|
+
{ 'declared_params' => declared(params) }
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
namespace :required_param_endpoint do
|
41
|
+
desc 'This endpoint has hidden defined for a required parameter'
|
42
|
+
params do
|
43
|
+
requires :name, type: String, documentation: { desc: 'name', hidden: true }
|
44
|
+
end
|
45
|
+
|
46
|
+
post do
|
47
|
+
{ 'declared_params' => declared(params) }
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
add_swagger_documentation
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
let(:app) { TheApi::HideParamsApi }
|
57
|
+
|
58
|
+
describe 'simple flat parameter hierarchy' do
|
59
|
+
subject do
|
60
|
+
get '/swagger_doc/flat_params_endpoint'
|
61
|
+
JSON.parse(last_response.body)
|
62
|
+
end
|
63
|
+
|
64
|
+
specify do
|
65
|
+
expect(subject['paths']['/flat_params_endpoint']['post']['parameters'].map { |p| p['name'] }).not_to include('favourite_color', 'proc_param')
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
describe 'nested parameter hierarchy' do
|
70
|
+
subject do
|
71
|
+
get '/swagger_doc/nested_params_endpoint'
|
72
|
+
JSON.parse(last_response.body)
|
73
|
+
end
|
74
|
+
|
75
|
+
specify do
|
76
|
+
expect(subject['paths']['/nested_params_endpoint']['post']['parameters'].map { |p| p['name'] }).not_to include(/hidden_attribute/)
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
80
|
+
describe 'hidden defined for required parameter' do
|
81
|
+
subject do
|
82
|
+
get '/swagger_doc/required_param_endpoint'
|
83
|
+
JSON.parse(last_response.body)
|
84
|
+
end
|
85
|
+
|
86
|
+
specify do
|
87
|
+
expect(subject['paths']['/required_param_endpoint']['post']['parameters'].map { |p| p['name'] }).to include('name')
|
88
|
+
end
|
89
|
+
end
|
90
|
+
end
|
@@ -1,6 +1,6 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
|
3
|
-
describe '
|
3
|
+
describe 'moving body/formData Params to definitions' do
|
4
4
|
include_context "#{MODEL_PARSER} swagger example"
|
5
5
|
|
6
6
|
before :all do
|
@@ -11,12 +11,14 @@ describe 'setting of param type, such as `query`, `path`, `formData`, `body`, `h
|
|
11
11
|
detail: 'more details description',
|
12
12
|
success: Entities::UseNestedWithAddress
|
13
13
|
params do
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
14
|
+
optional :contact, type: Hash do
|
15
|
+
requires :name, type: String, documentation: { desc: 'name', in: 'body' }
|
16
|
+
optional :addresses, type: Array do
|
17
|
+
requires :street, type: String, documentation: { desc: 'street', in: 'body' }
|
18
|
+
requires :postcode, type: String, documentation: { desc: 'postcode', in: 'body' }
|
19
|
+
requires :city, type: String, documentation: { desc: 'city', in: 'body' }
|
20
|
+
optional :country, type: String, documentation: { desc: 'country', in: 'body' }
|
21
|
+
end
|
20
22
|
end
|
21
23
|
end
|
22
24
|
|
@@ -44,6 +46,30 @@ describe 'setting of param type, such as `query`, `path`, `formData`, `body`, `h
|
|
44
46
|
end
|
45
47
|
|
46
48
|
namespace :multiple_nested_params do
|
49
|
+
desc 'put in body with multiple nested parameters',
|
50
|
+
success: Entities::UseNestedWithAddress
|
51
|
+
params do
|
52
|
+
optional :contact, type: Hash do
|
53
|
+
requires :name, type: String, documentation: { desc: 'name', in: 'body' }
|
54
|
+
optional :addresses, type: Array do
|
55
|
+
optional :street, type: String, documentation: { desc: 'street', in: 'body' }
|
56
|
+
requires :postcode, type: Integer, documentation: { desc: 'postcode', in: 'formData' }
|
57
|
+
optional :city, type: String, documentation: { desc: 'city', in: 'body' }
|
58
|
+
optional :country, type: String, documentation: { desc: 'country', in: 'body' }
|
59
|
+
end
|
60
|
+
optional :delivery_address, type: Hash do
|
61
|
+
optional :street, type: String, documentation: { desc: 'street', in: 'body' }
|
62
|
+
optional :postcode, type: String, documentation: { desc: 'postcode', in: 'formData' }
|
63
|
+
optional :city, type: String, documentation: { desc: 'city', in: 'body' }
|
64
|
+
optional :country, type: String, documentation: { desc: 'country', in: 'body' }
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
post '/in_body' do
|
70
|
+
{ 'declared_params' => declared(params) }
|
71
|
+
end
|
72
|
+
|
47
73
|
desc 'put in body with multiple nested parameters',
|
48
74
|
success: Entities::UseNestedWithAddress
|
49
75
|
params do
|
@@ -83,74 +109,73 @@ describe 'setting of param type, such as `query`, `path`, `formData`, `body`, `h
|
|
83
109
|
JSON.parse(last_response.body)
|
84
110
|
end
|
85
111
|
|
86
|
-
|
87
|
-
|
88
|
-
[
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
)
|
95
|
-
end
|
112
|
+
describe 'POST' do
|
113
|
+
specify do
|
114
|
+
expect(subject['paths']['/simple_nested_params/in_body']['post']['parameters']).to eql(
|
115
|
+
[
|
116
|
+
{ 'name' => 'SimpleNestedParamsInBody', 'in' => 'body', 'required' => true, 'schema' => { '$ref' => '#/definitions/postSimpleNestedParamsInBody' } }
|
117
|
+
]
|
118
|
+
)
|
119
|
+
end
|
96
120
|
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
121
|
+
specify do
|
122
|
+
expect(subject['definitions']['postSimpleNestedParamsInBody']).to eql(
|
123
|
+
'type' => 'object',
|
124
|
+
'properties' => {
|
125
|
+
'contact' => {
|
126
|
+
'type' => 'object',
|
127
|
+
'properties' => {
|
128
|
+
'name' => { 'type' => 'string', 'description' => 'name' },
|
129
|
+
'addresses' => {
|
130
|
+
'type' => 'array',
|
131
|
+
'items' => {
|
132
|
+
'type' => 'object',
|
133
|
+
'properties' => {
|
134
|
+
'street' => { 'type' => 'string', 'description' => 'street' },
|
135
|
+
'postcode' => { 'type' => 'string', 'description' => 'postcode' },
|
136
|
+
'city' => { 'type' => 'string', 'description' => 'city' },
|
137
|
+
'country' => { 'type' => 'string', 'description' => 'country' }
|
138
|
+
},
|
139
|
+
'required' => %w(street postcode city)
|
140
|
+
}
|
141
|
+
}
|
142
|
+
},
|
143
|
+
'required' => %w(name)
|
144
|
+
}
|
145
|
+
},
|
146
|
+
'description' => 'post in body with nested parameters'
|
147
|
+
)
|
148
|
+
end
|
118
149
|
end
|
119
150
|
|
120
|
-
|
121
|
-
|
122
|
-
[
|
123
|
-
|
124
|
-
|
125
|
-
'name' => '
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
}
|
130
|
-
]
|
131
|
-
)
|
132
|
-
end
|
151
|
+
describe 'PUT' do
|
152
|
+
specify do
|
153
|
+
expect(subject['paths']['/simple_nested_params/in_body/{id}']['put']['parameters']).to eql(
|
154
|
+
[
|
155
|
+
{ 'in' => 'path', 'name' => 'id', 'type' => 'integer', 'format' => 'int32', 'required' => true },
|
156
|
+
{ 'name' => 'SimpleNestedParamsInBody', 'in' => 'body', 'required' => true, 'schema' => { '$ref' => '#/definitions/putSimpleNestedParamsInBody' } }
|
157
|
+
]
|
158
|
+
)
|
159
|
+
end
|
133
160
|
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
|
148
|
-
|
149
|
-
'
|
150
|
-
|
151
|
-
|
152
|
-
}
|
153
|
-
)
|
161
|
+
specify do
|
162
|
+
expect(subject['definitions']['putSimpleNestedParamsInBody']).to eql(
|
163
|
+
'type' => 'object',
|
164
|
+
'properties' => {
|
165
|
+
'name' => { 'type' => 'string', 'description' => 'name' },
|
166
|
+
'address' => {
|
167
|
+
'type' => 'object',
|
168
|
+
'properties' => {
|
169
|
+
'street' => { 'type' => 'string', 'description' => 'street' },
|
170
|
+
'postcode' => { 'type' => 'string', 'description' => 'postcode' },
|
171
|
+
'city' => { 'type' => 'string', 'description' => 'city' },
|
172
|
+
'country' => { 'type' => 'string', 'description' => 'country' }
|
173
|
+
}
|
174
|
+
}
|
175
|
+
},
|
176
|
+
'description' => 'put in body with nested parameters'
|
177
|
+
)
|
178
|
+
end
|
154
179
|
end
|
155
180
|
end
|
156
181
|
|
@@ -160,47 +185,97 @@ describe 'setting of param type, such as `query`, `path`, `formData`, `body`, `h
|
|
160
185
|
JSON.parse(last_response.body)
|
161
186
|
end
|
162
187
|
|
163
|
-
|
164
|
-
|
165
|
-
[
|
166
|
-
|
167
|
-
|
168
|
-
|
169
|
-
|
188
|
+
describe 'POST' do
|
189
|
+
specify do
|
190
|
+
expect(subject['paths']['/multiple_nested_params/in_body']['post']['parameters']).to eql(
|
191
|
+
[
|
192
|
+
{
|
193
|
+
'name' => 'MultipleNestedParamsInBody',
|
194
|
+
'in' => 'body',
|
195
|
+
'required' => true,
|
196
|
+
'schema' => { '$ref' => '#/definitions/postMultipleNestedParamsInBody' }
|
197
|
+
}
|
198
|
+
]
|
199
|
+
)
|
200
|
+
end
|
201
|
+
|
202
|
+
specify do
|
203
|
+
expect(subject['definitions']['postMultipleNestedParamsInBody']).to eql(
|
204
|
+
'type' => 'object',
|
205
|
+
'properties' => {
|
206
|
+
'contact' => {
|
207
|
+
'type' => 'object',
|
208
|
+
'properties' => {
|
209
|
+
'name' => { 'type' => 'string', 'description' => 'name' },
|
210
|
+
'addresses' => {
|
211
|
+
'type' => 'array',
|
212
|
+
'items' => {
|
213
|
+
'type' => 'object',
|
214
|
+
'properties' => {
|
215
|
+
'street' => { 'type' => 'string', 'description' => 'street' },
|
216
|
+
'postcode' => { 'type' => 'integer', 'format' => 'int32', 'description' => 'postcode' },
|
217
|
+
'city' => { 'type' => 'string', 'description' => 'city' },
|
218
|
+
'country' => { 'type' => 'string', 'description' => 'country' }
|
219
|
+
},
|
220
|
+
'required' => ['postcode']
|
221
|
+
}
|
222
|
+
},
|
223
|
+
'delivery_address' => {
|
224
|
+
'type' => 'object',
|
225
|
+
'properties' => {
|
226
|
+
'street' => { 'type' => 'string', 'description' => 'street' },
|
227
|
+
'postcode' => { 'type' => 'string', 'description' => 'postcode' },
|
228
|
+
'city' => { 'type' => 'string', 'description' => 'city' },
|
229
|
+
'country' => { 'type' => 'string', 'description' => 'country' }
|
230
|
+
}
|
231
|
+
}
|
232
|
+
},
|
233
|
+
'required' => %w(name)
|
234
|
+
}
|
235
|
+
},
|
236
|
+
'description' => 'put in body with multiple nested parameters'
|
237
|
+
)
|
238
|
+
end
|
170
239
|
end
|
171
240
|
|
172
|
-
|
173
|
-
|
174
|
-
'
|
175
|
-
|
176
|
-
|
177
|
-
|
178
|
-
|
179
|
-
|
180
|
-
|
181
|
-
|
182
|
-
|
183
|
-
|
184
|
-
|
185
|
-
|
186
|
-
|
187
|
-
|
188
|
-
|
189
|
-
|
190
|
-
|
191
|
-
|
192
|
-
|
193
|
-
|
194
|
-
|
195
|
-
|
196
|
-
|
197
|
-
|
198
|
-
|
199
|
-
|
200
|
-
|
201
|
-
|
202
|
-
|
203
|
-
|
241
|
+
describe 'PUT' do
|
242
|
+
specify do
|
243
|
+
expect(subject['paths']['/multiple_nested_params/in_body/{id}']['put']['parameters']).to eql(
|
244
|
+
[
|
245
|
+
{ 'in' => 'path', 'name' => 'id', 'type' => 'integer', 'format' => 'int32', 'required' => true },
|
246
|
+
{ 'name' => 'MultipleNestedParamsInBody', 'in' => 'body', 'required' => true, 'schema' => { '$ref' => '#/definitions/putMultipleNestedParamsInBody' } }
|
247
|
+
]
|
248
|
+
)
|
249
|
+
end
|
250
|
+
|
251
|
+
specify do
|
252
|
+
expect(subject['definitions']['putMultipleNestedParamsInBody']).to eql(
|
253
|
+
'type' => 'object',
|
254
|
+
'properties' => {
|
255
|
+
'name' => { 'type' => 'string', 'description' => 'name' },
|
256
|
+
'address' => {
|
257
|
+
'type' => 'object',
|
258
|
+
'properties' => {
|
259
|
+
'street' => { 'type' => 'string', 'description' => 'street' },
|
260
|
+
'postcode' => { 'type' => 'string', 'description' => 'postcode' },
|
261
|
+
'city' => { 'type' => 'string', 'description' => 'city' },
|
262
|
+
'country' => { 'type' => 'string', 'description' => 'country' }
|
263
|
+
},
|
264
|
+
'required' => ['postcode']
|
265
|
+
},
|
266
|
+
'delivery_address' => {
|
267
|
+
'type' => 'object',
|
268
|
+
'properties' => {
|
269
|
+
'street' => { 'type' => 'string', 'description' => 'street' },
|
270
|
+
'postcode' => { 'type' => 'string', 'description' => 'postcode' },
|
271
|
+
'city' => { 'type' => 'string', 'description' => 'city' },
|
272
|
+
'country' => { 'type' => 'string', 'description' => 'country' }
|
273
|
+
}
|
274
|
+
}
|
275
|
+
},
|
276
|
+
'description' => 'put in body with multiple nested parameters'
|
277
|
+
)
|
278
|
+
end
|
204
279
|
end
|
205
280
|
end
|
206
281
|
end
|