gitlab-grape-swagger 1.5.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.
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,93 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'spec_helper'
4
+
5
+ describe 'http status code behaviours' do
6
+ include_context "#{MODEL_PARSER} swagger example"
7
+
8
+ subject do
9
+ get '/swagger_doc'
10
+ JSON.parse(last_response.body)
11
+ end
12
+
13
+ context 'when non-default success codes are defined' do
14
+ let(:app) do
15
+ Class.new(Grape::API) do
16
+ desc 'Has explicit success http_codes defined' do
17
+ http_codes [{ code: 202, message: 'We got it!' },
18
+ { code: 204, message: 'Or returned no content' },
19
+ { code: 400, message: 'Bad request' }]
20
+ end
21
+
22
+ post '/accepting_endpoint' do
23
+ 'We got the message!'
24
+ end
25
+ add_swagger_documentation
26
+ end
27
+ end
28
+
29
+ it 'only includes the defined http_codes' do
30
+ expect(subject['paths']['/accepting_endpoint']['post']['responses'].keys.sort).to eq(%w[202 204 400].sort)
31
+ end
32
+ end
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
+
54
+ context 'when no success codes defined' do
55
+ let(:app) do
56
+ Class.new(Grape::API) do
57
+ desc 'Has explicit error http_codes defined' do
58
+ http_codes [{ code: 400, message: 'Error!' },
59
+ { code: 404, message: 'Not found' }]
60
+ end
61
+
62
+ post '/error_endpoint' do
63
+ 'We got the message!'
64
+ end
65
+ add_swagger_documentation
66
+ end
67
+ end
68
+
69
+ it 'adds the success codes to the response' do
70
+ expect(subject['paths']['/error_endpoint']['post']['responses'].keys.sort).to eq(%w[201 400 404].sort)
71
+ end
72
+ end
73
+
74
+ context 'when success and error codes are defined' do
75
+ let(:app) do
76
+ Class.new(Grape::API) do
77
+ desc 'Has success and error codes defined' do
78
+ http_codes [{ code: 200, message: 'Found' },
79
+ { code: 404, message: 'Not found' }]
80
+ end
81
+
82
+ get '/endpoint' do
83
+ 'We got the message!'
84
+ end
85
+ add_swagger_documentation
86
+ end
87
+ end
88
+
89
+ it 'adds the success codes and error codes to the response' do
90
+ expect(subject['paths']['/endpoint']['get']['responses'].keys.sort).to eq(%w[200 404].sort)
91
+ end
92
+ end
93
+ end
@@ -0,0 +1,90 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'spec_helper'
4
+
5
+ # mapping of parameter types
6
+ # Grape -> Swagger (OpenApi)
7
+ # (type format)
8
+ # ---------------------------------------------------
9
+ # Integer -> integer int32
10
+ # Numeric -> integer int64
11
+ # Float -> number float
12
+ # BigDecimal -> number double
13
+ # String -> string
14
+ # Symbol -> string
15
+ # Date -> string date
16
+ # DateTime -> string date-time
17
+ # Time -> string date-time
18
+ # 'password' -> string password
19
+ # 'email' -> string email
20
+ # Boolean -> boolean
21
+ # JSON -> json
22
+ # Rack::Multipart::UploadedFile -> file
23
+
24
+ describe 'type format settings' do
25
+ include_context "#{MODEL_PARSER} swagger example"
26
+
27
+ before :all do
28
+ module TheApi
29
+ class TypeFormatApi < Grape::API
30
+ desc 'full set of request data types',
31
+ consumes: ['application/x-www-form-urlencoded'],
32
+ success: Entities::TypedDefinition
33
+
34
+ params do
35
+ # grape supported data types
36
+ requires :param_integer, type: Integer
37
+ requires :param_long, type: Numeric
38
+ requires :param_float, type: Float
39
+ requires :param_double, type: BigDecimal
40
+ optional :param_string, type: String
41
+ optional :param_symbol, type: Symbol
42
+ requires :param_date, type: Date
43
+ requires :param_date_time, type: DateTime
44
+ requires :param_time, type: Time
45
+ optional :param_boolean, type: Boolean
46
+ optional :param_file, type: File
47
+ optional :param_json, type: JSON
48
+ end
49
+
50
+ post '/request_types' do
51
+ { 'declared_params' => declared(params) }
52
+ end
53
+
54
+ add_swagger_documentation
55
+ end
56
+ end
57
+ end
58
+
59
+ def app
60
+ TheApi::TypeFormatApi
61
+ end
62
+
63
+ subject do
64
+ get '/swagger_doc/request_types'
65
+ JSON.parse(last_response.body)
66
+ end
67
+
68
+ specify do
69
+ expect(subject['paths']['/request_types']['post']['parameters']).to eql(
70
+ [
71
+ { 'in' => 'formData', 'name' => 'param_integer', 'required' => true, 'type' => 'integer', 'format' => 'int32' },
72
+ { 'in' => 'formData', 'name' => 'param_long', 'required' => true, 'type' => 'integer', 'format' => 'int64' },
73
+ { 'in' => 'formData', 'name' => 'param_float', 'required' => true, 'type' => 'number', 'format' => 'float' },
74
+ { 'in' => 'formData', 'name' => 'param_double', 'required' => true, 'type' => 'number', 'format' => 'double' },
75
+ { 'in' => 'formData', 'name' => 'param_string', 'required' => false, 'type' => 'string' },
76
+ { 'in' => 'formData', 'name' => 'param_symbol', 'required' => false, 'type' => 'string' },
77
+ { 'in' => 'formData', 'name' => 'param_date', 'required' => true, 'type' => 'string', 'format' => 'date' },
78
+ { 'in' => 'formData', 'name' => 'param_date_time', 'required' => true, 'type' => 'string', 'format' => 'date-time' },
79
+ { 'in' => 'formData', 'name' => 'param_time', 'required' => true, 'type' => 'string', 'format' => 'date-time' },
80
+ { 'in' => 'formData', 'name' => 'param_boolean', 'required' => false, 'type' => 'boolean' },
81
+ { 'in' => 'formData', 'name' => 'param_file', 'required' => false, 'type' => 'file' },
82
+ { 'in' => 'formData', 'name' => 'param_json', 'required' => false, 'type' => 'json' }
83
+ ]
84
+ )
85
+ end
86
+
87
+ specify do
88
+ expect(subject['definitions']['TypedDefinition']['properties']).to eql(swagger_typed_defintion)
89
+ end
90
+ end
@@ -0,0 +1,38 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'spec_helper'
4
+
5
+ describe 'Boolean Params' do
6
+ def app
7
+ Class.new(Grape::API) do
8
+ format :json
9
+
10
+ desc 'splines' do
11
+ consumes ['application/x-www-form-urlencoded']
12
+ end
13
+ params do
14
+ requires :a_boolean, type: Grape::API::Boolean
15
+ optional :another_boolean, type: Grape::API::Boolean, default: false
16
+ end
17
+ post :splines do
18
+ { message: 'hi' }
19
+ end
20
+
21
+ add_swagger_documentation
22
+ end
23
+ end
24
+
25
+ subject do
26
+ get '/swagger_doc/splines'
27
+ expect(last_response.status).to eq 200
28
+ body = JSON.parse last_response.body
29
+ body['paths']['/splines']['post']['parameters']
30
+ end
31
+
32
+ it 'converts boolean types' do
33
+ expect(subject).to eq [
34
+ { 'in' => 'formData', 'name' => 'a_boolean', 'type' => 'boolean', 'required' => true },
35
+ { 'in' => 'formData', 'name' => 'another_boolean', 'type' => 'boolean', 'required' => false, 'default' => false }
36
+ ]
37
+ end
38
+ end
@@ -0,0 +1,175 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'spec_helper'
4
+ # require 'grape_version'
5
+
6
+ describe 'Default API' do
7
+ context 'with no additional options' do
8
+ def app
9
+ Class.new(Grape::API) do
10
+ format :json
11
+ desc 'This gets something.'
12
+ get '/something' do
13
+ { bla: 'something' }
14
+ end
15
+ add_swagger_documentation
16
+ end
17
+ end
18
+
19
+ subject do
20
+ get '/swagger_doc'
21
+ JSON.parse(last_response.body)
22
+ end
23
+
24
+ it 'documents api' do
25
+ expect(subject).to eq(
26
+ 'info' => { 'title' => 'API title', 'version' => '0.0.1' },
27
+ 'swagger' => '2.0',
28
+ 'produces' => ['application/json'],
29
+ 'host' => 'example.org',
30
+ 'tags' => [{ 'name' => 'something', 'description' => 'Operations about somethings' }],
31
+ 'paths' => {
32
+ '/something' => {
33
+ 'get' => {
34
+ 'description' => 'This gets something.',
35
+ 'produces' => ['application/json'],
36
+ 'tags' => ['something'],
37
+ 'operationId' => 'getSomething',
38
+ 'responses' => { '200' => { 'description' => 'This gets something.' } }
39
+ }
40
+ }
41
+ }
42
+ )
43
+ end
44
+
45
+ context 'path inside the apis array' do
46
+ it 'starts with a forward slash' do
47
+ subject['paths'].each do |path|
48
+ expect(path.first).to start_with '/'
49
+ end
50
+ end
51
+ end
52
+ end
53
+
54
+ context 'with additional option block given to desc', if: GrapeVersion.satisfy?('>= 0.12.0') do
55
+ def app
56
+ Class.new(Grape::API) do
57
+ format :json
58
+ desc 'This gets something.'
59
+ get '/something' do
60
+ { bla: 'something' }
61
+ end
62
+ add_swagger_documentation
63
+ end
64
+ end
65
+
66
+ subject do
67
+ get '/swagger_doc/something'
68
+ JSON.parse(last_response.body)
69
+ end
70
+
71
+ it 'documents endpoint' do
72
+ expect(subject).to eq('info' => { 'title' => 'API title', 'version' => '0.0.1' },
73
+ 'swagger' => '2.0',
74
+ 'produces' => ['application/json'],
75
+ 'host' => 'example.org',
76
+ 'tags' => [{ 'name' => 'something', 'description' => 'Operations about somethings' }],
77
+ 'paths' => {
78
+ '/something' => {
79
+ 'get' => {
80
+ 'description' => 'This gets something.',
81
+ 'produces' => ['application/json'],
82
+ 'tags' => ['something'],
83
+ 'operationId' => 'getSomething',
84
+ 'responses' => { '200' => { 'description' => 'This gets something.' } }
85
+ }
86
+ }
87
+ })
88
+ end
89
+ end
90
+
91
+ context 'with additional info' do
92
+ def app
93
+ Class.new(Grape::API) do
94
+ format :json
95
+ add_swagger_documentation info: {
96
+ title: 'My API Title',
97
+ description: 'A description of my API',
98
+ license: 'Apache 2',
99
+ license_url: 'http://test.com',
100
+ terms_of_service_url: 'http://terms.com',
101
+ contact_email: 'support@test.com',
102
+ x: {
103
+ logo: 'http://logo.com/img.png'
104
+ }
105
+ }
106
+ end
107
+ end
108
+
109
+ subject do
110
+ get '/swagger_doc'
111
+ JSON.parse(last_response.body)['info']
112
+ end
113
+
114
+ it 'documents API title' do
115
+ expect(subject['title']).to eql('My API Title')
116
+ end
117
+
118
+ it 'documents API description' do
119
+ expect(subject['description']).to eql('A description of my API')
120
+ end
121
+
122
+ it 'should document the license' do
123
+ expect(subject['license']['name']).to eql('Apache 2')
124
+ end
125
+
126
+ it 'documents the license url' do
127
+ expect(subject['license']['url']).to eql('http://test.com')
128
+ end
129
+
130
+ it 'documents the terms of service url' do
131
+ expect(subject['termsOfService']).to eql('http://terms.com')
132
+ end
133
+
134
+ it 'documents the contact email' do
135
+ expect(subject['contact']['email']).to eql('support@test.com')
136
+ end
137
+
138
+ it 'documents the extension field' do
139
+ expect(subject['x-logo']).to eql('http://logo.com/img.png')
140
+ end
141
+ end
142
+
143
+ context 'with tags' do
144
+ def app
145
+ Class.new(Grape::API) do
146
+ format :json
147
+ desc 'This gets something.'
148
+ get '/something' do
149
+ { bla: 'something' }
150
+ end
151
+ get '/somethingelse' do
152
+ { bla: 'somethingelse' }
153
+ end
154
+
155
+ add_swagger_documentation tags: [
156
+ { name: 'something', description: 'customized description' }
157
+ ]
158
+ end
159
+ end
160
+
161
+ subject do
162
+ get '/swagger_doc'
163
+ JSON.parse(last_response.body)
164
+ end
165
+
166
+ it 'documents the customized tag' do
167
+ expect(subject['tags']).to eql(
168
+ [
169
+ { 'name' => 'somethingelse', 'description' => 'Operations about somethingelses' },
170
+ { 'name' => 'something', 'description' => 'customized description' }
171
+ ]
172
+ )
173
+ end
174
+ end
175
+ end
@@ -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
@@ -0,0 +1,39 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'spec_helper'
4
+
5
+ describe 'has no description, if details or description are nil' do
6
+ include_context "#{MODEL_PARSER} swagger example"
7
+
8
+ before :all do
9
+ module TheApi
10
+ class GfmRcDetailApi < Grape::API
11
+ format :json
12
+
13
+ desc nil,
14
+ detail: nil,
15
+ entity: Entities::UseResponse,
16
+ failure: [{ code: 400, model: Entities::ApiError }]
17
+ get '/use_gfm_rc_detail' do
18
+ { 'declared_params' => declared(params) }
19
+ end
20
+
21
+ add_swagger_documentation
22
+ end
23
+ end
24
+ end
25
+
26
+ def app
27
+ TheApi::GfmRcDetailApi
28
+ end
29
+
30
+ subject do
31
+ get '/swagger_doc'
32
+ JSON.parse(last_response.body)
33
+ end
34
+
35
+ specify do
36
+ expect(subject['paths']['/use_gfm_rc_detail']['get']).not_to include('description')
37
+ expect(subject['paths']['/use_gfm_rc_detail']['get']['description']).to eql(nil)
38
+ end
39
+ end
@@ -0,0 +1,130 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'spec_helper'
4
+
5
+ describe 'Grape::Endpoint#path_and_definitions' do
6
+ context 'when mounting an API once' do
7
+ let(:item) do
8
+ Class.new(Grape::API) do
9
+ version 'v1', using: :path
10
+
11
+ resource :item do
12
+ get '/'
13
+ end
14
+ end
15
+ end
16
+
17
+ let(:api) do
18
+ item_api = item
19
+
20
+ Class.new(Grape::API) do
21
+ mount item_api
22
+ add_swagger_documentation add_version: true
23
+ end
24
+ end
25
+
26
+ let(:options) { { add_version: true } }
27
+ let(:target_routes) { api.combined_namespace_routes }
28
+
29
+ subject { api.endpoints[0].path_and_definition_objects(target_routes, options) }
30
+
31
+ it 'is returning a versioned path' do
32
+ expect(subject[0].keys[0]).to eq '/v1/item'
33
+ end
34
+
35
+ it 'tags the endpoint with the resource name' do
36
+ expect(subject.first['/v1/item'][:get][:tags]).to eq ['item']
37
+ end
38
+
39
+ context 'when custom tags are specified' do
40
+ let(:item) do
41
+ Class.new(Grape::API) do
42
+ version 'v1', using: :path
43
+
44
+ resource :item do
45
+ desc 'Item description', tags: ['special-item']
46
+ get '/'
47
+ end
48
+ end
49
+ end
50
+
51
+ it 'tags the endpoint with the custom tags' do
52
+ expect(subject.first['/v1/item'][:get][:tags]).to eq ['special-item']
53
+ end
54
+ end
55
+
56
+ context 'when parameter with a custom type is specified' do
57
+ let(:item) do
58
+ Class.new(Grape::API) do
59
+ Color = Struct.new(:value) do
60
+ def self.parse(value)
61
+ new(value: value)
62
+ end
63
+ end
64
+
65
+ class ColorEntity < Grape::Entity
66
+ expose :value
67
+ end
68
+
69
+ version 'v1', using: :path
70
+
71
+ resource :item do
72
+ params do
73
+ requires :root, type: Hash do
74
+ optional :color, type: Color, documentation: { type: ColorEntity }
75
+ end
76
+ end
77
+ post '/'
78
+ end
79
+ end
80
+ end
81
+
82
+ it 'creates a reference to the model instead of using the non-existent type' do
83
+ color = subject.dig(1, 'postV1Item', :properties, :root, :properties, :color)
84
+ expect(color).not_to eq(type: 'ColorEntity')
85
+ expect(color).to eq('$ref' => '#/definitions/ColorEntity')
86
+ end
87
+ end
88
+ end
89
+
90
+ context 'when mounting an API more than once', if: GrapeVersion.satisfy?('>= 1.2.0') do
91
+ let(:item) do
92
+ Class.new(Grape::API) do
93
+ resource :item do
94
+ desc 'Item description', tags: [configuration[:tag] || 'item']
95
+ get '/'
96
+ end
97
+ end
98
+ end
99
+
100
+ let(:api) do
101
+ item_api = item
102
+ Class.new(Grape::API) do
103
+ version 'v1', using: :path do
104
+ mount item_api
105
+ end
106
+
107
+ version 'v2', using: :path do
108
+ mount item_api, with: { tag: 'special-item' }
109
+ end
110
+
111
+ add_swagger_documentation add_version: true
112
+ end
113
+ end
114
+
115
+ let(:options) { { add_version: true } }
116
+ let(:target_routes) { api.combined_namespace_routes }
117
+
118
+ subject { api.endpoints[0].path_and_definition_objects(target_routes, options) }
119
+
120
+ it 'retrieves both apis respecting their configured tags' do
121
+ expect(subject.first['/v1/item'][:get][:tags]).to eq ['item']
122
+ expect(subject.first['/v2/item'][:get][:tags]).to eq ['special-item']
123
+ end
124
+
125
+ it 'retrieves both apis with descriptions' do
126
+ expect(subject.first['/v1/item'][:get][:description]).to eq 'Item description'
127
+ expect(subject.first['/v2/item'][:get][:description]).to eq 'Item description'
128
+ end
129
+ end
130
+ end
@@ -0,0 +1,77 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'spec_helper'
4
+
5
+ describe 'Errors' do
6
+ describe 'Empty model error' do
7
+ let!(:app) do
8
+ Class.new(Grape::API) do
9
+ format :json
10
+
11
+ desc 'Empty model get.' do
12
+ http_codes [
13
+ { code: 200, message: 'get Empty model', model: EmptyClass }
14
+ ]
15
+ end
16
+ get '/empty_model' do
17
+ something = OpenStruct.new text: 'something'
18
+ present something, with: EmptyClass
19
+ end
20
+
21
+ version 'v3', using: :path
22
+ add_swagger_documentation api_version: 'v1',
23
+ base_path: '/api',
24
+ info: {
25
+ title: 'The API title to be displayed on the API homepage.',
26
+ description: 'A description of the API.',
27
+ contact_name: 'Contact name',
28
+ contact_email: 'Contact@email.com',
29
+ contact_url: 'Contact URL',
30
+ license: 'The name of the license.',
31
+ license_url: 'www.The-URL-of-the-license.org',
32
+ terms_of_service_url: 'www.The-URL-of-the-terms-and-service.com'
33
+ }
34
+ end
35
+ end
36
+
37
+ it 'should raise SwaggerSpec exception' do
38
+ expect { get '/v3/swagger_doc' }.to raise_error(GrapeSwagger::Errors::SwaggerSpec, "Empty model EmptyClass, swagger 2.0 doesn't support empty definitions.")
39
+ end
40
+ end
41
+
42
+ describe 'Parser not found error' do
43
+ let!(:app) do
44
+ Class.new(Grape::API) do
45
+ format :json
46
+
47
+ desc 'Wrong model get.' do
48
+ http_codes [
49
+ { code: 200, message: 'get Wrong model', model: Hash }
50
+ ]
51
+ end
52
+ get '/wrong_model' do
53
+ something = OpenStruct.new text: 'something'
54
+ present something, with: Hash
55
+ end
56
+
57
+ version 'v3', using: :path
58
+ add_swagger_documentation api_version: 'v1',
59
+ base_path: '/api',
60
+ info: {
61
+ title: 'The API title to be displayed on the API homepage.',
62
+ description: 'A description of the API.',
63
+ contact_name: 'Contact name',
64
+ contact_email: 'Contact@email.com',
65
+ contact_url: 'Contact URL',
66
+ license: 'The name of the license.',
67
+ license_url: 'www.The-URL-of-the-license.org',
68
+ terms_of_service_url: 'www.The-URL-of-the-terms-and-service.com'
69
+ }
70
+ end
71
+ end
72
+
73
+ it 'should raise UnregisteredParser exception' do
74
+ expect { get '/v3/swagger_doc' }.to raise_error(GrapeSwagger::Errors::UnregisteredParser, 'No parser registered for Hash.')
75
+ end
76
+ end
77
+ end