From 4d675056c18acd197fb5609ca39af08b8652ea17 Mon Sep 17 00:00:00 2001 From: richie Date: Thu, 13 Oct 2016 18:17:19 -0700 Subject: [PATCH] Support parameters provided at the 'path' level --- .../lib/rswag/specs/example_group_helpers.rb | 10 ++++++++-- rswag-specs/lib/rswag/specs/request_factory.rb | 8 +++++++- rswag-specs/lib/rswag/specs/swagger_formatter.rb | 14 +++++++------- .../rswag/specs/example_group_helpers_spec.rb | 16 ++++++++++++++-- .../spec/rswag/specs/request_factory_spec.rb | 11 +++++++++++ test-app/spec/integration/blogs_spec.rb | 3 ++- test-app/swagger/v1/swagger.json | 16 ++++++++-------- 7 files changed, 57 insertions(+), 21 deletions(-) diff --git a/rswag-specs/lib/rswag/specs/example_group_helpers.rb b/rswag-specs/lib/rswag/specs/example_group_helpers.rb index 79c67ab..3024b15 100644 --- a/rswag-specs/lib/rswag/specs/example_group_helpers.rb +++ b/rswag-specs/lib/rswag/specs/example_group_helpers.rb @@ -37,8 +37,14 @@ module Rswag def parameter(attributes) attributes[:required] = true if attributes[:in].to_sym == :path - metadata[:operation][:parameters] ||= [] - metadata[:operation][:parameters] << attributes + + if metadata.has_key?(:operation) + metadata[:operation][:parameters] ||= [] + metadata[:operation][:parameters] << attributes + else + metadata[:path_item][:parameters] ||= [] + metadata[:path_item][:parameters] << attributes + end end def response(code, description, &block) diff --git a/rswag-specs/lib/rswag/specs/request_factory.rb b/rswag-specs/lib/rswag/specs/request_factory.rb index fb15045..d1d6045 100644 --- a/rswag-specs/lib/rswag/specs/request_factory.rb +++ b/rswag-specs/lib/rswag/specs/request_factory.rb @@ -44,7 +44,13 @@ module Rswag private def parameters_in(location) - (@api_metadata[:operation][:parameters] || []) + path_item_params = @api_metadata[:path_item][:parameters] || [] + operation_params = @api_metadata[:operation][:parameters] || [] + applicable_params = operation_params + .concat(path_item_params) + .uniq { |p| p[:name] } # operation params should override path_item params + + applicable_params .map { |p| p['$ref'] ? resolve_parameter(p['$ref']) : p } # resolve any references .concat(resolve_api_key_parameters) .select { |p| p[:in] == location } diff --git a/rswag-specs/lib/rswag/specs/swagger_formatter.rb b/rswag-specs/lib/rswag/specs/swagger_formatter.rb index 9d941dc..794a9d9 100644 --- a/rswag-specs/lib/rswag/specs/swagger_formatter.rb +++ b/rswag-specs/lib/rswag/specs/swagger_formatter.rb @@ -49,18 +49,18 @@ module Rswag def metadata_to_swagger(metadata) response_code = metadata[:response][:code] response = metadata[:response].reject { |k,v| k == :code } + verb = metadata[:operation][:verb] operation = metadata[:operation] .reject { |k,v| k == :verb } .merge(responses: { response_code => response }) - { - paths: { - metadata[:path_item][:template] => { - verb => operation - } - } - } + path_template = metadata[:path_item][:template] + path_item = metadata[:path_item] + .reject { |k,v| k == :template } + .merge(verb => operation) + + { paths: { path_template => path_item } } end end end diff --git a/rswag-specs/spec/rswag/specs/example_group_helpers_spec.rb b/rswag-specs/spec/rswag/specs/example_group_helpers_spec.rb index d5ce7d7..76c3278 100644 --- a/rswag-specs/spec/rswag/specs/example_group_helpers_spec.rb +++ b/rswag-specs/spec/rswag/specs/example_group_helpers_spec.rb @@ -87,10 +87,21 @@ module Rswag end describe '#parameter(attributes)' do - let(:api_metadata) { { operation: {} } } - context 'always' do + context "when called at the 'path' level" do before { subject.parameter(name: :blog, in: :body, schema: { type: 'object' }) } + let(:api_metadata) { { path_item: {} } } # i.e. operation not defined yet + + it "adds to the 'path_item parameters' metadata" do + expect(api_metadata[:path_item][:parameters]).to match( + [ name: :blog, in: :body, schema: { type: 'object' } ] + ) + end + end + + context "when called at the 'operation' level" do + before { subject.parameter(name: :blog, in: :body, schema: { type: 'object' }) } + let(:api_metadata) { { path_item: {}, operation: {} } } # i.e. operation defined it "adds to the 'operation parameters' metadata" do expect(api_metadata[:operation][:parameters]).to match( @@ -101,6 +112,7 @@ module Rswag context "'path' parameter" do before { subject.parameter(name: :id, in: :path) } + let(:api_metadata) { { operation: {} } } it "automatically sets the 'required' flag" do expect(api_metadata[:operation][:parameters]).to match( diff --git a/rswag-specs/spec/rswag/specs/request_factory_spec.rb b/rswag-specs/spec/rswag/specs/request_factory_spec.rb index 98556c6..6a5d92a 100644 --- a/rswag-specs/spec/rswag/specs/request_factory_spec.rb +++ b/rswag-specs/spec/rswag/specs/request_factory_spec.rb @@ -125,6 +125,17 @@ module Rswag expect(path).to eq('/foobar/blogs/1/comments/2') end end + + context "defined at the 'path' level" do + before do + api_metadata[:path_item][:parameters] = [ { name: :blog_id, in: :path } ] + api_metadata[:operation][:parameters] = [ { name: :id, in: :path } ] + end + + it "builds path from parameters defined at path and operation levels" do + expect(path).to eq('/blogs/1/comments/2') + end + end end describe '#build_body(example)' do diff --git a/test-app/spec/integration/blogs_spec.rb b/test-app/spec/integration/blogs_spec.rb index 8d5aa41..15fe8a9 100644 --- a/test-app/spec/integration/blogs_spec.rb +++ b/test-app/spec/integration/blogs_spec.rb @@ -41,12 +41,13 @@ describe 'Blogs API', type: :request, swagger_doc: 'v1/swagger.json' do end path '/blogs/{id}' do + parameter name: :id, :in => :path, :type => :string + get 'Retrieves a blog' do tags 'Blogs' description 'Retrieves a specific blog by id' operationId 'getBlog' produces 'application/json' - parameter name: :id, :in => :path, :type => :string response '200', 'blog found' do schema '$ref' => '#/definitions/blog' diff --git a/test-app/swagger/v1/swagger.json b/test-app/swagger/v1/swagger.json index 820a0c3..3b135ff 100644 --- a/test-app/swagger/v1/swagger.json +++ b/test-app/swagger/v1/swagger.json @@ -68,6 +68,14 @@ } }, "/blogs/{id}": { + "parameters": [ + { + "name": "id", + "in": "path", + "type": "string", + "required": true + } + ], "get": { "summary": "Retrieves a blog", "tags": [ @@ -78,14 +86,6 @@ "produces": [ "application/json" ], - "parameters": [ - { - "name": "id", - "in": "path", - "type": "string", - "required": true - } - ], "responses": { "200": { "description": "blog found",