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
data/spec/i18n_spec.rb DELETED
@@ -1,364 +0,0 @@
1
- require 'spec_helper'
2
-
3
- describe 'I18n Default Translation' do
4
- module Entities
5
- class User < Grape::Entity
6
- expose :id, documentation: { type: String }
7
- expose :name, documentation: { type: String }
8
- expose :email, documentation: { type: String }
9
- expose :sign_up_at, documentation: { type: String }
10
- end
11
-
12
- class AdminUser < User
13
- expose :level, documentation: { type: Integer }
14
- end
15
-
16
- class PasswordStrength < Grape::Entity
17
- expose :level, documentation: { type: Integer }
18
- expose :crack_time, documentation: { type: Float }
19
- end
20
- end
21
-
22
- def app
23
- Class.new(Grape::API) do
24
- format :json
25
-
26
- params do
27
- optional :locale, type: Symbol
28
- end
29
- namespace :users do
30
- desc nil do
31
- success Entities::User
32
- end
33
- params do
34
- optional :sort, type: String
35
- end
36
- get do
37
- []
38
- end
39
-
40
- params do
41
- requires :id, type: String
42
- end
43
- route_param :id do
44
- desc '' do
45
- success Entities::AdminUser
46
- end
47
- get do
48
- {}
49
- end
50
-
51
- params do
52
- requires :email, type: String
53
- end
54
- put :email do
55
- end
56
-
57
- desc nil do
58
- success Entities::PasswordStrength
59
- end
60
- get :'password/strength' do
61
- {}
62
- end
63
- end
64
- end
65
-
66
- add_swagger_documentation
67
- end
68
- end
69
-
70
- def api_translations
71
- yaml_en = <<-EOS.strip_heredoc
72
- info:
73
- title: My Awesome API
74
- desc: Some detail information about this API.
75
- entities:
76
- default:
77
- id: Resource identifier
78
- user:
79
- name: User's real name
80
- email: User's login email address
81
- sign_up_at: When the user signed up
82
- admin_user:
83
- level: Which level the admin is
84
- password_strength:
85
- level: A 0~4 integer indicates `very_weak` to `strong`
86
- crack_time: An estimated time for force cracking the password, in seconds
87
- params:
88
- locale: Used to change locale of endpoint's responding message
89
- sort: To specify the order of result list
90
- users:
91
- desc: Operations about not-disabled users
92
- get:
93
- desc: Gets a list of users
94
- detail: You can control how to sort the results.
95
- ':id':
96
- params:
97
- id: User id
98
- get:
99
- desc: Finds user by id
100
- email:
101
- put:
102
- desc: Changes a user's email
103
- params:
104
- email: A new email
105
- password:
106
- strength:
107
- get:
108
- desc: Gets the strength estimation of a user's password
109
- detail: The estimation is done by a well-known algorithm when he changed his password
110
- swagger_doc:
111
- desc: Endpoints for API documents
112
- get:
113
- desc: Gets root API document
114
- ':name':
115
- get:
116
- desc: Gets specific resource API document
117
- params:
118
- name: Resource name
119
- EOS
120
-
121
- YAML.load(yaml_en)
122
- end
123
-
124
- context 'swagger_doc' do
125
- subject do
126
- with_translations :en, api: api_translations do
127
- get '/swagger_doc'
128
- JSON.parse(last_response.body).deep_symbolize_keys
129
- end
130
- end
131
-
132
- it 'translates api info' do
133
- expect(subject[:info]).to eq(
134
- title: 'My Awesome API',
135
- description: 'Some detail information about this API.'
136
- )
137
- end
138
-
139
- it 'translates root namespace description (including swagger_doc)' do
140
- expect(subject[:apis]).to eq [
141
- { path: '/users.{format}', description: 'Operations about not-disabled users' },
142
- { path: '/swagger_doc.{format}', description: 'Endpoints for API documents' }
143
- ]
144
- end
145
- end
146
-
147
- it 'translates endpoint description, notes and params' do
148
- result = with_translations :en, api: api_translations do
149
- get '/swagger_doc/users'
150
- JSON.parse(last_response.body).deep_symbolize_keys
151
- end
152
-
153
- api_index = 0
154
- expect(result[:apis][api_index][:operations][0]).to include(
155
- summary: 'Gets a list of users', notes: 'You can control how to sort the results.'
156
- )
157
- expect(result[:apis][api_index][:operations][0][:parameters]).to eq [
158
- { paramType: 'query', name: 'locale', description: "Used to change locale of endpoint's responding message", type: 'string', required: false, allowMultiple: false },
159
- { paramType: 'query', name: 'sort', description: 'To specify the order of result list', type: 'string', required: false, allowMultiple: false }
160
- ]
161
-
162
- api_index += 1
163
- expect(result[:apis][api_index][:operations][0]).to include(
164
- summary: 'Finds user by id', notes: ''
165
- )
166
- expect(result[:apis][api_index][:operations][0][:parameters]).to eq [
167
- { paramType: 'query', name: 'locale', description: "Used to change locale of endpoint's responding message", type: 'string', required: false, allowMultiple: false },
168
- { paramType: 'path', name: 'id', description: 'User id', type: 'string', required: true, allowMultiple: false }
169
- ]
170
-
171
- api_index += 1
172
- expect(result[:apis][api_index][:operations][0]).to include(
173
- summary: "Changes a user's email", notes: ''
174
- )
175
- expect(result[:apis][api_index][:operations][0][:parameters]).to eq [
176
- { paramType: 'form', name: 'locale', description: "Used to change locale of endpoint's responding message", type: 'string', required: false, allowMultiple: false },
177
- { paramType: 'path', name: 'id', description: 'User id', type: 'string', required: true, allowMultiple: false },
178
- { paramType: 'form', name: 'email', description: 'A new email', type: 'string', required: true, allowMultiple: false }
179
- ]
180
-
181
- api_index += 1
182
- expect(result[:apis][api_index][:operations][0]).to include(
183
- summary: "Gets the strength estimation of a user's password", notes: 'The estimation is done by a well-known algorithm when he changed his password'
184
- )
185
- expect(result[:apis][api_index][:operations][0][:parameters]).to eq [
186
- { paramType: 'query', name: 'locale', description: "Used to change locale of endpoint's responding message", type: 'string', required: false, allowMultiple: false },
187
- { paramType: 'path', name: 'id', description: 'User id', type: 'string', required: true, allowMultiple: false }
188
- ]
189
- end
190
-
191
- it 'translates swagger doc endpoints description, notes and params' do
192
- result = with_translations :en, api: api_translations do
193
- get '/swagger_doc/swagger_doc'
194
- JSON.parse(last_response.body).deep_symbolize_keys
195
- end
196
-
197
- api_index = 0
198
- expect(result[:apis][api_index][:operations][0]).to include(
199
- summary: 'Gets root API document'
200
- )
201
- expect(result[:apis][api_index][:operations][0][:parameters]).to eq [
202
- { paramType: 'query', name: 'locale', description: "Used to change locale of endpoint's responding message", type: 'string', required: false, allowMultiple: false }
203
- ]
204
-
205
- api_index += 1
206
- expect(result[:apis][api_index][:operations][0]).to include(
207
- summary: 'Gets specific resource API document'
208
- )
209
- expect(result[:apis][api_index][:operations][0][:parameters]).to eq [
210
- { paramType: 'query', name: 'locale', description: "Used to change locale of endpoint's responding message", type: 'string', required: false, allowMultiple: false },
211
- { paramType: 'path', name: 'name', description: 'Resource name', type: 'string', required: true, allowMultiple: false }
212
- ]
213
- end
214
- end
215
-
216
- describe 'I18n Customized Translation' do
217
- def api_translations
218
- yaml_en = <<-EOS.strip_heredoc
219
- info:
220
- title: My Awesome I18n API
221
- desc: Some details in English
222
- custom:
223
- api_info: My Custom Awesome API
224
- interpolation: My %{keyword} API
225
- EOS
226
-
227
- YAML.load(yaml_en)
228
- end
229
-
230
- def extra_translations
231
- yaml_en = <<-EOS.strip_heredoc
232
- info:
233
- title: My Awesome I18n API in Extra Scope
234
- desc: Some details in English in Extra Scope
235
- custom:
236
- api_info: My Custom Awesome API in Extra Scope
237
- interpolation: This API supports %{count} languages, and by default it is in %{language}.
238
- EOS
239
-
240
- YAML.load(yaml_en)
241
- end
242
-
243
- subject do
244
- with_translations :en, api: api_translations, extra: extra_translations do
245
- get '/swagger_doc'
246
- JSON.parse(last_response.body).deep_symbolize_keys
247
- end
248
- end
249
-
250
- context 'a string' do
251
- def app
252
- Class.new(Grape::API) do
253
- format :json
254
- add_swagger_documentation info: {
255
- title: 'My Plain API', description: 'Boring description', license: 'MIT License'
256
- }
257
- end
258
- end
259
-
260
- it 'became default message when translation missing' do
261
- expect(subject[:info]).to eq(
262
- title: 'My Awesome I18n API',
263
- description: 'Some details in English',
264
- license: 'MIT License'
265
- )
266
- end
267
- end
268
-
269
- context 'a symbol' do
270
- def app
271
- Class.new(Grape::API) do
272
- format :json
273
- add_swagger_documentation info: { title: :'custom.api_info', description: :missing }
274
- end
275
- end
276
-
277
- it 'acts as custom lookup key' do
278
- expect(subject[:info][:title]).to eq 'My Custom Awesome API'
279
- end
280
-
281
- it 'can fallback to default key' do
282
- expect(subject[:info][:description]).to eq 'Some details in English'
283
- end
284
- end
285
-
286
- context 'a hash' do
287
- context 'using :key and :default' do
288
- def app
289
- Class.new(Grape::API) do
290
- format :json
291
- add_swagger_documentation info: {
292
- title: { key: :'custom.api_info', default: 'A Demo API' },
293
- description: { key: :missing, default: 'No need to say anything more' },
294
- license: { key: :license, default: 'MIT License' }
295
- }
296
- end
297
- end
298
-
299
- it 'to define custom lookup key and default message together' do
300
- expect(subject[:info]).to eq(
301
- title: 'My Custom Awesome API',
302
- description: 'Some details in English',
303
- license: 'MIT License'
304
- )
305
- end
306
- end
307
-
308
- context 'using :translate with "false"' do
309
- def app
310
- Class.new(Grape::API) do
311
- format :json
312
- add_swagger_documentation info: {
313
- title: { default: 'A Demo API', translate: false },
314
- description: { translate: false }
315
- }
316
- end
317
- end
318
-
319
- it 'to skip translation' do
320
- expect(subject[:info]).to eq(
321
- title: 'A Demo API'
322
- )
323
- end
324
- end
325
-
326
- context 'using :scope' do
327
- def app
328
- Class.new(Grape::API) do
329
- format :json
330
- add_swagger_documentation info: {
331
- title: { key: :'custom.api_info', scope: :extra },
332
- description: { scope: 'extra' }
333
- }
334
- end
335
- end
336
-
337
- it 'to look up in custom scope' do
338
- expect(subject[:info]).to eq(
339
- title: 'My Custom Awesome API in Extra Scope',
340
- description: 'Some details in English in Extra Scope'
341
- )
342
- end
343
- end
344
-
345
- context 'all other params' do
346
- def app
347
- Class.new(Grape::API) do
348
- format :json
349
- add_swagger_documentation info: {
350
- title: { key: :interpolation, keyword: 'Best' },
351
- description: { key: :interpolation, scope: :extra, count: 2, language: 'English' }
352
- }
353
- end
354
- end
355
-
356
- it 'can be interpolated into the translation' do
357
- expect(subject[:info]).to eq(
358
- title: 'My Best API',
359
- description: 'This API supports 2 languages, and by default it is in English.'
360
- )
361
- end
362
- end
363
- end
364
- end
@@ -1,27 +0,0 @@
1
- require 'spec_helper'
2
-
3
- describe GrapeSwagger::Markdown do
4
- context 'initialization' do
5
- it 'initializes with an class that respond to markdown' do
6
- adapter = GrapeSwagger::Markdown::KramdownAdapter.new
7
-
8
- markdown = GrapeSwagger::Markdown.new adapter
9
-
10
- expect(markdown.adapter).to eq(adapter)
11
- end
12
-
13
- it 'raises an exception when the class does not respond to markdown' do
14
- expect { GrapeSwagger::Markdown.new(Class.new) }.to raise_error(ArgumentError, 'The configured markdown adapter should implement the method markdown')
15
- end
16
- end
17
-
18
- context 'as_markdown' do
19
- it 'calls markdown on the configured adapter' do
20
- text = '# Hello world #'
21
- adapter = GrapeSwagger::Markdown::KramdownAdapter.new
22
- expect(adapter).to receive(:markdown).with(text)
23
-
24
- GrapeSwagger::Markdown.new(adapter).as_markdown(text)
25
- end
26
- end
27
- end
@@ -1,63 +0,0 @@
1
- require 'spec_helper'
2
-
3
- describe 'docs mounted separately from api' do
4
- before :all do
5
- class ActualApi < Grape::API
6
- desc 'Document root'
7
-
8
- desc 'This gets something.',
9
- notes: '_test_'
10
- get '/simple' do
11
- { bla: 'something' }
12
- end
13
- end
14
-
15
- class MountedDocs < Grape::API
16
- add_swagger_documentation(target_class: ActualApi)
17
- end
18
-
19
- class WholeApp < Grape::API
20
- mount ActualApi
21
- mount MountedDocs
22
- end
23
- end
24
-
25
- def app
26
- WholeApp
27
- end
28
-
29
- it 'retrieves docs for actual api class' 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' => '/simple.{format}', 'description' => 'Operations about simples' }
38
- ]
39
- )
40
- end
41
-
42
- it 'retrieves docs for endpoint in actual api class' do
43
- get '/swagger_doc/simple.json'
44
- expect(JSON.parse(last_response.body)).to eq(
45
- 'apiVersion' => '0.1',
46
- 'swaggerVersion' => '1.2',
47
- 'basePath' => 'http://example.org',
48
- 'resourcePath' => '/simple',
49
- 'produces' => Grape::ContentTypes::CONTENT_TYPES.values.uniq,
50
- 'apis' => [{
51
- 'path' => '/simple.{format}',
52
- 'operations' => [{
53
- 'notes' => '_test_',
54
- 'summary' => 'This gets something.',
55
- 'nickname' => 'GET-simple---format-',
56
- 'method' => 'GET',
57
- 'parameters' => [],
58
- 'type' => 'void'
59
- }]
60
- }]
61
- )
62
- end
63
- end