grape-swagger 0.11.0 → 0.20.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (104) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +8 -1
  3. data/.rubocop.yml +3 -0
  4. data/.rubocop_todo.yml +14 -22
  5. data/.travis.yml +7 -4
  6. data/CHANGELOG.md +53 -26
  7. data/Gemfile +1 -1
  8. data/README.md +414 -327
  9. data/RELEASING.md +3 -4
  10. data/example/api/endpoints.rb +132 -0
  11. data/example/api/entities.rb +18 -0
  12. data/example/config.ru +36 -2
  13. data/example/example_requests.postman_collection +146 -0
  14. data/example/swagger-example.png +0 -0
  15. data/grape-swagger.gemspec +9 -6
  16. data/lib/grape-swagger.rb +69 -99
  17. data/lib/grape-swagger/doc_methods.rb +69 -544
  18. data/lib/grape-swagger/doc_methods/data_type.rb +77 -0
  19. data/lib/grape-swagger/doc_methods/extensions.rb +75 -0
  20. data/lib/grape-swagger/doc_methods/move_params.rb +153 -0
  21. data/lib/grape-swagger/doc_methods/operation_id.rb +27 -0
  22. data/lib/grape-swagger/doc_methods/optional_object.rb +15 -0
  23. data/lib/grape-swagger/doc_methods/parse_params.rb +113 -0
  24. data/lib/grape-swagger/doc_methods/path_string.rb +29 -0
  25. data/lib/grape-swagger/doc_methods/produces_consumes.rb +12 -0
  26. data/lib/grape-swagger/doc_methods/status_codes.rb +17 -0
  27. data/lib/grape-swagger/doc_methods/tag_name_description.rb +26 -0
  28. data/lib/grape-swagger/endpoint.rb +317 -0
  29. data/lib/grape-swagger/version.rb +1 -1
  30. data/spec/lib/data_type_spec.rb +57 -0
  31. data/spec/lib/endpoint_spec.rb +6 -0
  32. data/spec/lib/extensions_spec.rb +127 -0
  33. data/spec/lib/move_params_spec.rb +298 -0
  34. data/spec/lib/operation_id_spec.rb +24 -0
  35. data/spec/lib/optional_object_spec.rb +40 -0
  36. data/spec/lib/path_string_spec.rb +38 -0
  37. data/spec/lib/produces_consumes_spec.rb +98 -0
  38. data/spec/markdown/kramdown_adapter_spec.rb +2 -9
  39. data/spec/markdown/redcarpet_adapter_spec.rb +2 -16
  40. data/spec/spec_helper.rb +7 -13
  41. data/spec/support/api_swagger_v2_result.rb +204 -0
  42. data/spec/support/namespace_tags.rb +73 -0
  43. data/spec/support/the_api_entities.rb +52 -0
  44. data/spec/support/the_paths_definitions.rb +94 -0
  45. data/spec/swagger_v2/api_swagger_v2_definitions-models_spec.rb +32 -0
  46. data/spec/swagger_v2/api_swagger_v2_detail_spec.rb +151 -0
  47. data/spec/swagger_v2/api_swagger_v2_extensions_spec.rb +109 -0
  48. data/spec/swagger_v2/api_swagger_v2_format-content_type_spec.rb +124 -0
  49. data/spec/swagger_v2/api_swagger_v2_global_configuration_spec.rb +51 -0
  50. data/spec/swagger_v2/api_swagger_v2_headers_spec.rb +44 -0
  51. data/spec/swagger_v2/api_swagger_v2_hide_documentation_path_spec.rb +56 -0
  52. data/spec/swagger_v2/api_swagger_v2_mounted_spec.rb +146 -0
  53. data/spec/swagger_v2/api_swagger_v2_param_type_body_nested_spec.rb +197 -0
  54. data/spec/swagger_v2/api_swagger_v2_param_type_body_spec.rb +151 -0
  55. data/spec/swagger_v2/api_swagger_v2_param_type_spec.rb +217 -0
  56. data/spec/swagger_v2/api_swagger_v2_request_params_fix_spec.rb +64 -0
  57. data/spec/swagger_v2/api_swagger_v2_response_spec.rb +184 -0
  58. data/spec/swagger_v2/api_swagger_v2_spec.rb +207 -0
  59. data/spec/swagger_v2/api_swagger_v2_type-format_spec.rb +121 -0
  60. data/spec/{boolean_params_spec.rb → swagger_v2/boolean_params_spec.rb} +2 -2
  61. data/spec/{default_api_spec.rb → swagger_v2/default_api_spec.rb} +40 -36
  62. data/spec/swagger_v2/description_not_initialized.rb +39 -0
  63. data/spec/{float_api_spec.rb → swagger_v2/float_api_spec.rb} +2 -2
  64. data/spec/{form_params_spec.rb → swagger_v2/form_params_spec.rb} +9 -9
  65. data/spec/{grape-swagger_spec.rb → swagger_v2/grape-swagger_spec.rb} +0 -0
  66. data/spec/swagger_v2/hide_api_spec.rb +131 -0
  67. data/spec/swagger_v2/mounted_target_class_spec.rb +76 -0
  68. data/spec/swagger_v2/namespace_tags_prefix_spec.rb +84 -0
  69. data/spec/swagger_v2/namespace_tags_spec.rb +76 -0
  70. data/spec/{namespaced_api_spec.rb → swagger_v2/namespaced_api_spec.rb} +6 -26
  71. data/spec/{param_type_spec.rb → swagger_v2/param_type_spec.rb} +10 -8
  72. data/spec/{param_values_spec.rb → swagger_v2/param_values_spec.rb} +52 -22
  73. data/spec/swagger_v2/params_array_spec.rb +63 -0
  74. data/spec/swagger_v2/params_hash_spec.rb +65 -0
  75. data/spec/swagger_v2/params_nested_spec.rb +63 -0
  76. data/spec/{reference_entity.rb → swagger_v2/reference_entity.rb} +18 -23
  77. data/spec/swagger_v2/response_model_spec.rb +212 -0
  78. data/spec/swagger_v2/simple_mounted_api_spec.rb +264 -0
  79. metadata +175 -90
  80. data/example/api.rb +0 -66
  81. data/lib/grape-swagger/markdown.rb +0 -23
  82. data/spec/api_description_spec.rb +0 -43
  83. data/spec/api_global_models_spec.rb +0 -77
  84. data/spec/api_models_spec.rb +0 -364
  85. data/spec/api_paths_spec.rb +0 -128
  86. data/spec/api_root_spec.rb +0 -30
  87. data/spec/api_with_nil_types.rb +0 -50
  88. data/spec/api_with_path_versioning_spec.rb +0 -33
  89. data/spec/api_with_prefix_and_namespace_spec.rb +0 -32
  90. data/spec/api_with_standalone_namespace_spec.rb +0 -215
  91. data/spec/array_entity_spec.rb +0 -34
  92. data/spec/array_params_spec.rb +0 -85
  93. data/spec/grape-swagger_helper_spec.rb +0 -152
  94. data/spec/group_params_spec.rb +0 -31
  95. data/spec/hash_params_spec.rb +0 -30
  96. data/spec/hide_api_spec.rb +0 -124
  97. data/spec/i18n_spec.rb +0 -364
  98. data/spec/markdown/markdown_spec.rb +0 -27
  99. data/spec/mounted_target_class_spec.rb +0 -63
  100. data/spec/mutually_exclusive_spec.rb +0 -36
  101. data/spec/non_default_api_spec.rb +0 -733
  102. data/spec/response_model_spec.rb +0 -121
  103. data/spec/simple_mounted_api_spec.rb +0 -213
  104. data/spec/support/i18n_helper.rb +0 -8
