grape-swagger 0.28.0 → 0.29.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.
- checksums.yaml +4 -4
- data/.rubocop_todo.yml +1 -1
- data/.travis.yml +5 -9
- data/CHANGELOG.md +14 -0
- data/README.md +79 -43
- data/grape-swagger.gemspec +1 -1
- data/lib/grape-swagger/endpoint.rb +25 -13
- data/lib/grape-swagger/version.rb +1 -1
- data/spec/spec_helper.rb +1 -1
- data/spec/support/model_parsers/entity_parser.rb +0 -8
- data/spec/support/model_parsers/mock_parser.rb +0 -8
- data/spec/support/model_parsers/representable_parser.rb +2 -10
- data/spec/swagger_v2/api_swagger_v2_mounted_spec.rb +1 -2
- data/spec/swagger_v2/api_swagger_v2_response_spec.rb +0 -3
- data/spec/swagger_v2/api_swagger_v2_response_with_examples_spec.rb +135 -0
- data/spec/swagger_v2/api_swagger_v2_status_codes_spec.rb +22 -2
- data/spec/swagger_v2/default_api_spec.rb +0 -2
- data/spec/swagger_v2/deprecated_field_spec.rb +25 -0
- data/spec/swagger_v2/guarded_endpoint_spec.rb +0 -1
- data/spec/swagger_v2/hide_api_spec.rb +0 -4
- data/spec/swagger_v2/mount_override_api_spec.rb +0 -1
- data/spec/swagger_v2/mounted_target_class_spec.rb +0 -2
- data/spec/swagger_v2/simple_mounted_api_spec.rb +0 -11
- metadata +7 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 3fd414192a99ad92ea5ebdc015373059ab02819a7512119897a6fa71f309c083
|
4
|
+
data.tar.gz: 8ed9bd4a2fcb9d8e07b86aa899bf5ca7da74d716c8e45bf90667741abeedb718
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 7abb761a0965db3a41dca82d2a72a451f95c2e5a13cfaaede2603c8312cb9077499ca446e1b551f308ecb293a8c2b3c8c1fad7aa378e674457848e817b84e934
|
7
|
+
data.tar.gz: f284e5a252115e1b0d673ec07ec4b2ace2371b001cdf62e4d9e48331e0f115547ec2ee659ccba2a2d1fdc7f868c1c0ecfb1f5c341e84f1f6f7369782a4eb4f58
|
data/.rubocop_todo.yml
CHANGED
data/.travis.yml
CHANGED
@@ -11,33 +11,29 @@ after_success:
|
|
11
11
|
- bundle exec danger
|
12
12
|
|
13
13
|
rvm:
|
14
|
-
- 2.5.
|
15
|
-
- 2.4.
|
16
|
-
|
14
|
+
- 2.5.1
|
15
|
+
- 2.4.4
|
17
16
|
env:
|
18
17
|
- MODEL_PARSER=grape-swagger-entity
|
19
18
|
- MODEL_PARSER=grape-swagger-representable
|
20
19
|
- GRAPE_VERSION=0.17.0
|
21
20
|
- GRAPE_VERSION=0.18.0
|
22
21
|
- GRAPE_VERSION=0.19.2
|
23
|
-
- GRAPE_VERSION=1.0.
|
22
|
+
- GRAPE_VERSION=1.0.3
|
24
23
|
- GRAPE_VERSION=HEAD
|
25
24
|
|
26
25
|
matrix:
|
27
26
|
fast_finish: true
|
28
27
|
|
29
28
|
include:
|
30
|
-
- rvm: 2.3.
|
29
|
+
- rvm: 2.3.7
|
31
30
|
env:
|
32
31
|
- rvm: ruby-head
|
33
32
|
env:
|
34
33
|
- rvm: jruby-head
|
35
34
|
env:
|
36
|
-
- rvm: rbx-3
|
37
|
-
env:
|
38
35
|
|
39
36
|
allow_failures:
|
40
|
-
- rvm: 2.3.
|
37
|
+
- rvm: 2.3.7
|
41
38
|
- rvm: ruby-head
|
42
39
|
- rvm: jruby-head
|
43
|
-
- rvm: rbx-3
|
data/CHANGELOG.md
CHANGED
@@ -8,6 +8,20 @@
|
|
8
8
|
|
9
9
|
* Your contribution here.
|
10
10
|
|
11
|
+
### 0.29.0 (May 22, 2018)
|
12
|
+
|
13
|
+
#### Features
|
14
|
+
|
15
|
+
* [#667](https://github.com/ruby-grape/grape-swagger/pull/667): Make route summary optional - [@obduk](https://github.com/obduk).
|
16
|
+
* [#670](https://github.com/ruby-grape/grape-swagger/pull/670): Add support for deprecated field - [@ioanatia](https://github.com/ioanatia).
|
17
|
+
* [#675](https://github.com/ruby-grape/grape-swagger/pull/675): Add response examples - [@gamartin](https://github.com/gamartin).
|
18
|
+
|
19
|
+
#### Fixes
|
20
|
+
|
21
|
+
* [#664](https://github.com/ruby-grape/grape-swagger/pull/662): Removed all references to obsolete `hide_format` parameter - [@jonmchan](https://github.com/jonmchan).
|
22
|
+
* [#669](https://github.com/ruby-grape/grape-swagger/pull/669): Fix handling of http status codes from routes - [@milgner](https://github.com/milgner).
|
23
|
+
* [#672](https://github.com/ruby-grape/grape-swagger/pull/672): Rename 'notes' to 'detail' in README - [@kjleitz](https://github.com/kjleitz).
|
24
|
+
|
11
25
|
### 0.28.0 (February 3, 2018)
|
12
26
|
|
13
27
|
#### Features
|
data/README.md
CHANGED
@@ -334,7 +334,7 @@ add_swagger_documentation \
|
|
334
334
|
```
|
335
335
|
|
336
336
|
|
337
|
-
|
337
|
+
#### tags: <a name="tags" />
|
338
338
|
A list of tags to document. By default tags are automatically generated
|
339
339
|
for endpoints based on route names.
|
340
340
|
|
@@ -372,26 +372,6 @@ add_swagger_documentation \
|
|
372
372
|
|
373
373
|
A hash merged into the `info` key of the JSON documentation.
|
374
374
|
|
375
|
-
<!-- #### *authorizations*:
|
376
|
-
This value is added to the `authorizations` key in the JSON documentation. -->
|
377
|
-
|
378
|
-
<!-- #### *api_documentation*:
|
379
|
-
Customize the Swagger API documentation route, typically contains a `desc` field. The default description is "Swagger compatible API description".
|
380
|
-
|
381
|
-
```ruby
|
382
|
-
add_swagger_documentation \
|
383
|
-
api_documentation: { desc: 'Reticulated splines API swagger-compatible documentation.' }
|
384
|
-
```
|
385
|
-
|
386
|
-
|
387
|
-
#### *specific_api_documentation*:
|
388
|
-
Customize the Swagger API specific documentation route, typically contains a `desc` field. The default description is "Swagger compatible API description for specific API".
|
389
|
-
|
390
|
-
```ruby
|
391
|
-
add_swagger_documentation \
|
392
|
-
specific_api_documentation: { desc: 'Reticulated splines API swagger-compatible endpoint documentation.' }
|
393
|
-
``` -->
|
394
|
-
|
395
375
|
|
396
376
|
|
397
377
|
## Routes Configuration <a name="routes" />
|
@@ -402,6 +382,8 @@ add_swagger_documentation \
|
|
402
382
|
* [Specify endpoint details](#details)
|
403
383
|
* [Overriding the route summary](#summary)
|
404
384
|
* [Overriding the tags](#tags)
|
385
|
+
* [Deprecating routes](#deprecating-routes)
|
386
|
+
* [Overriding the name of the body parameter](#body-param)
|
405
387
|
* [Defining an endpoint as an array](#array)
|
406
388
|
* [Using an options hash](#options)
|
407
389
|
* [Overriding parameter type](#overriding-param-type)
|
@@ -415,11 +397,10 @@ add_swagger_documentation \
|
|
415
397
|
* [Changing default status codes](#change-status)
|
416
398
|
* [File response](#file-response)
|
417
399
|
* [Extensions](#extensions)
|
418
|
-
|
419
|
-
|
400
|
+
* [Response examples documentation](#response-examples)
|
420
401
|
|
421
402
|
#### Swagger Header Parameters <a name="headers" />
|
422
|
-
|
403
|
+
|
423
404
|
Swagger also supports the documentation of parameters passed in the header. Since grape's ```params[]``` doesn't return header parameters we can specify header parameters seperately in a block after the description.
|
424
405
|
|
425
406
|
```ruby
|
@@ -438,7 +419,6 @@ desc "Return super-secret information", {
|
|
438
419
|
```
|
439
420
|
|
440
421
|
|
441
|
-
|
442
422
|
#### Hiding an Endpoint <a name="hiding" />
|
443
423
|
|
444
424
|
You can hide an endpoint by adding ```hidden: true``` in the description of the endpoint:
|
@@ -468,7 +448,6 @@ desc 'Conditionally hide this endpoint', hidden: lambda { ENV['EXPERIMENTAL'] !=
|
|
468
448
|
```
|
469
449
|
|
470
450
|
|
471
|
-
|
472
451
|
#### Overriding Auto-Generated Nicknames <a name="overriding-auto-generated-nicknames" />
|
473
452
|
|
474
453
|
You can specify a swagger nickname to use instead of the auto generated name by adding `:nickname 'string'``` in the description of the endpoint.
|
@@ -478,7 +457,6 @@ desc 'Get a full list of pets', nickname: 'getAllPets'
|
|
478
457
|
```
|
479
458
|
|
480
459
|
|
481
|
-
|
482
460
|
#### Specify endpoint details <a name="details" />
|
483
461
|
|
484
462
|
To specify further details for an endpoint, use the `detail` option within a block passed to `desc`:
|
@@ -491,7 +469,6 @@ get '/kittens' do
|
|
491
469
|
```
|
492
470
|
|
493
471
|
|
494
|
-
|
495
472
|
#### Overriding the route summary <a name="summary" />
|
496
473
|
|
497
474
|
To override the summary, add `summary: '[string]'` after the description.
|
@@ -507,7 +484,6 @@ end
|
|
507
484
|
```
|
508
485
|
|
509
486
|
|
510
|
-
|
511
487
|
#### Overriding the tags <a name="tags" />
|
512
488
|
|
513
489
|
Tags are used for logical grouping of operations by resources or any other qualifier. To override the
|
@@ -523,7 +499,21 @@ end
|
|
523
499
|
```
|
524
500
|
|
525
501
|
|
526
|
-
####
|
502
|
+
#### Deprecating routes <a name="deprecating-routes" />
|
503
|
+
|
504
|
+
To deprecate a route add `deprecated: true` after the description.
|
505
|
+
|
506
|
+
```ruby
|
507
|
+
namespace 'order' do
|
508
|
+
desc 'This is a deprecated route', deprecated: true
|
509
|
+
get :order_id do
|
510
|
+
...
|
511
|
+
end
|
512
|
+
end
|
513
|
+
```
|
514
|
+
|
515
|
+
|
516
|
+
#### Overriding the name of the body parameter <a name="body-param" />
|
527
517
|
|
528
518
|
By default, body parameters have a generated name based on the operation. For
|
529
519
|
deeply nested resources, this name can get very long. To override the name of
|
@@ -538,6 +528,7 @@ namespace 'order' do
|
|
538
528
|
end
|
539
529
|
```
|
540
530
|
|
531
|
+
|
541
532
|
#### Defining an endpoint as an array <a name="array" />
|
542
533
|
|
543
534
|
You can define an endpoint as an array by adding `is_array` in the description:
|
@@ -547,7 +538,6 @@ desc 'Get a full list of pets', is_array: true
|
|
547
538
|
```
|
548
539
|
|
549
540
|
|
550
|
-
|
551
541
|
#### Using an options hash <a name="options" />
|
552
542
|
|
553
543
|
The Grape DSL supports either an options hash or a restricted block to pass settings. Passing the `nickname`, `hidden` and `is_array` options together with response codes is only possible when passing an options hash.
|
@@ -568,7 +558,6 @@ get '/kittens' do
|
|
568
558
|
```
|
569
559
|
|
570
560
|
|
571
|
-
|
572
561
|
#### Overriding parameter type <a name="overriding-param-type" />
|
573
562
|
|
574
563
|
You can override paramType, using the documentation hash. See [parameter object](https://github.com/OAI/OpenAPI-Specification/blob/master/versions/2.0.md#parameter-object) for available types.
|
@@ -583,7 +572,6 @@ end
|
|
583
572
|
```
|
584
573
|
|
585
574
|
|
586
|
-
|
587
575
|
#### Overriding data type of the parameter <a name="overriding-type-of-param" />
|
588
576
|
|
589
577
|
You can override type, using the documentation hash.
|
@@ -608,7 +596,6 @@ end
|
|
608
596
|
```
|
609
597
|
|
610
598
|
|
611
|
-
|
612
599
|
#### Multiple types <a name="multiple-types" />
|
613
600
|
|
614
601
|
By default when you set multiple types, the first type is selected as swagger type
|
@@ -632,7 +619,6 @@ end
|
|
632
619
|
```
|
633
620
|
|
634
621
|
|
635
|
-
|
636
622
|
#### Array of data type <a name="array-type" />
|
637
623
|
|
638
624
|
Array types are also supported.
|
@@ -659,7 +645,6 @@ end
|
|
659
645
|
```
|
660
646
|
|
661
647
|
|
662
|
-
|
663
648
|
#### Collection format of arrays <a name="collection-format" />
|
664
649
|
|
665
650
|
You can set the collection format of an array, using the documentation hash.
|
@@ -694,7 +679,6 @@ end
|
|
694
679
|
```
|
695
680
|
|
696
681
|
|
697
|
-
|
698
682
|
#### Hiding parameters <a name="hiding-parameters" />
|
699
683
|
|
700
684
|
Exclude single optional parameter from the documentation
|
@@ -710,7 +694,6 @@ end
|
|
710
694
|
```
|
711
695
|
|
712
696
|
|
713
|
-
|
714
697
|
#### Setting a Swagger default value <a name="default-value" />
|
715
698
|
|
716
699
|
Grape allows for an additional documentation hash to be passed to a parameter.
|
@@ -781,7 +764,6 @@ end
|
|
781
764
|
```
|
782
765
|
|
783
766
|
|
784
|
-
|
785
767
|
#### Response documentation <a name="response" />
|
786
768
|
|
787
769
|
You can also document the HTTP status codes with a description and a specified model, as ref in the schema to the definitions, that your API returns with one of the following syntax.
|
@@ -1001,6 +983,60 @@ route_setting :x_def, [{ for: 422, other: 'stuff' }, { for: 200, some: 'stuff' }
|
|
1001
983
|
```
|
1002
984
|
|
1003
985
|
|
986
|
+
#### Response examples documentation <a name="response-examples" />
|
987
|
+
|
988
|
+
You can also add examples to your responses by using the `desc` DSL with block syntax.
|
989
|
+
|
990
|
+
By specifying examples to `success` and `failure`.
|
991
|
+
|
992
|
+
```ruby
|
993
|
+
desc 'This returns examples' do
|
994
|
+
success model: Thing, examples: { 'application/json' => { description: 'Names list', items: [{ id: '123', name: 'John' }] } }
|
995
|
+
failure [[404, 'NotFound', ApiError, { 'application/json' => { code: 404, message: 'Not found' } }]]
|
996
|
+
end
|
997
|
+
get '/thing' do
|
998
|
+
...
|
999
|
+
end
|
1000
|
+
```
|
1001
|
+
|
1002
|
+
The result will look like following:
|
1003
|
+
|
1004
|
+
```json
|
1005
|
+
"responses": {
|
1006
|
+
"200": {
|
1007
|
+
"description": "This returns examples",
|
1008
|
+
"schema": {
|
1009
|
+
"$ref": "#/definitions/Thing"
|
1010
|
+
},
|
1011
|
+
"examples": {
|
1012
|
+
"application/json": {
|
1013
|
+
"description": "Names list",
|
1014
|
+
"items": [
|
1015
|
+
{
|
1016
|
+
"id": "123",
|
1017
|
+
"name": "John"
|
1018
|
+
}
|
1019
|
+
]
|
1020
|
+
}
|
1021
|
+
}
|
1022
|
+
},
|
1023
|
+
"404": {
|
1024
|
+
"description": "NotFound",
|
1025
|
+
"schema": {
|
1026
|
+
"$ref": "#/definitions/ApiError"
|
1027
|
+
},
|
1028
|
+
"examples": {
|
1029
|
+
"application/json": {
|
1030
|
+
"code": 404,
|
1031
|
+
"message": "Not found"
|
1032
|
+
}
|
1033
|
+
}
|
1034
|
+
}
|
1035
|
+
}
|
1036
|
+
```
|
1037
|
+
|
1038
|
+
Failure information can be passed as an array of arrays or an array of hashes.
|
1039
|
+
|
1004
1040
|
|
1005
1041
|
## Using Grape Entities <a name="grape-entity" />
|
1006
1042
|
|
@@ -1122,8 +1158,8 @@ end
|
|
1122
1158
|
```
|
1123
1159
|
|
1124
1160
|
|
1125
|
-
## Securing the Swagger UI <a name="oauth" />
|
1126
1161
|
|
1162
|
+
## Securing the Swagger UI <a name="oauth" />
|
1127
1163
|
|
1128
1164
|
The Swagger UI on Grape could be secured from unauthorized access using any middleware, which provides certain methods:
|
1129
1165
|
|
@@ -1145,7 +1181,6 @@ This is how to configure the grape_swagger documentation:
|
|
1145
1181
|
title: 'My API',
|
1146
1182
|
doc_version: '0.0.1',
|
1147
1183
|
hide_documentation_path: true,
|
1148
|
-
hide_format: true,
|
1149
1184
|
endpoint_auth_wrapper: WineBouncer::OAuth2, # This is the middleware for securing the Swagger UI
|
1150
1185
|
swagger_endpoint_guard: 'oauth2 false', # this is the guard method and scope
|
1151
1186
|
token_owner: 'resource_owner' # This is the method returning the owner of the token
|
@@ -1156,7 +1191,7 @@ The guard method should inject the Security Requirement Object into the endpoint
|
|
1156
1191
|
The 'oauth2 false' added to swagger_documentation is making the main Swagger endpoint protected with OAuth, i.e. the
|
1157
1192
|
access_token is being retreiving from the HTTP request, but the 'false' scope is for skipping authorization and
|
1158
1193
|
showing the UI for everyone. If the scope would be set to something else, like 'oauth2 admin', for example, than the UI
|
1159
|
-
wouldn't be displayed at all to unauthorized users.
|
1194
|
+
wouldn't be displayed at all to unauthorized users.
|
1160
1195
|
|
1161
1196
|
Further on, the guard could be used, where necessary, for endpoint access protection. Put it prior to the endpoint's method:
|
1162
1197
|
|
@@ -1193,6 +1228,7 @@ The lambda is checking whether the user is authenticated (if not, the token_owne
|
|
1193
1228
|
role - only admins can see this endpoint.
|
1194
1229
|
|
1195
1230
|
|
1231
|
+
|
1196
1232
|
## Examples <a="example" />
|
1197
1233
|
|
1198
1234
|
Go into example directory and run it: `$ bundle exec rackup`
|
@@ -1216,7 +1252,7 @@ class NamespaceApi < Grape::API
|
|
1216
1252
|
end
|
1217
1253
|
|
1218
1254
|
desc 'This gets something.',
|
1219
|
-
|
1255
|
+
detail: '_test_'
|
1220
1256
|
|
1221
1257
|
get '/simple' do
|
1222
1258
|
{ bla: 'something' }
|
data/grape-swagger.gemspec
CHANGED
@@ -123,18 +123,23 @@ module Grape
|
|
123
123
|
method[:responses] = response_object(route)
|
124
124
|
method[:tags] = route.options.fetch(:tags, tag_object(route, path))
|
125
125
|
method[:operationId] = GrapeSwagger::DocMethods::OperationId.build(route, path)
|
126
|
+
method[:deprecated] = deprecated_object(route)
|
126
127
|
method.delete_if { |_, value| value.blank? }
|
127
128
|
|
128
129
|
[route.request_method.downcase.to_sym, method]
|
129
130
|
end
|
130
131
|
|
132
|
+
def deprecated_object(route)
|
133
|
+
route.options[:deprecated] if route.options.key?(:deprecated)
|
134
|
+
end
|
135
|
+
|
131
136
|
def security_object(route)
|
132
137
|
route.options[:security] if route.options.key?(:security)
|
133
138
|
end
|
134
139
|
|
135
140
|
def summary_object(route)
|
136
141
|
summary = route.options[:desc] if route.options.key?(:desc)
|
137
|
-
summary = route.description if route.description.present?
|
142
|
+
summary = route.description if route.description.present? && route.options.key?(:detail)
|
138
143
|
summary = route.options[:summary] if route.options.key?(:summary)
|
139
144
|
|
140
145
|
summary
|
@@ -190,7 +195,7 @@ module Grape
|
|
190
195
|
|
191
196
|
def response_object(route)
|
192
197
|
codes = http_codes_from_route(route)
|
193
|
-
codes.map! { |x| x.is_a?(Array) ? { code: x[0], message: x[1], model: x[2] } : x }
|
198
|
+
codes.map! { |x| x.is_a?(Array) ? { code: x[0], message: x[1], model: x[2], examples: x[3] } : x }
|
194
199
|
|
195
200
|
codes.each_with_object({}) do |value, memo|
|
196
201
|
value[:message] ||= ''
|
@@ -209,18 +214,19 @@ module Grape
|
|
209
214
|
next unless !response_model.start_with?('Swagger_doc') && (@definitions[response_model] || value[:model])
|
210
215
|
|
211
216
|
@definitions[response_model][:description] = description_object(route)
|
212
|
-
|
213
|
-
|
214
|
-
memo[value[:code]][:
|
215
|
-
{ type: 'array', items: reference }
|
216
|
-
else
|
217
|
-
reference
|
218
|
-
end
|
217
|
+
|
218
|
+
memo[value[:code]][:schema] = build_reference(route, value, response_model)
|
219
|
+
memo[value[:code]][:examples] = value[:examples] if value[:examples]
|
219
220
|
end
|
220
221
|
end
|
221
222
|
|
223
|
+
def success_code?(code)
|
224
|
+
status = code.is_a?(Array) ? code.first : code[:code]
|
225
|
+
status.between?(200, 299)
|
226
|
+
end
|
227
|
+
|
222
228
|
def http_codes_from_route(route)
|
223
|
-
if route.http_codes.is_a?(Array) && route.http_codes.any? { |code|
|
229
|
+
if route.http_codes.is_a?(Array) && route.http_codes.any? { |code| success_code?(code) }
|
224
230
|
route.http_codes.clone
|
225
231
|
else
|
226
232
|
success_codes_from_route(route) + (route.http_codes || route.options[:failure] || [])
|
@@ -233,6 +239,7 @@ module Grape
|
|
233
239
|
default_code[:code] = @entity[:code] if @entity[:code].present?
|
234
240
|
default_code[:model] = @entity[:model] if @entity[:model].present?
|
235
241
|
default_code[:message] = @entity[:message] || route.description || default_code[:message].sub('{item}', @item)
|
242
|
+
default_code[:examples] = @entity[:examples] if @entity[:examples]
|
236
243
|
else
|
237
244
|
default_code = GrapeSwagger::DocMethods::StatusCodes.get[route.request_method.downcase.to_sym]
|
238
245
|
default_code[:model] = @entity if @entity
|
@@ -254,6 +261,12 @@ module Grape
|
|
254
261
|
|
255
262
|
private
|
256
263
|
|
264
|
+
def build_reference(route, value, response_model)
|
265
|
+
# TODO: proof that the definition exist, if model isn't specified
|
266
|
+
reference = { '$ref' => "#/definitions/#{response_model}" }
|
267
|
+
route.options[:is_array] && value[:code] < 300 ? { type: 'array', items: reference } : reference
|
268
|
+
end
|
269
|
+
|
257
270
|
def file_response?(value)
|
258
271
|
value.to_s.casecmp('file').zero? ? true : false
|
259
272
|
end
|
@@ -284,9 +297,8 @@ module Grape
|
|
284
297
|
end
|
285
298
|
|
286
299
|
def default_type(params)
|
287
|
-
|
288
|
-
|
289
|
-
end
|
300
|
+
default_param_type = { required: true, type: 'Integer' }
|
301
|
+
params.each { |param| param[-1] = param.last == '' ? default_param_type : param.last }
|
290
302
|
end
|
291
303
|
|
292
304
|
def parse_request_params(params)
|
data/spec/spec_helper.rb
CHANGED
@@ -10,7 +10,7 @@ SimpleCov.start do
|
|
10
10
|
end
|
11
11
|
Coveralls.wear!
|
12
12
|
|
13
|
-
$LOAD_PATH.unshift File.expand_path('
|
13
|
+
$LOAD_PATH.unshift File.expand_path('../lib', __dir__)
|
14
14
|
|
15
15
|
MODEL_PARSER = ENV.key?('MODEL_PARSER') ? ENV['MODEL_PARSER'].to_s.downcase.sub('grape-swagger-', '') : 'mock'
|
16
16
|
|
@@ -207,7 +207,6 @@ RSpec.shared_context 'entity swagger example' do
|
|
207
207
|
'paths' => {
|
208
208
|
'/v3/other_thing/{elements}' => {
|
209
209
|
'get' => {
|
210
|
-
'summary' => 'nested route inside namespace',
|
211
210
|
'description' => 'nested route inside namespace',
|
212
211
|
'produces' => ['application/json'],
|
213
212
|
'parameters' => [{ 'in' => 'body', 'name' => 'elements', 'description' => 'Set of configuration', 'type' => 'array', 'items' => { 'type' => 'string' }, 'required' => true }],
|
@@ -220,7 +219,6 @@ RSpec.shared_context 'entity swagger example' do
|
|
220
219
|
},
|
221
220
|
'/thing' => {
|
222
221
|
'get' => {
|
223
|
-
'summary' => 'This gets Things.',
|
224
222
|
'description' => 'This gets Things.',
|
225
223
|
'produces' => ['application/json'],
|
226
224
|
'parameters' => [
|
@@ -234,7 +232,6 @@ RSpec.shared_context 'entity swagger example' do
|
|
234
232
|
'operationId' => 'getThing'
|
235
233
|
},
|
236
234
|
'post' => {
|
237
|
-
'summary' => 'This creates Thing.',
|
238
235
|
'description' => 'This creates Thing.',
|
239
236
|
'produces' => ['application/json'],
|
240
237
|
'consumes' => ['application/json'],
|
@@ -249,7 +246,6 @@ RSpec.shared_context 'entity swagger example' do
|
|
249
246
|
},
|
250
247
|
'/thing/{id}' => {
|
251
248
|
'get' => {
|
252
|
-
'summary' => 'This gets Thing.',
|
253
249
|
'description' => 'This gets Thing.',
|
254
250
|
'produces' => ['application/json'],
|
255
251
|
'parameters' => [{ 'in' => 'path', 'name' => 'id', 'type' => 'integer', 'format' => 'int32', 'required' => true }],
|
@@ -258,7 +254,6 @@ RSpec.shared_context 'entity swagger example' do
|
|
258
254
|
'operationId' => 'getThingId'
|
259
255
|
},
|
260
256
|
'put' => {
|
261
|
-
'summary' => 'This updates Thing.',
|
262
257
|
'description' => 'This updates Thing.',
|
263
258
|
'produces' => ['application/json'],
|
264
259
|
'consumes' => ['application/json'],
|
@@ -272,7 +267,6 @@ RSpec.shared_context 'entity swagger example' do
|
|
272
267
|
'operationId' => 'putThingId'
|
273
268
|
},
|
274
269
|
'delete' => {
|
275
|
-
'summary' => 'This deletes Thing.',
|
276
270
|
'description' => 'This deletes Thing.',
|
277
271
|
'produces' => ['application/json'],
|
278
272
|
'parameters' => [{ 'in' => 'path', 'name' => 'id', 'type' => 'integer', 'format' => 'int32', 'required' => true }],
|
@@ -283,7 +277,6 @@ RSpec.shared_context 'entity swagger example' do
|
|
283
277
|
},
|
284
278
|
'/thing2' => {
|
285
279
|
'get' => {
|
286
|
-
'summary' => 'This gets Things.',
|
287
280
|
'description' => 'This gets Things.',
|
288
281
|
'produces' => ['application/json'],
|
289
282
|
'responses' => { '200' => { 'description' => 'get Horses', 'schema' => { '$ref' => '#/definitions/Something' } }, '401' => { 'description' => 'HorsesOutError', 'schema' => { '$ref' => '#/definitions/ApiError' } } },
|
@@ -293,7 +286,6 @@ RSpec.shared_context 'entity swagger example' do
|
|
293
286
|
},
|
294
287
|
'/dummy/{id}' => {
|
295
288
|
'delete' => {
|
296
|
-
'summary' => 'dummy route.',
|
297
289
|
'description' => 'dummy route.',
|
298
290
|
'produces' => ['application/json'],
|
299
291
|
'parameters' => [{ 'in' => 'path', 'name' => 'id', 'type' => 'integer', 'format' => 'int32', 'required' => true }],
|
@@ -199,7 +199,6 @@ RSpec.shared_context 'mock swagger example' do
|
|
199
199
|
'paths' => {
|
200
200
|
'/v3/other_thing/{elements}' => {
|
201
201
|
'get' => {
|
202
|
-
'summary' => 'nested route inside namespace',
|
203
202
|
'description' => 'nested route inside namespace',
|
204
203
|
'produces' => ['application/json'],
|
205
204
|
'parameters' => [{ 'in' => 'body', 'name' => 'elements', 'description' => 'Set of configuration', 'type' => 'array', 'items' => { 'type' => 'string' }, 'required' => true }],
|
@@ -212,7 +211,6 @@ RSpec.shared_context 'mock swagger example' do
|
|
212
211
|
},
|
213
212
|
'/thing' => {
|
214
213
|
'get' => {
|
215
|
-
'summary' => 'This gets Things.',
|
216
214
|
'description' => 'This gets Things.',
|
217
215
|
'produces' => ['application/json'],
|
218
216
|
'parameters' => [
|
@@ -226,7 +224,6 @@ RSpec.shared_context 'mock swagger example' do
|
|
226
224
|
'operationId' => 'getThing'
|
227
225
|
},
|
228
226
|
'post' => {
|
229
|
-
'summary' => 'This creates Thing.',
|
230
227
|
'description' => 'This creates Thing.',
|
231
228
|
'produces' => ['application/json'],
|
232
229
|
'consumes' => ['application/json'],
|
@@ -241,7 +238,6 @@ RSpec.shared_context 'mock swagger example' do
|
|
241
238
|
},
|
242
239
|
'/thing/{id}' => {
|
243
240
|
'get' => {
|
244
|
-
'summary' => 'This gets Thing.',
|
245
241
|
'description' => 'This gets Thing.',
|
246
242
|
'produces' => ['application/json'],
|
247
243
|
'parameters' => [{ 'in' => 'path', 'name' => 'id', 'type' => 'integer', 'format' => 'int32', 'required' => true }],
|
@@ -250,7 +246,6 @@ RSpec.shared_context 'mock swagger example' do
|
|
250
246
|
'operationId' => 'getThingId'
|
251
247
|
},
|
252
248
|
'put' => {
|
253
|
-
'summary' => 'This updates Thing.',
|
254
249
|
'description' => 'This updates Thing.',
|
255
250
|
'produces' => ['application/json'],
|
256
251
|
'consumes' => ['application/json'],
|
@@ -264,7 +259,6 @@ RSpec.shared_context 'mock swagger example' do
|
|
264
259
|
'operationId' => 'putThingId'
|
265
260
|
},
|
266
261
|
'delete' => {
|
267
|
-
'summary' => 'This deletes Thing.',
|
268
262
|
'description' => 'This deletes Thing.',
|
269
263
|
'produces' => ['application/json'],
|
270
264
|
'parameters' => [{ 'in' => 'path', 'name' => 'id', 'type' => 'integer', 'format' => 'int32', 'required' => true }],
|
@@ -275,7 +269,6 @@ RSpec.shared_context 'mock swagger example' do
|
|
275
269
|
},
|
276
270
|
'/thing2' => {
|
277
271
|
'get' => {
|
278
|
-
'summary' => 'This gets Things.',
|
279
272
|
'description' => 'This gets Things.',
|
280
273
|
'produces' => ['application/json'],
|
281
274
|
'responses' => { '200' => { 'description' => 'get Horses', 'schema' => { '$ref' => '#/definitions/Something' } }, '401' => { 'description' => 'HorsesOutError', 'schema' => { '$ref' => '#/definitions/ApiError' } } },
|
@@ -285,7 +278,6 @@ RSpec.shared_context 'mock swagger example' do
|
|
285
278
|
},
|
286
279
|
'/dummy/{id}' => {
|
287
280
|
'delete' => {
|
288
|
-
'summary' => 'dummy route.',
|
289
281
|
'description' => 'dummy route.',
|
290
282
|
'produces' => ['application/json'],
|
291
283
|
'parameters' => [{ 'in' => 'path', 'name' => 'id', 'type' => 'integer', 'format' => 'int32', 'required' => true }],
|
@@ -211,7 +211,7 @@ RSpec.shared_context 'representable swagger example' do
|
|
211
211
|
{
|
212
212
|
'ApiError' => { 'type' => 'object', 'properties' => { 'code' => { 'description' => 'status code', 'type' => 'integer', 'format' => 'int32' }, 'message' => { 'description' => 'error message', 'type' => 'string' } } },
|
213
213
|
'ResponseItem' => { 'type' => 'object', 'properties' => { 'id' => { 'description' => '', 'type' => 'integer', 'format' => 'int32' }, 'name' => { 'description' => '', 'type' => 'string' } } },
|
214
|
-
'UseResponse' => { 'type' => 'object', 'properties' => { 'description' => { 'description' => '', 'type' => 'string' }, '
|
214
|
+
'UseResponse' => { 'type' => 'object', 'properties' => { 'description' => { 'description' => '', 'type' => 'string' }, '$responses' => { 'type' => 'array', 'items' => { '$ref' => '#/definitions/ResponseItem' }, 'description' => '' } } },
|
215
215
|
'RecursiveModel' => { 'type' => 'object', 'properties' => { 'name' => { 'type' => 'string', 'description' => 'The name.' }, 'children' => { 'type' => 'array', 'items' => { '$ref' => '#/definitions/RecursiveModel' }, 'description' => 'The child nodes.' } } }
|
216
216
|
}
|
217
217
|
end
|
@@ -227,7 +227,7 @@ RSpec.shared_context 'representable swagger example' do
|
|
227
227
|
{
|
228
228
|
'ApiError' => { 'type' => 'object', 'properties' => { 'code' => { 'description' => 'status code', 'type' => 'integer', 'format' => 'int32' }, 'message' => { 'description' => 'error message', 'type' => 'string' } }, 'description' => 'This returns something' },
|
229
229
|
'ResponseItem' => { 'type' => 'object', 'properties' => { 'id' => { 'description' => '', 'type' => 'integer', 'format' => 'int32' }, 'name' => { 'description' => '', 'type' => 'string' } } },
|
230
|
-
'UseResponse' => { 'type' => 'object', 'properties' => { 'description' => { 'description' => '', 'type' => 'string' }, '
|
230
|
+
'UseResponse' => { 'type' => 'object', 'properties' => { 'description' => { 'description' => '', 'type' => 'string' }, '$responses' => { 'type' => 'array', 'items' => { '$ref' => '#/definitions/ResponseItem' }, 'description' => '' } }, 'description' => 'This returns something' }
|
231
231
|
}
|
232
232
|
end
|
233
233
|
|
@@ -279,7 +279,6 @@ RSpec.shared_context 'representable swagger example' do
|
|
279
279
|
'paths' => {
|
280
280
|
'/v3/other_thing/{elements}' => {
|
281
281
|
'get' => {
|
282
|
-
'summary' => 'nested route inside namespace',
|
283
282
|
'description' => 'nested route inside namespace',
|
284
283
|
'produces' => ['application/json'],
|
285
284
|
'parameters' => [{ 'in' => 'body', 'name' => 'elements', 'description' => 'Set of configuration', 'type' => 'array', 'items' => { 'type' => 'string' }, 'required' => true }],
|
@@ -292,7 +291,6 @@ RSpec.shared_context 'representable swagger example' do
|
|
292
291
|
},
|
293
292
|
'/thing' => {
|
294
293
|
'get' => {
|
295
|
-
'summary' => 'This gets Things.',
|
296
294
|
'description' => 'This gets Things.',
|
297
295
|
'produces' => ['application/json'],
|
298
296
|
'parameters' => [
|
@@ -306,7 +304,6 @@ RSpec.shared_context 'representable swagger example' do
|
|
306
304
|
'operationId' => 'getThing'
|
307
305
|
},
|
308
306
|
'post' => {
|
309
|
-
'summary' => 'This creates Thing.',
|
310
307
|
'description' => 'This creates Thing.',
|
311
308
|
'produces' => ['application/json'],
|
312
309
|
'consumes' => ['application/json'],
|
@@ -321,7 +318,6 @@ RSpec.shared_context 'representable swagger example' do
|
|
321
318
|
},
|
322
319
|
'/thing/{id}' => {
|
323
320
|
'get' => {
|
324
|
-
'summary' => 'This gets Thing.',
|
325
321
|
'description' => 'This gets Thing.',
|
326
322
|
'produces' => ['application/json'],
|
327
323
|
'parameters' => [{ 'in' => 'path', 'name' => 'id', 'type' => 'integer', 'format' => 'int32', 'required' => true }],
|
@@ -330,7 +326,6 @@ RSpec.shared_context 'representable swagger example' do
|
|
330
326
|
'operationId' => 'getThingId'
|
331
327
|
},
|
332
328
|
'put' => {
|
333
|
-
'summary' => 'This updates Thing.',
|
334
329
|
'description' => 'This updates Thing.',
|
335
330
|
'produces' => ['application/json'],
|
336
331
|
'consumes' => ['application/json'],
|
@@ -344,7 +339,6 @@ RSpec.shared_context 'representable swagger example' do
|
|
344
339
|
'operationId' => 'putThingId'
|
345
340
|
},
|
346
341
|
'delete' => {
|
347
|
-
'summary' => 'This deletes Thing.',
|
348
342
|
'description' => 'This deletes Thing.',
|
349
343
|
'produces' => ['application/json'],
|
350
344
|
'parameters' => [{ 'in' => 'path', 'name' => 'id', 'type' => 'integer', 'format' => 'int32', 'required' => true }],
|
@@ -355,7 +349,6 @@ RSpec.shared_context 'representable swagger example' do
|
|
355
349
|
},
|
356
350
|
'/thing2' => {
|
357
351
|
'get' => {
|
358
|
-
'summary' => 'This gets Things.',
|
359
352
|
'description' => 'This gets Things.',
|
360
353
|
'produces' => ['application/json'],
|
361
354
|
'responses' => { '200' => { 'description' => 'get Horses', 'schema' => { '$ref' => '#/definitions/Something' } }, '401' => { 'description' => 'HorsesOutError', 'schema' => { '$ref' => '#/definitions/ApiError' } } },
|
@@ -365,7 +358,6 @@ RSpec.shared_context 'representable swagger example' do
|
|
365
358
|
},
|
366
359
|
'/dummy/{id}' => {
|
367
360
|
'delete' => {
|
368
|
-
'summary' => 'dummy route.',
|
369
361
|
'description' => 'dummy route.',
|
370
362
|
'produces' => ['application/json'],
|
371
363
|
'parameters' => [{ 'in' => 'path', 'name' => 'id', 'type' => 'integer', 'format' => 'int32', 'required' => true }],
|
@@ -106,8 +106,7 @@ describe 'swagger spec v2.0' do
|
|
106
106
|
end
|
107
107
|
|
108
108
|
version 'v3', using: :path
|
109
|
-
add_swagger_documentation
|
110
|
-
base_path: '/api',
|
109
|
+
add_swagger_documentation base_path: '/api',
|
111
110
|
info: {
|
112
111
|
title: 'The API title to be displayed on the API homepage.',
|
113
112
|
description: 'A description of the API.',
|
@@ -47,7 +47,6 @@ describe 'response' do
|
|
47
47
|
end
|
48
48
|
specify do
|
49
49
|
expect(subject['paths']['/nested_type']['get']).to eql(
|
50
|
-
'summary' => 'This returns something',
|
51
50
|
'description' => 'This returns something',
|
52
51
|
'produces' => ['application/json'],
|
53
52
|
'responses' => {
|
@@ -69,7 +68,6 @@ describe 'response' do
|
|
69
68
|
|
70
69
|
specify do
|
71
70
|
expect(subject['paths']['/entity_response']['get']).to eql(
|
72
|
-
'summary' => 'This returns something',
|
73
71
|
'description' => 'This returns something',
|
74
72
|
'produces' => ['application/json'],
|
75
73
|
'responses' => {
|
@@ -91,7 +89,6 @@ describe 'response' do
|
|
91
89
|
|
92
90
|
specify do
|
93
91
|
expect(subject['paths']['/params_given']['post']).to eql(
|
94
|
-
'summary' => 'This returns something',
|
95
92
|
'description' => 'This returns something',
|
96
93
|
'produces' => ['application/json'],
|
97
94
|
'consumes' => ['application/json'],
|
@@ -0,0 +1,135 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'spec_helper'
|
4
|
+
|
5
|
+
describe 'response with examples' do
|
6
|
+
include_context "#{MODEL_PARSER} swagger example"
|
7
|
+
|
8
|
+
before :all do
|
9
|
+
module TheApi
|
10
|
+
class ResponseApiExamples < Grape::API
|
11
|
+
format :json
|
12
|
+
|
13
|
+
desc 'This returns examples' do
|
14
|
+
success model: Entities::UseResponse, examples: { 'application/json' => { description: 'Names list', items: [{ id: '123', name: 'John' }] } }
|
15
|
+
failure [[404, 'NotFound', Entities::ApiError, { 'application/json' => { code: 404, message: 'Not found' } }]]
|
16
|
+
end
|
17
|
+
get '/response_examples' do
|
18
|
+
{ 'declared_params' => declared(params) }
|
19
|
+
end
|
20
|
+
|
21
|
+
desc 'This syntax also returns examples' do
|
22
|
+
success model: Entities::UseResponse, examples: { 'application/json' => { description: 'Names list', items: [{ id: '123', name: 'John' }] } }
|
23
|
+
failure [
|
24
|
+
{
|
25
|
+
code: 404,
|
26
|
+
message: 'NotFound',
|
27
|
+
model: Entities::ApiError,
|
28
|
+
examples: { 'application/json' => { code: 404, message: 'Not found' } }
|
29
|
+
},
|
30
|
+
{
|
31
|
+
code: 400,
|
32
|
+
message: 'BadRequest',
|
33
|
+
model: Entities::ApiError,
|
34
|
+
examples: { 'application/json' => { code: 400, message: 'Bad Request' } }
|
35
|
+
}
|
36
|
+
]
|
37
|
+
end
|
38
|
+
get '/response_failure_examples' do
|
39
|
+
{ 'declared_params' => declared(params) }
|
40
|
+
end
|
41
|
+
|
42
|
+
desc 'This does not return examples' do
|
43
|
+
success model: Entities::UseResponse
|
44
|
+
failure [[404, 'NotFound', Entities::ApiError]]
|
45
|
+
end
|
46
|
+
get '/response_no_examples' do
|
47
|
+
{ 'declared_params' => declared(params) }
|
48
|
+
end
|
49
|
+
add_swagger_documentation
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
def app
|
55
|
+
TheApi::ResponseApiExamples
|
56
|
+
end
|
57
|
+
|
58
|
+
describe 'response examples' do
|
59
|
+
let(:example_200) do
|
60
|
+
{ 'application/json' => { 'description' => 'Names list', 'items' => [{ 'id' => '123', 'name' => 'John' }] } }
|
61
|
+
end
|
62
|
+
let(:example_404) do
|
63
|
+
{ 'application/json' => { 'code' => 404, 'message' => 'Not found' } }
|
64
|
+
end
|
65
|
+
|
66
|
+
subject do
|
67
|
+
get '/swagger_doc/response_examples'
|
68
|
+
JSON.parse(last_response.body)
|
69
|
+
end
|
70
|
+
|
71
|
+
specify do
|
72
|
+
expect(subject['paths']['/response_examples']['get']).to eql(
|
73
|
+
'description' => 'This returns examples',
|
74
|
+
'produces' => ['application/json'],
|
75
|
+
'responses' => {
|
76
|
+
'200' => { 'description' => 'This returns examples', 'schema' => { '$ref' => '#/definitions/UseResponse' }, 'examples' => example_200 },
|
77
|
+
'404' => { 'description' => 'NotFound', 'schema' => { '$ref' => '#/definitions/ApiError' }, 'examples' => example_404 }
|
78
|
+
},
|
79
|
+
'tags' => ['response_examples'],
|
80
|
+
'operationId' => 'getResponseExamples'
|
81
|
+
)
|
82
|
+
end
|
83
|
+
end
|
84
|
+
|
85
|
+
describe 'response failure examples' do
|
86
|
+
let(:example_200) do
|
87
|
+
{ 'application/json' => { 'description' => 'Names list', 'items' => [{ 'id' => '123', 'name' => 'John' }] } }
|
88
|
+
end
|
89
|
+
let(:example_404) do
|
90
|
+
{ 'application/json' => { 'code' => 404, 'message' => 'Not found' } }
|
91
|
+
end
|
92
|
+
let(:example_400) do
|
93
|
+
{ 'application/json' => { 'code' => 400, 'message' => 'Bad Request' } }
|
94
|
+
end
|
95
|
+
|
96
|
+
subject do
|
97
|
+
get '/swagger_doc/response_failure_examples'
|
98
|
+
JSON.parse(last_response.body)
|
99
|
+
end
|
100
|
+
|
101
|
+
specify do
|
102
|
+
expect(subject['paths']['/response_failure_examples']['get']).to eql(
|
103
|
+
'description' => 'This syntax also returns examples',
|
104
|
+
'produces' => ['application/json'],
|
105
|
+
'responses' => {
|
106
|
+
'200' => { 'description' => 'This syntax also returns examples', 'schema' => { '$ref' => '#/definitions/UseResponse' }, 'examples' => example_200 },
|
107
|
+
'404' => { 'description' => 'NotFound', 'schema' => { '$ref' => '#/definitions/ApiError' }, 'examples' => example_404 },
|
108
|
+
'400' => { 'description' => 'BadRequest', 'schema' => { '$ref' => '#/definitions/ApiError' }, 'examples' => example_400 }
|
109
|
+
},
|
110
|
+
'tags' => ['response_failure_examples'],
|
111
|
+
'operationId' => 'getResponseFailureExamples'
|
112
|
+
)
|
113
|
+
end
|
114
|
+
end
|
115
|
+
|
116
|
+
describe 'response no examples' do
|
117
|
+
subject do
|
118
|
+
get '/swagger_doc/response_no_examples'
|
119
|
+
JSON.parse(last_response.body)
|
120
|
+
end
|
121
|
+
|
122
|
+
specify do
|
123
|
+
expect(subject['paths']['/response_no_examples']['get']).to eql(
|
124
|
+
'description' => 'This does not return examples',
|
125
|
+
'produces' => ['application/json'],
|
126
|
+
'responses' => {
|
127
|
+
'200' => { 'description' => 'This does not return examples', 'schema' => { '$ref' => '#/definitions/UseResponse' } },
|
128
|
+
'404' => { 'description' => 'NotFound', 'schema' => { '$ref' => '#/definitions/ApiError' } }
|
129
|
+
},
|
130
|
+
'tags' => ['response_no_examples'],
|
131
|
+
'operationId' => 'getResponseNoExamples'
|
132
|
+
)
|
133
|
+
end
|
134
|
+
end
|
135
|
+
end
|
@@ -2,7 +2,7 @@
|
|
2
2
|
|
3
3
|
require 'spec_helper'
|
4
4
|
|
5
|
-
describe 'http status code
|
5
|
+
describe 'http status code behaviours' do
|
6
6
|
include_context "#{MODEL_PARSER} swagger example"
|
7
7
|
|
8
8
|
subject do
|
@@ -10,7 +10,7 @@ describe 'http status code behaivours' do
|
|
10
10
|
JSON.parse(last_response.body)
|
11
11
|
end
|
12
12
|
|
13
|
-
context 'when non-default success codes are
|
13
|
+
context 'when non-default success codes are defined' do
|
14
14
|
let(:app) do
|
15
15
|
Class.new(Grape::API) do
|
16
16
|
desc 'Has explicit success http_codes defined' do
|
@@ -31,6 +31,26 @@ describe 'http status code behaivours' do
|
|
31
31
|
end
|
32
32
|
end
|
33
33
|
|
34
|
+
context 'when success and failures are defined' do
|
35
|
+
let(:app) do
|
36
|
+
Class.new(Grape::API) do
|
37
|
+
desc 'Has explicit success http_codes defined' do
|
38
|
+
success code: 202, model: Entities::UseResponse, message: 'a changed status code'
|
39
|
+
failure [[400, 'Bad Request']]
|
40
|
+
end
|
41
|
+
|
42
|
+
post '/accepting_endpoint' do
|
43
|
+
'We got the message!'
|
44
|
+
end
|
45
|
+
add_swagger_documentation
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
it 'only includes the defined http codes' do
|
50
|
+
expect(subject['paths']['/accepting_endpoint']['post']['responses'].keys.sort).to eq(%w[202 400].sort)
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
34
54
|
context 'when no success codes defined' do
|
35
55
|
let(:app) do
|
36
56
|
Class.new(Grape::API) do
|
@@ -31,7 +31,6 @@ describe 'Default API' do
|
|
31
31
|
'paths' => {
|
32
32
|
'/something' => {
|
33
33
|
'get' => {
|
34
|
-
'summary' => 'This gets something.',
|
35
34
|
'description' => 'This gets something.',
|
36
35
|
'produces' => ['application/json'],
|
37
36
|
'tags' => ['something'],
|
@@ -78,7 +77,6 @@ describe 'Default API' do
|
|
78
77
|
'paths' => {
|
79
78
|
'/something' => {
|
80
79
|
'get' => {
|
81
|
-
'summary' => 'This gets something.',
|
82
80
|
'description' => 'This gets something.',
|
83
81
|
'produces' => ['application/json'],
|
84
82
|
'tags' => ['something'],
|
@@ -0,0 +1,25 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'spec_helper'
|
4
|
+
|
5
|
+
describe 'deprecated endpoint' do
|
6
|
+
def app
|
7
|
+
Class.new(Grape::API) do
|
8
|
+
desc 'Deprecated endpoint', deprecated: true
|
9
|
+
get '/foobar' do
|
10
|
+
{ foo: 'bar' }
|
11
|
+
end
|
12
|
+
|
13
|
+
add_swagger_documentation
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
subject do
|
18
|
+
get '/swagger_doc.json'
|
19
|
+
JSON.parse(last_response.body)
|
20
|
+
end
|
21
|
+
|
22
|
+
it 'includes the deprecated field' do
|
23
|
+
expect(subject['paths']['/foobar']['get']['deprecated']).to eql(true)
|
24
|
+
end
|
25
|
+
end
|
@@ -52,7 +52,6 @@ describe 'a hide mounted api' do
|
|
52
52
|
'paths' => {
|
53
53
|
'/simple' => {
|
54
54
|
'get' => {
|
55
|
-
'summary' => 'Show this endpoint',
|
56
55
|
'description' => 'Show this endpoint',
|
57
56
|
'produces' => ['application/json'],
|
58
57
|
'tags' => ['simple'],
|
@@ -62,7 +61,6 @@ describe 'a hide mounted api' do
|
|
62
61
|
},
|
63
62
|
'/lazy' => {
|
64
63
|
'get' => {
|
65
|
-
'summary' => 'Lazily show endpoint',
|
66
64
|
'description' => 'Lazily show endpoint',
|
67
65
|
'produces' => ['application/json'],
|
68
66
|
'tags' => ['lazy'],
|
@@ -115,7 +113,6 @@ describe 'a hide mounted api with same namespace' do
|
|
115
113
|
'paths' => {
|
116
114
|
'/simple/show' => {
|
117
115
|
'get' => {
|
118
|
-
'summary' => 'Show this endpoint',
|
119
116
|
'description' => 'Show this endpoint',
|
120
117
|
'produces' => ['application/json'],
|
121
118
|
'operationId' => 'getSimpleShow',
|
@@ -137,7 +134,6 @@ describe 'a hide mounted api with same namespace' do
|
|
137
134
|
'paths' => {
|
138
135
|
'/simple/show' => {
|
139
136
|
'get' => {
|
140
|
-
'summary' => 'Show this endpoint',
|
141
137
|
'description' => 'Show this endpoint',
|
142
138
|
'produces' => ['application/json'],
|
143
139
|
'tags' => ['simple'],
|
@@ -50,7 +50,6 @@ describe 'mount override api' do
|
|
50
50
|
end
|
51
51
|
|
52
52
|
it 'shows documentation from new endpoint' do
|
53
|
-
expect(subject['summary']).to eql('new endpoint')
|
54
53
|
expect(subject['parameters'][0]['description']).to eql('new param')
|
55
54
|
expect(subject['parameters'][0]['type']).to eql('string')
|
56
55
|
expect(subject['responses']['200']['description']).to eql('new message')
|
@@ -39,7 +39,6 @@ describe 'docs mounted separately from api' do
|
|
39
39
|
'paths' => {
|
40
40
|
'/simple' => {
|
41
41
|
'get' => {
|
42
|
-
'summary' => 'This gets something.',
|
43
42
|
'description' => 'This gets something.',
|
44
43
|
'produces' => ['application/json'],
|
45
44
|
'responses' => { '200' => { 'description' => 'This gets something.' } },
|
@@ -62,7 +61,6 @@ describe 'docs mounted separately from api' do
|
|
62
61
|
'paths' => {
|
63
62
|
'/simple' => {
|
64
63
|
'get' => {
|
65
|
-
'summary' => 'This gets something.',
|
66
64
|
'description' => 'This gets something.',
|
67
65
|
'produces' => ['application/json'],
|
68
66
|
'responses' => {
|
@@ -102,7 +102,6 @@ describe 'a simple mounted api' do
|
|
102
102
|
'paths' => {
|
103
103
|
'/' => {
|
104
104
|
'get' => {
|
105
|
-
'summary' => 'Document root',
|
106
105
|
'description' => 'Document root',
|
107
106
|
'produces' => ['application/json'],
|
108
107
|
'responses' => { '200' => { 'description' => 'Document root' } },
|
@@ -111,7 +110,6 @@ describe 'a simple mounted api' do
|
|
111
110
|
},
|
112
111
|
'/simple' => {
|
113
112
|
'get' => {
|
114
|
-
'summary' => 'This gets something.',
|
115
113
|
'description' => 'This gets something.',
|
116
114
|
'produces' => ['application/json'],
|
117
115
|
'tags' => ['simple'],
|
@@ -121,7 +119,6 @@ describe 'a simple mounted api' do
|
|
121
119
|
},
|
122
120
|
'/simple-test' => {
|
123
121
|
'get' => {
|
124
|
-
'summary' => 'This gets something for URL using - separator.',
|
125
122
|
'description' => 'This gets something for URL using - separator.',
|
126
123
|
'produces' => ['application/json'],
|
127
124
|
'tags' => ['simple-test'],
|
@@ -147,7 +144,6 @@ describe 'a simple mounted api' do
|
|
147
144
|
},
|
148
145
|
'/simple_with_headers' => {
|
149
146
|
'get' => {
|
150
|
-
'summary' => 'this gets something else',
|
151
147
|
'description' => 'this gets something else',
|
152
148
|
'produces' => ['application/json'],
|
153
149
|
'parameters' => [
|
@@ -165,7 +161,6 @@ describe 'a simple mounted api' do
|
|
165
161
|
},
|
166
162
|
'/items' => {
|
167
163
|
'post' => {
|
168
|
-
'summary' => 'this takes an array of parameters',
|
169
164
|
'description' => 'this takes an array of parameters',
|
170
165
|
'produces' => ['application/json'],
|
171
166
|
'consumes' => ['application/json'],
|
@@ -177,7 +172,6 @@ describe 'a simple mounted api' do
|
|
177
172
|
},
|
178
173
|
'/custom' => {
|
179
174
|
'get' => {
|
180
|
-
'summary' => 'this uses a custom parameter',
|
181
175
|
'description' => 'this uses a custom parameter',
|
182
176
|
'produces' => ['application/json'],
|
183
177
|
'parameters' => [{ 'in' => 'formData', 'name' => 'custom', 'description' => 'array of items', 'required' => false, 'type' => 'array', 'items' => { 'type' => 'CustomType' } }],
|
@@ -209,7 +203,6 @@ describe 'a simple mounted api' do
|
|
209
203
|
'paths' => {
|
210
204
|
'/simple' => {
|
211
205
|
'get' => {
|
212
|
-
'summary' => 'This gets something.',
|
213
206
|
'description' => 'This gets something.',
|
214
207
|
'produces' => ['application/json'],
|
215
208
|
'tags' => ['simple'],
|
@@ -241,7 +234,6 @@ describe 'a simple mounted api' do
|
|
241
234
|
'paths' => {
|
242
235
|
'/simple-test' => {
|
243
236
|
'get' => {
|
244
|
-
'summary' => 'This gets something for URL using - separator.',
|
245
237
|
'description' => 'This gets something for URL using - separator.',
|
246
238
|
'produces' => ['application/json'],
|
247
239
|
'tags' => ['simple-test'],
|
@@ -264,7 +256,6 @@ describe 'a simple mounted api' do
|
|
264
256
|
expect(subject['paths']).to eq(
|
265
257
|
'/simple_with_headers' => {
|
266
258
|
'get' => {
|
267
|
-
'summary' => 'this gets something else',
|
268
259
|
'description' => 'this gets something else',
|
269
260
|
'produces' => ['application/json'],
|
270
261
|
'parameters' => [
|
@@ -294,7 +285,6 @@ describe 'a simple mounted api' do
|
|
294
285
|
expect(subject['paths']).to eq(
|
295
286
|
'/items' => {
|
296
287
|
'post' => {
|
297
|
-
'summary' => 'this takes an array of parameters',
|
298
288
|
'description' => 'this takes an array of parameters',
|
299
289
|
'produces' => ['application/json'],
|
300
290
|
'consumes' => ['application/json'],
|
@@ -318,7 +308,6 @@ describe 'a simple mounted api' do
|
|
318
308
|
expect(subject['paths']).to eq(
|
319
309
|
'/custom' => {
|
320
310
|
'get' => {
|
321
|
-
'summary' => 'this uses a custom parameter',
|
322
311
|
'description' => 'this uses a custom parameter',
|
323
312
|
'produces' => ['application/json'],
|
324
313
|
'parameters' => [{ 'in' => 'formData', 'name' => 'custom', 'description' => 'array of items', 'required' => false, 'type' => 'array', 'items' => { 'type' => 'CustomType' } }],
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: grape-swagger
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.29.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Tim Vandecasteele
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2018-
|
11
|
+
date: 2018-05-22 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: grape
|
@@ -130,11 +130,13 @@ files:
|
|
130
130
|
- spec/swagger_v2/api_swagger_v2_param_type_spec.rb
|
131
131
|
- spec/swagger_v2/api_swagger_v2_request_params_fix_spec.rb
|
132
132
|
- spec/swagger_v2/api_swagger_v2_response_spec.rb
|
133
|
+
- spec/swagger_v2/api_swagger_v2_response_with_examples_spec.rb
|
133
134
|
- spec/swagger_v2/api_swagger_v2_spec.rb
|
134
135
|
- spec/swagger_v2/api_swagger_v2_status_codes_spec.rb
|
135
136
|
- spec/swagger_v2/api_swagger_v2_type-format_spec.rb
|
136
137
|
- spec/swagger_v2/boolean_params_spec.rb
|
137
138
|
- spec/swagger_v2/default_api_spec.rb
|
139
|
+
- spec/swagger_v2/deprecated_field_spec.rb
|
138
140
|
- spec/swagger_v2/description_not_initialized.rb
|
139
141
|
- spec/swagger_v2/endpoint_versioned_path_spec.rb
|
140
142
|
- spec/swagger_v2/errors_spec.rb
|
@@ -183,7 +185,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
183
185
|
version: '0'
|
184
186
|
requirements: []
|
185
187
|
rubyforge_project:
|
186
|
-
rubygems_version: 2.7.
|
188
|
+
rubygems_version: 2.7.6
|
187
189
|
signing_key:
|
188
190
|
specification_version: 4
|
189
191
|
summary: Add auto generated documentation to your Grape API that can be displayed
|
@@ -244,11 +246,13 @@ test_files:
|
|
244
246
|
- spec/swagger_v2/api_swagger_v2_param_type_spec.rb
|
245
247
|
- spec/swagger_v2/api_swagger_v2_request_params_fix_spec.rb
|
246
248
|
- spec/swagger_v2/api_swagger_v2_response_spec.rb
|
249
|
+
- spec/swagger_v2/api_swagger_v2_response_with_examples_spec.rb
|
247
250
|
- spec/swagger_v2/api_swagger_v2_spec.rb
|
248
251
|
- spec/swagger_v2/api_swagger_v2_status_codes_spec.rb
|
249
252
|
- spec/swagger_v2/api_swagger_v2_type-format_spec.rb
|
250
253
|
- spec/swagger_v2/boolean_params_spec.rb
|
251
254
|
- spec/swagger_v2/default_api_spec.rb
|
255
|
+
- spec/swagger_v2/deprecated_field_spec.rb
|
252
256
|
- spec/swagger_v2/description_not_initialized.rb
|
253
257
|
- spec/swagger_v2/endpoint_versioned_path_spec.rb
|
254
258
|
- spec/swagger_v2/errors_spec.rb
|