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.
- checksums.yaml +4 -4
- data/.gitignore +8 -1
- data/.rubocop.yml +3 -0
- data/.rubocop_todo.yml +14 -22
- data/.travis.yml +7 -4
- data/CHANGELOG.md +53 -26
- data/Gemfile +1 -1
- data/README.md +414 -327
- data/RELEASING.md +3 -4
- data/example/api/endpoints.rb +132 -0
- data/example/api/entities.rb +18 -0
- data/example/config.ru +36 -2
- data/example/example_requests.postman_collection +146 -0
- data/example/swagger-example.png +0 -0
- data/grape-swagger.gemspec +9 -6
- data/lib/grape-swagger.rb +69 -99
- data/lib/grape-swagger/doc_methods.rb +69 -544
- data/lib/grape-swagger/doc_methods/data_type.rb +77 -0
- data/lib/grape-swagger/doc_methods/extensions.rb +75 -0
- data/lib/grape-swagger/doc_methods/move_params.rb +153 -0
- data/lib/grape-swagger/doc_methods/operation_id.rb +27 -0
- data/lib/grape-swagger/doc_methods/optional_object.rb +15 -0
- data/lib/grape-swagger/doc_methods/parse_params.rb +113 -0
- data/lib/grape-swagger/doc_methods/path_string.rb +29 -0
- data/lib/grape-swagger/doc_methods/produces_consumes.rb +12 -0
- data/lib/grape-swagger/doc_methods/status_codes.rb +17 -0
- data/lib/grape-swagger/doc_methods/tag_name_description.rb +26 -0
- data/lib/grape-swagger/endpoint.rb +317 -0
- data/lib/grape-swagger/version.rb +1 -1
- data/spec/lib/data_type_spec.rb +57 -0
- data/spec/lib/endpoint_spec.rb +6 -0
- data/spec/lib/extensions_spec.rb +127 -0
- data/spec/lib/move_params_spec.rb +298 -0
- data/spec/lib/operation_id_spec.rb +24 -0
- data/spec/lib/optional_object_spec.rb +40 -0
- data/spec/lib/path_string_spec.rb +38 -0
- data/spec/lib/produces_consumes_spec.rb +98 -0
- data/spec/markdown/kramdown_adapter_spec.rb +2 -9
- data/spec/markdown/redcarpet_adapter_spec.rb +2 -16
- data/spec/spec_helper.rb +7 -13
- data/spec/support/api_swagger_v2_result.rb +204 -0
- data/spec/support/namespace_tags.rb +73 -0
- data/spec/support/the_api_entities.rb +52 -0
- data/spec/support/the_paths_definitions.rb +94 -0
- data/spec/swagger_v2/api_swagger_v2_definitions-models_spec.rb +32 -0
- data/spec/swagger_v2/api_swagger_v2_detail_spec.rb +151 -0
- data/spec/swagger_v2/api_swagger_v2_extensions_spec.rb +109 -0
- data/spec/swagger_v2/api_swagger_v2_format-content_type_spec.rb +124 -0
- data/spec/swagger_v2/api_swagger_v2_global_configuration_spec.rb +51 -0
- data/spec/swagger_v2/api_swagger_v2_headers_spec.rb +44 -0
- data/spec/swagger_v2/api_swagger_v2_hide_documentation_path_spec.rb +56 -0
- data/spec/swagger_v2/api_swagger_v2_mounted_spec.rb +146 -0
- data/spec/swagger_v2/api_swagger_v2_param_type_body_nested_spec.rb +197 -0
- data/spec/swagger_v2/api_swagger_v2_param_type_body_spec.rb +151 -0
- data/spec/swagger_v2/api_swagger_v2_param_type_spec.rb +217 -0
- data/spec/swagger_v2/api_swagger_v2_request_params_fix_spec.rb +64 -0
- data/spec/swagger_v2/api_swagger_v2_response_spec.rb +184 -0
- data/spec/swagger_v2/api_swagger_v2_spec.rb +207 -0
- data/spec/swagger_v2/api_swagger_v2_type-format_spec.rb +121 -0
- data/spec/{boolean_params_spec.rb → swagger_v2/boolean_params_spec.rb} +2 -2
- data/spec/{default_api_spec.rb → swagger_v2/default_api_spec.rb} +40 -36
- data/spec/swagger_v2/description_not_initialized.rb +39 -0
- data/spec/{float_api_spec.rb → swagger_v2/float_api_spec.rb} +2 -2
- data/spec/{form_params_spec.rb → swagger_v2/form_params_spec.rb} +9 -9
- data/spec/{grape-swagger_spec.rb → swagger_v2/grape-swagger_spec.rb} +0 -0
- data/spec/swagger_v2/hide_api_spec.rb +131 -0
- data/spec/swagger_v2/mounted_target_class_spec.rb +76 -0
- data/spec/swagger_v2/namespace_tags_prefix_spec.rb +84 -0
- data/spec/swagger_v2/namespace_tags_spec.rb +76 -0
- data/spec/{namespaced_api_spec.rb → swagger_v2/namespaced_api_spec.rb} +6 -26
- data/spec/{param_type_spec.rb → swagger_v2/param_type_spec.rb} +10 -8
- data/spec/{param_values_spec.rb → swagger_v2/param_values_spec.rb} +52 -22
- data/spec/swagger_v2/params_array_spec.rb +63 -0
- data/spec/swagger_v2/params_hash_spec.rb +65 -0
- data/spec/swagger_v2/params_nested_spec.rb +63 -0
- data/spec/{reference_entity.rb → swagger_v2/reference_entity.rb} +18 -23
- data/spec/swagger_v2/response_model_spec.rb +212 -0
- data/spec/swagger_v2/simple_mounted_api_spec.rb +264 -0
- metadata +175 -90
- data/example/api.rb +0 -66
- data/lib/grape-swagger/markdown.rb +0 -23
- data/spec/api_description_spec.rb +0 -43
- data/spec/api_global_models_spec.rb +0 -77
- data/spec/api_models_spec.rb +0 -364
- data/spec/api_paths_spec.rb +0 -128
- data/spec/api_root_spec.rb +0 -30
- data/spec/api_with_nil_types.rb +0 -50
- data/spec/api_with_path_versioning_spec.rb +0 -33
- data/spec/api_with_prefix_and_namespace_spec.rb +0 -32
- data/spec/api_with_standalone_namespace_spec.rb +0 -215
- data/spec/array_entity_spec.rb +0 -34
- data/spec/array_params_spec.rb +0 -85
- data/spec/grape-swagger_helper_spec.rb +0 -152
- data/spec/group_params_spec.rb +0 -31
- data/spec/hash_params_spec.rb +0 -30
- data/spec/hide_api_spec.rb +0 -124
- data/spec/i18n_spec.rb +0 -364
- data/spec/markdown/markdown_spec.rb +0 -27
- data/spec/mounted_target_class_spec.rb +0 -63
- data/spec/mutually_exclusive_spec.rb +0 -36
- data/spec/non_default_api_spec.rb +0 -733
- data/spec/response_model_spec.rb +0 -121
- data/spec/simple_mounted_api_spec.rb +0 -213
- 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['
|
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
|
-
{
|
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
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
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['
|
38
|
-
expect(
|
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.'
|
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
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
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
|
-
|
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['
|
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
|