@@ -0,0 +1,207 @@
1
+ require 'spec_helper'
2
+
3
+ describe 'swagger spec v2.0' do
4
+ include_context "swagger example"
5
+
6
+ def app
7
+ Class.new(Grape::API) do
8
+ format :json
9
+
10
+ # Thing stuff
11
+ desc 'This gets Things.' do
12
+ params Entities::Something.documentation
13
+ http_codes [ { code: 401, message: 'Unauthorized', model: Entities::ApiError } ]
14
+ end
15
+ get '/thing' do
16
+ something = OpenStruct.new text: 'something'
17
+ present something, with: Entities::Something
18
+ end
19
+
20
+ desc 'This gets Things.' do
21
+ http_codes [
22
+ { code: 200, message: 'get Horses', model: Entities::Something },
23
+ { code: 401, message: 'HorsesOutError', model: Entities::ApiError }
24
+ ]
25
+ end
26
+ get '/thing2' do
27
+ something = OpenStruct.new text: 'something'
28
+ present something, with: Entities::Something
29
+ end
30
+
31
+ desc 'This gets Thing.' do
32
+ http_codes [ { code: 200, message: 'getting a single thing' }, { code: 401, message: 'Unauthorized' } ]
33
+ end
34
+ params do
35
+ requires :id, type: Integer
36
+ end
37
+ get '/thing/:id' do
38
+ something = OpenStruct.new text: 'something'
39
+ present something, with: Entities::Something
40
+ end
41
+
42
+ desc 'This creates Thing.',
43
+ success: Entities::Something
44
+ params do
45
+ requires :text, type: String, documentation: { type: 'string', desc: 'Content of something.' }
46
+ requires :links, type: Array, documentation: { type: 'link', is_array: true }
47
+ end
48
+ post '/thing', http_codes: [ { code: 422, message: 'Unprocessible Entity' } ] do
49
+ something = OpenStruct.new text: 'something'
50
+ present something, with: Entities::Something
51
+ end
52
+
53
+ desc 'This updates Thing.',
54
+ success: Entities::Something
55
+ params do
56
+ requires :id, type: Integer
57
+ optional :text, type: String, desc: 'Content of something.'
58
+ optional :links, type: Array, documentation: { type: 'link', is_array: true }
59
+ end
60
+ put '/thing/:id' do
61
+ something = OpenStruct.new text: 'something'
62
+ present something, with: Entities::Something
63
+ end
64
+
65
+ desc 'This deletes Thing.',
66
+ entity: Entities::Something
67
+ params do
68
+ requires :id, type: Integer
69
+ end
70
+ delete '/thing/:id' do
71
+ something = OpenStruct.new text: 'something'
72
+ present something, with: Entities::Something
73
+ end
74
+
75
+ desc 'dummy route.',
76
+ failure: [{ code: 401, message: 'Unauthorized' }]
77
+ params do
78
+ requires :id, type: Integer
79
+ end
80
+ delete '/dummy/:id' do
81
+ end
82
+
83
+ namespace :other_thing do
84
+ desc 'nested route inside namespace',
85
+ entity: Entities::QueryInput,
86
+ x: {
87
+ 'amazon-apigateway-auth' => {type: 'none'},
88
+ 'amazon-apigateway-integration' => {type: 'aws', uri: 'foo_bar_uri', httpMethod: 'get'}
89
+ }
90
+
91
+ params do
92
+ requires :elements, documentation: {
93
+ type: 'QueryInputElement',
94
+ desc: 'Set of configuration',
95
+ param_type: 'body',
96
+ is_array: true,
97
+ required: true
98
+ }
99
+ end
100
+ get '/:elements' do
101
+ present something, with: Entities::QueryInput
102
+ end
103
+ end
104
+
105
+
106
+ version 'v3', using: :path
107
+ add_swagger_documentation api_version: 'v1',
108
+ base_path: '/api',
109
+ info: {
110
+ title: "The API title to be displayed on the API homepage.",
111
+ description: "A description of the API.",
112
+ contact_name: "Contact name",
113
+ contact_email: "Contact@email.com",
114
+ contact_url: "Contact URL",
115
+ license: "The name of the license.",
116
+ license_url: "www.The-URL-of-the-license.org",
117
+ terms_of_service_url: "www.The-URL-of-the-terms-and-service.com",
118
+ }
119
+ end
120
+ end
121
+
122
+ before do
123
+ get '/v3/swagger_doc'
124
+ end
125
+
126
+ let(:json) { JSON.parse(last_response.body) }
127
+
128
+ describe 'swagger object' do
129
+ describe 'required keys' do
130
+ it { expect(json.keys).to include 'swagger' }
131
+ it { expect(json['swagger']).to eql '2.0' }
132
+ it { expect(json.keys).to include 'info' }
133
+ it { expect(json['info']).to be_a Hash }
134
+ it { expect(json.keys).to include 'paths' }
135
+ it { expect(json['paths']).to be_a Hash }
136
+ end
137
+
138
+ describe 'info object required keys' do
139
+ let(:info) { json['info'] }
140
+
141
+ it { expect(info.keys).to include 'title' }
142
+ it { expect(info['title']).to be_a String }
143
+ it { expect(info.keys).to include 'version' }
144
+ it { expect(info['version']).to be_a String }
145
+
146
+ describe 'license object' do
147
+ let(:license) { json['info']['license'] }
148
+
149
+ it { expect(license.keys).to include 'name' }
150
+ it { expect(license['name']).to be_a String }
151
+ it { expect(license.keys).to include 'url' }
152
+ it { expect(license['url']).to be_a String }
153
+ end
154
+
155
+ describe 'contact object' do
156
+ let(:contact) { json['info']['contact'] }
157
+
158
+ it { expect(contact.keys).to include 'name' }
159
+ it { expect(contact['name']).to be_a String }
160
+ it { expect(contact.keys).to include 'email' }
161
+ it { expect(contact['email']).to be_a String }
162
+ it { expect(contact.keys).to include 'url' }
163
+ it { expect(contact['url']).to be_a String }
164
+ end
165
+ end
166
+
167
+ describe 'path object' do
168
+ let(:paths) { json['paths'] }
169
+
170
+ it "hides documentation paths per default" do
171
+ expect(paths.keys).not_to include '/swagger_doc', '/swagger_doc/{name}'
172
+ end
173
+
174
+ specify do
175
+ paths.each_pair do |path, value|
176
+ expect(path).to start_with('/')
177
+ expect(value).to be_a Hash
178
+ expect(value).not_to be_empty
179
+
180
+ value.each do |method, declaration|
181
+ expect(http_verbs).to include method
182
+ expect(declaration).to have_key('responses')
183
+
184
+ declaration["responses"].each do |status_code, response|
185
+ expect(status_code).to match(/\d{3}/)
186
+ expect(response).to have_key('description')
187
+ end
188
+ end
189
+ end
190
+ end
191
+ end
192
+
193
+ describe 'definitions object' do
194
+ let(:definitions) { json['definitions'] }
195
+ specify do
196
+ definitions.each do |model, properties|
197
+ expect(model).to match(/\w+/)
198
+ expect(properties).to have_key('properties')
199
+ end
200
+ end
201
+ end
202
+ end
203
+
204
+ describe "swagger file" do
205
+ it { expect(json).to eql swagger_json }
206
+ end
207
+ end
@@ -0,0 +1,121 @@
1
+ require 'spec_helper'
2
+
3
+ # mapping of parameter types
4
+ # Grape -> Swagger (OpenApi)
5
+ # (type format)
6
+ # ---------------------------------------------------
7
+ # Integer -> integer int32
8
+ # Numeric -> integer int64
9
+ # Float -> number float
10
+ # BigDecimal -> number double
11
+ # String -> string
12
+ # Symbol -> string
13
+ # Date -> string date
14
+ # DateTime -> string date-time
15
+ # Time -> string date-time
16
+ # 'password' -> string password
17
+ # 'email' -> string email
18
+ # Boolean -> boolean
19
+ # JSON -> json
20
+ # Rack::Multipart::UploadedFile -> file
21
+
22
+ describe 'type format settings' do
23
+ before :all do
24
+ module TheApi
25
+ module Entities
26
+ class TypedDefinition < Grape::Entity
27
+ expose :prop_integer, documentation: { type: Integer, desc: 'prop_integer' }
28
+ expose :prop_long, documentation: { type: Numeric, desc: 'prop_long' }
29
+ expose :prop_float, documentation: { type: Float, desc: 'prop_float' }
30
+ expose :prop_double, documentation: { type: BigDecimal, desc: 'prop_double' }
31
+ expose :prop_string, documentation: { type: String, desc: 'prop_string' }
32
+ expose :prop_symbol, documentation: { type: Symbol, desc: 'prop_symbol' }
33
+ expose :prop_date, documentation: { type: Date, desc: 'prop_date' }
34
+ expose :prop_date_time, documentation: { type: DateTime, desc: 'prop_date_time' }
35
+ expose :prop_time, documentation: { type: Time, desc: 'prop_time' }
36
+ expose :prop_password, documentation: { type: 'password', desc: 'prop_password' }
37
+ expose :prop_email, documentation: { type: 'email', desc: 'prop_email' }
38
+ expose :prop_boolean, documentation: { type: Virtus::Attribute::Boolean, desc: 'prop_boolean' }
39
+ expose :prop_file, documentation: { type: File, desc: 'prop_file' }
40
+ expose :prop_json, documentation: { type: JSON, desc: 'prop_json' }
41
+ end
42
+ end
43
+
44
+ class TypeFormatApi < Grape::API
45
+ desc 'full set of request data types',
46
+ success: TheApi::Entities::TypedDefinition
47
+
48
+ params do
49
+ # grape supported data types
50
+ requires :param_integer, type: Integer
51
+ requires :param_long, type: Numeric
52
+ requires :param_float, type: Float
53
+ requires :param_double, type: BigDecimal
54
+ optional :param_string, type: String
55
+ optional :param_symbol, type: Symbol
56
+ requires :param_date, type: Date
57
+ requires :param_date_time, type: DateTime
58
+ requires :param_time, type: Time
59
+ requires :param_password, type: 'password'
60
+ requires :param_email, type: 'email'
61
+ optional :param_boolean, type: Boolean
62
+ optional :param_file, type: File
63
+ optional :param_json, type: JSON
64
+ end
65
+
66
+ post '/request_types' do
67
+ { "declared_params" => declared(params) }
68
+ end
69
+
70
+ add_swagger_documentation
71
+ end
72
+ end
73
+ end
74
+
75
+ def app
76
+ TheApi::TypeFormatApi
77
+ end
78
+
79
+ subject do
80
+ get '/swagger_doc/request_types'
81
+ JSON.parse(last_response.body)
82
+ end
83
+
84
+ specify do
85
+ expect(subject['paths']['/request_types']['post']['parameters']).to eql([
86
+ {"in"=>"formData", "name"=>"param_integer", "description"=>nil, "required"=>true, "type"=>"integer", "format"=>"int32"},
87
+ {"in"=>"formData", "name"=>"param_long", "description"=>nil, "required"=>true, "type"=>"integer", "format"=>"int64"},
88
+ {"in"=>"formData", "name"=>"param_float", "description"=>nil, "required"=>true, "type"=>"number", "format"=>"float"},
89
+ {"in"=>"formData", "name"=>"param_double", "description"=>nil, "required"=>true, "type"=>"number", "format"=>"double"},
90
+ {"in"=>"formData", "name"=>"param_string", "description"=>nil, "required"=>false, "type"=>"string"},
91
+ {"in"=>"formData", "name"=>"param_symbol", "description"=>nil, "required"=>false, "type"=>"string"},
92
+ {"in"=>"formData", "name"=>"param_date", "description"=>nil, "required"=>true, "type"=>"string", "format"=>"date"},
93
+ {"in"=>"formData", "name"=>"param_date_time", "description"=>nil, "required"=>true, "type"=>"string", "format"=>"date-time"},
94
+ {"in"=>"formData", "name"=>"param_time", "description"=>nil, "required"=>true, "type"=>"string", "format"=>"date-time"},
95
+ {"in"=>"formData", "name"=>"param_password", "description"=>nil, "required"=>true, "type"=>"string", "format"=>"password"},
96
+ {"in"=>"formData", "name"=>"param_email", "description"=>nil, "required"=>true, "type"=>"string", "format"=>"email"},
97
+ {"in"=>"formData", "name"=>"param_boolean", "description"=>nil, "required"=>false, "type"=>"boolean"},
98
+ {"in"=>"formData", "name"=>"param_file", "description"=>nil, "required"=>false, "type"=>"file"},
99
+ {"in"=>"formData", "name"=>"param_json", "description"=>nil, "required"=>false, "type"=>"json"}
100
+ ])
101
+ end
102
+
103
+ specify do
104
+ expect(subject['definitions']['TypedDefinition']['properties']).to eql({
105
+ "prop_integer"=>{"type"=>"integer", "format"=>"int32"},
106
+ "prop_long"=>{"type"=>"integer", "format"=>"int64"},
107
+ "prop_float"=>{"type"=>"number", "format"=>"float"},
108
+ "prop_double"=>{"type"=>"number", "format"=>"double"},
109
+ "prop_string"=>{"type"=>"string"},
110
+ "prop_symbol"=>{"type"=>"string"},
111
+ "prop_date"=>{"type"=>"string", "format"=>"date"},
112
+ "prop_date_time"=>{"type"=>"string", "format"=>"date-time"},
113
+ "prop_time"=>{"type"=>"string", "format"=>"date-time"},
114
+ "prop_password"=>{"type"=>"string", "format"=>"password"},
115
+ "prop_email"=>{"type"=>"string", "format"=>"email"},
116
+ "prop_boolean"=>{"type"=>"boolean"},
117
+ "prop_file"=>{"type"=>"file"},
118
+ "prop_json"=>{"type"=>"json"}
119
+ })
120
+ end
121
+ end
@@ -19,12 +19,12 @@ describe 'Boolean Params' do
19
19
  get '/swagger_doc/splines'
