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,37 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'spec_helper'
4
+
5
+ describe '#847 route_param type is included in documentation' do
6
+ let(:app) do
7
+ Class.new(Grape::API) do
8
+ resource :accounts do
9
+ route_param :account_number, type: String do
10
+ resource :records do
11
+ route_param :id do
12
+ get do
13
+ { message: 'hello world' }
14
+ end
15
+ end
16
+ end
17
+ end
18
+ end
19
+
20
+ add_swagger_documentation
21
+ end
22
+ end
23
+ let(:parameters) { subject['paths']['/accounts/{account_number}/records/{id}']['get']['parameters'] }
24
+
25
+ subject do
26
+ get '/swagger_doc'
27
+ JSON.parse(last_response.body)
28
+ end
29
+
30
+ specify do
31
+ account_number_param = parameters.find { |param| param['name'] == 'account_number' }
32
+ expect(account_number_param['type']).to eq 'string'
33
+ id_param = parameters.find { |param| param['name'] == 'id' }
34
+ # Default is still integer
35
+ expect(id_param['type']).to eq 'integer'
36
+ end
37
+ end
@@ -0,0 +1,28 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'spec_helper'
4
+
5
+ describe '#873 detect wildcard segments as path parameters' do
6
+ let(:app) do
7
+ Class.new(Grape::API) do
8
+ resource :books do
9
+ get '*section/:title' do
10
+ { message: 'hello world' }
11
+ end
12
+ end
13
+
14
+ add_swagger_documentation
15
+ end
16
+ end
17
+ let(:parameters) { subject['paths']['/books/{section}/{title}']['get']['parameters'] }
18
+
19
+ subject do
20
+ get '/swagger_doc'
21
+ JSON.parse(last_response.body)
22
+ end
23
+
24
+ specify do
25
+ section_param = parameters.find { |param| param['name'] == 'section' }
26
+ expect(section_param['in']).to eq 'path'
27
+ end
28
+ end
@@ -0,0 +1,29 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'spec_helper'
4
+
5
+ describe '#878 handle optional path segments' do
6
+ let(:app) do
7
+ Class.new(Grape::API) do
8
+ resource :books do
9
+ get 'page(/one)(/:two)/three' do
10
+ { message: 'hello world' }
11
+ end
12
+ end
13
+
14
+ add_swagger_documentation
15
+ end
16
+ end
17
+ let(:parameters) { subject['paths']['/books/page/{two}/three']['get']['parameters'] }
18
+
19
+ subject do
20
+ get '/swagger_doc'
21
+ JSON.parse(last_response.body)
22
+ end
23
+
24
+ specify do
25
+ section_param = parameters.find { |param| param['name'] == 'two' }
26
+ expect(section_param['in']).to eq 'path'
27
+ expect(subject['paths'].keys).to eq ['/books/page/three', '/books/page/{two}/three', '/books/page/one/three', '/books/page/one/{two}/three']
28
+ end
29
+ end
@@ -0,0 +1,38 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'spec_helper'
4
+
5
+ describe '#881 handle file params' do
6
+ let(:app) do
7
+ Class.new(Grape::API) do
8
+ namespace :issue_881 do
9
+ params do
10
+ requires :upload, type: File
11
+ end
12
+
13
+ post do
14
+ present params
15
+ end
16
+ end
17
+
18
+ add_swagger_documentation format: :json
19
+ end
20
+ end
21
+
22
+ subject do
23
+ get '/swagger_doc'
24
+ JSON.parse(last_response.body)
25
+ end
26
+
27
+ let(:consumes) { subject['paths']['/issue_881']['post']['consumes'] }
28
+ let(:parameters) { subject['paths']['/issue_881']['post']['parameters'] }
29
+
30
+ specify do
31
+ expect(consumes).to eql(
32
+ ["application/x-www-form-urlencoded", "multipart/form-data"]
33
+ )
34
+ expect(parameters).to eql(
35
+ [{"in"=>"formData", "name"=>"upload", "required"=>true, "type"=>"file"}]
36
+ )
37
+ end
38
+ end
@@ -0,0 +1,46 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'spec_helper'
4
+
5
+ describe '#883 Group Params as Array' do
6
+ let(:app) do
7
+ Class.new(Grape::API) do
8
+ namespace :issue_883 do
9
+ params do
10
+ requires :array_of_string, type: [String]
11
+ requires :array_of_integer, type: [Integer]
12
+ end
13
+ get '/get_primitive_array_parameters' do
14
+ 'accepts array query parameters of primitive value types'
15
+ end
16
+
17
+ params do
18
+ requires :array_of, type: Array, documentation: { type: 'link', is_array: true }
19
+ end
20
+ get '/get_object_array_parameters' do
21
+ 'does not accept array query parameters of object value types'
22
+ end
23
+ end
24
+ add_swagger_documentation
25
+ end
26
+ end
27
+
28
+ describe 'retrieves the documentation for typed group range parameters' do
29
+ subject do
30
+ get '/swagger_doc'
31
+ JSON.parse(last_response.body)
32
+ end
33
+
34
+ specify do
35
+ expect(subject['paths']['/issue_883/get_primitive_array_parameters']['get']['parameters']).to eql(
36
+ [
37
+ {'in'=>'query', 'name'=>'array_of_string', 'type'=>'array', 'items'=>{'type'=>'string'}, 'required'=>true},
38
+ {'in'=>'query', 'name'=>'array_of_integer', 'type'=>'array', 'items'=>{'type'=>'integer', 'format'=>'int32'}, 'required'=>true}
39
+ ]
40
+ )
41
+ expect(subject['paths']['/issue_883/get_object_array_parameters']['get']['parameters']).to eql(
42
+ [{'in'=>'formData', 'items'=>{'type'=>'string'}, 'name'=>'array_of', 'required'=>true, 'type'=>'array'}]
43
+ )
44
+ end
45
+ end
46
+ end
@@ -0,0 +1,49 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'spec_helper'
4
+
5
+ RSpec::Matchers.define_negated_matcher :exclude, :include
6
+
7
+ describe '#884 dont document non-schema examples' do
8
+ let(:app) do
9
+ Class.new(Grape::API) do
10
+ namespace :issue_884 do
11
+ params do
12
+ requires :id, type: Integer, documentation: { example: 123 }
13
+ optional :name, type: String, documentation: { example: 'Buddy Guy' }
14
+ end
15
+
16
+ post 'document_example' do
17
+ present params
18
+ end
19
+
20
+ desc 'do not document this' do
21
+ consumes ['application/x-www-form-urlencoded']
22
+ end
23
+ params do
24
+ requires :id, type: Integer, documentation: { example: 123 }
25
+ optional :name, type: String, documentation: { example: 'Buddy Guy' }
26
+ end
27
+
28
+ post 'dont_document_example' do
29
+ present params
30
+ end
31
+ end
32
+
33
+ add_swagger_documentation format: :json
34
+ end
35
+ end
36
+
37
+ subject do
38
+ get '/swagger_doc'
39
+ JSON.parse(last_response.body)
40
+ end
41
+
42
+ let(:parameters_document_example) { subject['definitions']['postIssue884DocumentExample']['properties'] }
43
+ let(:parameters_dont_document_example) { subject['paths']['/issue_884/dont_document_example']['post']['parameters'] }
44
+
45
+ specify do
46
+ expect(parameters_document_example.values).to all(include('example'))
47
+ expect(parameters_dont_document_example).to all(exclude('example'))
48
+ end
49
+ end
@@ -0,0 +1,35 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'spec_helper'
4
+
5
+ describe '#887 avoid duplciate operationIds' do
6
+ let(:app) do
7
+ Class.new(Grape::API) do
8
+ namespace :issue_887 do
9
+ get 'item/{id}/-/search' do
10
+ status 200
11
+ end
12
+
13
+ get 'item{id}/search' do
14
+ status 200
15
+ end
16
+
17
+ get 'item/{id}/search' do
18
+ status 200
19
+ end
20
+ end
21
+
22
+ add_swagger_documentation format: :json
23
+ end
24
+ end
25
+ let(:operation_ids) { subject['paths'].values.map{ |path| path['get']['operationId'] } }
26
+
27
+ subject do
28
+ get '/swagger_doc'
29
+ JSON.parse(last_response.body)
30
+ end
31
+
32
+ specify do
33
+ expect(operation_ids).to eq ["getIssue887ItemIdSearch", "getIssue887ItemIdSearch2", "getIssue887ItemIdSearch3"]
34
+ end
35
+ end
@@ -0,0 +1,111 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'spec_helper'
4
+
5
+ describe GrapeSwagger::DocMethods::DataType do
6
+ subject { described_class.call(value) }
7
+
8
+ describe 'standards' do
9
+ ['Boolean', Date, Integer, String, Float].each do |type|
10
+ specify do
11
+ data_type = described_class.call(type: type)
12
+ expect(data_type).to eql type.to_s.downcase
13
+ end
14
+ end
15
+ end
16
+
17
+ describe 'Hash' do
18
+ let(:value) { { type: Hash } }
19
+
20
+ it { is_expected.to eq 'object' }
21
+ end
22
+
23
+ describe 'Multi types in a string' do
24
+ let(:value) { { type: '[String, Integer]' } }
25
+
26
+ it { is_expected.to eq 'string' }
27
+ end
28
+
29
+ describe 'Multi types in a string stating with A' do
30
+ let(:value) { { type: '[Apple, Orange]' } }
31
+
32
+ it { is_expected.to eq 'Apple' }
33
+ end
34
+
35
+ describe 'Multi types in array' do
36
+ let(:value) { { type: [String, Integer] } }
37
+
38
+ it { is_expected.to eq 'string' }
39
+ end
40
+
41
+ describe 'Types in array with entity_name' do
42
+ before do
43
+ stub_const 'MyEntity', Class.new
44
+ allow(MyEntity).to receive(:entity_name).and_return 'MyInteger'
45
+ end
46
+
47
+ let(:value) { { type: '[MyEntity]' } }
48
+
49
+ it { is_expected.to eq 'MyInteger' }
50
+ end
51
+
52
+ describe 'Types in array with inherited entity_name' do
53
+ before do
54
+ stub_const 'EntityBase', Class.new
55
+ allow(EntityBase).to receive(:entity_name).and_return 'MyInteger'
56
+ stub_const 'MyEntity', Class.new(EntityBase)
57
+ end
58
+
59
+ let(:value) { { type: '[MyEntity]' } }
60
+
61
+ it { is_expected.to eq 'MyInteger' }
62
+ end
63
+
64
+ describe 'Rack::Multipart::UploadedFile' do
65
+ let(:value) { { type: Rack::Multipart::UploadedFile } }
66
+
67
+ it { is_expected.to eq 'file' }
68
+ end
69
+
70
+ describe 'Grape::API::Boolean' do
71
+ let(:value) { { type: Grape::API::Boolean } }
72
+
73
+ it { is_expected.to eq 'boolean' }
74
+ end
75
+
76
+ describe 'BigDecimal' do
77
+ let(:value) { { type: BigDecimal } }
78
+
79
+ it { is_expected.to eq 'double' }
80
+ end
81
+
82
+ describe 'DateTime' do
83
+ let(:value) { { type: DateTime } }
84
+
85
+ it { is_expected.to eq 'dateTime' }
86
+ end
87
+
88
+ describe 'Numeric' do
89
+ let(:value) { { type: Numeric } }
90
+
91
+ it { is_expected.to eq 'long' }
92
+ end
93
+
94
+ describe 'Symbol' do
95
+ let(:value) { { type: Symbol } }
96
+
97
+ it { is_expected.to eq 'string' }
98
+ end
99
+
100
+ describe '[String]' do
101
+ let(:value) { { type: '[String]' } }
102
+
103
+ it { is_expected.to eq('string') }
104
+ end
105
+
106
+ describe '[Integer]' do
107
+ let(:value) { { type: '[Integer]' } }
108
+
109
+ it { is_expected.to eq('integer') }
110
+ end
111
+ end
@@ -0,0 +1,124 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'spec_helper'
4
+
5
+ describe GrapeSwagger::Endpoint::ParamsParser do
6
+ let(:settings) { {} }
7
+ let(:params) { [] }
8
+ let(:endpoint) { nil }
9
+
10
+ let(:parser) { described_class.new(params, settings, endpoint) }
11
+
12
+ describe '#parse_request_params' do
13
+ subject(:parse_request_params) { parser.parse_request_params }
14
+
15
+ context 'when param is of array type' do
16
+ let(:params) { [['param_1', { type: 'Array[String]' }]] }
17
+
18
+ it 'adds is_array option' do
19
+ expect(parse_request_params['param_1']).to eq(type: 'Array[String]', is_array: true)
20
+ end
21
+
22
+ context 'and array_use_braces setting set to true' do
23
+ let(:settings) { { array_use_braces: true } }
24
+
25
+ it 'adds braces to the param key' do
26
+ expect(parse_request_params.keys.first).to eq 'param_1[]'
27
+ end
28
+ end
29
+ end
30
+
31
+ context 'when param is of simple type' do
32
+ let(:params) { [['param_1', { type: 'String' }]] }
33
+
34
+ it 'does not change options' do
35
+ expect(parse_request_params['param_1']).to eq(type: 'String')
36
+ end
37
+
38
+ context 'and array_use_braces setting set to true' do
39
+ let(:settings) { { array_use_braces: true } }
40
+
41
+ it 'does not add braces to the param key' do
42
+ expect(parser.parse_request_params.keys.first).to eq 'param_1'
43
+ end
44
+ end
45
+ end
46
+
47
+ context 'when param is nested in a param of array type' do
48
+ let(:params) { [['param_1', { type: 'Array' }], ['param_1[param_2]', { type: 'String' }]] }
49
+
50
+ context 'and array_use_braces setting set to true' do
51
+ let(:settings) { { array_use_braces: true } }
52
+
53
+ it 'adds braces to the param key' do
54
+ expect(parse_request_params.keys.last).to eq 'param_1[param_2]'
55
+ end
56
+ end
57
+ end
58
+
59
+ context 'when param is nested in a param of hash type' do
60
+ let(:params) { [param_1, param_2] }
61
+ let(:param_1) { ['param_1', { type: 'Hash' }] }
62
+ let(:param_2) { ['param_1[param_2]', { type: 'String' }] }
63
+
64
+ context 'and array_use_braces setting set to true' do
65
+ let(:settings) { { array_use_braces: true } }
66
+
67
+ context 'and param is of simple type' do
68
+ it 'does not add braces to the param key' do
69
+ expect(parse_request_params.keys.last).to eq 'param_1[param_2]'
70
+ end
71
+ end
72
+
73
+ context 'and param is of array type' do
74
+ let(:param_2) { ['param_1[param_2]', { type: 'Array[String]' }] }
75
+
76
+ it 'adds braces to the param key' do
77
+ expect(parse_request_params.keys.last).to eq 'param_1[param_2][]'
78
+ end
79
+
80
+ context 'and `param_type` option is set to body' do
81
+ let(:param_2) do
82
+ ['param_1[param_2]', { type: 'Array[String]', documentation: { param_type: 'body' } }]
83
+ end
84
+
85
+ it 'does not add braces to the param key' do
86
+ expect(parse_request_params.keys.last).to eq 'param_1[param_2]'
87
+ end
88
+ end
89
+
90
+ context 'and `in` option is set to body' do
91
+ let(:param_2) do
92
+ ['param_1[param_2]', { type: 'Array[String]', documentation: { in: 'body' } }]
93
+ end
94
+
95
+ it 'does not add braces to the param key' do
96
+ expect(parse_request_params.keys.last).to eq 'param_1[param_2]'
97
+ end
98
+ end
99
+
100
+ context 'and hash `param_type` option is set to body' do
101
+ let(:param_1) { ['param_1', { type: 'Hash', documentation: { param_type: 'body' } }] }
102
+
103
+ it 'does not add braces to the param key' do
104
+ expect(parse_request_params.keys.last).to eq 'param_1[param_2]'
105
+ end
106
+ end
107
+ end
108
+ end
109
+ end
110
+ end
111
+
112
+ describe '#param_type_is_array?' do
113
+ it 'returns true if the value passed represents an array' do
114
+ expect(parser.send(:param_type_is_array?, 'Array')).to be_truthy
115
+ expect(parser.send(:param_type_is_array?, '[String]')).to be_truthy
116
+ expect(parser.send(:param_type_is_array?, 'Array[Integer]')).to be_truthy
117
+ end
118
+
119
+ it 'returns false if the value passed does not represent an array' do
120
+ expect(parser.send(:param_type_is_array?, 'String')).to be_falsey
121
+ expect(parser.send(:param_type_is_array?, '[String, Integer]')).to be_falsey
122
+ end
123
+ end
124
+ end
@@ -0,0 +1,153 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'spec_helper'
4
+
5
+ describe Grape::Endpoint do
6
+ subject do
7
+ described_class.new(Grape::Util::InheritableSetting.new, path: '/', method: :get)
8
+ end
9
+
10
+ describe '.content_types_for' do
11
+ describe 'defined on target_class' do
12
+ let(:own_json) { 'text/own-json' }
13
+ let(:own_xml) { 'text/own-xml' }
14
+ let(:content_types) do
15
+ {
16
+ own_json: own_json,
17
+ own_xml: own_xml
18
+ }
19
+ end
20
+ let(:target_class) { OpenStruct.new(content_types: content_types) }
21
+
22
+ let(:object) { subject.content_types_for(target_class) }
23
+ specify do
24
+ expect(object).to eql [own_json, own_xml]
25
+ end
26
+ end
27
+
28
+ describe 'not defined' do
29
+ describe 'format given' do
30
+ let(:format) { :json }
31
+ let(:target_class) { OpenStruct.new(format: format) }
32
+ let(:object) { subject.content_types_for(target_class) }
33
+ specify do
34
+ expect(object).to eql ['application/json']
35
+ end
36
+
37
+ describe 'format not given' do
38
+ let(:target_class) { OpenStruct.new }
39
+ let(:object) { subject.content_types_for(target_class) }
40
+
41
+ specify do
42
+ expect(object).to eql %w[application/xml application/json text/plain]
43
+ end
44
+ end
45
+ end
46
+ end
47
+ end
48
+
49
+ describe 'parse_request_params' do
50
+ let(:subject) { GrapeSwagger::Endpoint::ParamsParser }
51
+ before do
52
+ subject.send(:parse_request_params, params, {}, nil)
53
+ end
54
+
55
+ context 'when params do not contain an array' do
56
+ let(:params) do
57
+ [
58
+ ['id', { required: true, type: 'String' }],
59
+ ['description', { required: false, type: 'String' }]
60
+ ]
61
+ end
62
+
63
+ let(:expected_params) do
64
+ [
65
+ ['id', { required: true, type: 'String' }],
66
+ ['description', { required: false, type: 'String' }]
67
+ ]
68
+ end
69
+
70
+ it 'parses params correctly' do
71
+ expect(params).to eq expected_params
72
+ end
73
+ end
74
+
75
+ context 'when params contain a simple array' do
76
+ let(:params) do
77
+ [
78
+ ['id', { required: true, type: 'String' }],
79
+ ['description', { required: false, type: 'String' }],
80
+ ['stuffs', { required: true, type: 'Array[String]' }]
81
+ ]
82
+ end
83
+
84
+ let(:expected_params) do
85
+ [
86
+ ['id', { required: true, type: 'String' }],
87
+ ['description', { required: false, type: 'String' }],
88
+ ['stuffs', { required: true, type: 'Array[String]', is_array: true }]
89
+ ]
90
+ end
91
+
92
+ it 'parses params correctly and adds is_array to the array' do
93
+ expect(params).to eq expected_params
94
+ end
95
+ end
96
+
97
+ context 'when params contain a complex array' do
98
+ let(:params) do
99
+ [
100
+ ['id', { required: true, type: 'String' }],
101
+ ['description', { required: false, type: 'String' }],
102
+ ['stuffs', { required: true, type: 'Array' }],
103
+ ['stuffs[id]', { required: true, type: 'String' }]
104
+ ]
105
+ end
106
+
107
+ let(:expected_params) do
108
+ [
109
+ ['id', { required: true, type: 'String' }],
110
+ ['description', { required: false, type: 'String' }],
111
+ ['stuffs', { required: true, type: 'Array', is_array: true }],
112
+ ['stuffs[id]', { required: true, type: 'String' }]
113
+ ]
114
+ end
115
+
116
+ it 'parses params correctly and adds is_array to the array and all elements' do
117
+ expect(params).to eq expected_params
118
+ end
119
+
120
+ context 'when array params are not contiguous with parent array' do
121
+ let(:params) do
122
+ [
123
+ ['id', { required: true, type: 'String' }],
124
+ ['description', { required: false, type: 'String' }],
125
+ ['stuffs', { required: true, type: 'Array' }],
126
+ ['stuffs[owners]', { required: true, type: 'Array' }],
127
+ ['stuffs[creators]', { required: true, type: 'Array' }],
128
+ ['stuffs[owners][id]', { required: true, type: 'String' }],
129
+ ['stuffs[creators][id]', { required: true, type: 'String' }],
130
+ ['stuffs_and_things', { required: true, type: 'String' }]
131
+ ]
132
+ end
133
+
134
+ let(:expected_params) do
135
+ [
136
+ ['id', { required: true, type: 'String' }],
137
+ ['description', { required: false, type: 'String' }],
138
+ ['stuffs', { required: true, type: 'Array', is_array: true }],
139
+ ['stuffs[owners]', { required: true, type: 'Array', is_array: true }],
140
+ ['stuffs[creators]', { required: true, type: 'Array', is_array: true }],
141
+ ['stuffs[owners][id]', { required: true, type: 'String' }],
142
+ ['stuffs[creators][id]', { required: true, type: 'String' }],
143
+ ['stuffs_and_things', { required: true, type: 'String' }]
144
+ ]
145
+ end
146
+
147
+ it 'parses params correctly and adds is_array to the array and all elements' do
148
+ expect(params).to eq expected_params
149
+ end
150
+ end
151
+ end
152
+ end
153
+ end