diff --git a/CHANGELOG.md b/CHANGELOG.md index ee481d96..f9a58835 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,8 @@ #### Fixes +* [#580](https://github.com/ruby-grape/grape-swagger/pull/580): Issue #578: fixes duplicated path params - [@LeFnord](https://github.com/LeFnord). + * Your contribution here. ### 0.26.1 (February 3, 2014) diff --git a/lib/grape-swagger/endpoint.rb b/lib/grape-swagger/endpoint.rb index ab8578e1..1a99d872 100644 --- a/lib/grape-swagger/endpoint.rb +++ b/lib/grape-swagger/endpoint.rb @@ -237,21 +237,21 @@ def tag_object(route) def partition_params(route) declared_params = route.settings[:declared_params] if route.settings[:declared_params].present? - required, exposed = route.params.partition { |x| x.first.is_a? String } + required = merge_params(route) required = GrapeSwagger::DocMethods::Headers.parse(route) + required unless route.headers.nil? default_type(required) - default_type(exposed) request_params = unless declared_params.nil? && route.headers.nil? parse_request_params(required) end || {} - if route.params.present? && !route.settings[:declared_params].present? - request_params = route.params.merge(request_params) - end + request_params.empty? ? required : request_params + end - request_params + def merge_params(route) + param_keys = route.params.keys + route.params.delete_if { |key| key.is_a?(String) && param_keys.include?(key.to_sym) }.to_a end def default_type(params) diff --git a/spec/issues/532_allow_custom_format_spec.rb b/spec/issues/532_allow_custom_format_spec.rb index 9756809f..0a37e7ab 100644 --- a/spec/issues/532_allow_custom_format_spec.rb +++ b/spec/issues/532_allow_custom_format_spec.rb @@ -1,6 +1,6 @@ require 'spec_helper' -describe '#542 array of type in post params' do +describe '#532 allow custom format' do let(:app) do Class.new(Grape::API) do namespace :issue_532 do diff --git a/spec/issues/537_enum_values_spec.rb b/spec/issues/537_enum_values_spec.rb index 920c09e0..97227ca0 100644 --- a/spec/issues/537_enum_values_spec.rb +++ b/spec/issues/537_enum_values_spec.rb @@ -3,7 +3,7 @@ describe '#537 enum values spec' do let(:app) do Class.new(Grape::API) do - namespace :issue_539 do + namespace :issue_537 do class Spec < Grape::Entity expose :enum_property, documentation: { values: [:foo, :bar] } expose :enum_property_default, documentation: { values: %w(a b c), default: 'c' } diff --git a/spec/issues/579_align_put_post_parameters_spec.rb b/spec/issues/579_align_put_post_parameters_spec.rb new file mode 100644 index 00000000..ac519a7b --- /dev/null +++ b/spec/issues/579_align_put_post_parameters_spec.rb @@ -0,0 +1,177 @@ +require 'spec_helper' + +describe '#579 put / post parameters spec' do + let(:app) do + Class.new(Grape::API) do + namespace :issue_579 do + class BodySpec < Grape::Entity + expose :guid, documentation: { type: String, format: 'guid', in: 'body' } + expose :name, documentation: { type: String, in: 'body' } + expose :content, documentation: { type: String, in: 'body' } + end + + class Spec < Grape::Entity + expose :guid, documentation: { type: String, format: 'guid' } + expose :name, documentation: { type: String } + expose :content, documentation: { type: String } + end + + namespace :implicit do + namespace :body_parameter do + desc 'update spec', + success: BodySpec, + params: BodySpec.documentation + put ':guid' do + # your code goes here + end + end + + namespace :form_parameter do + desc 'update spec', + success: Spec, + params: Spec.documentation + put ':guid' do + # your code goes here + end + end + end + + namespace :explicit do + namespace :body_parameter do + desc 'update spec', + success: BodySpec, + params: BodySpec.documentation + params do + requires :guid + end + put ':guid' do + # your code goes here + end + end + + namespace :form_parameter do + desc 'update spec', + success: Spec, + params: Spec.documentation + params do + requires :guid + end + put ':guid' do + # your code goes here + end + end + end + + namespace :namespace_param do + route_param :guid do + namespace :body_parameter do + desc 'update spec', + success: BodySpec, + params: BodySpec.documentation + put do + # your code goes here + end + end + + namespace :form_parameter do + desc 'update spec', + success: Spec, + params: Spec.documentation + put do + # your code goes here + end + end + end + end + end + + add_swagger_documentation format: :json + end + end + + subject do + get '/swagger_doc' + JSON.parse(last_response.body) + end + + describe 'implicit path param given' do + let(:body_parameters) { subject['paths']['/issue_579/implicit/body_parameter/{guid}']['put']['parameters'] } + specify do + expect(body_parameters).to eql( + [ + { 'in' => 'path', 'name' => 'guid', 'type' => 'string', 'format' => 'guid', 'required' => true }, + { + 'name' => 'Issue579ImplicitBodyParameter', 'in' => 'body', 'required' => true, 'schema' => { + '$ref' => '#/definitions/putIssue579ImplicitBodyParameter' + } + } + ] + ) + end + + let(:form_parameters) { subject['paths']['/issue_579/implicit/form_parameter/{guid}']['put']['parameters'] } + specify do + expect(form_parameters).to eql( + [ + { 'in' => 'path', 'name' => 'guid', 'type' => 'string', 'format' => 'guid', 'required' => true }, + { 'in' => 'formData', 'name' => 'name', 'type' => 'string', 'required' => false }, + { 'in' => 'formData', 'name' => 'content', 'type' => 'string', 'required' => false } + ] + ) + end + end + + describe 'explicit path param given' do + let(:body_parameters) { subject['paths']['/issue_579/explicit/body_parameter/{guid}']['put']['parameters'] } + specify do + expect(body_parameters).to eql( + [ + { 'in' => 'path', 'name' => 'guid', 'type' => 'string', 'format' => 'guid', 'required' => true }, + { + 'name' => 'Issue579ExplicitBodyParameter', 'in' => 'body', 'required' => true, 'schema' => { + '$ref' => '#/definitions/putIssue579ExplicitBodyParameter' + } + } + ] + ) + end + + let(:form_parameters) { subject['paths']['/issue_579/explicit/form_parameter/{guid}']['put']['parameters'] } + specify do + expect(form_parameters).to eql( + [ + { 'in' => 'path', 'name' => 'guid', 'type' => 'string', 'format' => 'guid', 'required' => true }, + { 'in' => 'formData', 'name' => 'name', 'type' => 'string', 'required' => false }, + { 'in' => 'formData', 'name' => 'content', 'type' => 'string', 'required' => false } + ] + ) + end + end + + describe 'explicit as route param given' do + let(:body_parameters) { subject['paths']['/issue_579/namespace_param/{guid}/body_parameter']['put']['parameters'] } + specify do + expect(body_parameters).to eql( + [ + { 'in' => 'path', 'name' => 'guid', 'type' => 'string', 'format' => 'guid', 'required' => true }, + { + 'name' => 'Issue579NamespaceParamGuidBodyParameter', 'in' => 'body', 'required' => true, 'schema' => { + '$ref' => '#/definitions/putIssue579NamespaceParamGuidBodyParameter' + } + } + ] + ) + end + + let(:form_parameters) { subject['paths']['/issue_579/namespace_param/{guid}/form_parameter']['put']['parameters'] } + specify do + expect(form_parameters).to eql( + [ + { 'in' => 'path', 'name' => 'guid', 'type' => 'string', 'format' => 'guid', 'required' => true }, + { 'in' => 'formData', 'name' => 'name', 'type' => 'string', 'required' => false }, + { 'in' => 'formData', 'name' => 'content', 'type' => 'string', 'required' => false } + ] + ) + end + end +end