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,100 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'spec_helper'
4
+
5
+ describe '#677 consumes and produces options are included in add_swagger_documentation options' do
6
+ describe 'no override' do
7
+ let(:app) do
8
+ Class.new(Grape::API) do
9
+ resource :accounts do
10
+ route_param :account_number, type: String do
11
+ resource :records do
12
+ route_param :id do
13
+ post do
14
+ { message: 'hello world' }
15
+ end
16
+ end
17
+ end
18
+ end
19
+ end
20
+
21
+ add_swagger_documentation \
22
+ format: :json
23
+ end
24
+ end
25
+
26
+ subject do
27
+ get '/swagger_doc'
28
+ JSON.parse(last_response.body)
29
+ end
30
+
31
+ specify do
32
+ expect(subject['paths']['/accounts/{account_number}/records/{id}']['post']['produces']).to eq ['application/json']
33
+ expect(subject['paths']['/accounts/{account_number}/records/{id}']['post']['consumes']).to eq ['application/json']
34
+ end
35
+ end
36
+
37
+ describe 'override produces' do
38
+ let(:app) do
39
+ Class.new(Grape::API) do
40
+ resource :accounts do
41
+ route_param :account_number, type: String do
42
+ resource :records do
43
+ route_param :id do
44
+ post do
45
+ { message: 'hello world' }
46
+ end
47
+ end
48
+ end
49
+ end
50
+ end
51
+
52
+ add_swagger_documentation \
53
+ format: :json,
54
+ produces: ['text/plain']
55
+ end
56
+ end
57
+
58
+ subject do
59
+ get '/swagger_doc'
60
+ JSON.parse(last_response.body)
61
+ end
62
+
63
+ specify do
64
+ expect(subject['paths']['/accounts/{account_number}/records/{id}']['post']['produces']).to eq ['text/plain']
65
+ expect(subject['paths']['/accounts/{account_number}/records/{id}']['post']['consumes']).to eq ['application/json']
66
+ end
67
+ end
68
+
69
+ describe 'override consumes' do
70
+ let(:app) do
71
+ Class.new(Grape::API) do
72
+ resource :accounts do
73
+ route_param :account_number, type: String do
74
+ resource :records do
75
+ route_param :id do
76
+ post do
77
+ { message: 'hello world' }
78
+ end
79
+ end
80
+ end
81
+ end
82
+ end
83
+
84
+ add_swagger_documentation \
85
+ format: :json, \
86
+ consumes: ['application/json', 'application/x-www-form-urlencoded']
87
+ end
88
+ end
89
+
90
+ subject do
91
+ get '/swagger_doc'
92
+ JSON.parse(last_response.body)
93
+ end
94
+
95
+ specify do
96
+ expect(subject['paths']['/accounts/{account_number}/records/{id}']['post']['produces']).to eq ['application/json']
97
+ expect(subject['paths']['/accounts/{account_number}/records/{id}']['post']['consumes']).to eq ['application/json', 'application/x-www-form-urlencoded']
98
+ end
99
+ end
100
+ end
@@ -0,0 +1,55 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'spec_helper'
4
+
5
+ describe 'when the main endpoint response is a 204 all error schemas are lost' do
6
+ let(:app) do
7
+ Class.new(Grape::API) do
8
+ namespace :issue_680 do
9
+ desc 'delete something',
10
+ is_array: true,
11
+ success: { status: 204 },
12
+ failure: [
13
+ [401, 'Unauthorized', Entities::ApiError],
14
+ [403, 'Forbidden', Entities::ApiError],
15
+ [404, 'Not Found', Entities::ApiError]
16
+ ]
17
+
18
+ delete do
19
+ status 204
20
+ end
21
+ end
22
+
23
+ add_swagger_documentation format: :json
24
+ end
25
+ end
26
+
27
+ subject do
28
+ get '/swagger_doc'
29
+ JSON.parse(last_response.body)
30
+ end
31
+
32
+ context 'when an endpoint can return a 204' do
33
+ let(:responses) { subject['paths']['/issue_680']['delete']['responses'] }
34
+
35
+ it 'returns the description but not a schema for a 204 response' do
36
+ expect(responses['204']['description']).to eq('delete something')
37
+ expect(responses['204']['schema']).to be_nil
38
+ end
39
+
40
+ it 'returns a description AND a schema for a 401 response' do
41
+ expect(responses['401']['description']).to eq('Unauthorized')
42
+ expect(responses['401']['schema']).to_not be_nil
43
+ end
44
+
45
+ it 'returns a description AND a schema for a 403 response' do
46
+ expect(responses['403']['description']).to eq('Forbidden')
47
+ expect(responses['403']['schema']).to_not be_nil
48
+ end
49
+
50
+ it 'returns a description AND a schema for a 404 response' do
51
+ expect(responses['404']['description']).to eq('Not Found')
52
+ expect(responses['404']['schema']).to_not be_nil
53
+ end
54
+ end
55
+ end
@@ -0,0 +1,62 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'spec_helper'
4
+
5
+ describe '#721 set default parameter location based on consumes' do
6
+ let(:app) do
7
+ Class.new(Grape::API) do
8
+ namespace :issue_721 do
9
+ desc 'create item' do
10
+ consumes ['application/json']
11
+ end
12
+
13
+ params do
14
+ requires :logs, type: String
15
+ optional :phone_number, type: Integer
16
+ end
17
+
18
+ post do
19
+ present params
20
+ end
21
+
22
+ desc 'modify item' do
23
+ consumes ['application/x-www-form-urlencoded']
24
+ end
25
+
26
+ params do
27
+ requires :id, type: Integer
28
+ requires :logs, type: String
29
+ optional :phone_number, type: Integer
30
+ end
31
+
32
+ put ':id' do
33
+ present params
34
+ end
35
+ end
36
+
37
+ add_swagger_documentation
38
+ end
39
+ end
40
+
41
+ subject do
42
+ get '/swagger_doc'
43
+ JSON.parse(last_response.body)
44
+ end
45
+
46
+ let(:post_parameters) { subject['paths']['/issue_721']['post']['parameters'] }
47
+ let(:post_schema) { subject['definitions']['postIssue721'] }
48
+ let(:put_parameters) { subject['paths']['/issue_721/{id}']['put']['parameters'] }
49
+
50
+ specify do
51
+ expect(post_parameters).to eql(
52
+ [{'in'=>'body', 'name'=>'postIssue721', 'required'=>true, 'schema'=>{'$ref'=>'#/definitions/postIssue721'}}]
53
+ )
54
+ expect(post_schema).to eql(
55
+ {'description'=>'create item', 'properties'=>{'logs'=>{'type'=>'string'}, 'phone_number'=>{'format'=>'int32', 'type'=>'integer'}}, 'required'=>['logs'], 'type'=>'object'}
56
+ )
57
+ puts put_parameters
58
+ expect(put_parameters).to eql(
59
+ [{'in'=>'path', 'name'=>'id', 'type'=>'integer', 'format'=>'int32', 'required'=>true}, {'in'=>'formData', 'name'=>'logs', 'type'=>'string', 'required'=>true}, {'in'=>'formData', 'name'=>'phone_number', 'type'=>'integer', 'format'=>'int32', 'required'=>false}]
60
+ )
61
+ end
62
+ end
@@ -0,0 +1,190 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'spec_helper'
4
+
5
+ describe '751 deeply nested objects' do
6
+ let(:app) do
7
+ Class.new(Grape::API) do
8
+ content_type :json, 'application/json; charset=UTF-8'
9
+ default_format :json
10
+ class Vrp < Grape::API
11
+ def self.vrp_request_timewindow(this)
12
+ this.optional(:start, types: [String, Float, Integer])
13
+ this.optional(:end, types: [String, Float, Integer])
14
+ end
15
+
16
+ def self.vrp_request_point(this)
17
+ this.requires(:id, type: String, allow_blank: false)
18
+ this.optional(:matrix_index, type: Integer)
19
+ this.optional(:location, type: Hash) do
20
+ requires(:lat, type: Float, allow_blank: false)
21
+ requires(:lon, type: Float, allow_blank: false)
22
+ end
23
+ this.at_least_one_of :matrix_index, :location
24
+ end
25
+
26
+ def self.vrp_request_activity(this)
27
+ this.optional(:duration, types: [String, Float, Integer])
28
+ this.requires(:point_id, type: String, allow_blank: false)
29
+ this.optional(:timewindows, type: Array) do
30
+ Vrp.vrp_request_timewindow(self)
31
+ end
32
+ end
33
+
34
+ def self.vrp_request_service(this)
35
+ this.requires(:id, type: String, allow_blank: false)
36
+ this.optional(:skills, type: Array[String])
37
+
38
+ this.optional(:activity, type: Hash) do
39
+ Vrp.vrp_request_activity(self)
40
+ end
41
+ this.optional(:activities, type: Array) do
42
+ Vrp.vrp_request_activity(self)
43
+ end
44
+ this.mutually_exclusive :activity, :activities
45
+ end
46
+ end
47
+
48
+ namespace :vrp do
49
+ resource :submit do
50
+ desc 'Submit Problems', nickname: 'vrp'
51
+ params do
52
+ optional(:vrp, type: Hash, documentation: { param_type: 'body' }) do
53
+ optional(:points, type: Array) do
54
+ Vrp.vrp_request_point(self)
55
+ end
56
+
57
+ optional(:services, type: Array) do
58
+ Vrp.vrp_request_service(self)
59
+ end
60
+ end
61
+ end
62
+ post do
63
+ { vrp: params[:vrp] }.to_json
64
+ end
65
+ end
66
+ end
67
+
68
+ add_swagger_documentation format: :json
69
+ end
70
+ end
71
+
72
+ subject do
73
+ get '/swagger_doc'
74
+ JSON.parse(last_response.body)
75
+ end
76
+
77
+ describe 'Correctness of vrp Points' do
78
+ let(:get_points_response) { subject['definitions']['vrp']['properties']['vrp']['properties']['points'] }
79
+ specify do
80
+ expect(get_points_response).to eql(
81
+ 'type' => 'array',
82
+ 'items' => {
83
+ 'type' => 'object',
84
+ 'properties' => {
85
+ 'id' => {
86
+ 'type' => 'string'
87
+ },
88
+ 'matrix_index' => {
89
+ 'type' => 'integer',
90
+ 'format' => 'int32'
91
+ },
92
+ 'location' => {
93
+ 'type' => 'object',
94
+ 'properties' => {
95
+ 'lat' => {
96
+ 'type' => 'number',
97
+ 'format' => 'float'
98
+ },
99
+ 'lon' => {
100
+ 'type' => 'number',
101
+ 'format' => 'float'
102
+ }
103
+ },
104
+ 'required' => %w[lat lon]
105
+ }
106
+ },
107
+ 'required' => ['id']
108
+ }
109
+ )
110
+ end
111
+ end
112
+
113
+ describe 'Correctness of vrp Services' do
114
+ let(:get_service_response) { subject['definitions']['vrp']['properties']['vrp']['properties']['services'] }
115
+ specify do
116
+ expect(get_service_response).to include(
117
+ 'type' => 'array',
118
+ 'items' => {
119
+ 'type' => 'object',
120
+ 'properties' => {
121
+ 'id' => {
122
+ 'type' => 'string'
123
+ },
124
+ 'skills' => {
125
+ 'type' => 'array',
126
+ 'items' => {
127
+ 'type' => 'string'
128
+ }
129
+ },
130
+ 'activity' => {
131
+ 'type' => 'object',
132
+ 'properties' => {
133
+ 'duration' => {
134
+ 'type' => 'string'
135
+ },
136
+ 'point_id' => {
137
+ 'type' => 'string'
138
+ },
139
+ 'timewindows' => {
140
+ 'type' => 'array',
141
+ 'items' => {
142
+ 'type' => 'object',
143
+ 'properties' => {
144
+ 'start' => {
145
+ 'type' => 'string'
146
+ },
147
+ 'end' => {
148
+ 'type' => 'string'
149
+ }
150
+ }
151
+ }
152
+ }
153
+ },
154
+ 'required' => ['point_id']
155
+ }, 'activities' => {
156
+ 'type' => 'array',
157
+ 'items' => {
158
+ 'type' => 'object',
159
+ 'properties' => {
160
+ 'duration' => {
161
+ 'type' => 'string'
162
+ },
163
+ 'point_id' => {
164
+ 'type' => 'string'
165
+ },
166
+ 'timewindows' => {
167
+ 'type' => 'array',
168
+ 'items' => {
169
+ 'type' => 'object',
170
+ 'properties' => {
171
+ 'start' => {
172
+ 'type' => 'string'
173
+ },
174
+ 'end' => {
175
+ 'type' => 'string'
176
+ }
177
+ }
178
+ }
179
+ }
180
+ },
181
+ 'required' => ['point_id']
182
+ }
183
+ }
184
+ },
185
+ 'required' => ['id']
186
+ }
187
+ )
188
+ end
189
+ end
190
+ end
@@ -0,0 +1,59 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'spec_helper'
4
+
5
+ describe '#776 multiple presents spec' do
6
+ include_context "#{MODEL_PARSER} swagger example"
7
+
8
+ let(:app) do
9
+ Class.new(Grape::API) do
10
+ namespace :issue_776 do
11
+ desc 'Get multiple presents',
12
+ success: [
13
+ { model: Entities::EnumValues, as: :gender },
14
+ { model: Entities::Something, as: :somethings, is_array: true, required: true }
15
+ ]
16
+
17
+ get do
18
+ present :gender, { number: 1, gender: 'Male' }, with: Entities::EnumValues
19
+ present :somethings, [
20
+ { id: 1, text: 'element_1', links: %w[link1 link2] },
21
+ { id: 2, text: 'element_2', links: %w[link1 link2] }
22
+ ], with: Entities::Something, is_array: true
23
+ end
24
+ end
25
+
26
+ add_swagger_documentation format: :json
27
+ end
28
+ end
29
+
30
+ subject do
31
+ get '/swagger_doc'
32
+ JSON.parse(last_response.body)
33
+ end
34
+
35
+ let(:definitions) { subject['definitions'] }
36
+ let(:schema) { subject['paths']['/issue_776']['get']['responses']['200']['schema'] }
37
+
38
+ specify { expect(definitions.keys).to include 'EnumValues', 'Something' }
39
+
40
+ specify do
41
+ expect(schema).to eql({
42
+ 'properties' => {
43
+ 'somethings' => {
44
+ 'items' => {
45
+ '$ref' => '#/definitions/Something'
46
+ },
47
+ 'type' => 'array'
48
+ },
49
+ 'gender' => {
50
+ '$ref' => '#/definitions/EnumValues'
51
+ }
52
+ },
53
+ 'type' => 'object',
54
+ 'required' => [
55
+ 'somethings'
56
+ ]
57
+ })
58
+ end
59
+ end
@@ -0,0 +1,42 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'spec_helper'
4
+
5
+ describe '#532 allow custom format' do
6
+ let(:app) do
7
+ Class.new(Grape::API) do
8
+ namespace :issue_784 do
9
+ desc 'issue_784' do
10
+ consumes ['application/x-www-form-urlencoded']
11
+ end
12
+
13
+ params do
14
+ requires :logs, type: String, documentation: { format: 'log', x: { name: 'Log' } }
15
+ optional :phone_number, type: Integer, documentation: { format: 'phone_number', x: { name: 'PhoneNumber' } }
16
+ end
17
+
18
+ post do
19
+ present params
20
+ end
21
+ end
22
+
23
+ add_swagger_documentation format: :json
24
+ end
25
+ end
26
+
27
+ subject do
28
+ get '/swagger_doc'
29
+ JSON.parse(last_response.body)
30
+ end
31
+
32
+ let(:parameters) { subject['paths']['/issue_784']['post']['parameters'] }
33
+
34
+ specify do
35
+ expect(parameters).to eql(
36
+ [
37
+ { 'in' => 'formData', 'name' => 'logs', 'type' => 'string', 'format' => 'log', 'required' => true, 'x-name' => 'Log' },
38
+ { 'in' => 'formData', 'name' => 'phone_number', 'type' => 'integer', 'format' => 'phone_number', 'required' => false, 'x-name' => 'PhoneNumber' }
39
+ ]
40
+ )
41
+ end
42
+ end
@@ -0,0 +1,55 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'spec_helper'
4
+
5
+ describe '#605 root route documentation' do
6
+ let(:app) do
7
+ Class.new(Grape::API) do
8
+ resource :grunnbeløp do
9
+ desc 'returnerer grunnbeløp'
10
+ get do
11
+ { message: 'hello world' }
12
+ end
13
+ end
14
+
15
+ resource :εσόδων do
16
+ desc 'εσόδων'
17
+ get do
18
+ { message: 'hello world' }
19
+ end
20
+ end
21
+
22
+ resource :数 do
23
+ desc '数'
24
+ get do
25
+ { message: 'hello world' }
26
+ end
27
+ end
28
+
29
+ resource :amount do
30
+ desc 'returns amount'
31
+ get do
32
+ { message: 'hello world' }
33
+ end
34
+ end
35
+
36
+ resource :👍 do
37
+ desc 'returns 👍'
38
+ get do
39
+ { message: 'hello world' }
40
+ end
41
+ end
42
+
43
+ add_swagger_documentation
44
+ end
45
+ end
46
+
47
+ subject do
48
+ get '/swagger_doc'
49
+ JSON.parse(last_response.body)['paths']
50
+ end
51
+
52
+ specify do
53
+ expect(subject.keys).to match_array ['/grunnbeløp', '/amount', '/εσόδων', '/数']
54
+ end
55
+ end
@@ -0,0 +1,114 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'spec_helper'
4
+
5
+ describe '#832 array of objects with nested Float/BigDecimal fields' do
6
+ let(:app) do
7
+ Class.new(Grape::API) do
8
+ resource :issue_832 do
9
+ desc 'issue_832' do
10
+ consumes ['application/x-www-form-urlencoded']
11
+ end
12
+ params do
13
+ requires :array_param, type: Array do
14
+ requires :float_param, type: Float
15
+ requires :big_decimal_param, type: BigDecimal
16
+ requires :object_param, type: Hash do
17
+ requires :float_param, type: Float
18
+ requires :big_decimal_param, type: BigDecimal
19
+ requires :object_param, type: Hash do
20
+ requires :float_param, type: Float
21
+ requires :big_decimal_param, type: BigDecimal
22
+ requires :array_param, type: Array do
23
+ requires :integer_param, type: Integer
24
+ end
25
+ end
26
+ end
27
+ end
28
+ end
29
+ post do
30
+ { message: 'hello world' }
31
+ end
32
+ end
33
+
34
+ add_swagger_documentation
35
+ end
36
+ end
37
+ let(:parameters) { subject['paths']['/issue_832']['post']['parameters'] }
38
+
39
+ subject do
40
+ get '/swagger_doc'
41
+ JSON.parse(last_response.body)
42
+ end
43
+
44
+ specify do
45
+ expect(parameters).to eql(
46
+ [
47
+ {
48
+ 'in' => 'formData',
49
+ 'name' => 'array_param[float_param]',
50
+ 'type' => 'array',
51
+ 'required' => true,
52
+ 'items' => {
53
+ 'type' => 'number',
54
+ 'format' => 'float'
55
+ }
56
+ }, {
57
+ 'in' => 'formData',
58
+ 'name' => 'array_param[big_decimal_param]',
59
+ 'type' => 'array',
60
+ 'required' => true,
61
+ 'items' => {
62
+ 'type' => 'number',
63
+ 'format' => 'double'
64
+ }
65
+ }, {
66
+ 'in' => 'formData',
67
+ 'name' => 'array_param[object_param][float_param]',
68
+ 'type' => 'array',
69
+ 'required' => true,
70
+ 'items' => {
71
+ 'type' => 'number',
72
+ 'format' => 'float'
73
+ }
74
+ }, {
75
+ 'in' => 'formData',
76
+ 'name' => 'array_param[object_param][big_decimal_param]',
77
+ 'type' => 'array',
78
+ 'required' => true,
79
+ 'items' => {
80
+ 'type' => 'number',
81
+ 'format' => 'double'
82
+ }
83
+ }, {
84
+ 'in' => 'formData',
85
+ 'name' => 'array_param[object_param][object_param][float_param]',
86
+ 'type' => 'array',
87
+ 'required' => true,
88
+ 'items' => {
89
+ 'type' => 'number',
90
+ 'format' => 'float'
91
+ }
92
+ }, {
93
+ 'in' => 'formData',
94
+ 'name' => 'array_param[object_param][object_param][big_decimal_param]',
95
+ 'type' => 'array',
96
+ 'required' => true,
97
+ 'items' => {
98
+ 'type' => 'number',
99
+ 'format' => 'double'
100
+ }
101
+ }, {
102
+ 'in' => 'formData',
103
+ 'name' => 'array_param[object_param][object_param][array_param][integer_param]',
104
+ 'type' => 'array',
105
+ 'required' => true,
106
+ 'items' => {
107
+ 'type' => 'integer',
108
+ 'format' => 'int32'
109
+ }
110
+ }
111
+ ]
112
+ )
113
+ end
114
+ end