grape-swagger 0.8.0 → 0.9.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.
@@ -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