gitlab-grape-swagger 1.5.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (166) hide show
  1. checksums.yaml +7 -0
  2. data/.coveralls.yml +1 -0
  3. data/.github/dependabot.yml +20 -0
  4. data/.github/workflows/ci.yml +45 -0
  5. data/.gitignore +44 -0
  6. data/.gitlab-ci.yml +19 -0
  7. data/.rspec +3 -0
  8. data/.rubocop.yml +136 -0
  9. data/.rubocop_todo.yml +60 -0
  10. data/.ruby-gemset +1 -0
  11. data/CHANGELOG.md +671 -0
  12. data/CONTRIBUTING.md +126 -0
  13. data/Dangerfile +3 -0
  14. data/Gemfile +45 -0
  15. data/Gemfile.lock +249 -0
  16. data/LICENSE.txt +20 -0
  17. data/README.md +1772 -0
  18. data/RELEASING.md +82 -0
  19. data/Rakefile +20 -0
  20. data/UPGRADING.md +201 -0
  21. data/example/api/endpoints.rb +131 -0
  22. data/example/api/entities.rb +18 -0
  23. data/example/config.ru +42 -0
  24. data/example/example_requests.postman_collection +146 -0
  25. data/example/splines.png +0 -0
  26. data/example/swagger-example.png +0 -0
  27. data/grape-swagger.gemspec +23 -0
  28. data/lib/grape-swagger/doc_methods/build_model_definition.rb +68 -0
  29. data/lib/grape-swagger/doc_methods/data_type.rb +110 -0
  30. data/lib/grape-swagger/doc_methods/extensions.rb +101 -0
  31. data/lib/grape-swagger/doc_methods/file_params.rb +17 -0
  32. data/lib/grape-swagger/doc_methods/format_data.rb +53 -0
  33. data/lib/grape-swagger/doc_methods/headers.rb +20 -0
  34. data/lib/grape-swagger/doc_methods/move_params.rb +209 -0
  35. data/lib/grape-swagger/doc_methods/operation_id.rb +32 -0
  36. data/lib/grape-swagger/doc_methods/optional_object.rb +30 -0
  37. data/lib/grape-swagger/doc_methods/parse_params.rb +190 -0
  38. data/lib/grape-swagger/doc_methods/path_string.rb +52 -0
  39. data/lib/grape-swagger/doc_methods/produces_consumes.rb +15 -0
  40. data/lib/grape-swagger/doc_methods/status_codes.rb +21 -0
  41. data/lib/grape-swagger/doc_methods/tag_name_description.rb +34 -0
  42. data/lib/grape-swagger/doc_methods/version.rb +20 -0
  43. data/lib/grape-swagger/doc_methods.rb +142 -0
  44. data/lib/grape-swagger/endpoint/params_parser.rb +76 -0
  45. data/lib/grape-swagger/endpoint.rb +476 -0
  46. data/lib/grape-swagger/errors.rb +17 -0
  47. data/lib/grape-swagger/instance.rb +7 -0
  48. data/lib/grape-swagger/model_parsers.rb +42 -0
  49. data/lib/grape-swagger/rake/oapi_tasks.rb +135 -0
  50. data/lib/grape-swagger/version.rb +5 -0
  51. data/lib/grape-swagger.rb +174 -0
  52. data/spec/issues/267_nested_namespaces.rb +55 -0
  53. data/spec/issues/403_versions_spec.rb +124 -0
  54. data/spec/issues/427_entity_as_string_spec.rb +39 -0
  55. data/spec/issues/430_entity_definitions_spec.rb +94 -0
  56. data/spec/issues/532_allow_custom_format_spec.rb +42 -0
  57. data/spec/issues/533_specify_status_code_spec.rb +78 -0
  58. data/spec/issues/537_enum_values_spec.rb +50 -0
  59. data/spec/issues/539_array_post_body_spec.rb +65 -0
  60. data/spec/issues/542_array_of_type_in_post_body_spec.rb +46 -0
  61. data/spec/issues/553_align_array_put_post_params_spec.rb +152 -0
  62. data/spec/issues/572_array_post_body_spec.rb +51 -0
  63. data/spec/issues/579_align_put_post_parameters_spec.rb +185 -0
  64. data/spec/issues/582_file_response_spec.rb +55 -0
  65. data/spec/issues/587_range_parameter_delimited_by_dash_spec.rb +26 -0
  66. data/spec/issues/605_root_route_documentation_spec.rb +23 -0
  67. data/spec/issues/650_params_array_spec.rb +65 -0
  68. data/spec/issues/677_consumes_produces_add_swagger_documentation_options_spec.rb +100 -0
  69. data/spec/issues/680_keep_204_error_schemas_spec.rb +55 -0
  70. data/spec/issues/721_set_default_parameter_location_based_on_consumes_spec.rb +62 -0
  71. data/spec/issues/751_deeply_nested_objects_spec.rb +190 -0
  72. data/spec/issues/776_multiple_presents_spec.rb +59 -0
  73. data/spec/issues/784_extensions_on_params_spec.rb +42 -0
  74. data/spec/issues/809_utf8_routes_spec.rb +55 -0
  75. data/spec/issues/832_array_hash_float_decimal_spec.rb +114 -0
  76. data/spec/issues/847_route_param_options_spec.rb +37 -0
  77. data/spec/issues/873_wildcard_segments_path_parameters_spec.rb +28 -0
  78. data/spec/issues/878_optional_path_segments_spec.rb +29 -0
  79. data/spec/issues/881_handle_file_params_spec.rb +38 -0
  80. data/spec/issues/883_query_array_parameter_spec.rb +46 -0
  81. data/spec/issues/884_dont_document_non_schema_examples_spec.rb +49 -0
  82. data/spec/issues/887_prevent_duplicate_operation_ids_spec.rb +35 -0
  83. data/spec/lib/data_type_spec.rb +111 -0
  84. data/spec/lib/endpoint/params_parser_spec.rb +124 -0
  85. data/spec/lib/endpoint_spec.rb +153 -0
  86. data/spec/lib/extensions_spec.rb +185 -0
  87. data/spec/lib/format_data_spec.rb +115 -0
  88. data/spec/lib/model_parsers_spec.rb +104 -0
  89. data/spec/lib/move_params_spec.rb +444 -0
  90. data/spec/lib/oapi_tasks_spec.rb +163 -0
  91. data/spec/lib/operation_id_spec.rb +55 -0
  92. data/spec/lib/optional_object_spec.rb +47 -0
  93. data/spec/lib/parse_params_spec.rb +68 -0
  94. data/spec/lib/path_string_spec.rb +101 -0
  95. data/spec/lib/produces_consumes_spec.rb +116 -0
  96. data/spec/lib/tag_name_description_spec.rb +80 -0
  97. data/spec/lib/version_spec.rb +28 -0
  98. data/spec/spec_helper.rb +39 -0
  99. data/spec/support/empty_model_parser.rb +23 -0
  100. data/spec/support/grape_version.rb +13 -0
  101. data/spec/support/mock_parser.rb +23 -0
  102. data/spec/support/model_parsers/entity_parser.rb +334 -0
  103. data/spec/support/model_parsers/mock_parser.rb +346 -0
  104. data/spec/support/model_parsers/representable_parser.rb +406 -0
  105. data/spec/support/namespace_tags.rb +93 -0
  106. data/spec/support/the_paths_definitions.rb +109 -0
  107. data/spec/swagger_v2/api_documentation_spec.rb +42 -0
  108. data/spec/swagger_v2/api_swagger_v2_additional_properties_spec.rb +83 -0
  109. data/spec/swagger_v2/api_swagger_v2_body_definitions_spec.rb +48 -0
  110. data/spec/swagger_v2/api_swagger_v2_definitions-models_spec.rb +36 -0
  111. data/spec/swagger_v2/api_swagger_v2_detail_spec.rb +79 -0
  112. data/spec/swagger_v2/api_swagger_v2_extensions_spec.rb +145 -0
  113. data/spec/swagger_v2/api_swagger_v2_format-content_type_spec.rb +137 -0
  114. data/spec/swagger_v2/api_swagger_v2_global_configuration_spec.rb +56 -0
  115. data/spec/swagger_v2/api_swagger_v2_hash_and_array_spec.rb +64 -0
  116. data/spec/swagger_v2/api_swagger_v2_headers_spec.rb +58 -0
  117. data/spec/swagger_v2/api_swagger_v2_hide_documentation_path_spec.rb +57 -0
  118. data/spec/swagger_v2/api_swagger_v2_hide_param_spec.rb +109 -0
  119. data/spec/swagger_v2/api_swagger_v2_ignore_defaults_spec.rb +48 -0
  120. data/spec/swagger_v2/api_swagger_v2_mounted_spec.rb +153 -0
  121. data/spec/swagger_v2/api_swagger_v2_param_type_body_nested_spec.rb +355 -0
  122. data/spec/swagger_v2/api_swagger_v2_param_type_body_spec.rb +217 -0
  123. data/spec/swagger_v2/api_swagger_v2_param_type_spec.rb +247 -0
  124. data/spec/swagger_v2/api_swagger_v2_request_params_fix_spec.rb +80 -0
  125. data/spec/swagger_v2/api_swagger_v2_response_spec.rb +147 -0
  126. data/spec/swagger_v2/api_swagger_v2_response_with_examples_spec.rb +135 -0
  127. data/spec/swagger_v2/api_swagger_v2_response_with_headers_spec.rb +216 -0
  128. data/spec/swagger_v2/api_swagger_v2_response_with_models_spec.rb +53 -0
  129. data/spec/swagger_v2/api_swagger_v2_response_with_root_spec.rb +153 -0
  130. data/spec/swagger_v2/api_swagger_v2_spec.rb +245 -0
  131. data/spec/swagger_v2/api_swagger_v2_status_codes_spec.rb +93 -0
  132. data/spec/swagger_v2/api_swagger_v2_type-format_spec.rb +90 -0
  133. data/spec/swagger_v2/boolean_params_spec.rb +38 -0
  134. data/spec/swagger_v2/default_api_spec.rb +175 -0
  135. data/spec/swagger_v2/deprecated_field_spec.rb +25 -0
  136. data/spec/swagger_v2/description_not_initialized_spec.rb +39 -0
  137. data/spec/swagger_v2/endpoint_versioned_path_spec.rb +130 -0
  138. data/spec/swagger_v2/errors_spec.rb +77 -0
  139. data/spec/swagger_v2/float_api_spec.rb +36 -0
  140. data/spec/swagger_v2/form_params_spec.rb +76 -0
  141. data/spec/swagger_v2/grape-swagger_spec.rb +17 -0
  142. data/spec/swagger_v2/guarded_endpoint_spec.rb +162 -0
  143. data/spec/swagger_v2/hide_api_spec.rb +147 -0
  144. data/spec/swagger_v2/host_spec.rb +43 -0
  145. data/spec/swagger_v2/inheritance_and_discriminator_spec.rb +57 -0
  146. data/spec/swagger_v2/mount_override_api_spec.rb +58 -0
  147. data/spec/swagger_v2/mounted_target_class_spec.rb +76 -0
  148. data/spec/swagger_v2/namespace_tags_prefix_spec.rb +122 -0
  149. data/spec/swagger_v2/namespace_tags_spec.rb +78 -0
  150. data/spec/swagger_v2/namespaced_api_spec.rb +121 -0
  151. data/spec/swagger_v2/nicknamed_api_spec.rb +25 -0
  152. data/spec/swagger_v2/operation_id_api_spec.rb +27 -0
  153. data/spec/swagger_v2/param_multi_type_spec.rb +82 -0
  154. data/spec/swagger_v2/param_type_spec.rb +95 -0
  155. data/spec/swagger_v2/param_values_spec.rb +180 -0
  156. data/spec/swagger_v2/params_array_collection_format_spec.rb +105 -0
  157. data/spec/swagger_v2/params_array_spec.rb +225 -0
  158. data/spec/swagger_v2/params_example_spec.rb +38 -0
  159. data/spec/swagger_v2/params_hash_spec.rb +77 -0
  160. data/spec/swagger_v2/params_nested_spec.rb +92 -0
  161. data/spec/swagger_v2/parent_less_namespace_spec.rb +32 -0
  162. data/spec/swagger_v2/reference_entity_spec.rb +129 -0
  163. data/spec/swagger_v2/security_requirement_spec.rb +46 -0
  164. data/spec/swagger_v2/simple_mounted_api_spec.rb +332 -0
  165. data/spec/version_spec.rb +10 -0
  166. metadata +225 -0
