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,334 @@
1
+ # frozen_string_literal: true
2
+
3
+ RSpec.shared_context 'entity swagger example' do
4
+ before :all do
5
+ module Entities
6
+ class Something < Grape::Entity
7
+ expose :id, documentation: { type: Integer, desc: 'Identity of Something' }
8
+ expose :text, documentation: { type: String, desc: 'Content of something.' }
9
+ expose :links, documentation: { type: 'link', is_array: true }
10
+ expose :others, documentation: { type: 'text', is_array: false }
11
+ end
12
+
13
+ class EnumValues < Grape::Entity
14
+ expose :gender, documentation: { type: 'string', desc: 'Content of something.', values: %w[Male Female] }
15
+ expose :number, documentation: { type: 'integer', desc: 'Content of something.', values: [1, 2] }
16
+ end
17
+
18
+ class AliasedThing < Grape::Entity
19
+ expose :something, as: :post, using: Entities::Something, documentation: { type: 'Something', desc: 'Reference to something.' }
20
+ end
21
+
22
+ class FourthLevel < Grape::Entity
23
+ expose :text, documentation: { type: 'string' }
24
+ end
25
+
26
+ class ThirdLevel < Grape::Entity
27
+ expose :parts, using: Entities::FourthLevel, documentation: { type: 'FourthLevel' }
28
+ end
29
+
30
+ class SecondLevel < Grape::Entity
31
+ expose :parts, using: Entities::ThirdLevel, documentation: { type: 'ThirdLevel' }
32
+ end
33
+
34
+ class FirstLevel < Grape::Entity
35
+ expose :parts, using: Entities::SecondLevel, documentation: { type: 'SecondLevel' }
36
+ end
37
+
38
+ class QueryInputElement < Grape::Entity
39
+ expose :key, documentation: {
40
+ type: String, desc: 'Name of parameter', required: true
41
+ }
42
+ expose :value, documentation: {
43
+ type: String, desc: 'Value of parameter', required: true
44
+ }
45
+ end
46
+
47
+ class QueryInput < Grape::Entity
48
+ expose :elements, using: Entities::QueryInputElement, documentation: {
49
+ type: 'QueryInputElement',
50
+ desc: 'Set of configuration',
51
+ param_type: 'body',
52
+ is_array: true,
53
+ required: true
54
+ }
55
+ end
56
+
57
+ class ApiError < Grape::Entity
58
+ expose :code, documentation: { type: Integer, desc: 'status code' }
59
+ expose :message, documentation: { type: String, desc: 'error message' }
60
+ end
61
+
62
+ module NestedModule
63
+ class ApiResponse < Grape::Entity
64
+ expose :status, documentation: { type: String }
65
+ expose :error, documentation: { type: ::Entities::ApiError }
66
+ end
67
+ end
68
+
69
+ class SecondApiError < Grape::Entity
70
+ expose :code, documentation: { type: Integer }
71
+ expose :severity, documentation: { type: String }
72
+ expose :message, documentation: { type: String }
73
+ end
74
+
75
+ class ResponseItem < Grape::Entity
76
+ expose :id, documentation: { type: Integer }
77
+ expose :name, documentation: { type: String }
78
+ end
79
+
80
+ class OtherItem < Grape::Entity
81
+ expose :key, documentation: { type: Integer }
82
+ expose :symbol, documentation: { type: String }
83
+ end
84
+
85
+ class UseResponse < Grape::Entity
86
+ expose :description, documentation: { type: String }
87
+ expose :items, as: '$responses', using: Entities::ResponseItem, documentation: { is_array: true }
88
+ end
89
+
90
+ class UseItemResponseAsType < Grape::Entity
91
+ expose :description, documentation: { type: String }
92
+ expose :responses, documentation: { type: Entities::ResponseItem, is_array: false }
93
+ end
94
+
95
+ class UseAddress < Grape::Entity
96
+ expose :street, documentation: { type: String, desc: 'street' }
97
+ expose :postcode, documentation: { type: String, desc: 'postcode' }
98
+ expose :city, documentation: { type: String, desc: 'city' }
99
+ expose :country, documentation: { type: String, desc: 'country' }
100
+ end
101
+
102
+ class UseNestedWithAddress < Grape::Entity
103
+ expose :name, documentation: { type: String }
104
+ expose :address, using: Entities::UseAddress
105
+ end
106
+
107
+ class TypedDefinition < Grape::Entity
108
+ expose :prop_integer, documentation: { type: Integer, desc: 'prop_integer description' }
109
+ expose :prop_long, documentation: { type: Numeric, desc: 'prop_long description' }
110
+ expose :prop_float, documentation: { type: Float, desc: 'prop_float description' }
111
+ expose :prop_double, documentation: { type: BigDecimal, desc: 'prop_double description' }
112
+ expose :prop_string, documentation: { type: String, desc: 'prop_string description' }
113
+ expose :prop_symbol, documentation: { type: Symbol, desc: 'prop_symbol description' }
114
+ expose :prop_date, documentation: { type: Date, desc: 'prop_date description' }
115
+ expose :prop_date_time, documentation: { type: DateTime, desc: 'prop_date_time description' }
116
+ expose :prop_time, documentation: { type: Time, desc: 'prop_time description' }
117
+ expose :prop_password, documentation: { type: 'password', desc: 'prop_password description' }
118
+ expose :prop_email, documentation: { type: 'email', desc: 'prop_email description' }
119
+ expose :prop_boolean, documentation: { type: Grape::API::Boolean, desc: 'prop_boolean description' }
120
+ expose :prop_file, documentation: { type: File, desc: 'prop_file description' }
121
+ expose :prop_json, documentation: { type: JSON, desc: 'prop_json description' }
122
+ end
123
+
124
+ class RecursiveModel < Grape::Entity
125
+ expose :name, documentation: { type: String, desc: 'The name.' }
126
+ expose :children, using: self, documentation: { type: 'RecursiveModel', is_array: true, desc: 'The child nodes.' }
127
+ end
128
+
129
+ class DocumentedHashAndArrayModel < Grape::Entity
130
+ expose :raw_hash, documentation: { type: Hash, desc: 'Example Hash.', documentation: { in: 'body' } }
131
+ expose :raw_array, documentation: { type: Array, desc: 'Example Array', documentation: { in: 'body' } }
132
+ end
133
+ end
134
+ end
135
+
136
+ let(:swagger_definitions_models) do
137
+ {
138
+ 'ApiError' => { 'type' => 'object', 'properties' => { 'code' => { 'type' => 'integer', 'format' => 'int32', 'description' => 'status code' }, 'message' => { 'type' => 'string', 'description' => 'error message' } } },
139
+ 'ResponseItem' => { 'type' => 'object', 'properties' => { 'id' => { 'type' => 'integer', 'format' => 'int32' }, 'name' => { 'type' => 'string' } } },
140
+ 'UseResponse' => { 'type' => 'object', 'properties' => { 'description' => { 'type' => 'string' }, '$responses' => { 'type' => 'array', 'items' => { '$ref' => '#/definitions/ResponseItem' } } } },
141
+ 'RecursiveModel' => { 'type' => 'object', 'properties' => { 'name' => { 'type' => 'string', 'description' => 'The name.' }, 'children' => { 'type' => 'array', 'items' => { '$ref' => '#/definitions/RecursiveModel' }, 'description' => 'The child nodes.' } } },
142
+ 'DocumentedHashAndArrayModel' => { 'type' => 'object', 'properties' => { 'raw_hash' => { 'type' => 'object', 'description' => 'Example Hash.' }, 'raw_array' => { 'type' => 'array', 'description' => 'Example Array' } } }
143
+ }
144
+ end
145
+
146
+ let(:swagger_nested_type) do
147
+ {
148
+ 'ApiError' => { 'type' => 'object', 'properties' => { 'code' => { 'type' => 'integer', 'format' => 'int32', 'description' => 'status code' }, 'message' => { 'type' => 'string', 'description' => 'error message' } }, 'description' => 'ApiError model' },
149
+ 'ResponseItem' => { 'type' => 'object', 'properties' => { 'id' => { 'type' => 'integer', 'format' => 'int32' }, 'name' => { 'type' => 'string' } } },
150
+ 'UseItemResponseAsType' => { 'type' => 'object', 'properties' => { 'description' => { 'type' => 'string' }, 'responses' => { '$ref' => '#/definitions/ResponseItem' } }, 'description' => 'UseItemResponseAsType model' }
151
+ }
152
+ end
153
+
154
+ let(:swagger_entity_as_response_object) do
155
+ {
156
+ 'ApiError' => { 'type' => 'object', 'properties' => { 'code' => { 'type' => 'integer', 'format' => 'int32', 'description' => 'status code' }, 'message' => { 'type' => 'string', 'description' => 'error message' } }, 'description' => 'ApiError model' },
157
+ 'ResponseItem' => { 'type' => 'object', 'properties' => { 'id' => { 'type' => 'integer', 'format' => 'int32' }, 'name' => { 'type' => 'string' } } },
158
+ 'UseResponse' => { 'type' => 'object', 'properties' => { 'description' => { 'type' => 'string' }, '$responses' => { 'type' => 'array', 'items' => { '$ref' => '#/definitions/ResponseItem' } } }, 'description' => 'UseResponse model' }
159
+ }
160
+ end
161
+
162
+ let(:swagger_params_as_response_object) do
163
+ {
164
+ 'ApiError' => { 'type' => 'object', 'properties' => { 'code' => { 'description' => 'status code', 'type' => 'integer', 'format' => 'int32' }, 'message' => { 'description' => 'error message', 'type' => 'string' } }, 'description' => 'ApiError model' }
165
+ }
166
+ end
167
+
168
+ let(:swagger_typed_defintion) do
169
+ {
170
+ 'prop_boolean' => { 'description' => 'prop_boolean description', 'type' => 'boolean' },
171
+ 'prop_date' => { 'description' => 'prop_date description', 'type' => 'string', 'format' => 'date' },
172
+ 'prop_date_time' => { 'description' => 'prop_date_time description', 'type' => 'string', 'format' => 'date-time' },
173
+ 'prop_double' => { 'description' => 'prop_double description', 'type' => 'number', 'format' => 'double' },
174
+ 'prop_email' => { 'description' => 'prop_email description', 'type' => 'string', 'format' => 'email' },
175
+ 'prop_file' => { 'description' => 'prop_file description', 'type' => 'file' },
176
+ 'prop_float' => { 'description' => 'prop_float description', 'type' => 'number', 'format' => 'float' },
177
+ 'prop_integer' => { 'description' => 'prop_integer description', 'type' => 'integer', 'format' => 'int32' },
178
+ 'prop_json' => { 'description' => 'prop_json description', 'type' => 'json' },
179
+ 'prop_long' => { 'description' => 'prop_long description', 'type' => 'integer', 'format' => 'int64' },
180
+ 'prop_password' => { 'description' => 'prop_password description', 'type' => 'string', 'format' => 'password' },
181
+ 'prop_string' => { 'description' => 'prop_string description', 'type' => 'string' },
182
+ 'prop_symbol' => { 'description' => 'prop_symbol description', 'type' => 'string' },
183
+ 'prop_time' => { 'description' => 'prop_time description', 'type' => 'string', 'format' => 'date-time' }
184
+ }
185
+ end
186
+
187
+ let(:swagger_json) do
188
+ {
189
+ 'info' => {
190
+ 'title' => 'The API title to be displayed on the API homepage.',
191
+ 'description' => 'A description of the API.',
192
+ 'termsOfService' => 'www.The-URL-of-the-terms-and-service.com',
193
+ 'contact' => { 'name' => 'Contact name', 'email' => 'Contact@email.com', 'url' => 'Contact URL' },
194
+ 'license' => { 'name' => 'The name of the license.', 'url' => 'www.The-URL-of-the-license.org' },
195
+ 'version' => '0.0.1'
196
+ },
197
+ 'swagger' => '2.0',
198
+ 'produces' => ['application/json'],
199
+ 'host' => 'example.org',
200
+ 'basePath' => '/api',
201
+ 'tags' => [
202
+ { 'name' => 'other_thing', 'description' => 'Operations about other_things' },
203
+ { 'name' => 'thing', 'description' => 'Operations about things' },
204
+ { 'name' => 'thing2', 'description' => 'Operations about thing2s' },
205
+ { 'name' => 'dummy', 'description' => 'Operations about dummies' }
206
+ ],
207
+ 'paths' => {
208
+ '/v3/other_thing/{elements}' => {
209
+ 'get' => {
210
+ 'description' => 'nested route inside namespace',
211
+ 'produces' => ['application/json'],
212
+ 'parameters' => [{ 'in' => 'body', 'name' => 'elements', 'description' => 'Set of configuration', 'type' => 'array', 'items' => { 'type' => 'string' }, 'required' => true }],
213
+ 'responses' => { '200' => { 'description' => 'nested route inside namespace', 'schema' => { '$ref' => '#/definitions/QueryInput' } } },
214
+ 'tags' => ['other_thing'],
215
+ 'operationId' => 'getV3OtherThingElements',
216
+ 'x-amazon-apigateway-auth' => { 'type' => 'none' },
217
+ 'x-amazon-apigateway-integration' => { 'type' => 'aws', 'uri' => 'foo_bar_uri', 'httpMethod' => 'get' }
218
+ }
219
+ },
220
+ '/thing' => {
221
+ 'get' => {
222
+ 'description' => 'This gets Things.',
223
+ 'produces' => ['application/json'],
224
+ 'parameters' => [
225
+ { 'in' => 'query', 'name' => 'id', 'description' => 'Identity of Something', 'type' => 'integer', 'format' => 'int32', 'required' => false },
226
+ { 'in' => 'query', 'name' => 'text', 'description' => 'Content of something.', 'type' => 'string', 'required' => false },
227
+ { 'in' => 'formData', 'name' => 'links', 'type' => 'array', 'items' => { 'type' => 'link' }, 'required' => false },
228
+ { 'in' => 'query', 'name' => 'others', 'type' => 'text', 'required' => false }
229
+ ],
230
+ 'responses' => { '200' => { 'description' => 'This gets Things.' }, '401' => { 'description' => 'Unauthorized', 'schema' => { '$ref' => '#/definitions/ApiError' } } },
231
+ 'tags' => ['thing'],
232
+ 'operationId' => 'getThing'
233
+ },
234
+ 'post' => {
235
+ 'description' => 'This creates Thing.',
236
+ 'produces' => ['application/json'],
237
+ 'consumes' => ['application/x-www-form-urlencoded'],
238
+ 'parameters' => [
239
+ { 'in' => 'formData', 'name' => 'text', 'description' => 'Content of something.', 'type' => 'string', 'required' => true },
240
+ { 'in' => 'formData', 'name' => 'links', 'type' => 'array', 'items' => { 'type' => 'string' }, 'required' => true }
241
+ ],
242
+ 'responses' => { '201' => { 'description' => 'This creates Thing.', 'schema' => { '$ref' => '#/definitions/Something' } }, '422' => { 'description' => 'Unprocessible Entity' } },
243
+ 'tags' => ['thing'],
244
+ 'operationId' => 'postThing'
245
+ }
246
+ },
247
+ '/thing/{id}' => {
248
+ 'get' => {
249
+ 'description' => 'This gets Thing.',
250
+ 'produces' => ['application/json'],
251
+ 'parameters' => [{ 'in' => 'path', 'name' => 'id', 'type' => 'integer', 'format' => 'int32', 'required' => true }],
252
+ 'responses' => { '200' => { 'description' => 'getting a single thing' }, '401' => { 'description' => 'Unauthorized' } },
253
+ 'tags' => ['thing'],
254
+ 'operationId' => 'getThingId'
255
+ },
256
+ 'put' => {
257
+ 'description' => 'This updates Thing.',
258
+ 'produces' => ['application/json'],
259
+ 'consumes' => ['application/x-www-form-urlencoded'],
260
+ 'parameters' => [
261
+ { 'in' => 'path', 'name' => 'id', 'type' => 'integer', 'format' => 'int32', 'required' => true },
262
+ { 'in' => 'formData', 'name' => 'text', 'description' => 'Content of something.', 'type' => 'string', 'required' => false },
263
+ { 'in' => 'formData', 'name' => 'links', 'type' => 'array', 'items' => { 'type' => 'string' }, 'required' => false }
264
+ ],
265
+ 'responses' => { '200' => { 'description' => 'This updates Thing.', 'schema' => { '$ref' => '#/definitions/Something' } } },
266
+ 'tags' => ['thing'],
267
+ 'operationId' => 'putThingId'
268
+ },
269
+ 'delete' => {
270
+ 'description' => 'This deletes Thing.',
271
+ 'produces' => ['application/json'],
272
+ 'parameters' => [{ 'in' => 'path', 'name' => 'id', 'type' => 'integer', 'format' => 'int32', 'required' => true }],
273
+ 'responses' => { '200' => { 'description' => 'This deletes Thing.', 'schema' => { '$ref' => '#/definitions/Something' } } },
274
+ 'tags' => ['thing'],
275
+ 'operationId' => 'deleteThingId'
276
+ }
277
+ },
278
+ '/thing2' => {
279
+ 'get' => {
280
+ 'description' => 'This gets Things.',
281
+ 'produces' => ['application/json'],
282
+ 'responses' => { '200' => { 'description' => 'get Horses', 'schema' => { '$ref' => '#/definitions/Something' } }, '401' => { 'description' => 'HorsesOutError', 'schema' => { '$ref' => '#/definitions/ApiError' } } },
283
+ 'tags' => ['thing2'],
284
+ 'operationId' => 'getThing2'
285
+ }
286
+ },
287
+ '/dummy/{id}' => {
288
+ 'delete' => {
289
+ 'description' => 'dummy route.',
290
+ 'produces' => ['application/json'],
291
+ 'parameters' => [{ 'in' => 'path', 'name' => 'id', 'type' => 'integer', 'format' => 'int32', 'required' => true }],
292
+ 'responses' => { '204' => { 'description' => 'dummy route.' }, '401' => { 'description' => 'Unauthorized' } },
293
+ 'tags' => ['dummy'],
294
+ 'operationId' => 'deleteDummyId'
295
+ }
296
+ }
297
+ },
298
+ 'definitions' => {
299
+ 'QueryInput' => {
300
+ 'type' => 'object',
301
+ 'required' => ['elements'],
302
+ 'properties' => { 'elements' => { 'type' => 'array', 'items' => { '$ref' => '#/definitions/QueryInputElement' }, 'description' => 'Set of configuration' } },
303
+ 'description' => 'QueryInput model'
304
+ },
305
+ 'QueryInputElement' => {
306
+ 'type' => 'object',
307
+ 'required' => %w[key value],
308
+ 'properties' => { 'key' => { 'type' => 'string', 'description' => 'Name of parameter' }, 'value' => { 'type' => 'string', 'description' => 'Value of parameter' } }
309
+ },
310
+ 'ApiError' => {
311
+ 'type' => 'object',
312
+ 'properties' => { 'code' => { 'type' => 'integer', 'format' => 'int32', 'description' => 'status code' }, 'message' => { 'type' => 'string', 'description' => 'error message' } },
313
+ 'description' => 'ApiError model'
314
+ },
315
+ 'Something' => {
316
+ 'type' => 'object',
317
+ 'properties' => {
318
+ 'id' => { 'type' => 'integer', 'format' => 'int32', 'description' => 'Identity of Something' },
319
+ 'text' => { 'type' => 'string', 'description' => 'Content of something.' },
320
+ 'links' => { 'type' => 'array', 'items' => { 'type' => 'link' } },
321
+ 'others' => { 'type' => 'text' }
322
+ },
323
+ 'description' => 'Something model'
324
+ }
325
+ }
326
+ }
327
+ end
328
+
329
+ let(:http_verbs) { %w[get post put delete] }
330
+ end
331
+
332
+ def mounted_paths
333
+ %w[/thing /other_thing /dummy]
334
+ end