mirror of
https://github.com/ditkrg/rswag.git
synced 2026-01-25 07:16:40 +00:00
Merge branch 'master' into add-formData-support
This commit is contained in:
@@ -14,7 +14,7 @@ module Rswag
|
||||
api_metadata[:operation][:verb],
|
||||
factory.build_fullpath(self),
|
||||
factory.build_body(self),
|
||||
factory.build_headers(self)
|
||||
rackify_headers(factory.build_headers(self)) # Rails test infrastructure requires Rack headers
|
||||
)
|
||||
else
|
||||
send(
|
||||
@@ -36,6 +36,22 @@ module Rswag
|
||||
|
||||
private
|
||||
|
||||
def rackify_headers(headers)
|
||||
name_value_pairs = headers.map do |name, value|
|
||||
[
|
||||
case name
|
||||
when 'Accept' then 'HTTP_ACCEPT'
|
||||
when 'Content-Type' then 'CONTENT_TYPE'
|
||||
when 'Authorization' then 'HTTP_AUTHORIZATION'
|
||||
else name
|
||||
end,
|
||||
value
|
||||
]
|
||||
end
|
||||
|
||||
Hash[ name_value_pairs ]
|
||||
end
|
||||
|
||||
def rswag_config
|
||||
::Rswag::Specs.config
|
||||
end
|
||||
|
||||
@@ -2,18 +2,18 @@ require 'json-schema'
|
||||
|
||||
module Rswag
|
||||
module Specs
|
||||
class ExtendedSchema < JSON::Schema::Validator
|
||||
|
||||
class ExtendedSchema < JSON::Schema::Draft4
|
||||
|
||||
def initialize
|
||||
super
|
||||
extend_schema_definition("http://json-schema.org/draft-04/schema#")
|
||||
@attributes['type'] = ExtendedTypeAttribute
|
||||
@uri = URI.parse('http://tempuri.org/rswag/specs/extended_schema')
|
||||
@names = ['http://tempuri.org/rswag/specs/extended_schema']
|
||||
end
|
||||
end
|
||||
|
||||
class ExtendedTypeAttribute < JSON::Schema::TypeV4Attribute
|
||||
|
||||
|
||||
def self.validate(current_schema, data, fragments, processor, validator, options={})
|
||||
return if data.nil? && current_schema.schema['x-nullable'] == true
|
||||
super
|
||||
|
||||
@@ -33,13 +33,20 @@ module Rswag
|
||||
end
|
||||
|
||||
def build_headers(example)
|
||||
headers = Hash[ parameters_in(:header).map { |p| [ p[:name], example.send(p[:name]).to_s ] } ]
|
||||
headers.tap do |h|
|
||||
produces = @api_metadata[:operation][:produces] || @global_metadata[:produces]
|
||||
consumes = @api_metadata[:operation][:consumes] || @global_metadata[:consumes]
|
||||
h['ACCEPT'] = produces.join(';') unless produces.nil?
|
||||
h['CONTENT_TYPE'] = consumes.join(';') unless consumes.nil?
|
||||
name_value_pairs = parameters_in(:header).map do |param|
|
||||
[
|
||||
param[:name],
|
||||
example.send(param[:name]).to_s
|
||||
]
|
||||
end
|
||||
|
||||
# Add MIME type headers based on produces/consumes metadata
|
||||
produces = @api_metadata[:operation][:produces] || @global_metadata[:produces]
|
||||
consumes = @api_metadata[:operation][:consumes] || @global_metadata[:consumes]
|
||||
name_value_pairs << [ 'Accept', produces.join(';') ] unless produces.nil?
|
||||
name_value_pairs << [ 'Content-Type', consumes.join(';') ] unless consumes.nil?
|
||||
|
||||
Hash[ name_value_pairs ]
|
||||
end
|
||||
|
||||
private
|
||||
@@ -53,42 +60,48 @@ module Rswag
|
||||
|
||||
applicable_params
|
||||
.map { |p| p['$ref'] ? resolve_parameter(p['$ref']) : p } # resolve any references
|
||||
.concat(resolve_api_key_parameters)
|
||||
.concat(security_parameters)
|
||||
.select { |p| p[:in] == location }
|
||||
end
|
||||
|
||||
def resolve_parameter(ref)
|
||||
defined_params = @global_metadata[:parameters]
|
||||
defined_params = @global_metadata[:parameters]
|
||||
key = ref.sub('#/parameters/', '')
|
||||
raise "Referenced parameter '#{ref}' must be defined" unless defined_params && defined_params[key]
|
||||
defined_params[key]
|
||||
end
|
||||
|
||||
def resolve_api_key_parameters
|
||||
@api_key_params ||= begin
|
||||
# First figure out the security requirement applicable to the operation
|
||||
global_requirements = (@global_metadata[:security] || [] ).map { |r| r.keys.first }
|
||||
operation_requirements = (@api_metadata[:operation][:security] || [] ).map { |r| r.keys.first }
|
||||
requirements = global_requirements | operation_requirements
|
||||
|
||||
# Then obtain the scheme definitions for those requirements
|
||||
definitions = (@global_metadata[:securityDefinitions] || {}).slice(*requirements)
|
||||
definitions.values.select { |d| d[:type] == :apiKey }
|
||||
def security_parameters
|
||||
applicable_security_schemes.map do |scheme|
|
||||
if scheme[:type] == :apiKey
|
||||
{ name: scheme[:name], type: :string, in: scheme[:in] }
|
||||
else
|
||||
{ name: 'Authorization', type: :string, in: :header } # use auth header for basic & oauth2
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def applicable_security_schemes
|
||||
# First figure out the security requirement applicable to the operation
|
||||
requirements = @api_metadata[:operation][:security] || @global_metadata[:security]
|
||||
scheme_names = requirements ? requirements.map { |r| r.keys.first } : []
|
||||
|
||||
# Then obtain the scheme definitions for those requirements
|
||||
(@global_metadata[:securityDefinitions] || {}).slice(*scheme_names).values
|
||||
end
|
||||
|
||||
def build_query_string_part(param, value)
|
||||
return "#{param[:name]}=#{value.to_s}" unless param[:type].to_sym == :array
|
||||
|
||||
name = param[:name]
|
||||
case param[:collectionFormat]
|
||||
when :ssv
|
||||
when :ssv
|
||||
"#{name}=#{value.join(' ')}"
|
||||
when :tsv
|
||||
when :tsv
|
||||
"#{name}=#{value.join('\t')}"
|
||||
when :pipes
|
||||
when :pipes
|
||||
"#{name}=#{value.join('|')}"
|
||||
when :multi
|
||||
when :multi
|
||||
value.map { |v| "#{name}=#{v}" }.join('&')
|
||||
else
|
||||
"#{name}=#{value.join(',')}" # csv is default
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
module Rswag
|
||||
module Specs
|
||||
VERSION = '1.2.0'
|
||||
VERSION = '1.3.0'
|
||||
end
|
||||
end
|
||||
|
||||
@@ -16,8 +16,7 @@ Gem::Specification.new do |s|
|
||||
|
||||
s.files = Dir["{lib}/**/*"] + ["MIT-LICENSE", "Rakefile" ]
|
||||
|
||||
s.add_dependency "rails", ">= 3.1", "< 5.1"
|
||||
s.add_dependency 'json', '~> 1.8'
|
||||
s.add_dependency 'activesupport', '>= 3.1'
|
||||
s.add_dependency 'railties', '>= 3.1'
|
||||
s.add_dependency 'json-schema', '~> 2.2'
|
||||
s.add_dependency 'rspec-rails', '>= 2.14', '< 4'
|
||||
end
|
||||
|
||||
@@ -218,6 +218,33 @@ module Rswag
|
||||
end
|
||||
end
|
||||
|
||||
context "global definition for 'basic auth'" do
|
||||
before do
|
||||
global_metadata[:securityDefinitions] = { basic_auth: { type: :basic} }
|
||||
allow(example).to receive(:'Authorization').and_return('Basic foobar')
|
||||
end
|
||||
|
||||
context 'global requirement' do
|
||||
before { global_metadata[:security] = [ { basic_auth: [] } ] }
|
||||
|
||||
it "includes a corresponding Authorization header" do
|
||||
expect(headers).to match(
|
||||
'Authorization' => 'Basic foobar'
|
||||
)
|
||||
end
|
||||
end
|
||||
|
||||
context 'operation-specific requirement' do
|
||||
before { api_metadata[:operation][:security] = [ { basic_auth: [] } ] }
|
||||
|
||||
it "includes a corresponding Authorization header" do
|
||||
expect(headers).to match(
|
||||
'Authorization' => 'Basic foobar'
|
||||
)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
context 'consumes & produces' do
|
||||
before do
|
||||
api_metadata[:operation][:consumes] = [ 'application/json', 'application/xml' ]
|
||||
@@ -226,8 +253,8 @@ module Rswag
|
||||
|
||||
it "includes corresponding 'Accept' & 'Content-Type' headers" do
|
||||
expect(headers).to match(
|
||||
'ACCEPT' => 'application/json;application/xml',
|
||||
'CONTENT_TYPE' => 'application/json;application/xml'
|
||||
'Accept' => 'application/json;application/xml',
|
||||
'Content-Type' => 'application/json;application/xml'
|
||||
)
|
||||
end
|
||||
end
|
||||
@@ -242,8 +269,8 @@ module Rswag
|
||||
|
||||
it "includes corresponding 'Accept' & 'Content-Type' headers" do
|
||||
expect(headers).to match(
|
||||
'ACCEPT' => 'application/json;application/xml',
|
||||
'CONTENT_TYPE' => 'application/json;application/xml'
|
||||
'Accept' => 'application/json;application/xml',
|
||||
'Content-Type' => 'application/json;application/xml'
|
||||
)
|
||||
end
|
||||
end
|
||||
|
||||
Reference in New Issue
Block a user