@@ -0,0 +1,92 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'spec_helper'
4
+
5
+ describe 'nested group params' do
6
+ [true, false].each do |array_use_braces|
7
+ context "when array_use_braces option is set to #{array_use_braces}" do
8
+ let(:braces) { array_use_braces ? '[]' : '' }
9
+ let(:app) do
10
+ Class.new(Grape::API) do
11
+ format :json
12
+
13
+ desc 'nested array' do
14
+ consumes ['application/x-www-form-urlencoded']
15
+ end
16
+ params do
17
+ requires :a_array, type: Array do
18
+ requires :param_1, type: Integer
19
+ requires :b_array, type: Array do
20
+ requires :param_2, type: String
21
+ end
22
+ requires :c_hash, type: Hash do
23
+ requires :param_3, type: String
24
+ end
25
+ end
26
+ requires :a_array_foo, type: String
27
+ end
28
+ post '/nested_array' do
29
+ { 'declared_params' => declared(params) }
30
+ end
31
+
32
+ desc 'nested hash' do
33
+ consumes ['application/x-www-form-urlencoded']
34
+ end
35
+ params do
36
+ requires :a_hash, type: Hash do
37
+ requires :param_1, type: Integer
38
+ requires :b_hash, type: Hash do
39
+ requires :param_2, type: String
40
+ end
41
+ requires :c_array, type: Array do
42
+ requires :param_3, type: String
43
+ end
44
+ end
45
+ requires :a_hash_foo, type: String
46
+ end
47
+ post '/nested_hash' do
48
+ { 'declared_params' => declared(params) }
49
+ end
50
+
51
+ add_swagger_documentation array_use_braces: array_use_braces
52
+ end
53
+ end
54
+
55
+ describe 'retrieves the documentation for nested array parameters' do
56
+ subject do
57
+ get '/swagger_doc/nested_array'
58
+ JSON.parse(last_response.body)
59
+ end
60
+
61
+ specify do
62
+ expect(subject['paths']['/nested_array']['post']['parameters']).to eql(
63
+ [
64
+ { 'in' => 'formData', 'name' => "a_array#{braces}[param_1]", 'required' => true, 'type' => 'array', 'items' => { 'type' => 'integer', 'format' => 'int32' } },
65
+ { 'in' => 'formData', 'name' => "a_array#{braces}[b_array]#{braces}[param_2]", 'required' => true, 'type' => 'array', 'items' => { 'type' => 'string' } },
66
+ { 'in' => 'formData', 'name' => "a_array#{braces}[c_hash][param_3]", 'required' => true, 'type' => 'array', 'items' => { 'type' => 'string' } },
67
+ { 'in' => 'formData', 'name' => 'a_array_foo', 'required' => true, 'type' => 'string' }
68
+ ]
69
+ )
70
+ end
71
+ end
72
+
73
+ describe 'retrieves the documentation for nested hash parameters' do
74
+ subject do
75
+ get '/swagger_doc/nested_hash'
76
+ JSON.parse(last_response.body)
77
+ end
78
+
79
+ specify do
80
+ expect(subject['paths']['/nested_hash']['post']['parameters']).to eql(
81
+ [
82
+ { 'in' => 'formData', 'name' => 'a_hash[param_1]', 'required' => true, 'type' => 'integer', 'format' => 'int32' },
83
+ { 'in' => 'formData', 'name' => 'a_hash[b_hash][param_2]', 'required' => true, 'type' => 'string' },
84
+ { 'in' => 'formData', 'name' => "a_hash[c_array]#{braces}[param_3]", 'required' => true, 'type' => 'array', 'items' => { 'type' => 'string' } },
85
+ { 'in' => 'formData', 'name' => 'a_hash_foo', 'required' => true, 'type' => 'string' }
86
+ ]
87
+ )
88
+ end
89
+ end
90
+ end
91
+ end
92
+ end
@@ -0,0 +1,32 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'spec_helper'
4
+
5
+ describe 'a parent less namespace' do
6
+ include_context 'namespace example'
7
+
8
+ before :all do
9
+ class ParentLessApi < Grape::API
10
+ prefix :api
11
+ mount TheApi::ParentLessNamespaceApi
12
+ add_swagger_documentation version: 'v1'
13
+ end
14
+ end
15
+
16
+ def app
17
+ ParentLessApi
18
+ end
19
+
20
+ describe 'retrieves swagger-documentation on /swagger_doc' do
21
+ let(:route_name) { ':animal/:breed/queues/:queue_id/reservations' }
22
+ subject do
23
+ get '/api/swagger_doc.json'
24
+ JSON.parse(last_response.body)
25
+ end
26
+
27
+ specify do
28
+ expect(subject['paths']['/api/{animal}/{breed}/queues/{queue_id}/reservations']['get']['operationId'])
29
+ .to start_with('getApiAnimalBreedQueuesQueueIdReservations')
30
+ end
31
+ end
32
+ end
@@ -0,0 +1,129 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'spec_helper'
4
+
5
+ describe 'referenceEntity' do
6
+ before :all do
7
+ module MyAPI
8
+ module Entities
9
+ class Something < Grape::Entity
10
+ def self.entity_name
11
+ 'SomethingCustom'
12
+ end
13
+
14
+ expose :text, documentation: { type: 'string', desc: 'Content of something.' }
15
+ end
16
+
17
+ class Kind < Grape::Entity
18
+ def self.entity_name
19
+ 'KindCustom'
20
+ end
21
+
22
+ expose :title, documentation: { type: 'string', desc: 'Title of the kind.' }
23
+ expose :something, documentation: { type: Something, desc: 'Something interesting.' }
24
+ end
25
+
26
+ class Base < Grape::Entity
27
+ def self.entity_name
28
+ parts = to_s.split('::')
29
+
30
+ "MyAPI::#{parts.last}"
31
+ end
32
+
33
+ expose :title, documentation: { type: 'string', desc: 'Title of the parent.' }
34
+ end
35
+
36
+ class Child < Base
37
+ expose :child, documentation: { type: 'string', desc: 'Child property.' }
38
+ end
39
+ end
40
+
41
+ class ResponseModelApi < Grape::API
42
+ format :json
43
+ desc 'This returns kind and something or an error',
44
+ params: Entities::Kind.documentation.slice(:something),
45
+ entity: Entities::Kind,
46
+ http_codes: [
47
+ { code: 200, message: 'OK', model: Entities::Kind }
48
+ ]
49
+ params do
50
+ optional :something, desc: 'something as parameter'
51
+ end
52
+ get '/kind' do
53
+ kind = OpenStruct.new text: 'kind'
54
+ present kind, with: Entities::Kind
55
+ end
56
+
57
+ desc 'This returns a child entity',
58
+ entity: Entities::Child,
59
+ http_codes: [
60
+ { code: 200, message: 'OK', model: Entities::Child }
61
+ ]
62
+ get '/child' do
63
+ child = OpenStruct.new text: 'child'
64
+ present child, with: Entities::Child
65
+ end
66
+
67
+ add_swagger_documentation # models: [MyAPI::Entities::Something, MyAPI::Entities::Kind]
68
+ end
69
+ end
70
+ end
71
+
72
+ def app
73
+ MyAPI::ResponseModelApi
74
+ end
75
+
76
+ describe 'kind' do
77
+ subject do
78
+ get '/swagger_doc/kind'
79
+ JSON.parse(last_response.body)
80
+ end
81
+
82
+ it 'should document specified models' do
83
+ expect(subject['paths']['/kind']['get']['parameters']).to eq [{
84
+ 'in' => 'query',
85
+ 'name' => 'something',
86
+ 'description' => 'Something interesting.',
87
+ 'type' => 'SomethingCustom',
88
+ 'required' => false
89
+ }]
90
+
91
+ expect(subject['definitions'].keys).to include 'SomethingCustom'
92
+ expect(subject['definitions']['SomethingCustom']).to eq(
93
+ 'type' => 'object', 'properties' => { 'text' => { 'type' => 'string', 'description' => 'Content of something.' } }
94
+ )
95
+
96
+ expect(subject['definitions'].keys).to include 'KindCustom'
97
+ expect(subject['definitions']['KindCustom']).to eq(
98
+ 'type' => 'object',
99
+ 'properties' => {
100
+ 'title' => { 'type' => 'string', 'description' => 'Title of the kind.' },
101
+ 'something' => {
102
+ '$ref' => '#/definitions/SomethingCustom',
103
+ 'description' => 'Something interesting.'
104
+ }
105
+ },
106
+ 'description' => 'KindCustom model'
107
+ )
108
+ end
109
+ end
110
+
111
+ describe 'child' do
112
+ subject do
113
+ get '/swagger_doc/child'
114
+ JSON.parse(last_response.body)
115
+ end
116
+
117
+ it 'should document specified models' do
118
+ expect(subject['definitions'].keys).to include 'MyAPI::Child'
119
+ expect(subject['definitions']['MyAPI::Child']).to eq(
120
+ 'type' => 'object',
121
+ 'properties' => {
122
+ 'title' => { 'type' => 'string', 'description' => 'Title of the parent.' },
123
+ 'child' => { 'type' => 'string', 'description' => 'Child property.' }
124
+ },
125
+ 'description' => 'MyAPI::Child model'
126
+ )
127
+ end
128
+ end
129
+ end
@@ -0,0 +1,46 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'spec_helper'
4
+
5
+ describe 'security requirement on endpoint method' do
6
+ def app
7
+ Class.new(Grape::API) do
8
+ desc 'Endpoint with security requirement', security: [{ oauth_pets: ['read:pets', 'write:pets'] }]
9
+ get '/with_security' do
10
+ { foo: 'bar' }
11
+ end
12
+
13
+ desc 'Endpoint without security requirement', security: []
14
+ get '/without_security' do
15
+ { foo: 'bar' }
16
+ end
17
+
18
+ add_swagger_documentation(
19
+ security_definitions: {
20
+ petstore_auth: {
21
+ type: 'oauth2',
22
+ flow: 'implicit',
23
+ authorizationUrl: 'https://petstore.swagger.io/oauth/dialog',
24
+ scopes: {
25
+ 'read:pets': 'read your pets',
26
+ 'write:pets': 'modify pets in your account'
27
+ }
28
+ }
29
+ }
30
+ )
31
+ end
32
+ end
33
+
34
+ subject do
35
+ get '/swagger_doc.json'
36
+ JSON.parse(last_response.body)
37
+ end
38
+
39
+ it 'defines the security requirement on the endpoint method' do
40
+ expect(subject['paths']['/with_security']['get']['security']).to eql [{ 'oauth_pets' => ['read:pets', 'write:pets'] }]
41
+ end
42
+
43
+ it 'defines an empty security requirement on the endpoint method' do
44
+ expect(subject['paths']['/without_security']['get']['security']).to eql []
45
+ end
46
+ end
@@ -0,0 +1,332 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'spec_helper'
4
+
5
+ describe 'a simple mounted api' do
6
+ before :all do
7
+ # rubocop:disable Lint/EmptyClass
8
+ class CustomType; end
9
+ # rubocop:enable Lint/EmptyClass
10
+
11
+ class SimpleMountedApi < Grape::API
12
+ desc 'Document root',
13
+ consumes: ['application/x-www-form-urlencoded']
14
+ get do
15
+ { message: 'hi' }
16
+ end
17
+
18
+ desc 'This gets something.',
19
+ consumes: ['application/x-www-form-urlencoded'],
20
+ notes: '_test_'
21
+
22
+ get '/simple' do
23
+ { bla: 'something' }
24
+ end
25
+
26
+ desc 'This gets something for URL using - separator.',
27
+ consumes: ['application/x-www-form-urlencoded'],
28
+ notes: '_test_'
29
+
30
+ get '/simple-test' do
31
+ { bla: 'something' }
32
+ end
33
+
34
+ head '/simple-head-test' do
35
+ status 200
36
+ end
37
+
38
+ options '/simple-options-test' do
39
+ status 200
40
+ end
41
+
42
+ desc 'this gets something else',
43
+ consumes: ['application/x-www-form-urlencoded'],
44
+ headers: {
45
+ 'XAuthToken' => { description: 'A required header.', required: true },
46
+ 'XOtherHeader' => { description: 'An optional header.', required: false }
47
+ },
48
+ http_codes: [
49
+ { code: 403, message: 'invalid pony' },
50
+ { code: 405, message: 'no ponies left!' }
51
+ ]
52
+
53
+ get '/simple_with_headers' do
54
+ { bla: 'something_else' }
55
+ end
56
+
57
+ desc 'this takes an array of parameters',
58
+ consumes: ['application/x-www-form-urlencoded'],
59
+ params: {
60
+ 'items[]' => { description: 'array of items', is_array: true }
61
+ }
62
+
63
+ post '/items' do
64
+ {}
65
+ end
66
+
67
+ desc 'this uses a custom parameter',
68
+ consumes: ['application/x-www-form-urlencoded'],
69
+ params: {
70
+ 'custom' => { type: CustomType, description: 'array of items', is_array: true }
71
+ }
72
+
73
+ get '/custom' do
74
+ {}
75
+ end
76
+ end
77
+
78
+ class SimpleApi < Grape::API
79
+ mount SimpleMountedApi
80
+ add_swagger_documentation
81
+ end
82
+ end
83
+
84
+ def app
85
+ SimpleApi
86
+ end
87
+
88
+ describe 'retrieves swagger-documentation on /swagger_doc' do
89
+ subject do
90
+ get '/swagger_doc.json'
91
+ JSON.parse(last_response.body)
92
+ end
93
+
94
+ specify do
95
+ expect(subject).to eq(
96
+ 'info' => {
97
+ 'title' => 'API title', 'version' => '0.0.1'
98
+ },
99
+ 'swagger' => '2.0',
100
+ 'produces' => ['application/xml', 'application/json', 'application/octet-stream', 'text/plain'],
101
+ 'host' => 'example.org',
102
+ 'tags' => [
103
+ { 'name' => 'simple', 'description' => 'Operations about simples' },
104
+ { 'name' => 'simple-test', 'description' => 'Operations about simple-tests' },
105
+ { 'name' => 'simple-head-test', 'description' => 'Operations about simple-head-tests' },
106
+ { 'name' => 'simple-options-test', 'description' => 'Operations about simple-options-tests' },
107
+ { 'name' => 'simple_with_headers', 'description' => 'Operations about simple_with_headers' },
108
+ { 'name' => 'items', 'description' => 'Operations about items' },
109
+ { 'name' => 'custom', 'description' => 'Operations about customs' }
110
+ ],
111
+ 'paths' => {
112
+ '/' => {
113
+ 'get' => {
114
+ 'description' => 'Document root',
115
+ 'produces' => ['application/json'],
116
+ 'responses' => { '200' => { 'description' => 'Document root' } },
117
+ 'operationId' => 'get'
118
+ }
119
+ },
120
+ '/simple' => {
121
+ 'get' => {
122
+ 'description' => 'This gets something.',
123
+ 'produces' => ['application/json'],
124
+ 'tags' => ['simple'],
125
+ 'operationId' => 'getSimple',
126
+ 'responses' => { '200' => { 'description' => 'This gets something.' } }
127
+ }
128
+ },
129
+ '/simple-test' => {
130
+ 'get' => {
131
+ 'description' => 'This gets something for URL using - separator.',
132
+ 'produces' => ['application/json'],
133
+ 'tags' => ['simple-test'],
134
+ 'operationId' => 'getSimpleTest',
135
+ 'responses' => { '200' => { 'description' => 'This gets something for URL using - separator.' } }
136
+ }
137
+ },
138
+ '/simple-head-test' => {
139
+ 'head' => {
140
+ 'produces' => ['application/json'],
141
+ 'responses' => { '200' => { 'description' => 'head SimpleHeadTest' } },
142
+ 'tags' => ['simple-head-test'],
143
+ 'operationId' => 'headSimpleHeadTest'
144
+ }
145
+ },
146
+ '/simple-options-test' => {
147
+ 'options' => {
148
+ 'produces' => ['application/json'],
149
+ 'responses' => { '200' => { 'description' => 'option SimpleOptionsTest' } },
150
+ 'tags' => ['simple-options-test'],
151
+ 'operationId' => 'optionsSimpleOptionsTest'
152
+ }
153
+ },
154
+ '/simple_with_headers' => {
155
+ 'get' => {
156
+ 'description' => 'this gets something else',
157
+ 'produces' => ['application/json'],
158
+ 'parameters' => [
159
+ { 'in' => 'header', 'name' => 'XAuthToken', 'description' => 'A required header.', 'type' => 'string', 'required' => true },
160
+ { 'in' => 'header', 'name' => 'XOtherHeader', 'description' => 'An optional header.', 'type' => 'string', 'required' => false }
161
+ ],
162
+ 'tags' => ['simple_with_headers'],
163
+ 'operationId' => 'getSimpleWithHeaders',
164
+ 'responses' => {
165
+ '200' => { 'description' => 'this gets something else' },
166
+ '403' => { 'description' => 'invalid pony' },
167
+ '405' => { 'description' => 'no ponies left!' }
168
+ }
169
+ }
170
+ },
171
+ '/items' => {
172
+ 'post' => {
173
+ 'description' => 'this takes an array of parameters',
174
+ 'produces' => ['application/json'],
175
+ 'consumes' => ['application/x-www-form-urlencoded'],
176
+ 'parameters' => [{ 'in' => 'formData', 'name' => 'items[]', 'description' => 'array of items', 'required' => false, 'type' => 'array', 'items' => { 'type' => 'string' } }],
177
+ 'tags' => ['items'],
178
+ 'operationId' => 'postItems',
179
+ 'responses' => { '201' => { 'description' => 'this takes an array of parameters' } }
180
+ }
181
+ },
182
+ '/custom' => {
183
+ 'get' => {
184
+ 'description' => 'this uses a custom parameter',
185
+ 'produces' => ['application/json'],
186
+ 'parameters' => [{ 'in' => 'formData', 'name' => 'custom', 'description' => 'array of items', 'required' => false, 'type' => 'array', 'items' => { 'type' => 'CustomType' } }],
187
+ 'tags' => ['custom'],
188
+ 'operationId' => 'getCustom',
189
+ 'responses' => { '200' => { 'description' => 'this uses a custom parameter' } }
190
+ }
191
+ }
192
+ }
193
+ )
194
+ end
195
+ end
196
+
197
+ describe 'retrieves the documentation for mounted-api' do
198
+ subject do
199
+ get '/swagger_doc/simple.json'
200
+ JSON.parse(last_response.body)
201
+ end
202
+
203
+ specify do
204
+ expect(subject).to eq(
205
+ 'info' => { 'title' => 'API title', 'version' => '0.0.1' },
206
+ 'swagger' => '2.0',
207
+ 'produces' => ['application/xml', 'application/json', 'application/octet-stream', 'text/plain'],
208
+ 'host' => 'example.org',
209
+ 'tags' => [
210
+ { 'name' => 'simple', 'description' => 'Operations about simples' }
211
+ ],
212
+ 'paths' => {
213
+ '/simple' => {
214
+ 'get' => {
215
+ 'description' => 'This gets something.',
216
+ 'produces' => ['application/json'],
217
+ 'tags' => ['simple'],
218
+ 'operationId' => 'getSimple',
219
+ 'responses' => { '200' => { 'description' => 'This gets something.' } }
220
+ }
221
+ }
222
+ }
223
+ )
224
+ end
225
+ end
226
+
227
+ describe 'retrieves the documentation for mounted-api that' do
228
+ describe "contains '-' in URL" do
229
+ subject do
230
+ get '/swagger_doc/simple-test.json'
231
+ JSON.parse(last_response.body)
232
+ end
233
+
234
+ specify do
235
+ expect(subject).to eq(
236
+ 'info' => { 'title' => 'API title', 'version' => '0.0.1' },
237
+ 'swagger' => '2.0',
238
+ 'produces' => ['application/xml', 'application/json', 'application/octet-stream', 'text/plain'],
239
+ 'host' => 'example.org',
240
+ 'tags' => [
241
+ { 'name' => 'simple-test', 'description' => 'Operations about simple-tests' }
242
+ ],
243
+ 'paths' => {
244
+ '/simple-test' => {
245
+ 'get' => {
246
+ 'description' => 'This gets something for URL using - separator.',
247
+ 'produces' => ['application/json'],
248
+ 'tags' => ['simple-test'],
249
+ 'operationId' => 'getSimpleTest',
250
+ 'responses' => { '200' => { 'description' => 'This gets something for URL using - separator.' } }
251
+ }
252
+ }
253
+ }
254
+ )
255
+ end
256
+ end
257
+
258
+ describe 'includes headers' do
259
+ subject do
260
+ get '/swagger_doc/simple_with_headers.json'
261
+ JSON.parse(last_response.body)
262
+ end
263
+
264
+ specify do
265
+ expect(subject['paths']).to eq(
266
+ '/simple_with_headers' => {
267
+ 'get' => {
268
+ 'description' => 'this gets something else',
269
+ 'produces' => ['application/json'],
270
+ 'parameters' => [
271
+ { 'in' => 'header', 'name' => 'XAuthToken', 'description' => 'A required header.', 'type' => 'string', 'required' => true },
272
+ { 'in' => 'header', 'name' => 'XOtherHeader', 'description' => 'An optional header.', 'type' => 'string', 'required' => false }
273
+ ],
274
+ 'tags' => ['simple_with_headers'],
275
+ 'operationId' => 'getSimpleWithHeaders',
276
+ 'responses' => {
277
+ '200' => { 'description' => 'this gets something else' },
278
+ '403' => { 'description' => 'invalid pony' },
279
+ '405' => { 'description' => 'no ponies left!' }
280
+ }
281
+ }
282
+ }
283
+ )
284
+ end
285
+ end
286
+
287
+ describe 'supports array params' do
288
+ subject do
289
+ get '/swagger_doc/items.json'
290
+ JSON.parse(last_response.body)
291
+ end
292
+
293
+ specify do
294
+ expect(subject['paths']).to eq(
295
+ '/items' => {
296
+ 'post' => {
297
+ 'description' => 'this takes an array of parameters',
298
+ 'produces' => ['application/json'],
299
+ 'consumes' => ['application/x-www-form-urlencoded'],
300
+ 'parameters' => [{ 'in' => 'formData', 'name' => 'items[]', 'description' => 'array of items', 'required' => false, 'type' => 'array', 'items' => { 'type' => 'string' } }],
301
+ 'tags' => ['items'],
302
+ 'operationId' => 'postItems',
303
+ 'responses' => { '201' => { 'description' => 'this takes an array of parameters' } }
304
+ }
305
+ }
306
+ )
307
+ end
308
+ end
309
+
310
+ describe 'supports custom params types' do
311
+ subject do
312
+ get '/swagger_doc/custom.json'
313
+ JSON.parse(last_response.body)
314
+ end
315
+
316
+ specify do
317
+ expect(subject['paths']).to eq(
318
+ '/custom' => {
319
+ 'get' => {
320
+ 'description' => 'this uses a custom parameter',
321
+ 'produces' => ['application/json'],
322
+ 'parameters' => [{ 'in' => 'formData', 'name' => 'custom', 'description' => 'array of items', 'required' => false, 'type' => 'array', 'items' => { 'type' => 'CustomType' } }],
323
+ 'tags' => ['custom'],
324
+ 'operationId' => 'getCustom',
325
+ 'responses' => { '200' => { 'description' => 'this uses a custom parameter' } }
326
+ }
327
+ }
328
+ )
329
+ end
330
+ end
331
+ end
332
+ end
@@ -0,0 +1,10 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'spec_helper'
4
+
5
+ describe GrapeSwagger do
6
+ it '#version' do
7
+ expect(GrapeSwagger::VERSION).to_not be_nil
8
+ expect(GrapeSwagger::VERSION.split('.').count).to eq 3
9
+ end
10
+ end