20
20
  expect(last_response.status).to eq 200
21
21
  body = JSON.parse last_response.body
22
- body['apis'].first['operations'].first['parameters']
22
+ body['paths']['/splines']['post']['parameters']
23
23
  end
24
24
 
25
25
  it 'converts boolean types' do
26
26
  expect(subject).to eq [
27
- { 'paramType' => 'form', 'name' => 'a_boolean', 'description' => '', 'type' => 'boolean', 'required' => true, 'allowMultiple' => false }
27
+ {"in"=>"formData", "name"=>"a_boolean", "description"=>nil, "type"=>"boolean", "required"=>true}
28
28
  ]
29
29
  end
30
30
  end
@@ -1,5 +1,5 @@
1
1
  require 'spec_helper'
2
- require 'grape_version'
2
+ # require 'grape_version'
3
3
 
4
4
  describe 'Default API' do
5
5
  context 'with no additional options' do
@@ -21,32 +21,38 @@ describe 'Default API' do
21
21
 
22
22
  it 'documents api' do
23
23
  expect(subject).to eq(
24
- 'apiVersion' => '0.1',
25
- 'swaggerVersion' => '1.2',
26
- 'info' => {},
27
- 'produces' => ['application/json'],
28
- 'apis' => [
29
- { 'path' => '/something.{format}', 'description' => 'Operations about somethings' },
30
- { 'path' => '/swagger_doc.{format}', 'description' => 'Operations about swagger_docs' }
31
- ]
24
+ {
25
+ "info"=>{"title"=>"API title", "version"=>"v1"},
26
+ "swagger"=>"2.0",
27
+ "produces"=>["application/json"],
28
+ "host"=>"example.org",
29
+ "tags" => [{"name"=>"something", "description"=>"Operations about somethings"}],
30
+ "schemes" => ["https", "http"],
31
+ "paths"=>{
32
+ "/something"=>{
33
+ "get"=>{
34
+ "description"=>"This gets something.",
35
+ "produces"=>["application/json"],
36
+ "tags"=>["something"],
37
+ "operationId"=>"getSomething",
38
+ "responses"=>{"200"=>{"description"=>"This gets something."}}}}}}
32
39
  )
