Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
* [#1011](https://github.com/ruby-grape/grape-swagger/pull/1011): Preserve string length, array item and object property limits in body parameter definitions, and emit `minLength`/`maxLength` only for strings (`minProperties`/`maxProperties` for hashes) instead of any non-array type - [@numbata](https://github.com/numbata).
* [#1009](https://github.com/ruby-grape/grape-swagger/pull/1009): Bump the Danger `danger-comment.yml` workflow from 0.1.0 to 0.1.1 - [@dependabot[bot]](https://github.com/dependabot%5Bbot%5D).
* [#1008](https://github.com/ruby-grape/grape-swagger/pull/1008): Bump the Danger `danger-run.yml` workflow from 0.1.0 to 0.1.1 - [@dependabot[bot]](https://github.com/dependabot%5Bbot%5D).
* [#990](https://github.com/ruby-grape/grape-swagger/pull/990): Honor the documented `desc ..., default:` spelling for a default response (alongside `default_response:`), and stop reading `route.desc` (`get '/', desc:` is no longer a swagger summary). See [UPGRADING](UPGRADING.md) - [@numbata](https://github.com/numbata).
* [#986](https://github.com/ruby-grape/grape-swagger/pull/986): Read a route's tags through `route.tags` instead of `route.options`; a blank `tags:` (`nil` or `[]`) now means "not specified" and derives the tag from the path. See [UPGRADING](UPGRADING.md) - [@ericproulx](https://github.com/ericproulx).
* [#988](https://github.com/ruby-grape/grape-swagger/pull/988): Fix CI by replacing single-statement `rubocop:disable`/`enable` pairs with `rubocop:disable-next`, per rubocop 1.90's new `Style/DirectiveScope` cop - [@numbata](https://github.com/numbata).
* [#992](https://github.com/ruby-grape/grape-swagger/pull/992): Fix CI by pinning `json` to `< 3.0` in the Gemfile; `json` 3.0 dropped support for the `quirks_mode:` keyword that `multi_json`'s adapter still passes by default, breaking JSON request parsing wherever Grape resolves `Grape::Json` to `MultiJson` - [@numbata](https://github.com/numbata).
Expand Down
8 changes: 4 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -1123,13 +1123,13 @@ end

#### Default response <a name="default-response"></a>

By setting the `default` option you can also define a default response that is the result returned for all unspecified status codes.
The definition supports the same syntax as `success` or `failure`.
By setting the `default_response` option you can also define a default response that is the result returned for all unspecified status codes.
The definition supports the same syntax as `success` or `failure`. Prefer `default_response:`; `default:` is still read until grape-swagger 3.0.

In the following cases, the schema ref would be taken from route.

```ruby
desc 'thing', default: { message: 'the default response' }
desc 'thing', default_response: { message: 'the default response' }
get '/thing' do
# ...
end
Expand All @@ -1147,7 +1147,7 @@ Just like with `success` or `failure` you can also provide a `model` parameter.

```ruby
desc 'Get a list of stuff',
default: { model: Entities::UseResponse, message: 'the default response' }
default_response: { model: Entities::UseResponse, message: 'the default response' }
get do
# your code comes here
end
Expand Down
2 changes: 2 additions & 0 deletions UPGRADING.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@

### Upgrading to >= 2.3.0

- **`desc(..., default_response:)` is the supported spelling for a default response.** The README previously documented `default:`, but grape-swagger only ever read `default_response:`, so the documented form was a silent no-op. 2.3 reads both. Prefer `default_response:`; `default:` remains until grape-swagger 3.0. (Grape itself is also renaming that key; see [ruby-grape/grape#2862](https://github.com/ruby-grape/grape/pull/2862).)
- **`get '/', desc: '…'` no longer sets the swagger `summary`.** That option is a passthrough onto the route, not Grape's `desc` DSL (which stores `:description`). Use `desc '…'` for the operation description, or `desc '…', summary: '…'` for a summary.
- **A blank `desc(..., tags:)` now means "not specified".** `tags: nil` no longer suppresses the tag and `tags: []` no longer emits an empty `"tags": []`; both derive the tag from the path, as if `tags:` had been omitted. `tags:` is an override, and only a non-empty list overrides anything.

The old `nil` behaviour was never a deliberate one: [#523](https://github.com/ruby-grape/grape-swagger/pull/523) introduced route-level tags to *override* path-derived grouping and read them with `route.options.fetch(:tags, tag_object(route))`, whose default-on-absence semantics happened to give `nil` a meaning of its own. It was never documented or tested.
Expand Down
6 changes: 4 additions & 2 deletions lib/grape-swagger/endpoint.rb
Original file line number Diff line number Diff line change
Expand Up @@ -140,7 +140,6 @@ def security_object(route)
end

def summary_object(route)
summary = route.desc if route.desc
summary = route.description if route.description.present? && route.detail
summary = route.summary if route.summary

Expand Down Expand Up @@ -267,7 +266,10 @@ def tag_object(route, path)
private

def default_code_from_route(route)
entity = route.default_response
# `route.default` is OrderedOptions / Hash#default, not the desc key. Grape < 4 keeps
# `desc ..., default:` under settings[:description][:default] instead of remapping it to
# `default_response`; drop this fallback with `default:` in grape-swagger 3.0.
entity = route.default_response || route.settings.dig(:description, :default)
return [] if entity.nil?

default_code = { code: 'default', message: 'Default Response' }
Expand Down
41 changes: 41 additions & 0 deletions spec/swagger_v2/api_swagger_v2_response_with_models_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -52,4 +52,45 @@ def app
expect(subject['definitions']).to eql(swagger_entity_as_response_object)
end
end

# The README spelling that grape-swagger used to ignore. Grape 2.x/3.x keep it as
# `:default`, which grape-swagger reads itself; Grape 4 remaps it onto `default_response:`
# and deprecates it, so there the example only covers Grape's remap.
describe 'uses the documented default: spelling' do
before :all do
module TheApi
class ResponseApiDefaultAlias < Grape::API
format :json

# Grape 4 emits its `default:` deprecation from `desc`.
Grape.deprecator.silence do
desc 'This returns something',
success: [{ code: 200 }],
default: { message: 'Error', model: Entities::ApiError }
end
Comment thread
numbata marked this conversation as resolved.
Resolved
get '/use-default' do
{ 'declared_params' => declared(params) }
end

add_swagger_documentation(models: [Entities::UseResponse])
end
end
end

def app
TheApi::ResponseApiDefaultAlias
end

subject do
get '/swagger_doc/use-default'
JSON.parse(last_response.body)
end

specify do
expect(subject['paths']['/use-default']['get']['responses']['default']).to eql(
'description' => 'Error',
'schema' => { '$ref' => '#/definitions/ApiError' }
)
end
end
end
56 changes: 41 additions & 15 deletions spec/swagger_v2/namespaced_api_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,8 @@
def app
Class.new(Grape::API) do
namespace :aspace do
get '/', desc: 'Description for aspace'
desc 'Description for aspace'
get '/'
end
add_swagger_documentation format: :json
end
Expand All @@ -18,16 +19,17 @@ def app
JSON.parse(last_response.body)['paths']['/aspace']['get']
end

it 'shows the namespace summary in the json spec' do
expect(subject['summary']).to eql('Description for aspace')
it 'shows the namespace description in the json spec' do
expect(subject['description']).to eql('Description for aspace')
end
end

context 'with camel case namespace' do
def app
Class.new(Grape::API) do
namespace :camelCases do
get '/', desc: 'Look! An endpoint.'
desc 'Look! An endpoint.'
get '/'
end
add_swagger_documentation format: :json
end
Expand All @@ -38,16 +40,17 @@ def app
JSON.parse(last_response.body)['paths']['/camelCases']['get']
end

it 'shows the namespace summary in the json spec' do
expect(subject['summary']).to eql('Look! An endpoint.')
it 'shows the namespace description in the json spec' do
expect(subject['description']).to eql('Look! An endpoint.')
end
end

context 'mounted' do
def app
namespaced_api = Class.new(Grape::API) do
namespace :bspace do
get '/', desc: 'Description for aspace'
desc 'Description for aspace'
get '/'
end
end

Expand All @@ -62,16 +65,17 @@ def app
JSON.parse(last_response.body)['paths']['/bspace']['get']
end

it 'shows the namespace summary in the json spec' do
expect(subject['summary']).to eql('Description for aspace')
it 'shows the namespace description in the json spec' do
expect(subject['description']).to eql('Description for aspace')
end
end

context 'mounted under a route' do
def app
namespaced_api = Class.new(Grape::API) do
namespace :bspace do
get '/', desc: 'Description for aspace'
desc 'Description for aspace'
get '/'
end
end

Expand All @@ -86,16 +90,17 @@ def app
JSON.parse(last_response.body)['paths']['/mounted/bspace']['get']
end

it 'shows the namespace summary in the json spec' do
expect(subject['summary']).to eql('Description for aspace')
it 'shows the namespace description in the json spec' do
expect(subject['description']).to eql('Description for aspace')
end
end

context 'arbitrary mounting' do
def app
inner_namespaced_api = Class.new(Grape::API) do
namespace :bspace do
get '/', desc: 'Description for aspace'
desc 'Description for aspace'
get '/'
end
end

Expand All @@ -114,8 +119,29 @@ def app
JSON.parse(last_response.body)['paths']['/mounted/bspace']['get']
end

it 'shows the namespace summary in the json spec' do
expect(subject['summary']).to eql('Description for aspace')
it 'shows the namespace description in the json spec' do
expect(subject['description']).to eql('Description for aspace')
end
end

context 'get with desc: option' do
def app
Class.new(Grape::API) do
namespace :aspace do
get '/', desc: 'passthrough, not the desc DSL'
end
add_swagger_documentation format: :json
end
end

subject do
get '/swagger_doc'
JSON.parse(last_response.body)['paths']['/aspace']['get']
end

it 'does not treat get desc: as a swagger summary or description' do
expect(subject).not_to include('summary')
expect(subject).not_to include('description')
end
end
end
Loading