grape-swagger 0.8.0 → 0.9.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,3 +1,3 @@
1
1
  module GrapeSwagger
2
- VERSION = '0.8.0'
2
+ VERSION = '0.9.0'
3
3
  end
@@ -7,10 +7,12 @@ describe 'Global Models' do
7
7
  module Some
8
8
  class Thing < Grape::Entity
9
9
  expose :text, documentation: { type: 'string', desc: 'Content of something.' }
10
+ expose :name, documentation: { type: String, desc: 'Name of something.' }
10
11
  end
11
12
 
12
13
  class CombinedThing < Grape::Entity
13
14
  expose :text, documentation: { type: 'string', desc: 'Content of something.' }
15
+ expose :created_at, documentation: { type: DateTime, desc: 'Creation of something.' }
14
16
  end
15
17
  end
16
18
  end
@@ -18,15 +20,13 @@ describe 'Global Models' do
18
20
 
19
21
  subject do
20
22
  Class.new(Grape::API) do
21
- desc 'This gets thing.', params: Entities::Some::Thing.documentation
23
+ desc 'This gets thing.'
22
24
  get '/thing' do
23
25
  thing = OpenStruct.new text: 'thing'
24
26
  present thing, with: Entities::Some::Thing
25
27
  end
26
28
 
27
- desc 'This gets combined thing.',
28
- params: Entities::Some::CombinedThing.documentation,
29
- entity: Entities::Some::CombinedThing
29
+ desc 'This gets combined thing.', entity: Entities::Some::CombinedThing
30
30
  get '/combined_thing' do
31
31
  thing = OpenStruct.new text: 'thing'
32
32
  present thing, with: Entities::Some::CombinedThing
@@ -47,7 +47,8 @@ describe 'Global Models' do
47
47
  'Some::Thing' => {
48
48
  'id' => 'Some::Thing',
49
49
  'properties' => {
50
- 'text' => { 'type' => 'string', 'description' => 'Content of something.' }
50
+ 'text' => { 'type' => 'string', 'description' => 'Content of something.' },
51
+ 'name' => { 'type' => 'string', 'description' => 'Name of something.' }
51
52
  }
52
53
  })
53
54
  end
@@ -60,7 +61,8 @@ describe 'Global Models' do
60
61
  'Some::Thing' => {
61
62
  'id' => 'Some::Thing',
62
63
  'properties' => {
63
- 'text' => { 'type' => 'string', 'description' => 'Content of something.' }
64
+ 'text' => { 'type' => 'string', 'description' => 'Content of something.' },
65
+ 'name' => { 'type' => 'string', 'description' => 'Name of something.' }
64
66
  }
65
67
  })
66
68
 
@@ -68,7 +70,8 @@ describe 'Global Models' do
68
70
  'Some::CombinedThing' => {
69
71
  'id' => 'Some::CombinedThing',
70
72
  'properties' => {
71
- 'text' => { 'type' => 'string', 'description' => 'Content of something.' }
73
+ 'text' => { 'type' => 'string', 'description' => 'Content of something.' },
74
+ 'created_at' => { 'type' => 'dateTime', 'description' => 'Creation of something.' }
72
75
  }
73
76
  })
74
77
 
@@ -6,6 +6,7 @@ describe 'API Models' do
6
6
  module Entities
7
7
  class Something < Grape::Entity
8
8
  expose :text, documentation: { type: 'string', desc: 'Content of something.' }
9
+ expose :links, documentation: { type: 'link', is_array: true }
9
10
  end
10
11
  end
11
12
 
@@ -51,6 +52,24 @@ describe 'API Models' do
51
52
  expose :something, as: :post, using: Entities::Something, documentation: { type: 'Something', desc: 'Reference to something.' }
52
53
  end
53
54
  end