33
40
  end
34
41
 
35
42
  context 'path inside the apis array' do
36
43
  it 'starts with a forward slash' do
37
- subject['apis'].each do |api|
38
- expect(api['path']).to start_with '/'
44
+ subject['paths'].each do |path|
45
+ expect(path.first).to start_with '/'
39
46
  end
40
47
  end
41
48
  end
42
49
  end
50
+
43
51
  context 'with additional option block given to desc', if: GrapeVersion.satisfy?('>= 0.12.0') do
44
52
  def app
45
53
  Class.new(Grape::API) do
46
54
  format :json
47
- desc 'This gets something.' do
48
- detail 'more details about the endpoint'
49
- end
55
+ desc 'This gets something.'
50
56
  get '/something' do
51
57
  { bla: 'something' }
52
58
  end
@@ -60,24 +66,22 @@ describe 'Default API' do
60
66
  end
61
67
 
62
68
  it 'documents endpoint' do
63
- expect(subject).to eq(
64
- 'apiVersion' => '0.1',
65
- 'swaggerVersion' => '1.2',
66
- 'basePath' => 'http://example.org',
67
- 'produces' => ['application/json'],
68
- 'resourcePath' => '/something',
69
- 'apis' => [{
70
- 'path' => '/something.{format}',
71
- 'operations' => [{
72
- 'notes' => 'more details about the endpoint',
73
- 'summary' => 'This gets something.',
74
- 'nickname' => 'GET-something--json-',
75
- 'method' => 'GET',
76
- 'parameters' => [],
77
- 'type' => 'void'
78
- }]
79
- }]
80
- )
69
+ expect(subject).to eq({
70
+ "info"=>{"title"=>"API title", "version"=>"v1"},
71
+ "swagger"=>"2.0",
72
+ "produces"=>["application/json"],
73
+ "host"=>"example.org",
74
+ "tags" => [{"name"=>"something", "description"=>"Operations about somethings"}],
75
+ "schemes" => ["https", "http"],
76
+ "paths"=>{
77
+ "/something"=>{
78
+ "get"=>{
79
+ "description"=>"This gets something.",
80
+ "produces"=>["application/json"],
81
+ "tags"=>["something"],
82
+ "operationId"=>"getSomething",
83
+ "responses"=>{"200"=>{"description"=>"This gets something."}}}}}
84
+ })
81
85
  end
82
86
  end
83
87
 
@@ -91,7 +95,7 @@ describe 'Default API' do
91
95
  license: 'Apache 2',
92
96
  license_url: 'http://test.com',
93
97
  terms_of_service_url: 'http://terms.com',
94
- contact: 'support@test.com'
98
+ contact_email: 'support@test.com'
95
99
  }
96
100
  end
97
101
  end
@@ -110,11 +114,11 @@ describe 'Default API' do
110
114
  end
111
115
 
112
116
  it 'should document the license' do
113
- expect(subject['license']).to eql('Apache 2')
117
+ expect(subject['license']['name']).to eql('Apache 2')
114
118
  end
115
119
 
116
120
  it 'documents the license url' do
117
- expect(subject['licenseUrl']).to eql('http://test.com')
121
+ expect(subject['license']['url']).to eql('http://test.com')
118
122
  end
119
123
 
120
124
  it 'documents the terms of service url' do
@@ -122,7 +126,7 @@ describe 'Default API' do
122
126
  end
123
127
 
124
128
  it 'documents the contact email' do
125
- expect(subject['contact']).to eql('support@test.com')
129
+ expect(subject['contact']['email']).to eql('support@test.com')
126
130
  end
127
131
  end
128
132
  end