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.
- checksums.yaml +7 -0
- data/.coveralls.yml +1 -0
- data/.github/dependabot.yml +20 -0
- data/.github/workflows/ci.yml +45 -0
- data/.gitignore +44 -0
- data/.gitlab-ci.yml +19 -0
- data/.rspec +3 -0
- data/.rubocop.yml +136 -0
- data/.rubocop_todo.yml +60 -0
- data/.ruby-gemset +1 -0
- data/CHANGELOG.md +671 -0
- data/CONTRIBUTING.md +126 -0
- data/Dangerfile +3 -0
- data/Gemfile +45 -0
- data/Gemfile.lock +249 -0
- data/LICENSE.txt +20 -0
- data/README.md +1772 -0
- data/RELEASING.md +82 -0
- data/Rakefile +20 -0
- data/UPGRADING.md +201 -0
- data/example/api/endpoints.rb +131 -0
- data/example/api/entities.rb +18 -0
- data/example/config.ru +42 -0
- data/example/example_requests.postman_collection +146 -0
- data/example/splines.png +0 -0
- data/example/swagger-example.png +0 -0
- data/grape-swagger.gemspec +23 -0
- data/lib/grape-swagger/doc_methods/build_model_definition.rb +68 -0
- data/lib/grape-swagger/doc_methods/data_type.rb +110 -0
- data/lib/grape-swagger/doc_methods/extensions.rb +101 -0
- data/lib/grape-swagger/doc_methods/file_params.rb +17 -0
- data/lib/grape-swagger/doc_methods/format_data.rb +53 -0
- data/lib/grape-swagger/doc_methods/headers.rb +20 -0
- data/lib/grape-swagger/doc_methods/move_params.rb +209 -0
- data/lib/grape-swagger/doc_methods/operation_id.rb +32 -0
- data/lib/grape-swagger/doc_methods/optional_object.rb +30 -0
- data/lib/grape-swagger/doc_methods/parse_params.rb +190 -0
- data/lib/grape-swagger/doc_methods/path_string.rb +52 -0
- data/lib/grape-swagger/doc_methods/produces_consumes.rb +15 -0
- data/lib/grape-swagger/doc_methods/status_codes.rb +21 -0
- data/lib/grape-swagger/doc_methods/tag_name_description.rb +34 -0
- data/lib/grape-swagger/doc_methods/version.rb +20 -0
- data/lib/grape-swagger/doc_methods.rb +142 -0
- data/lib/grape-swagger/endpoint/params_parser.rb +76 -0
- data/lib/grape-swagger/endpoint.rb +476 -0
- data/lib/grape-swagger/errors.rb +17 -0
- data/lib/grape-swagger/instance.rb +7 -0
- data/lib/grape-swagger/model_parsers.rb +42 -0
- data/lib/grape-swagger/rake/oapi_tasks.rb +135 -0
- data/lib/grape-swagger/version.rb +5 -0
- data/lib/grape-swagger.rb +174 -0
- data/spec/issues/267_nested_namespaces.rb +55 -0
- data/spec/issues/403_versions_spec.rb +124 -0
- data/spec/issues/427_entity_as_string_spec.rb +39 -0
- data/spec/issues/430_entity_definitions_spec.rb +94 -0
- data/spec/issues/532_allow_custom_format_spec.rb +42 -0
- data/spec/issues/533_specify_status_code_spec.rb +78 -0
- data/spec/issues/537_enum_values_spec.rb +50 -0
- data/spec/issues/539_array_post_body_spec.rb +65 -0
- data/spec/issues/542_array_of_type_in_post_body_spec.rb +46 -0
- data/spec/issues/553_align_array_put_post_params_spec.rb +152 -0
- data/spec/issues/572_array_post_body_spec.rb +51 -0
- data/spec/issues/579_align_put_post_parameters_spec.rb +185 -0
- data/spec/issues/582_file_response_spec.rb +55 -0
- data/spec/issues/587_range_parameter_delimited_by_dash_spec.rb +26 -0
- data/spec/issues/605_root_route_documentation_spec.rb +23 -0
- data/spec/issues/650_params_array_spec.rb +65 -0
- data/spec/issues/677_consumes_produces_add_swagger_documentation_options_spec.rb +100 -0
- data/spec/issues/680_keep_204_error_schemas_spec.rb +55 -0
- data/spec/issues/721_set_default_parameter_location_based_on_consumes_spec.rb +62 -0
- data/spec/issues/751_deeply_nested_objects_spec.rb +190 -0
- data/spec/issues/776_multiple_presents_spec.rb +59 -0
- data/spec/issues/784_extensions_on_params_spec.rb +42 -0
- data/spec/issues/809_utf8_routes_spec.rb +55 -0
- data/spec/issues/832_array_hash_float_decimal_spec.rb +114 -0
- data/spec/issues/847_route_param_options_spec.rb +37 -0
- data/spec/issues/873_wildcard_segments_path_parameters_spec.rb +28 -0
- data/spec/issues/878_optional_path_segments_spec.rb +29 -0
- data/spec/issues/881_handle_file_params_spec.rb +38 -0
- data/spec/issues/883_query_array_parameter_spec.rb +46 -0
- data/spec/issues/884_dont_document_non_schema_examples_spec.rb +49 -0
- data/spec/issues/887_prevent_duplicate_operation_ids_spec.rb +35 -0
- data/spec/lib/data_type_spec.rb +111 -0
- data/spec/lib/endpoint/params_parser_spec.rb +124 -0
- data/spec/lib/endpoint_spec.rb +153 -0
- data/spec/lib/extensions_spec.rb +185 -0
- data/spec/lib/format_data_spec.rb +115 -0
- data/spec/lib/model_parsers_spec.rb +104 -0
- data/spec/lib/move_params_spec.rb +444 -0
- data/spec/lib/oapi_tasks_spec.rb +163 -0
- data/spec/lib/operation_id_spec.rb +55 -0
- data/spec/lib/optional_object_spec.rb +47 -0
- data/spec/lib/parse_params_spec.rb +68 -0
- data/spec/lib/path_string_spec.rb +101 -0
- data/spec/lib/produces_consumes_spec.rb +116 -0
- data/spec/lib/tag_name_description_spec.rb +80 -0
- data/spec/lib/version_spec.rb +28 -0
- data/spec/spec_helper.rb +39 -0
- data/spec/support/empty_model_parser.rb +23 -0
- data/spec/support/grape_version.rb +13 -0
- data/spec/support/mock_parser.rb +23 -0
- data/spec/support/model_parsers/entity_parser.rb +334 -0
- data/spec/support/model_parsers/mock_parser.rb +346 -0
- data/spec/support/model_parsers/representable_parser.rb +406 -0
- data/spec/support/namespace_tags.rb +93 -0
- data/spec/support/the_paths_definitions.rb +109 -0
- data/spec/swagger_v2/api_documentation_spec.rb +42 -0
- data/spec/swagger_v2/api_swagger_v2_additional_properties_spec.rb +83 -0
- data/spec/swagger_v2/api_swagger_v2_body_definitions_spec.rb +48 -0
- data/spec/swagger_v2/api_swagger_v2_definitions-models_spec.rb +36 -0
- data/spec/swagger_v2/api_swagger_v2_detail_spec.rb +79 -0
- data/spec/swagger_v2/api_swagger_v2_extensions_spec.rb +145 -0
- data/spec/swagger_v2/api_swagger_v2_format-content_type_spec.rb +137 -0
- data/spec/swagger_v2/api_swagger_v2_global_configuration_spec.rb +56 -0
- data/spec/swagger_v2/api_swagger_v2_hash_and_array_spec.rb +64 -0
- data/spec/swagger_v2/api_swagger_v2_headers_spec.rb +58 -0
- data/spec/swagger_v2/api_swagger_v2_hide_documentation_path_spec.rb +57 -0
- data/spec/swagger_v2/api_swagger_v2_hide_param_spec.rb +109 -0
- data/spec/swagger_v2/api_swagger_v2_ignore_defaults_spec.rb +48 -0
- data/spec/swagger_v2/api_swagger_v2_mounted_spec.rb +153 -0
- data/spec/swagger_v2/api_swagger_v2_param_type_body_nested_spec.rb +355 -0
- data/spec/swagger_v2/api_swagger_v2_param_type_body_spec.rb +217 -0
- data/spec/swagger_v2/api_swagger_v2_param_type_spec.rb +247 -0
- data/spec/swagger_v2/api_swagger_v2_request_params_fix_spec.rb +80 -0
- data/spec/swagger_v2/api_swagger_v2_response_spec.rb +147 -0
- data/spec/swagger_v2/api_swagger_v2_response_with_examples_spec.rb +135 -0
- data/spec/swagger_v2/api_swagger_v2_response_with_headers_spec.rb +216 -0
- data/spec/swagger_v2/api_swagger_v2_response_with_models_spec.rb +53 -0
- data/spec/swagger_v2/api_swagger_v2_response_with_root_spec.rb +153 -0
- data/spec/swagger_v2/api_swagger_v2_spec.rb +245 -0
- data/spec/swagger_v2/api_swagger_v2_status_codes_spec.rb +93 -0
- data/spec/swagger_v2/api_swagger_v2_type-format_spec.rb +90 -0
- data/spec/swagger_v2/boolean_params_spec.rb +38 -0
- data/spec/swagger_v2/default_api_spec.rb +175 -0
- data/spec/swagger_v2/deprecated_field_spec.rb +25 -0
- data/spec/swagger_v2/description_not_initialized_spec.rb +39 -0
- data/spec/swagger_v2/endpoint_versioned_path_spec.rb +130 -0
- data/spec/swagger_v2/errors_spec.rb +77 -0
- data/spec/swagger_v2/float_api_spec.rb +36 -0
- data/spec/swagger_v2/form_params_spec.rb +76 -0
- data/spec/swagger_v2/grape-swagger_spec.rb +17 -0
- data/spec/swagger_v2/guarded_endpoint_spec.rb +162 -0
- data/spec/swagger_v2/hide_api_spec.rb +147 -0
- data/spec/swagger_v2/host_spec.rb +43 -0
- data/spec/swagger_v2/inheritance_and_discriminator_spec.rb +57 -0
- data/spec/swagger_v2/mount_override_api_spec.rb +58 -0
- data/spec/swagger_v2/mounted_target_class_spec.rb +76 -0
- data/spec/swagger_v2/namespace_tags_prefix_spec.rb +122 -0
- data/spec/swagger_v2/namespace_tags_spec.rb +78 -0
- data/spec/swagger_v2/namespaced_api_spec.rb +121 -0
- data/spec/swagger_v2/nicknamed_api_spec.rb +25 -0
- data/spec/swagger_v2/operation_id_api_spec.rb +27 -0
- data/spec/swagger_v2/param_multi_type_spec.rb +82 -0
- data/spec/swagger_v2/param_type_spec.rb +95 -0
- data/spec/swagger_v2/param_values_spec.rb +180 -0
- data/spec/swagger_v2/params_array_collection_format_spec.rb +105 -0
- data/spec/swagger_v2/params_array_spec.rb +225 -0
- data/spec/swagger_v2/params_example_spec.rb +38 -0
- data/spec/swagger_v2/params_hash_spec.rb +77 -0
- data/spec/swagger_v2/params_nested_spec.rb +92 -0
- data/spec/swagger_v2/parent_less_namespace_spec.rb +32 -0
- data/spec/swagger_v2/reference_entity_spec.rb +129 -0
- data/spec/swagger_v2/security_requirement_spec.rb +46 -0
- data/spec/swagger_v2/simple_mounted_api_spec.rb +332 -0
- data/spec/version_spec.rb +10 -0
- metadata +225 -0
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require 'spec_helper'
|
|
4
|
+
|
|
5
|
+
describe 'Float 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_float, type: Float
|
|
15
|
+
end
|
|
16
|
+
post :splines do
|
|
17
|
+
{ message: 'hi' }
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
add_swagger_documentation
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
subject do
|
|
25
|
+
get '/swagger_doc/splines'
|
|
26
|
+
expect(last_response.status).to eq 200
|
|
27
|
+
body = JSON.parse last_response.body
|
|
28
|
+
body['paths']['/splines']['post']['parameters']
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
it 'converts float types' do
|
|
32
|
+
expect(subject).to eq [
|
|
33
|
+
{ 'in' => 'formData', 'name' => 'a_float', 'type' => 'number', 'required' => true, 'format' => 'float' }
|
|
34
|
+
]
|
|
35
|
+
end
|
|
36
|
+
end
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require 'spec_helper'
|
|
4
|
+
|
|
5
|
+
describe 'Form Params' do
|
|
6
|
+
def app
|
|
7
|
+
Class.new(Grape::API) do
|
|
8
|
+
format :json
|
|
9
|
+
|
|
10
|
+
desc 'get items' do
|
|
11
|
+
consumes ['application/x-www-form-urlencoded']
|
|
12
|
+
end
|
|
13
|
+
params do
|
|
14
|
+
requires :name, type: String, desc: 'name of item'
|
|
15
|
+
end
|
|
16
|
+
post '/items' do
|
|
17
|
+
{}
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
desc 'get item' do
|
|
21
|
+
consumes ['application/x-www-form-urlencoded']
|
|
22
|
+
end
|
|
23
|
+
params do
|
|
24
|
+
requires :id, type: Integer, desc: 'id of item'
|
|
25
|
+
requires :name, type: String, desc: 'name of item'
|
|
26
|
+
requires :conditions, type: Integer, desc: 'conditions of item', values: [1, 2, 3]
|
|
27
|
+
end
|
|
28
|
+
put '/items/:id' do
|
|
29
|
+
{}
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
params do
|
|
33
|
+
requires :id, type: Integer, desc: 'id of item'
|
|
34
|
+
requires :name, type: String, desc: 'name of item'
|
|
35
|
+
optional :conditions, type: String, desc: 'conditions of item', values: proc { %w[1 2] }
|
|
36
|
+
end
|
|
37
|
+
patch '/items/:id' do
|
|
38
|
+
{}
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
desc 'create item' do
|
|
42
|
+
consumes ['application/x-www-form-urlencoded']
|
|
43
|
+
end
|
|
44
|
+
params do
|
|
45
|
+
requires :id, type: Integer, desc: 'id of item'
|
|
46
|
+
requires :name, type: String, desc: 'name of item'
|
|
47
|
+
optional :conditions, type: Symbol, desc: 'conditions of item', values: %i[one two]
|
|
48
|
+
end
|
|
49
|
+
post '/items/:id' do
|
|
50
|
+
{}
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
add_swagger_documentation
|
|
54
|
+
end
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
subject do
|
|
58
|
+
get '/swagger_doc/items'
|
|
59
|
+
JSON.parse(last_response.body)
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
it 'retrieves the documentation form params' do
|
|
63
|
+
expect(subject['paths'].length).to eq 2
|
|
64
|
+
expect(subject['paths'].keys).to include('/items', '/items/{id}')
|
|
65
|
+
expect(subject['paths']['/items'].keys).to include 'post'
|
|
66
|
+
expect(subject['paths']['/items/{id}'].keys).to include('post', 'patch', 'put')
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
it 'treats Symbol parameter as form param' do
|
|
70
|
+
expect(subject['paths']['/items/{id}']['post']['parameters']).to eq [
|
|
71
|
+
{ 'in' => 'path', 'name' => 'id', 'description' => 'id of item', 'type' => 'integer', 'required' => true, 'format' => 'int32' },
|
|
72
|
+
{ 'in' => 'formData', 'name' => 'name', 'description' => 'name of item', 'type' => 'string', 'required' => true },
|
|
73
|
+
{ 'in' => 'formData', 'name' => 'conditions', 'description' => 'conditions of item', 'type' => 'string', 'required' => false, 'enum' => %w[one two] }
|
|
74
|
+
]
|
|
75
|
+
end
|
|
76
|
+
end
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require 'spec_helper'
|
|
4
|
+
|
|
5
|
+
describe GrapeInstance do
|
|
6
|
+
it 'added combined-routes' do
|
|
7
|
+
expect(described_class).to respond_to :combined_routes
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
it 'added add_swagger_documentation' do
|
|
11
|
+
expect(described_class).to respond_to :add_swagger_documentation
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
it 'added combined-namespaces' do
|
|
15
|
+
expect(described_class).to respond_to :combined_namespaces
|
|
16
|
+
end
|
|
17
|
+
end
|
|
@@ -0,0 +1,162 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require 'spec_helper'
|
|
4
|
+
|
|
5
|
+
class SampleAuth < Grape::Middleware::Base
|
|
6
|
+
module AuthMethods
|
|
7
|
+
attr_accessor :access_token
|
|
8
|
+
|
|
9
|
+
def protected_endpoint=(protected)
|
|
10
|
+
@protected_endpoint = protected
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
def protected_endpoint?
|
|
14
|
+
@protected_endpoint || false
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
def resource_owner
|
|
18
|
+
@resource_owner = true if access_token == '12345'
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
def context
|
|
23
|
+
env['api.endpoint']
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
def before
|
|
27
|
+
context.extend(SampleAuth::AuthMethods)
|
|
28
|
+
context.protected_endpoint = context.options[:route_options][:auth].present?
|
|
29
|
+
|
|
30
|
+
return unless context.protected_endpoint?
|
|
31
|
+
|
|
32
|
+
scopes = context.options[:route_options][:auth][:scopes]
|
|
33
|
+
authorize!(*scopes) unless scopes.include? false
|
|
34
|
+
context.access_token = env['HTTP_AUTHORIZATION']
|
|
35
|
+
end
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
module Extension
|
|
39
|
+
def sample_auth(*scopes)
|
|
40
|
+
description = route_setting(:description) || route_setting(:description, {})
|
|
41
|
+
description[:auth] = { scopes: scopes }
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
GrapeInstance.extend self
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
describe 'a guarded api endpoint' do
|
|
48
|
+
before :all do
|
|
49
|
+
class GuardedMountedApi < Grape::API
|
|
50
|
+
resource_owner_valid = proc { |token_owner = nil| token_owner.nil? }
|
|
51
|
+
|
|
52
|
+
desc 'Show endpoint if authenticated'
|
|
53
|
+
route_setting :swagger, hidden: resource_owner_valid
|
|
54
|
+
get '/auth' do
|
|
55
|
+
{ foo: 'bar' }
|
|
56
|
+
end
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
class GuardedApi < Grape::API
|
|
60
|
+
mount GuardedMountedApi
|
|
61
|
+
add_swagger_documentation endpoint_auth_wrapper: SampleAuth,
|
|
62
|
+
swagger_endpoint_guard: 'sample_auth false',
|
|
63
|
+
token_owner: 'resource_owner'
|
|
64
|
+
end
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
def app
|
|
68
|
+
GuardedApi
|
|
69
|
+
end
|
|
70
|
+
|
|
71
|
+
let(:endpoint) { '/swagger_doc.json' }
|
|
72
|
+
let(:auth_token) { nil }
|
|
73
|
+
|
|
74
|
+
subject do
|
|
75
|
+
get endpoint, {}, 'HTTP_AUTHORIZATION' => auth_token
|
|
76
|
+
JSON.parse(last_response.body)
|
|
77
|
+
end
|
|
78
|
+
|
|
79
|
+
context 'accessing the main doc endpoint' do
|
|
80
|
+
let(:endpoint) { '/swagger_doc.json' }
|
|
81
|
+
|
|
82
|
+
context 'when a correct token is passed with the request' do
|
|
83
|
+
let(:auth_token) { '12345' }
|
|
84
|
+
|
|
85
|
+
it 'retrieves swagger-documentation for the endpoint' do
|
|
86
|
+
expect(subject).to eq(
|
|
87
|
+
'info' => { 'title' => 'API title', 'version' => '0.0.1' },
|
|
88
|
+
'swagger' => '2.0',
|
|
89
|
+
'produces' => ['application/xml', 'application/json', 'application/octet-stream', 'text/plain'],
|
|
90
|
+
'host' => 'example.org',
|
|
91
|
+
'tags' => [{ 'name' => 'auth', 'description' => 'Operations about auths' }],
|
|
92
|
+
'paths' => {
|
|
93
|
+
'/auth' => {
|
|
94
|
+
'get' => {
|
|
95
|
+
'description' => 'Show endpoint if authenticated',
|
|
96
|
+
'produces' => ['application/json'],
|
|
97
|
+
'tags' => ['auth'],
|
|
98
|
+
'operationId' => 'getAuth',
|
|
99
|
+
'responses' => { '200' => { 'description' => 'Show endpoint if authenticated' } }
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
)
|
|
104
|
+
end
|
|
105
|
+
end
|
|
106
|
+
|
|
107
|
+
context 'when a bad token is passed with the request' do
|
|
108
|
+
let(:auth_token) { '123456' }
|
|
109
|
+
|
|
110
|
+
it 'does not retrieve swagger-documentation for the endpoint - only the info_object' do
|
|
111
|
+
expect(subject).to eq(
|
|
112
|
+
'info' => { 'title' => 'API title', 'version' => '0.0.1' },
|
|
113
|
+
'swagger' => '2.0',
|
|
114
|
+
'produces' => ['application/xml', 'application/json', 'application/octet-stream', 'text/plain'],
|
|
115
|
+
'host' => 'example.org'
|
|
116
|
+
)
|
|
117
|
+
end
|
|
118
|
+
end
|
|
119
|
+
end
|
|
120
|
+
|
|
121
|
+
context 'accessing the tag specific endpoint' do
|
|
122
|
+
let(:endpoint) { '/swagger_doc/auth.json' }
|
|
123
|
+
|
|
124
|
+
context 'when a correct token is passed with the request' do
|
|
125
|
+
let(:auth_token) { '12345' }
|
|
126
|
+
|
|
127
|
+
it 'retrieves swagger-documentation for the endpoint' do
|
|
128
|
+
expect(subject).to eq(
|
|
129
|
+
'info' => { 'title' => 'API title', 'version' => '0.0.1' },
|
|
130
|
+
'swagger' => '2.0',
|
|
131
|
+
'produces' => ['application/xml', 'application/json', 'application/octet-stream', 'text/plain'],
|
|
132
|
+
'host' => 'example.org',
|
|
133
|
+
'tags' => [{ 'name' => 'auth', 'description' => 'Operations about auths' }],
|
|
134
|
+
'paths' => {
|
|
135
|
+
'/auth' => {
|
|
136
|
+
'get' => {
|
|
137
|
+
'description' => 'Show endpoint if authenticated',
|
|
138
|
+
'produces' => ['application/json'],
|
|
139
|
+
'tags' => ['auth'],
|
|
140
|
+
'operationId' => 'getAuth',
|
|
141
|
+
'responses' => { '200' => { 'description' => 'Show endpoint if authenticated' } }
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
)
|
|
146
|
+
end
|
|
147
|
+
end
|
|
148
|
+
|
|
149
|
+
context 'when a bad token is passed with the request' do
|
|
150
|
+
let(:auth_token) { '123456' }
|
|
151
|
+
|
|
152
|
+
it 'does not retrieve swagger-documentation for the endpoint - only the info_object' do
|
|
153
|
+
expect(subject).to eq(
|
|
154
|
+
'info' => { 'title' => 'API title', 'version' => '0.0.1' },
|
|
155
|
+
'swagger' => '2.0',
|
|
156
|
+
'produces' => ['application/xml', 'application/json', 'application/octet-stream', 'text/plain'],
|
|
157
|
+
'host' => 'example.org'
|
|
158
|
+
)
|
|
159
|
+
end
|
|
160
|
+
end
|
|
161
|
+
end
|
|
162
|
+
end
|
|
@@ -0,0 +1,147 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require 'spec_helper'
|
|
4
|
+
|
|
5
|
+
describe 'a hide mounted api' do
|
|
6
|
+
before :all do
|
|
7
|
+
class HideMountedApi < Grape::API
|
|
8
|
+
desc 'Show this endpoint'
|
|
9
|
+
get '/simple' do
|
|
10
|
+
{ foo: 'bar' }
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
desc 'Hide this endpoint', hidden: true
|
|
14
|
+
get '/hide' do
|
|
15
|
+
{ foo: 'bar' }
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
desc 'Hide this endpoint using route setting'
|
|
19
|
+
route_setting :swagger, hidden: true
|
|
20
|
+
get '/hide_as_well' do
|
|
21
|
+
{ foo: 'bar' }
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
desc 'Lazily show endpoint', hidden: -> { false }
|
|
25
|
+
get '/lazy' do
|
|
26
|
+
{ foo: 'bar' }
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
class HideApi < Grape::API
|
|
31
|
+
mount HideMountedApi
|
|
32
|
+
add_swagger_documentation
|
|
33
|
+
end
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
def app
|
|
37
|
+
HideApi
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
subject do
|
|
41
|
+
get '/swagger_doc.json'
|
|
42
|
+
JSON.parse(last_response.body)
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
it "retrieves swagger-documentation that doesn't include hidden endpoints" do
|
|
46
|
+
expect(subject).to eq(
|
|
47
|
+
'info' => { 'title' => 'API title', 'version' => '0.0.1' },
|
|
48
|
+
'swagger' => '2.0',
|
|
49
|
+
'produces' => ['application/xml', 'application/json', 'application/octet-stream', 'text/plain'],
|
|
50
|
+
'host' => 'example.org',
|
|
51
|
+
'tags' => [{ 'name' => 'simple', 'description' => 'Operations about simples' }, { 'name' => 'lazy', 'description' => 'Operations about lazies' }],
|
|
52
|
+
'paths' => {
|
|
53
|
+
'/simple' => {
|
|
54
|
+
'get' => {
|
|
55
|
+
'description' => 'Show this endpoint',
|
|
56
|
+
'produces' => ['application/json'],
|
|
57
|
+
'tags' => ['simple'],
|
|
58
|
+
'operationId' => 'getSimple',
|
|
59
|
+
'responses' => { '200' => { 'description' => 'Show this endpoint' } }
|
|
60
|
+
}
|
|
61
|
+
},
|
|
62
|
+
'/lazy' => {
|
|
63
|
+
'get' => {
|
|
64
|
+
'description' => 'Lazily show endpoint',
|
|
65
|
+
'produces' => ['application/json'],
|
|
66
|
+
'tags' => ['lazy'],
|
|
67
|
+
'operationId' => 'getLazy',
|
|
68
|
+
'responses' => { '200' => { 'description' => 'Lazily show endpoint' } }
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
)
|
|
73
|
+
end
|
|
74
|
+
end
|
|
75
|
+
|
|
76
|
+
describe 'a hide mounted api with same namespace' do
|
|
77
|
+
before :all do
|
|
78
|
+
class HideNamespaceMountedApi < Grape::API
|
|
79
|
+
desc 'Show this endpoint'
|
|
80
|
+
get '/simple/show' do
|
|
81
|
+
{ foo: 'bar' }
|
|
82
|
+
end
|
|
83
|
+
|
|
84
|
+
desc 'Hide this endpoint', hidden: true
|
|
85
|
+
get '/simple/hide' do
|
|
86
|
+
{ foo: 'bar' }
|
|
87
|
+
end
|
|
88
|
+
|
|
89
|
+
desc 'Lazily hide endpoint', hidden: -> { true }
|
|
90
|
+
get '/simple/lazy' do
|
|
91
|
+
{ foo: 'bar' }
|
|
92
|
+
end
|
|
93
|
+
end
|
|
94
|
+
|
|
95
|
+
class HideNamespaceApi < Grape::API
|
|
96
|
+
mount HideNamespaceMountedApi
|
|
97
|
+
add_swagger_documentation
|
|
98
|
+
end
|
|
99
|
+
end
|
|
100
|
+
|
|
101
|
+
def app
|
|
102
|
+
HideNamespaceApi
|
|
103
|
+
end
|
|
104
|
+
|
|
105
|
+
it 'retrieves swagger-documentation on /swagger_doc' do
|
|
106
|
+
get '/swagger_doc.json'
|
|
107
|
+
expect(JSON.parse(last_response.body)).to eq(
|
|
108
|
+
'info' => { 'title' => 'API title', 'version' => '0.0.1' },
|
|
109
|
+
'swagger' => '2.0',
|
|
110
|
+
'produces' => ['application/xml', 'application/json', 'application/octet-stream', 'text/plain'],
|
|
111
|
+
'host' => 'example.org',
|
|
112
|
+
'tags' => [{ 'name' => 'simple', 'description' => 'Operations about simples' }],
|
|
113
|
+
'paths' => {
|
|
114
|
+
'/simple/show' => {
|
|
115
|
+
'get' => {
|
|
116
|
+
'description' => 'Show this endpoint',
|
|
117
|
+
'produces' => ['application/json'],
|
|
118
|
+
'operationId' => 'getSimpleShow',
|
|
119
|
+
'tags' => ['simple'], 'responses' => { '200' => { 'description' => 'Show this endpoint' } }
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
)
|
|
124
|
+
end
|
|
125
|
+
|
|
126
|
+
it "retrieves the documentation for mounted-api that doesn't include hidden endpoints" do
|
|
127
|
+
get '/swagger_doc/simple.json'
|
|
128
|
+
expect(JSON.parse(last_response.body)).to eq(
|
|
129
|
+
'info' => { 'title' => 'API title', 'version' => '0.0.1' },
|
|
130
|
+
'swagger' => '2.0',
|
|
131
|
+
'produces' => ['application/xml', 'application/json', 'application/octet-stream', 'text/plain'],
|
|
132
|
+
'host' => 'example.org',
|
|
133
|
+
'tags' => [{ 'name' => 'simple', 'description' => 'Operations about simples' }],
|
|
134
|
+
'paths' => {
|
|
135
|
+
'/simple/show' => {
|
|
136
|
+
'get' => {
|
|
137
|
+
'description' => 'Show this endpoint',
|
|
138
|
+
'produces' => ['application/json'],
|
|
139
|
+
'tags' => ['simple'],
|
|
140
|
+
'operationId' => 'getSimpleShow',
|
|
141
|
+
'responses' => { '200' => { 'description' => 'Show this endpoint' } }
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
)
|
|
146
|
+
end
|
|
147
|
+
end
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require 'spec_helper'
|
|
4
|
+
|
|
5
|
+
describe 'host in the swagger_doc' do
|
|
6
|
+
before :all do
|
|
7
|
+
module TheApi
|
|
8
|
+
class EmptyApi < Grape::API
|
|
9
|
+
format :json
|
|
10
|
+
|
|
11
|
+
add_swagger_documentation
|
|
12
|
+
end
|
|
13
|
+
end
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
def app
|
|
17
|
+
TheApi::EmptyApi
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
describe 'host should include port' do
|
|
21
|
+
subject do
|
|
22
|
+
get 'http://example.com:8080/swagger_doc'
|
|
23
|
+
JSON.parse(last_response.body)
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
specify do
|
|
27
|
+
expect(subject['host']).to eq 'example.com:8080'
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
describe 'respect X-Forwarded-Host over Host header' do
|
|
32
|
+
subject do
|
|
33
|
+
header 'Host', 'dummy.example.com'
|
|
34
|
+
header 'X-Forwarded-Host', 'real.example.com'
|
|
35
|
+
get '/swagger_doc'
|
|
36
|
+
JSON.parse(last_response.body)
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
specify do
|
|
40
|
+
expect(subject['host']).to eq 'real.example.com'
|
|
41
|
+
end
|
|
42
|
+
end
|
|
43
|
+
end
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require 'spec_helper'
|
|
4
|
+
|
|
5
|
+
describe 'Inheritance and Discriminator' do
|
|
6
|
+
before :all do
|
|
7
|
+
module InheritanceTest
|
|
8
|
+
module Entities
|
|
9
|
+
# example from https://github.com/OAI/OpenAPI-Specification/blob/master/versions/2.0.md#models-with-polymorphism-supports
|
|
10
|
+
class Pet < Grape::Entity
|
|
11
|
+
expose :type, documentation: {
|
|
12
|
+
type: 'string',
|
|
13
|
+
is_discriminator: true,
|
|
14
|
+
required: true
|
|
15
|
+
}
|
|
16
|
+
expose :name, documentation: {
|
|
17
|
+
type: 'string',
|
|
18
|
+
required: true
|
|
19
|
+
}
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
class Cat < Pet
|
|
23
|
+
expose :huntingSkill, documentation: {
|
|
24
|
+
type: 'string',
|
|
25
|
+
description: 'The measured skill for hunting',
|
|
26
|
+
default: 'lazy',
|
|
27
|
+
values: %w[
|
|
28
|
+
clueless
|
|
29
|
+
lazy
|
|
30
|
+
adventurous
|
|
31
|
+
aggressive
|
|
32
|
+
]
|
|
33
|
+
}
|
|
34
|
+
end
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
class NameApi < Grape::API
|
|
38
|
+
add_swagger_documentation models: [Entities::Pet, Entities::Cat]
|
|
39
|
+
end
|
|
40
|
+
end
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
context 'Parent model' do
|
|
44
|
+
let(:app) { InheritanceTest::NameApi }
|
|
45
|
+
|
|
46
|
+
subject do
|
|
47
|
+
get '/swagger_doc'
|
|
48
|
+
JSON.parse(last_response.body)['definitions']
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
specify do
|
|
52
|
+
subject['InheritanceTest_Entities_Pet'].key?('discriminator')
|
|
53
|
+
subject['InheritanceTest_Entities_Pet']['discriminator'] = 'type'
|
|
54
|
+
subject['InheritanceTest_Entities_Cat'].key?('allOf')
|
|
55
|
+
end
|
|
56
|
+
end
|
|
57
|
+
end
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require 'spec_helper'
|
|
4
|
+
|
|
5
|
+
describe 'mount override api' do
|
|
6
|
+
def app
|
|
7
|
+
old_api = Class.new(Grape::API) do
|
|
8
|
+
desc 'old endpoint', success: { code: 200, message: 'old message' }
|
|
9
|
+
params do
|
|
10
|
+
optional :param, type: Integer, desc: 'old param'
|
|
11
|
+
end
|
|
12
|
+
get do
|
|
13
|
+
'old'
|
|
14
|
+
end
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
new_api = Class.new(Grape::API) do
|
|
18
|
+
desc 'new endpoint', success: { code: 200, message: 'new message' }
|
|
19
|
+
params do
|
|
20
|
+
optional :param, type: String, desc: 'new param'
|
|
21
|
+
end
|
|
22
|
+
get do
|
|
23
|
+
'new'
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
Class.new(Grape::API) do
|
|
28
|
+
mount new_api
|
|
29
|
+
mount old_api
|
|
30
|
+
|
|
31
|
+
add_swagger_documentation format: :json
|
|
32
|
+
end
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
context 'actual api request' do
|
|
36
|
+
subject do
|
|
37
|
+
get '/'
|
|
38
|
+
last_response.body
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
it 'returns data from new endpoint' do
|
|
42
|
+
is_expected.to eq 'new'
|
|
43
|
+
end
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
context 'api documentation' do
|
|
47
|
+
subject do
|
|
48
|
+
get '/swagger_doc'
|
|
49
|
+
JSON.parse(last_response.body)['paths']['/']['get']
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
it 'shows documentation from new endpoint' do
|
|
53
|
+
expect(subject['parameters'][0]['description']).to eql('new param')
|
|
54
|
+
expect(subject['parameters'][0]['type']).to eql('string')
|
|
55
|
+
expect(subject['responses']['200']['description']).to eql('new message')
|
|
56
|
+
end
|
|
57
|
+
end
|
|
58
|
+
end
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require 'spec_helper'
|
|
4
|
+
|
|
5
|
+
xdescribe 'docs mounted separately from api' do
|
|
6
|
+
before :all do
|
|
7
|
+
class ActualApi < Grape::API
|
|
8
|
+
desc 'Document root'
|
|
9
|
+
|
|
10
|
+
desc 'This gets something.',
|
|
11
|
+
notes: '_test_'
|
|
12
|
+
get '/simple' do
|
|
13
|
+
{ bla: 'something' }
|
|
14
|
+
end
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
class MountedDocs < Grape::API
|
|
18
|
+
add_swagger_documentation(target_class: ActualApi)
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
class WholeApp < Grape::API
|
|
22
|
+
mount ActualApi
|
|
23
|
+
mount MountedDocs
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
def app
|
|
28
|
+
WholeApp
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
it 'retrieves docs for actual api class' do
|
|
32
|
+
get '/swagger_doc.json'
|
|
33
|
+
expect(JSON.parse(last_response.body)).to eq(
|
|
34
|
+
'info' => { 'title' => 'API title', 'version' => '0.0.1' },
|
|
35
|
+
'swagger' => '2.0',
|
|
36
|
+
'produces' => ['application/xml', 'application/json', 'application/octet-stream', 'text/plain'],
|
|
37
|
+
'host' => 'example.org',
|
|
38
|
+
'tags' => [{ 'name' => 'simple', 'description' => 'Operations about simples' }],
|
|
39
|
+
'paths' => {
|
|
40
|
+
'/simple' => {
|
|
41
|
+
'get' => {
|
|
42
|
+
'description' => 'This gets something.',
|
|
43
|
+
'produces' => ['application/json'],
|
|
44
|
+
'responses' => { '200' => { 'description' => 'This gets something.' } },
|
|
45
|
+
'tags' => ['simple'],
|
|
46
|
+
'operationId' => 'getSimple'
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
)
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
it 'retrieves docs for endpoint in actual api class' do
|
|
54
|
+
get '/swagger_doc/simple.json'
|
|
55
|
+
expect(JSON.parse(last_response.body)).to eq(
|
|
56
|
+
'info' => { 'title' => 'API title', 'version' => '0.0.1' },
|
|
57
|
+
'swagger' => '2.0',
|
|
58
|
+
'tags' => [{ 'name' => 'simple', 'description' => 'Operations about simples' }],
|
|
59
|
+
'produces' => ['application/xml', 'application/json', 'application/octet-stream', 'text/plain'],
|
|
60
|
+
'host' => 'example.org',
|
|
61
|
+
'paths' => {
|
|
62
|
+
'/simple' => {
|
|
63
|
+
'get' => {
|
|
64
|
+
'description' => 'This gets something.',
|
|
65
|
+
'produces' => ['application/json'],
|
|
66
|
+
'responses' => {
|
|
67
|
+
'200' => { 'description' => 'This gets something.' }
|
|
68
|
+
},
|
|
69
|
+
'tags' => ['simple'],
|
|
70
|
+
'operationId' => 'getSimple'
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
)
|
|
75
|
+
end
|
|
76
|
+
end
|