55
+
56
+ module Entities
57
+ class FourthLevel < Grape::Entity
58
+ expose :text, documentation: { type: 'string' }
59
+ end
60
+
61
+ class ThirdLevel < Grape::Entity
62
+ expose :parts, using: Entities::FourthLevel, documentation: { type: 'FourthLevel' }
63
+ end
64
+
65
+ class SecondLevel < Grape::Entity
66
+ expose :parts, using: Entities::ThirdLevel, documentation: { type: 'ThirdLevel' }
67
+ end
68
+
69
+ class FirstLevel < Grape::Entity
70
+ expose :parts, using: Entities::SecondLevel, documentation: { type: 'SecondLevel' }
71
+ end
72
+ end
54
73
  end
55
74
 
56
75
  def app
@@ -91,6 +110,16 @@ describe 'API Models' do
91
110
  present something, with: Entities::AliasedThing
92
111
  end
93
112
 
113
+ desc 'This gets all nested entities.', entity: Entities::FirstLevel
114
+ get '/nesting' do
115
+ fourth_level = OpenStruct.new text: 'something'
116
+ third_level = OpenStruct.new parts: [fourth_level]
117
+ second_level = OpenStruct.new parts: [third_level]
118
+ first_level = OpenStruct.new parts: [second_level]
119
+
120
+ present first_level, with: Entities::FirstLevel
121
+ end
122
+
94
123
  add_swagger_documentation
95
124
  end
96
125
  end
@@ -117,37 +146,28 @@ describe 'API Models' do
117
146
  { 'path' => '/somethingelse.{format}', 'description' => 'Operations about somethingelses' },
118
147
  { 'path' => '/enum_description_in_entity.{format}', 'description' => 'Operations about enum_description_in_entities' },
119
148
  { 'path' => '/aliasedthing.{format}', 'description' => 'Operations about aliasedthings' },
149
+ { 'path' => '/nesting.{format}', 'description' => 'Operations about nestings' },
120
150
  { 'path' => '/swagger_doc.{format}', 'description' => 'Operations about swagger_docs' }
121
151
  ]
122
152
  end
123
153
  end
124
154
 
125
155
  it 'returns type' do
126
- get '/swagger_doc/something.json'
156
+ get '/swagger_doc/something'
127
157
  result = JSON.parse(last_response.body)
128
158
  expect(result['apis'].first['operations'].first['type']).to eq 'Something'
129
159
  end
130
160
 
131
161
  it 'includes nested type' do
132
- get '/swagger_doc/thing.json'
162
+ get '/swagger_doc/thing'
133
163
  result = JSON.parse(last_response.body)
134
164
  expect(result['apis'].first['operations'].first['type']).to eq 'Some::Thing'
135
165
  end
136
166
 
137
167
  it 'includes entities which are only used as composition' do
138
- get '/swagger_doc/somethingelse.json'
168
+ get '/swagger_doc/somethingelse'
139
169
  result = JSON.parse(last_response.body)
140
- expect(result['apis']).to eq([{
141
- 'path' => '/somethingelse.{format}',
142
- 'operations' => [{
143
- 'notes' => '',
144
- 'type' => 'SomeThingElse',
145
- 'summary' => 'This gets somthing else.',
146
- 'nickname' => 'GET-somethingelse---format-',
147
- 'method' => 'GET',
148
- 'parameters' => []
149
- }]
150
- }])
170
+ expect(result['apis'][0]['path']).to start_with '/somethingelse'
151
171
 
