diff --git a/.rubocop_todo.yml b/.rubocop_todo.yml index 6e3322aa..6a032a99 100644 --- a/.rubocop_todo.yml +++ b/.rubocop_todo.yml @@ -28,7 +28,7 @@ Metrics/AbcSize: # Offense count: 3 # Configuration parameters: CountComments. Metrics/ClassLength: - Max: 201 + Max: 206 # Offense count: 10 Metrics/CyclomaticComplexity: diff --git a/lib/grape-swagger/endpoint.rb b/lib/grape-swagger/endpoint.rb index b50ac0eb..343721d7 100644 --- a/lib/grape-swagger/endpoint.rb +++ b/lib/grape-swagger/endpoint.rb @@ -102,7 +102,9 @@ def path_item(routes, options) end def method_object(route, options, path) + puts "lib/grape-swagger/endpoint.rb:105 DEBUG OUTPUT FOR GRAPE-SWAGGER: #{route.options}" method = {} + method[:summary] = summary_object(route) method[:description] = description_object(route, options[:markdown]) method[:produces] = produces_object(route, options[:produces] || options[:format]) method[:consumes] = consumes_object(route, options[:format]) @@ -115,6 +117,14 @@ def method_object(route, options, path) [route.request_method.downcase.to_sym, method] end + def summary_object(route) + summary = route.options[:desc] if route.options.key?(:desc) + summary = route.description if route.description.present? + summary = route.options[:summary] if route.options.key?(:summary) + + summary + end + def description_object(route, markdown) description = route.options[:desc] if route.options.key?(:desc) description = route.description if route.description.present? @@ -237,9 +247,7 @@ def expose_params_from_model(model) GrapeSwagger.model_parsers.each do |klass, ancestor| next unless model.ancestors.map(&:to_s).include?(ancestor) - parser = klass.new(model, self) - break end diff --git a/spec/issues/403_versions_spec.rb b/spec/issues/403_versions_spec.rb index b71a8b1b..2877bcc5 100644 --- a/spec/issues/403_versions_spec.rb +++ b/spec/issues/403_versions_spec.rb @@ -29,6 +29,7 @@ def app paths: { :'/nothings' => { get: { + summary: 'no versions given', description: 'no versions given', produces: ['application/json'], responses: { @@ -71,6 +72,7 @@ def app paths: { :'/v2/api_version' => { get: { + summary: 'api versions given', description: 'api versions given', produces: ['application/json'], responses: { @@ -112,6 +114,7 @@ def app paths: { :'/doc_version' => { get: { + summary: 'doc versions given', description: 'doc versions given', produces: ['application/json'], responses: { @@ -154,6 +157,7 @@ def app paths: { :'/v2/both_versions' => { get: { + summary: 'both versions given', description: 'both versions given', produces: ['application/json'], responses: { diff --git a/spec/support/model_parsers/entity_parser.rb b/spec/support/model_parsers/entity_parser.rb index e2a3e038..e665f714 100644 --- a/spec/support/model_parsers/entity_parser.rb +++ b/spec/support/model_parsers/entity_parser.rb @@ -192,6 +192,7 @@ class RecursiveModel < Grape::Entity 'paths' => { '/v3/other_thing/{elements}' => { 'get' => { + 'summary' => 'nested route inside namespace', 'description' => 'nested route inside namespace', 'produces' => ['application/json'], 'parameters' => [{ 'in' => 'body', 'name' => 'elements', 'description' => 'Set of configuration', 'type' => 'array', 'items' => { 'type' => 'string' }, 'required' => true }], @@ -204,6 +205,7 @@ class RecursiveModel < Grape::Entity }, '/thing' => { 'get' => { + 'summary' => 'This gets Things.', 'description' => 'This gets Things.', 'produces' => ['application/json'], 'parameters' => [ @@ -217,6 +219,7 @@ class RecursiveModel < Grape::Entity 'operationId' => 'getThing' }, 'post' => { + 'summary' => 'This creates Thing.', 'description' => 'This creates Thing.', 'produces' => ['application/json'], 'consumes' => ['application/json'], @@ -231,6 +234,7 @@ class RecursiveModel < Grape::Entity }, '/thing/{id}' => { 'get' => { + 'summary' => 'This gets Thing.', 'description' => 'This gets Thing.', 'produces' => ['application/json'], 'parameters' => [{ 'in' => 'path', 'name' => 'id', 'type' => 'integer', 'format' => 'int32', 'required' => true }], @@ -239,6 +243,7 @@ class RecursiveModel < Grape::Entity 'operationId' => 'getThingId' }, 'put' => { + 'summary' => 'This updates Thing.', 'description' => 'This updates Thing.', 'produces' => ['application/json'], 'consumes' => ['application/json'], @@ -252,6 +257,7 @@ class RecursiveModel < Grape::Entity 'operationId' => 'putThingId' }, 'delete' => { + 'summary' => 'This deletes Thing.', 'description' => 'This deletes Thing.', 'produces' => ['application/json'], 'parameters' => [{ 'in' => 'path', 'name' => 'id', 'type' => 'integer', 'format' => 'int32', 'required' => true }], @@ -262,6 +268,7 @@ class RecursiveModel < Grape::Entity }, '/thing2' => { 'get' => { + 'summary' => 'This gets Things.', 'description' => 'This gets Things.', 'produces' => ['application/json'], 'responses' => { '200' => { 'description' => 'get Horses', 'schema' => { '$ref' => '#/definitions/Something' } }, '401' => { 'description' => 'HorsesOutError', 'schema' => { '$ref' => '#/definitions/ApiError' } } }, @@ -271,6 +278,7 @@ class RecursiveModel < Grape::Entity }, '/dummy/{id}' => { 'delete' => { + 'summary' => 'dummy route.', 'description' => 'dummy route.', 'produces' => ['application/json'], 'parameters' => [{ 'in' => 'path', 'name' => 'id', 'type' => 'integer', 'format' => 'int32', 'required' => true }], @@ -284,6 +292,7 @@ class RecursiveModel < Grape::Entity 'QueryInput' => { 'type' => 'object', 'properties' => { 'elements' => { 'type' => 'array', 'items' => { '$ref' => '#/definitions/QueryInputElement' }, 'description' => 'Set of configuration' } }, + 'summary' => 'nested route inside namespace', 'description' => 'nested route inside namespace' }, 'QueryInputElement' => { @@ -293,6 +302,7 @@ class RecursiveModel < Grape::Entity 'ApiError' => { 'type' => 'object', 'properties' => { 'code' => { 'type' => 'integer', 'format' => 'int32', 'description' => 'status code' }, 'message' => { 'type' => 'string', 'description' => 'error message' } }, + 'summary' => 'This gets Things.', 'description' => 'This gets Things.' }, 'Something' => { @@ -303,6 +313,7 @@ class RecursiveModel < Grape::Entity 'links' => { 'type' => 'link' }, 'others' => { 'type' => 'text' } }, + 'summary' => 'This gets Things.', 'description' => 'This gets Things.' } } diff --git a/spec/support/model_parsers/mock_parser.rb b/spec/support/model_parsers/mock_parser.rb index ff66cf39..3d5f4ad0 100644 --- a/spec/support/model_parsers/mock_parser.rb +++ b/spec/support/model_parsers/mock_parser.rb @@ -184,6 +184,7 @@ class RecursiveModel < OpenStruct; end 'paths' => { '/v3/other_thing/{elements}' => { 'get' => { + 'summary' => 'nested route inside namespace', 'description' => 'nested route inside namespace', 'produces' => ['application/json'], 'parameters' => [{ 'in' => 'body', 'name' => 'elements', 'description' => 'Set of configuration', 'type' => 'array', 'items' => { 'type' => 'string' }, 'required' => true }], @@ -196,6 +197,7 @@ class RecursiveModel < OpenStruct; end }, '/thing' => { 'get' => { + 'summary' => 'This gets Things.', 'description' => 'This gets Things.', 'produces' => ['application/json'], 'parameters' => [ @@ -209,6 +211,7 @@ class RecursiveModel < OpenStruct; end 'operationId' => 'getThing' }, 'post' => { + 'summary' => 'This creates Thing.', 'description' => 'This creates Thing.', 'produces' => ['application/json'], 'consumes' => ['application/json'], @@ -223,6 +226,7 @@ class RecursiveModel < OpenStruct; end }, '/thing/{id}' => { 'get' => { + 'summary' => 'This gets Thing.', 'description' => 'This gets Thing.', 'produces' => ['application/json'], 'parameters' => [{ 'in' => 'path', 'name' => 'id', 'type' => 'integer', 'format' => 'int32', 'required' => true }], @@ -231,6 +235,7 @@ class RecursiveModel < OpenStruct; end 'operationId' => 'getThingId' }, 'put' => { + 'summary' => 'This updates Thing.', 'description' => 'This updates Thing.', 'produces' => ['application/json'], 'consumes' => ['application/json'], @@ -244,6 +249,7 @@ class RecursiveModel < OpenStruct; end 'operationId' => 'putThingId' }, 'delete' => { + 'summary' => 'This deletes Thing.', 'description' => 'This deletes Thing.', 'produces' => ['application/json'], 'parameters' => [{ 'in' => 'path', 'name' => 'id', 'type' => 'integer', 'format' => 'int32', 'required' => true }], @@ -254,6 +260,7 @@ class RecursiveModel < OpenStruct; end }, '/thing2' => { 'get' => { + 'summary' => 'This gets Things.', 'description' => 'This gets Things.', 'produces' => ['application/json'], 'responses' => { '200' => { 'description' => 'get Horses', 'schema' => { '$ref' => '#/definitions/Something' } }, '401' => { 'description' => 'HorsesOutError', 'schema' => { '$ref' => '#/definitions/ApiError' } } }, @@ -263,6 +270,7 @@ class RecursiveModel < OpenStruct; end }, '/dummy/{id}' => { 'delete' => { + 'summary' => 'dummy route.', 'description' => 'dummy route.', 'produces' => ['application/json'], 'parameters' => [{ 'in' => 'path', 'name' => 'id', 'type' => 'integer', 'format' => 'int32', 'required' => true }], diff --git a/spec/support/model_parsers/representable_parser.rb b/spec/support/model_parsers/representable_parser.rb index 1337c2a4..955abc53 100644 --- a/spec/support/model_parsers/representable_parser.rb +++ b/spec/support/model_parsers/representable_parser.rb @@ -261,6 +261,7 @@ class RecursiveModel < Representable::Decorator 'paths' => { '/v3/other_thing/{elements}' => { 'get' => { + 'summary' => 'nested route inside namespace', 'description' => 'nested route inside namespace', 'produces' => ['application/json'], 'parameters' => [{ 'in' => 'body', 'name' => 'elements', 'description' => 'Set of configuration', 'type' => 'array', 'items' => { 'type' => 'string' }, 'required' => true }], @@ -273,6 +274,7 @@ class RecursiveModel < Representable::Decorator }, '/thing' => { 'get' => { + 'summary' => 'This gets Things.', 'description' => 'This gets Things.', 'produces' => ['application/json'], 'parameters' => [ @@ -286,6 +288,7 @@ class RecursiveModel < Representable::Decorator 'operationId' => 'getThing' }, 'post' => { + 'summary' => 'This creates Thing.', 'description' => 'This creates Thing.', 'produces' => ['application/json'], 'consumes' => ['application/json'], @@ -300,6 +303,7 @@ class RecursiveModel < Representable::Decorator }, '/thing/{id}' => { 'get' => { + 'summary' => 'This gets Thing.', 'description' => 'This gets Thing.', 'produces' => ['application/json'], 'parameters' => [{ 'in' => 'path', 'name' => 'id', 'type' => 'integer', 'format' => 'int32', 'required' => true }], @@ -308,6 +312,7 @@ class RecursiveModel < Representable::Decorator 'operationId' => 'getThingId' }, 'put' => { + 'summary' => 'This updates Thing.', 'description' => 'This updates Thing.', 'produces' => ['application/json'], 'consumes' => ['application/json'], @@ -321,6 +326,7 @@ class RecursiveModel < Representable::Decorator 'operationId' => 'putThingId' }, 'delete' => { + 'summary' => 'This deletes Thing.', 'description' => 'This deletes Thing.', 'produces' => ['application/json'], 'parameters' => [{ 'in' => 'path', 'name' => 'id', 'type' => 'integer', 'format' => 'int32', 'required' => true }], @@ -331,6 +337,7 @@ class RecursiveModel < Representable::Decorator }, '/thing2' => { 'get' => { + 'summary' => 'This gets Things.', 'description' => 'This gets Things.', 'produces' => ['application/json'], 'responses' => { '200' => { 'description' => 'get Horses', 'schema' => { '$ref' => '#/definitions/Something' } }, '401' => { 'description' => 'HorsesOutError', 'schema' => { '$ref' => '#/definitions/ApiError' } } }, @@ -340,6 +347,7 @@ class RecursiveModel < Representable::Decorator }, '/dummy/{id}' => { 'delete' => { + 'summary' => 'dummy route.', 'description' => 'dummy route.', 'produces' => ['application/json'], 'parameters' => [{ 'in' => 'path', 'name' => 'id', 'type' => 'integer', 'format' => 'int32', 'required' => true }], @@ -353,6 +361,7 @@ class RecursiveModel < Representable::Decorator 'QueryInput' => { 'type' => 'object', 'properties' => { 'elements' => { 'type' => 'array', 'items' => { '$ref' => '#/definitions/QueryInputElement' }, 'description' => 'Set of configuration' } }, + 'summary' => 'nested route inside namespace', 'description' => 'nested route inside namespace' }, 'QueryInputElement' => { @@ -362,6 +371,7 @@ class RecursiveModel < Representable::Decorator 'ApiError' => { 'type' => 'object', 'properties' => { 'code' => { 'type' => 'integer', 'format' => 'int32', 'description' => 'status code' }, 'message' => { 'type' => 'string', 'description' => 'error message' } }, + 'summary' => 'This gets Things.', 'description' => 'This gets Things.' }, 'Something' => { @@ -372,6 +382,7 @@ class RecursiveModel < Representable::Decorator 'links' => { 'type' => 'array', 'items' => { 'description' => '', 'type' => 'link' } }, 'others' => { 'description' => '', 'type' => 'text' } }, + 'summary' => 'This gets Things.', 'description' => 'This gets Things.' } } diff --git a/spec/swagger_v2/api_swagger_v2_response_spec.rb b/spec/swagger_v2/api_swagger_v2_response_spec.rb index 1ab1a259..03543ef7 100644 --- a/spec/swagger_v2/api_swagger_v2_response_spec.rb +++ b/spec/swagger_v2/api_swagger_v2_response_spec.rb @@ -45,6 +45,7 @@ def app end specify do expect(subject['paths']['/nested_type']['get']).to eql( + 'summary' => 'This returns something', 'description' => 'This returns something', 'produces' => ['application/json'], 'responses' => { @@ -66,6 +67,7 @@ def app specify do expect(subject['paths']['/entity_response']['get']).to eql( + 'summary' => 'This returns something', 'description' => 'This returns something', 'produces' => ['application/json'], 'responses' => { @@ -87,6 +89,7 @@ def app specify do expect(subject['paths']['/params_response']['post']).to eql( + 'summary' => 'This returns something', 'description' => 'This returns something', 'produces' => ['application/json'], 'consumes' => ['application/json'], diff --git a/spec/swagger_v2/default_api_spec.rb b/spec/swagger_v2/default_api_spec.rb index 0fa4e67f..2e61bf0e 100644 --- a/spec/swagger_v2/default_api_spec.rb +++ b/spec/swagger_v2/default_api_spec.rb @@ -29,6 +29,7 @@ def app 'paths' => { '/something' => { 'get' => { + 'summary' => 'This gets something.', 'description' => 'This gets something.', 'produces' => ['application/json'], 'tags' => ['something'], @@ -75,6 +76,7 @@ def app 'paths' => { '/something' => { 'get' => { + 'summary' => 'This gets something.', 'description' => 'This gets something.', 'produces' => ['application/json'], 'tags' => ['something'], diff --git a/spec/swagger_v2/hide_api_spec.rb b/spec/swagger_v2/hide_api_spec.rb index f1215745..6757cc19 100644 --- a/spec/swagger_v2/hide_api_spec.rb +++ b/spec/swagger_v2/hide_api_spec.rb @@ -44,6 +44,7 @@ def app 'paths' => { '/simple' => { 'get' => { + 'summary' => 'Show this endpoint', 'description' => 'Show this endpoint', 'produces' => ['application/json'], 'tags' => ['simple'], @@ -53,6 +54,7 @@ def app }, '/lazy' => { 'get' => { + 'summary' => 'Lazily show endpoint', 'description' => 'Lazily show endpoint', 'produces' => ['application/json'], 'tags' => ['lazy'], @@ -105,6 +107,7 @@ def app 'paths' => { '/simple/show' => { 'get' => { + 'summary' => 'Show this endpoint', 'description' => 'Show this endpoint', 'produces' => ['application/json'], 'operationId' => 'getSimpleShow', @@ -126,6 +129,7 @@ def app 'paths' => { '/simple/show' => { 'get' => { + 'summary' => 'Show this endpoint', 'description' => 'Show this endpoint', 'produces' => ['application/json'], 'tags' => ['simple'], diff --git a/spec/swagger_v2/mounted_target_class_spec.rb b/spec/swagger_v2/mounted_target_class_spec.rb index 69d29e20..8ea22af3 100644 --- a/spec/swagger_v2/mounted_target_class_spec.rb +++ b/spec/swagger_v2/mounted_target_class_spec.rb @@ -37,6 +37,7 @@ def app 'paths' => { '/simple' => { 'get' => { + 'summary' => 'This gets something.', 'description' => 'This gets something.', 'produces' => ['application/json'], 'responses' => { '200' => { 'description' => 'This gets something.' } }, @@ -59,6 +60,7 @@ def app 'paths' => { '/simple' => { 'get' => { + 'summary' => 'This gets something.', 'description' => 'This gets something.', 'produces' => ['application/json'], 'responses' => { diff --git a/spec/swagger_v2/simple_mounted_api_spec.rb b/spec/swagger_v2/simple_mounted_api_spec.rb index 5065b8c7..0baa8608 100644 --- a/spec/swagger_v2/simple_mounted_api_spec.rb +++ b/spec/swagger_v2/simple_mounted_api_spec.rb @@ -100,6 +100,7 @@ def app 'paths' => { '/simple' => { 'get' => { + 'summary' => 'This gets something.', 'description' => 'This gets something.', 'produces' => ['application/json'], 'tags' => ['simple'], @@ -109,6 +110,7 @@ def app }, '/simple-test' => { 'get' => { + 'summary' => 'This gets something for URL using - separator.', 'description' => 'This gets something for URL using - separator.', 'produces' => ['application/json'], 'tags' => ['simple-test'], @@ -134,6 +136,7 @@ def app }, '/simple_with_headers' => { 'get' => { + 'summary' => 'this gets something else', 'description' => 'this gets something else', 'produces' => ['application/json'], 'parameters' => [ @@ -151,6 +154,7 @@ def app }, '/items' => { 'post' => { + 'summary' => 'this takes an array of parameters', 'description' => 'this takes an array of parameters', 'produces' => ['application/json'], 'consumes' => ['application/json'], @@ -162,6 +166,7 @@ def app }, '/custom' => { 'get' => { + 'summary' => 'this uses a custom parameter', 'description' => 'this uses a custom parameter', 'produces' => ['application/json'], 'parameters' => [{ 'in' => 'formData', 'name' => 'custom', 'description' => 'array of items', 'required' => false, 'type' => 'array', 'items' => { 'type' => 'CustomType' } }], @@ -199,6 +204,7 @@ def app 'paths' => { '/simple' => { 'get' => { + 'summary' => 'This gets something.', 'description' => 'This gets something.', 'produces' => ['application/json'], 'tags' => ['simple'], @@ -236,6 +242,7 @@ def app 'paths' => { '/simple-test' => { 'get' => { + 'summary' => 'This gets something for URL using - separator.', 'description' => 'This gets something for URL using - separator.', 'produces' => ['application/json'], 'tags' => ['simple-test'], @@ -258,6 +265,7 @@ def app expect(subject['paths']).to eq( '/simple_with_headers' => { 'get' => { + 'summary' => 'this gets something else', 'description' => 'this gets something else', 'produces' => ['application/json'], 'parameters' => [ @@ -287,6 +295,7 @@ def app expect(subject['paths']).to eq( '/items' => { 'post' => { + 'summary' => 'this takes an array of parameters', 'description' => 'this takes an array of parameters', 'produces' => ['application/json'], 'consumes' => ['application/json'], @@ -310,6 +319,7 @@ def app expect(subject['paths']).to eq( '/custom' => { 'get' => { + 'summary' => 'this uses a custom parameter', 'description' => 'this uses a custom parameter', 'produces' => ['application/json'], 'parameters' => [{ 'in' => 'formData', 'name' => 'custom', 'description' => 'array of items', 'required' => false, 'type' => 'array', 'items' => { 'type' => 'CustomType' } }],