Skip to content

Include documented Hashes #454

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 7 commits into from
Jun 14, 2016
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
9 changes: 6 additions & 3 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,17 @@
#### Features

* [#448](https://github.com/ruby-grape/grape-swagger/pull/448): Header parameters are now prepended to the parameter list - [@anakinj](https://github.com/anakinj).
* [#444](https://github.com/ruby-grape/grape-swagger/pull/444): With multi types parameter the first type is use as the documentation type [@scauglog](https://github.com/scauglog)
* [#444](https://github.com/ruby-grape/grape-swagger/pull/444): With multi types parameter the first type is use as the documentation type [@scauglog](https://github.com/scauglog).
* Your contribution here.

#### Fixes

* [#450](https://github.com/ruby-grape/grape-swagger/pull/438): Do not add :description to definitions if :description is missing on path - [@texpert](https://github.com/texpert).
* [#447](https://github.com/ruby-grape/grape-swagger/pull/447): Version part of the url is now ignored when generating tags for endpoint - [@anakinj](https://github.com/anakinj).
* [#444](https://github.com/ruby-grape/grape-swagger//pull/444): Default value provided in the documentation hash, override the grape default [@scauglog](https://github.com/scauglog)
* [#443](https://github.com/ruby-grape/grape-swagger/issues/443): Type provided in the documentation hash, override the grape type [@scauglog](https://github.com/scauglog)
* [#444](https://github.com/ruby-grape/grape-swagger//pull/444): Default value provided in the documentation hash, override the grape default [@scauglog](https://github.com/scauglog).
* [#443](https://github.com/ruby-grape/grape-swagger/issues/443): Type provided in the documentation hash, override the grape type [@scauglog](https://github.com/scauglog).
* [#454](https://github.com/ruby-grape/grape-swagger/pull/454): Include documented Hashes in documentation output - [@aschuster3](https://github.com/aschuster3).
* Your contribution here.

### 0.21.0 (June 1, 2016)

Expand Down
7 changes: 2 additions & 5 deletions lib/grape-swagger/doc_methods/move_params.rb
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,6 @@ def move_params_to_new(name, params)
end
end

properties[name][:readOnly] = true unless deletable?(param)
params.delete(param) if deletable?(param)

definition[:required] << name if deletable?(param) && param[:required]
Expand Down Expand Up @@ -144,13 +143,11 @@ def property_keys
end

def movable?(param)
return true if param[:in] == 'body' || param[:in] == 'path'
false
param[:in] == 'body'
end

def deletable?(param)
return true if movable?(param) && param[:in] == 'body'
false
param[:in] == 'body'
end

def should_move?(params)
Expand Down
2 changes: 1 addition & 1 deletion lib/grape-swagger/endpoint.rb
Original file line number Diff line number Diff line change
Expand Up @@ -231,7 +231,7 @@ def parse_request_params(required)
else
key = param.first
end
memo[key] = param.last unless param.last[:type] == 'Hash' || param.last[:type] == 'Array' && !param.last.key?(:documentation)
memo[key] = param.last unless (param.last[:type] == 'Hash' || param.last[:type] == 'Array') && !param.last.key?(:documentation)
end
end

Expand Down
2 changes: 1 addition & 1 deletion spec/lib/move_params_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -184,7 +184,7 @@
describe 'movable' do
describe 'path' do
let(:param) { { in: 'path', name: 'key', description: nil, type: 'integer', format: 'int32', required: true } }
it { expect(subject.send(:movable?, param)).to be true }
it { expect(subject.send(:movable?, param)).to be false }
end

describe 'body' do
Expand Down
8 changes: 7 additions & 1 deletion spec/support/model_parsers/entity_parser.rb
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,11 @@ class RecursiveModel < Grape::Entity
expose :name, documentation: { type: String, desc: 'The name.' }
expose :children, using: self, documentation: { type: 'RecursiveModel', is_array: true, desc: 'The child nodes.' }
end

class DocumentedHashAndArrayModel < Grape::Entity
expose :raw_hash, documentation: { type: Hash, desc: 'Example Hash.', documentation: { in: 'body' } }
expose :raw_array, documentation: { type: Array, desc: 'Example Array', documentation: { in: 'body' } }
end
end
end

Expand All @@ -124,7 +129,8 @@ class RecursiveModel < Grape::Entity
'ApiError' => { 'type' => 'object', 'properties' => { 'code' => { 'type' => 'integer', 'format' => 'int32', 'description' => 'status code' }, 'message' => { 'type' => 'string', 'description' => 'error message' } } },
'ResponseItem' => { 'type' => 'object', 'properties' => { 'id' => { 'type' => 'integer', 'format' => 'int32' }, 'name' => { 'type' => 'string' } } },
'UseResponse' => { 'type' => 'object', 'properties' => { 'description' => { 'type' => 'string' }, '$responses' => { 'type' => 'array', 'items' => { '$ref' => '#/definitions/ResponseItem' } } } },
'RecursiveModel' => { 'type' => 'object', 'properties' => { 'name' => { 'type' => 'string', 'description' => 'The name.' }, 'children' => { 'type' => 'array', 'items' => { '$ref' => '#/definitions/RecursiveModel' }, 'description' => 'The child nodes.' } } }
'RecursiveModel' => { 'type' => 'object', 'properties' => { 'name' => { 'type' => 'string', 'description' => 'The name.' }, 'children' => { 'type' => 'array', 'items' => { '$ref' => '#/definitions/RecursiveModel' }, 'description' => 'The child nodes.' } } },
'DocumentedHashAndArrayModel' => { 'type' => 'object', 'properties' => { 'raw_hash' => { 'type' => 'object', 'description' => 'Example Hash.' }, 'raw_array' => { 'type' => 'array', 'description' => 'Example Array' } } }
}
end

Expand Down
10 changes: 10 additions & 0 deletions spec/support/model_parsers/mock_parser.rb
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ class QueryInput < OpenStruct; end
class ApiError < OpenStruct; end
class SecondApiError < OpenStruct; end
class RecursiveModel < OpenStruct; end
class DocumentedHashAndArrayModel < OpenStruct; end
end
end

Expand Down Expand Up @@ -83,6 +84,15 @@ class RecursiveModel < OpenStruct; end
'description' => "it's a mock"
}
}
},
'DocumentedHashAndArrayModel' => {
'type' => 'object',
'properties' => {
'mock_data' => {
'type' => 'string',
'description' => "it's a mock"
}
}
}
}
end
Expand Down
7 changes: 7 additions & 0 deletions spec/support/model_parsers/representable_parser.rb
Original file line number Diff line number Diff line change
Expand Up @@ -186,6 +186,13 @@ class RecursiveModel < Representable::Decorator
property :name, documentation: { type: String, desc: 'The name.' }
property :children, decorator: self, documentation: { type: 'RecursiveModel', is_array: true, desc: 'The child nodes.' }
end

class DocumentedHashAndArrayModel < Representable::Decorator
include Representable::JSON

property :raw_hash, documentation: { type: Hash, desc: 'Example Hash.' }
property :raw_array, documentation: { type: Array, desc: 'Example Array' }
end
end
end

Expand Down
3 changes: 1 addition & 2 deletions spec/support/the_paths_definitions.rb
Original file line number Diff line number Diff line change
Expand Up @@ -97,8 +97,7 @@
properties: {
in_body_1: { type: 'integer', format: 'int32', description: 'in_body_1' },
in_body_2: { type: 'string', description: 'in_body_2' },
in_body_3: { type: 'string', description: 'in_body_3' },
key: { type: 'integer', format: 'int32', readOnly: true }
in_body_3: { type: 'string', description: 'in_body_3' }
},
required: [:in_body_1]
}
Expand Down
3 changes: 2 additions & 1 deletion spec/swagger_v2/api_swagger_v2_definitions-models_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,8 @@ class ModelApi < Grape::API
add_swagger_documentation models: [
::Entities::UseResponse,
::Entities::ApiError,
::Entities::RecursiveModel
::Entities::RecursiveModel,
::Entities::DocumentedHashAndArrayModel
]
end
end
Expand Down
60 changes: 60 additions & 0 deletions spec/swagger_v2/api_swagger_v2_hash_and_array_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
require 'spec_helper'

describe 'document hash and array' do
include_context "#{MODEL_PARSER} swagger example"

before :all do
module TheApi
class TestApi < Grape::API
format :json

documentation = ::Entities::DocumentedHashAndArrayModel.documentation if ::Entities::DocumentedHashAndArrayModel.respond_to?(:documentation)

desc 'This returns something'
namespace :arbitrary do
params do
requires :id, type: Integer
end
route_param :id do
desc 'Timeless treasure'
params do
requires :body, using: documentation unless documentation.nil?
requires :raw_hash, type: Hash, documentation: { param_type: 'body' } if documentation.nil?
requires :raw_array, type: Array, documentation: { param_type: 'body' } if documentation.nil?
end
put '/id_and_hash' do
{}
end
end
end

add_swagger_documentation
end
end
end

def app
TheApi::TestApi
end

subject do
get '/swagger_doc'
JSON.parse(last_response.body)
end
describe 'generated request definition' do
it 'has hash' do
expect(subject['definitions'].keys).to include('putArbitraryIdIdAndHash')
expect(subject['definitions']['putArbitraryIdIdAndHash']['properties'].keys).to include('raw_hash')
end

it 'has array' do
expect(subject['definitions'].keys).to include('putArbitraryIdIdAndHash')
expect(subject['definitions']['putArbitraryIdIdAndHash']['properties'].keys).to include('raw_array')
end

it 'does not have the path parameter' do
expect(subject['definitions'].keys).to include('putArbitraryIdIdAndHash')
expect(subject['definitions']['putArbitraryIdIdAndHash']).to_not include('id')
end
end
end
2 changes: 0 additions & 2 deletions spec/swagger_v2/api_swagger_v2_param_type_body_nested_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -137,7 +137,6 @@ def app
'type' => 'object',
'properties' => {
'address' => { '$ref' => '#/definitions/putRequestUseNestedWithAddressAddress' },
'id' => { 'type' => 'integer', 'format' => 'int32', 'readOnly' => true },
'name' => { 'type' => 'string', 'description' => 'name' }
}
)
Expand Down Expand Up @@ -176,7 +175,6 @@ def app
'properties' => {
'address' => { '$ref' => '#/definitions/putRequestUseNestedWithAddressAddress' },
'delivery_address' => { '$ref' => '#/definitions/putRequestUseNestedWithAddressDeliveryAddress' },
'id' => { 'type' => 'integer', 'format' => 'int32', 'readOnly' => true },
'name' => { 'type' => 'string', 'description' => 'name' }
}
)
Expand Down
2 changes: 0 additions & 2 deletions spec/swagger_v2/api_swagger_v2_param_type_body_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,6 @@ def app
'description' => 'put in body /wo entity',
'type' => 'object',
'properties' => {
'key' => { 'type' => 'integer', 'format' => 'int32', 'readOnly' => true },
'in_body_1' => { 'type' => 'integer', 'format' => 'int32', 'description' => 'in_body_1' },
'in_body_2' => { 'type' => 'string', 'description' => 'in_body_2' },
'in_body_3' => { 'type' => 'string', 'description' => 'in_body_3' }
Expand Down Expand Up @@ -152,7 +151,6 @@ def app
'description' => 'put in body with entity',
'type' => 'object',
'properties' => {
'id' => { 'type' => 'integer', 'format' => 'int32', 'readOnly' => true },
'name' => { 'type' => 'string', 'description' => 'name' }
}
)
Expand Down