152
172
  expect(result['models']['SomeThingElse']).to include('id' => 'SomeThingElse',
153
173
  'properties' => {
@@ -188,7 +208,7 @@ describe 'API Models' do
188
208
  end
189
209
 
190
210
  it 'includes enum values in params and documentation.' do
191
- get '/swagger_doc/enum_description_in_entity.json'
211
+ get '/swagger_doc/enum_description_in_entity'
192
212
  result = JSON.parse(last_response.body)
193
213
  expect(result['models']['EnumValues']).to eq(
194
214
  'id' => 'EnumValues',
@@ -210,7 +230,7 @@ describe 'API Models' do
210
230
  end
211
231
 
212
232
  it 'includes referenced models in those with aliased references.' do
213
- get '/swagger_doc/aliasedthing.json'
233
+ get '/swagger_doc/aliasedthing'
214
234
  result = JSON.parse(last_response.body)
215
235
  expect(result['models']['AliasedThing']).to eq(
216
236
  'id' => 'AliasedThing',
@@ -222,8 +242,16 @@ describe 'API Models' do
222
242
  expect(result['models']['Something']).to eq(
223
243
  'id' => 'Something',
224
244
  'properties' => {
225
- 'text' => { 'type' => 'string', 'description' => 'Content of something.' }
245
+ 'text' => { 'type' => 'string', 'description' => 'Content of something.' },
246
+ 'links' => { 'type' => 'array', 'items' => { '$ref' => 'link' } }
226
247
  }
227
248
  )
228
249
  end
250
+
251
+ it 'includes all entities with four levels of nesting' do
252
+ get '/swagger_doc/nesting'
253
+ result = JSON.parse(last_response.body)
254
+
255
+ expect(result['models']).to include('FirstLevel', 'SecondLevel', 'ThirdLevel', 'FourthLevel')
256
+ end
229
257
  end
@@ -0,0 +1,67 @@
1
+ require 'spec_helper'
2
+
3
+ describe 'simple api with prefix' do
4
+
5
+ before :all do
6
+ class ApiWithPrefix < Grape::API
7
+ prefix :api
8
+
9
+ desc 'This gets apitest'
10
+ get '/apitest' do
11
+ { test: 'something' }
12
+ end
13
+ end
14
+
15
+ class SimpleApiWithPrefix < Grape::API
16
+ mount ApiWithPrefix
17
+ add_swagger_documentation
18
+ end
19
+
20
+ end
21
+
22
+ def app
23
+ SimpleApiWithPrefix
24
+ end
25
+
26
+ it 'should not raise TypeError exception' do
27
+ end
28
+
29
+ it 'retrieves swagger-documentation on /swagger_doc that contains apitest' do
30
+ get '/swagger_doc.json'
31
+ expect(JSON.parse(last_response.body)).to eq(
32
+ 'apiVersion' => '0.1',
33
+ 'swaggerVersion' => '1.2',
34
+ 'info' => {},
35
+ 'produces' => Grape::ContentTypes::CONTENT_TYPES.values.uniq,
36
+ 'apis' => [
37
+ { 'path' => '/apitest.{format}', 'description' => 'Operations about apitests' },
38
+ { 'path' => '/swagger_doc.{format}', 'description' => 'Operations about swagger_docs' }
39
+ ]
40
+ )
41
+ end
42
+
43
+ context 'retrieves the documentation for apitest that' do
44
+ it 'contains returns something in URL' do
45
+ get '/swagger_doc/apitest.json'
46
+ expect(JSON.parse(last_response.body)).to eq(
47
+ 'apiVersion' => '0.1',
48
+ 'swaggerVersion' => '1.2',
49
+ 'basePath' => 'http://example.org',
50
+ 'resourcePath' => '/apitest',
51
+ 'produces' => Grape::ContentTypes::CONTENT_TYPES.values.uniq,
52
+ 'apis' => [{
53
+ 'path' => '/api/apitest.{format}',
54
+ 'operations' => [{
55
+ 'notes' => '',
56
+ 'summary' => 'This gets apitest',
57
+ 'nickname' => 'GET-api-apitest---format-',
58
+ 'method' => 'GET',
59
+ 'parameters' => [],
60
+ 'type' => 'void'
61
+ }]
62
+ }]
63
+ )
64
+ end
65
+ end
66
+
67
+ end
@@ -0,0 +1,31 @@
1
+ require 'spec_helper'
2
+
3
+ describe 'simple root api' do
4
+
5
+ before :all do
6
+ class ApiRoot < Grape::API
7
+ format :json
8
+ prefix 'api'
9
+ version 'v2', using: :header, vendor: 'artsy', strict: false
10
+ get do
11
+ {}
12
+ end
13
+ add_swagger_documentation
14
+ end
15
+ end
16
+
17
+ def app
18
+ ApiRoot
19
+ end
20
+
21
+ it 'retrieves swagger-documentation on /swagger_doc' do
22
+ get '/api/swagger_doc'
23
+ expect(JSON.parse(last_response.body)).to eq(
24
+ 'apiVersion' => '0.1',
25
+ 'swaggerVersion' => '1.2',
26
+ 'info' => {},
27
+ 'produces' => ['application/json'],
28
+ 'apis' => [{ 'path' => '/swagger_doc.{format}', 'description' => 'Operations about swagger_docs' }]
29
+ )
30
+ end
31
+ end
@@ -0,0 +1,30 @@
1
+ require 'spec_helper'
2
+
3
+ describe 'Boolean Params' do
4
+ def app
5
+ Class.new(Grape::API) do
6
+ format :json
7
+
8
+ params do
9
+ requires :a_boolean, type: Virtus::Attribute::Boolean
10
+ end
11
+ post :splines do
12
+ end
13
+
14
+ add_swagger_documentation
15
+ end
16
+ end
17
+
18
+ subject do
19
+ get '/swagger_doc/splines'
20
+ expect(last_response.status).to eq 200
21
+ body = JSON.parse last_response.body
22
+ body['apis'].first['operations'].first['parameters']
23
+ end
24
+
25
+ it 'converts boolean types' do
26
+ expect(subject).to eq [
27
+ { 'paramType' => 'form', 'name' => 'a_boolean', 'description' => nil, 'type' => 'boolean', 'required' => true, 'allowMultiple' => false }
28
+ ]
29
+ end
30
+ end
@@ -35,52 +35,16 @@ describe 'Form Params' do
35
35
  end
36
36
 
37
37
  subject do
38
- get '/swagger_doc/items.json'
38
+ get '/swagger_doc/items'
39
39
  JSON.parse(last_response.body)
40
40
  end
41
41
 
42
42
  it 'retrieves the documentation form params' do
43
- expect(subject['apis']).to eq([
44
- {
45
- 'path' => '/items.{format}',
46
- 'operations' => [
47
- {
48
- 'notes' => '',
49
- 'summary' => '',
50
- 'nickname' => 'POST-items---format-',
51
- 'method' => 'POST',
52
- 'parameters' => [{ 'paramType' => 'form', 'name' => 'name', 'description' => 'name of item', 'type' => 'string', 'required' => true, 'allowMultiple' => false }],
53
- 'type' => 'void'
54
- }
55
- ]
56
- }, {
57
- 'path' => '/items/{id}.{format}',
58
- 'operations' => [
59
- {
60
- 'notes' => '',
61
- 'summary' => '',
62
- 'nickname' => 'PUT-items--id---format-',
63
- 'method' => 'PUT',
64
- 'parameters' => [
65
- { 'paramType' => 'path', 'name' => 'id', 'description' => 'id of item', 'type' => 'integer', 'required' => true, 'allowMultiple' => false, 'format' => 'int32' },
66
- { 'paramType' => 'form', 'name' => 'name', 'description' => 'name of item', 'type' => 'string', 'required' => true, 'allowMultiple' => false },
67
- { 'paramType' => 'form', 'name' => 'conditions', 'description' => 'conditions of item', 'type' => 'integer', 'required' => true, 'allowMultiple' => false, 'format' => 'int32', 'enum' => [1, 2, 3] }
68
- ],
69
- 'type' => 'void'
70
- },
71
- {
72
- 'notes' => '',
73
- 'summary' => '',
74
- 'nickname' => 'PATCH-items--id---format-',
75
- 'method' => 'PATCH',
76
- 'parameters' => [
77
- { 'paramType' => 'path', 'name' => 'id', 'description' => 'id of item', 'type' => 'integer', 'required' => true, 'allowMultiple' => false, 'format' => 'int32' },
78
- { 'paramType' => 'form', 'name' => 'name', 'description' => 'name of item', 'type' => 'string', 'required' => true, 'allowMultiple' => false },
79
- { 'paramType' => 'form', 'name' => 'conditions', 'description' => 'conditions of item', 'type' => 'string', 'required' => false, 'allowMultiple' => false, 'enum' => %w(1 2) }
80
- ],
81
- 'type' => 'void'
82
- }
83
- ]
84
- }])
43
+ expect(subject['apis'].count).to eq 2
44
+ expect(subject['apis'][0]['path']).to start_with '/items'
45
+ expect(subject['apis'][0]['operations'][0]['method']).to eq 'POST'
46
+ expect(subject['apis'][1]['path']).to start_with '/items/{id}'
47
+ expect(subject['apis'][1]['operations'][0]['method']).to eq 'PUT'
48
+ expect(subject['apis'][1]['operations'][1]['method']).to eq 'PATCH'
85
49
  end
86
50
  end
@@ -4,19 +4,11 @@ describe 'helpers' do
4
4
 
5
5
  before :all do
6
6
  class HelperTestAPI < Grape::API
7
- add_swagger_documentation
8
7
  end
9
8
  end
10
9
 
11
10
  subject do
12
- api = Object.new
13
-
14
- # after injecting grape-swagger into the Test API we get the helper methods
15
- # back from the first endpoint's class (the API mounted by grape-swagger
16
- # to serve the swagger_doc
17
-
18
- api.extend HelperTestAPI.endpoints.first.options[:app].helpers
19
- api
11
+ HelperTestAPI.add_swagger_documentation
20
12
  end
21
13
 
22
14
  context 'parsing parameters' do
@@ -53,12 +45,6 @@ describe 'helpers' do
53
45
  desc: 'rack file',
54
46
  datafile: 'content',
55
47
  required: true
56
- },
57
- rails: {
58
- type: 'Hash',
59
- desc: 'rails file',
60
- datafile: 'content',
61
- required: true
62
48
  }
63
49
  }
64
50
  path = '/coolness'
@@ -71,14 +57,6 @@ describe 'helpers' do
71
57
  type: 'File',
72
58
  required: true,
73
59
  allowMultiple: false
74
- },
75
- {
76
- paramType: 'body',
77
- name: :rails,
78
- description: 'rails file',
79
- type: 'File',
80
- required: true,
81
- allowMultiple: false
82
60
  }
83
61
  ]
84
62
 
@@ -0,0 +1,31 @@
1
+ require 'spec_helper'
2
+
3
+ describe 'Group Params' do
4
+ def app
5
+ Class.new(Grape::API) do
6
+ format :json
7
+
8
+ params do
9
+ requires :required_group, type: Hash do
10
+ requires :required_param_1
11
+ requires :required_param_2
12
+ end
13
+ end
14
+ post '/groups' do
15
+ {}
16
+ end
17
+
18
+ add_swagger_documentation
19
+ end
20
+ end
21
+
22
+ it 'retrieves the documentation for group parameters' do
23
+ get '/swagger_doc/groups'
24
+
25
+ body = JSON.parse last_response.body
26
+ parameters = body['apis'].first['operations'].first['parameters']
27
+ expect(parameters).to eq [
28
+ { 'paramType' => 'form', 'name' => 'required_group[required_param_1]', 'description' => nil, 'type' => 'string', 'required' => true, 'allowMultiple' => false },
29
+ { 'paramType' => 'form', 'name' => 'required_group[required_param_2]', 'description' => nil, 'type' => 'string', 'required' => true, 'allowMultiple' => false }]
30
+ end
31
+ end