Skip to content

Commit 1f9c449

Browse files
blakenumbata
blake
authored andcommitted
Add spec
1 parent 9713a2b commit 1f9c449

File tree

1 file changed

+239
-0
lines changed

1 file changed

+239
-0
lines changed

spec/openapi_3/openapi_3_spec.rb

+239
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,239 @@
1+
# frozen_string_literal: true
2+
3+
require 'spec_helper'
4+
5+
describe 'swagger spec v2.0' do
6+
include_context "#{MODEL_PARSER} swagger example"
7+
8+
def app
9+
Class.new(Grape::API) do
10+
format :json
11+
12+
# Thing stuff
13+
desc 'This gets Things.' do
14+
params Entities::Something.documentation
15+
http_codes [{ code: 401, message: 'Unauthorized', model: Entities::ApiError }]
16+
end
17+
get '/thing' do
18+
something = OpenStruct.new text: 'something'
19+
present something, with: Entities::Something
20+
end
21+
22+
desc 'This gets Things.' do
23+
http_codes [
24+
{ code: 200, message: 'get Horses', model: Entities::Something },
25+
{ code: 401, message: 'HorsesOutError', model: Entities::ApiError }
26+
]
27+
end
28+
get '/thing2' do
29+
something = OpenStruct.new text: 'something'
30+
present something, with: Entities::Something
31+
end
32+
33+
desc 'This gets Thing.' do
34+
http_codes [{ code: 200, message: 'getting a single thing' }, { code: 401, message: 'Unauthorized' }]
35+
end
36+
params do
37+
requires :id, type: Integer
38+
end
39+
get '/thing/:id' do
40+
something = OpenStruct.new text: 'something'
41+
present something, with: Entities::Something
42+
end
43+
44+
desc 'This creates Thing.',
45+
success: Entities::Something
46+
params do
47+
requires :text, type: String, documentation: { type: 'string', desc: 'Content of something.' }
48+
requires :links, type: Array, documentation: { type: 'link', is_array: true }
49+
end
50+
post '/thing', http_codes: [{ code: 422, message: 'Unprocessible Entity' }] do
51+
something = OpenStruct.new text: 'something'
52+
present something, with: Entities::Something
53+
end
54+
55+
desc 'This updates Thing.',
56+
success: Entities::Something
57+
params do
58+
requires :id, type: Integer
59+
optional :text, type: String, desc: 'Content of something.'
60+
optional :links, type: Array, documentation: { type: 'link', is_array: true }
61+
end
62+
put '/thing/:id' do
63+
something = OpenStruct.new text: 'something'
64+
present something, with: Entities::Something
65+
end
66+
67+
desc 'This deletes Thing.',
68+
entity: Entities::Something
69+
params do
70+
requires :id, type: Integer
71+
end
72+
delete '/thing/:id' do
73+
something = OpenStruct.new text: 'something'
74+
present something, with: Entities::Something
75+
end
76+
77+
desc 'dummy route.',
78+
failure: [{ code: 401, message: 'Unauthorized' }]
79+
params do
80+
requires :id, type: Integer
81+
end
82+
delete '/dummy/:id' do
83+
end
84+
85+
namespace :other_thing do
86+
desc 'nested route inside namespace',
87+
entity: Entities::QueryInput,
88+
x: {
89+
'amazon-apigateway-auth' => { type: 'none' },
90+
'amazon-apigateway-integration' => { type: 'aws', uri: 'foo_bar_uri', httpMethod: 'get' }
91+
}
92+
93+
params do
94+
requires :elements, documentation: {
95+
type: 'QueryInputElement',
96+
desc: 'Set of configuration',
97+
param_type: 'body',
98+
is_array: true,
99+
required: true
100+
}
101+
end
102+
get '/:elements' do
103+
present something, with: Entities::QueryInput
104+
end
105+
end
106+
107+
version 'v3', using: :path
108+
add_swagger_documentation openapi_version: '3.0',
109+
api_version: 'v1',
110+
base_path: '/api',
111+
info: {
112+
title: 'The API title to be displayed on the API homepage.',
113+
description: 'A description of the API.',
114+
contact_name: 'Contact name',
115+
contact_email: '[email protected]',
116+
contact_url: 'www.The-Contact-URL.org',
117+
license: 'The name of the license.',
118+
license_url: 'www.The-URL-of-the-license.org',
119+
terms_of_service_url: 'www.The-URL-of-the-terms-and-service.com'
120+
}
121+
end
122+
end
123+
124+
describe 'whole documentation' do
125+
subject do
126+
get '/v3/swagger_doc'
127+
puts last_response.body
128+
JSON.parse(last_response.body)
129+
end
130+
131+
describe 'swagger object' do
132+
describe 'required keys' do
133+
it { expect(subject.keys).to include 'openapi' }
134+
it { expect(subject['openapi']).to eql '3.0.0' }
135+
it { expect(subject.keys).to include 'info' }
136+
it { expect(subject['info']).to be_a Hash }
137+
it { expect(subject.keys).to include 'paths' }
138+
it { expect(subject['paths']).to be_a Hash }
139+
end
140+
141+
describe 'info object required keys' do
142+
let(:info) { subject['info'] }
143+
144+
it { expect(info.keys).to include 'title' }
145+
it { expect(info['title']).to be_a String }
146+
it { expect(info.keys).to include 'version' }
147+
it { expect(info['version']).to be_a String }
148+
149+
describe 'license object' do
150+
let(:license) { subject['info']['license'] }
151+
152+
it { expect(license.keys).to include 'name' }
153+
it { expect(license['name']).to be_a String }
154+
it { expect(license.keys).to include 'url' }
155+
it { expect(license['url']).to be_a String }
156+
end
157+
158+
describe 'contact object' do
159+
let(:contact) { subject['info']['contact'] }
160+
161+
it { expect(contact.keys).to include 'name' }
162+
it { expect(contact['name']).to be_a String }
163+
it { expect(contact.keys).to include 'email' }
164+
it { expect(contact['email']).to be_a String }
165+
it { expect(contact.keys).to include 'url' }
166+
it { expect(contact['url']).to be_a String }
167+
end
168+
169+
describe 'global tags' do
170+
let(:tags) { subject['tags'] }
171+
172+
it { expect(tags).to be_a Array }
173+
it { expect(tags).not_to be_empty }
174+
end
175+
end
176+
177+
describe 'path object' do
178+
let(:paths) { subject['paths'] }
179+
180+
it 'hides documentation paths per default' do
181+
expect(paths.keys).not_to include '/swagger_doc', '/swagger_doc/{name}'
182+
end
183+
184+
specify do
185+
paths.each_pair do |path, value|
186+
expect(path).to start_with('/')
187+
expect(value).to be_a Hash
188+
expect(value).not_to be_empty
189+
190+
value.each do |method, declaration|
191+
expect(http_verbs).to include method
192+
expect(declaration).to have_key('responses')
193+
194+
declaration['responses'].each do |status_code, response|
195+
expect(status_code).to match(/\d{3}/)
196+
expect(response).to have_key('description')
197+
end
198+
end
199+
end
200+
end
201+
end
202+
203+
describe 'definitions object' do
204+
let(:definitions) { subject['components']['schemas'] }
205+
206+
specify do
207+
definitions.each do |model, properties|
208+
expect(model).to match(/\w+/)
209+
expect(properties).to have_key('properties')
210+
end
211+
end
212+
end
213+
end
214+
215+
describe 'swagger file' do
216+
it do
217+
# TODO: '/v3/other_thing/{elements}' path does not have a path parameter. Not sure on how to handle that.
218+
expect(subject).to eql openapi_json
219+
end
220+
end
221+
end
222+
223+
describe 'specific resource documentation' do
224+
subject do
225+
get '/v3/swagger_doc/other_thing'
226+
JSON.parse(last_response.body)
227+
end
228+
229+
let(:tags) { subject['tags'] }
230+
specify do
231+
expect(tags).to eql [
232+
{
233+
'name' => 'other_thing',
234+
'description' => 'Operations about other_things'
235+
}
236+
]
237+
end
238+
end
239+
end

0 commit comments

Comments
 (0)