Commit 8c27e79d by andrew morton

Handle param refs

parent cdbca3a8
...@@ -72,45 +72,59 @@ module RSpec ...@@ -72,45 +72,59 @@ module RSpec
def parameter name, attributes = {} def parameter name, attributes = {}
attributes.symbolize_keys! attributes.symbolize_keys!
validate_location! attributes[:in] # look for $refs
if name.respond_to?(:has_key?)
ref = name.delete(:ref) || name.delete('ref')
full_param = resolve_document(metadata).resolve_ref(ref)
# TODO validate there is only be one body param validate_parameter! full_param
# TODO validate there are not both body and formData params
if attributes[:in] == :body param = { '$ref' => ref }
unless attributes[:schema].present? key = parameter_key(full_param)
raise ArgumentError, "Parameter is missing required 'schema' value."
end
else else
validate_type! attributes[:type] validate_parameter! attributes
end
# Path attributes are always required # Path attributes are always required
attributes[:required] = true if attributes[:in] == :path attributes[:required] = true if attributes[:in] == :path
# if name.respond_to?(:has_key?) param = { name: name.to_s }.merge(attributes)
# param = { '$ref' => name.delete(:ref) || name.delete('ref') } key = parameter_key(param)
# end end
parameters_for_object[key] = param
end
private
# This key ensures uniqueness based on the 'name' and 'in' values.
def parameter_key parameter
"#{parameter[:in]}&#{parameter[:name]}"
end
def parameters_for_object
object_key = "swagger_#{metadata[:swagger_object]}".to_sym object_key = "swagger_#{metadata[:swagger_object]}".to_sym
object_data = metadata[object_key] ||= {} object_data = metadata[object_key] ||= {}
object_data[:parameters] ||= {}
end
params = object_data[:parameters] ||= {} def validate_parameter! attributes
param = { name: name.to_s }.merge(attributes) validate_location! attributes[:in]
# This key ensures uniqueness based on the 'name' and 'in' values. if attributes[:in].to_s == 'body'
param_key = "#{param[:in]}&#{param[:name]}" unless attributes[:schema].present?
params[param_key] = param raise ArgumentError, "Parameter is missing required 'schema' value."
end
else
validate_type! attributes[:type]
end
end end
private
def validate_location! location def validate_location! location
unless location.present? unless location.present?
raise ArgumentError, "Parameter is missing required 'in' value." raise ArgumentError, "Parameter is missing required 'in' value."
end end
locations = %i(query header path formData body) locations = %q(query header path formData body)
unless locations.include? location unless locations.include? location.to_s
raise ArgumentError, "Parameter has an invalid 'in' value. Try: #{locations}." raise ArgumentError, "Parameter has an invalid 'in' value. Try: #{locations}."
end end
end end
...@@ -120,8 +134,8 @@ module RSpec ...@@ -120,8 +134,8 @@ module RSpec
raise ArgumentError, "Parameter is missing required 'type' value." raise ArgumentError, "Parameter is missing required 'type' value."
end end
types = %i(string number integer boolean array file) types = %q(string number integer boolean array file)
unless types.include?(type) unless types.include? type.to_s
raise ArgumentError, "Parameter has an invalid 'type' value. Try: #{types}." raise ArgumentError, "Parameter has an invalid 'type' value. Try: #{types}."
end end
end end
...@@ -230,9 +244,9 @@ module RSpec ...@@ -230,9 +244,9 @@ module RSpec
operation = metadata[:swagger_operation] || {} operation = metadata[:swagger_operation] || {}
params = path_item.fetch(:parameters, {}).merge(operation.fetch(:parameters, {})) params = path_item.fetch(:parameters, {}).merge(operation.fetch(:parameters, {}))
# TODO resolve $refs params.keys.map do |key|
params.values.map do |p| location, name = key.split('&')
p.slice(:name, :in).merge(value: group_instance.send(p[:name])) {name: name, in: location.to_sym, value: group_instance.send(name)}
end end
end end
......
...@@ -84,6 +84,7 @@ RSpec.describe RSpec::Swagger::Helpers::Parameters do ...@@ -84,6 +84,7 @@ RSpec.describe RSpec::Swagger::Helpers::Parameters do
include RSpec::Swagger::Helpers::Parameters include RSpec::Swagger::Helpers::Parameters
attr_accessor :metadata attr_accessor :metadata
def describe *args ; end def describe *args ; end
def resolve_document *args ; end
end end
end end
subject { klass.new } subject { klass.new }
...@@ -91,13 +92,15 @@ RSpec.describe RSpec::Swagger::Helpers::Parameters do ...@@ -91,13 +92,15 @@ RSpec.describe RSpec::Swagger::Helpers::Parameters do
describe "#parameter" do describe "#parameter" do
before { subject.metadata = {swagger_object: :path_item} } before { subject.metadata = {swagger_object: :path_item} }
context "with parameters passed in" do
it "requires 'in' parameter" do it "requires 'in' parameter" do
expect{ subject.parameter("name", foo: :bar) }.to raise_exception(ArgumentError) expect{ subject.parameter("name", foo: :bar) }.to raise_exception(ArgumentError)
end end
it "validates 'in' parameter" do it "validates 'in' parameter" do
expect{ subject.parameter("name", in: :form_data, type: :string) }.to raise_exception(ArgumentError) expect{ subject.parameter("name", in: :form_data, type: :string) }.to raise_exception(ArgumentError)
expect{ subject.parameter("name", in: "formData", type: :string) }.to raise_exception(ArgumentError) expect{ subject.parameter("name", in: :pickles, type: :string) }.to raise_exception(ArgumentError)
expect{ subject.parameter("name", in: :formData, type: :string) }.not_to raise_exception expect{ subject.parameter("name", in: :formData, type: :string) }.not_to raise_exception
end end
...@@ -135,6 +138,22 @@ RSpec.describe RSpec::Swagger::Helpers::Parameters do ...@@ -135,6 +138,22 @@ RSpec.describe RSpec::Swagger::Helpers::Parameters do
expect(subject.metadata[:swagger_path_item][:parameters].length).to eq 3 expect(subject.metadata[:swagger_path_item][:parameters].length).to eq 3
end end
end end
context "with references" do
it "stores them" do
expect(subject).to receive(:resolve_document) do
double(resolve_ref: {in: 'path', name: 'petId', description: 'ID of pet',
required: true, type: 'string'})
end
subject.parameter(ref: '#/parameters/Pet')
expect(subject.metadata[:swagger_path_item][:parameters]).to eq({
'path&petId' => {'$ref' => '#/parameters/Pet'}
})
end
end
end
end end
...@@ -174,7 +193,15 @@ RSpec.describe RSpec::Swagger::Helpers::Resolver do ...@@ -174,7 +193,15 @@ RSpec.describe RSpec::Swagger::Helpers::Resolver do
# Tthis helper is an include rather than an extend we can get it pulled into # Tthis helper is an include rather than an extend we can get it pulled into
# the test just by matching the filter metadata. # the test just by matching the filter metadata.
describe("#resolve_params", :swagger_object) do describe("#resolve_params", :swagger_object) do
let(:metadata) { {swagger_operation: {parameters: params}} } let(:metadata) do
{
swagger_document: 'example.json',
swagger_operation: {parameters: params}
}
end
let(:document) { { } }
before { allow(self).to receive(:resolve_document) { document } }
describe "with a missing value" do describe "with a missing value" do
let(:params) { {"path&post_id" => {name: "post_id", in: :path}} } let(:params) { {"path&post_id" => {name: "post_id", in: :path}} }
...@@ -194,6 +221,18 @@ RSpec.describe RSpec::Swagger::Helpers::Resolver do ...@@ -194,6 +221,18 @@ RSpec.describe RSpec::Swagger::Helpers::Resolver do
expect(resolve_params(metadata, self)).to eq([{name: "post_id", in: :path, value: 123}]) expect(resolve_params(metadata, self)).to eq([{name: "post_id", in: :path, value: 123}])
end end
end end
describe "with a $ref" do
let(:document) do
{ parameters: { skipParam: {name: "skipper", in: "path", required: true, type: "integer"} } }
end
let(:params) { {"path&skipper" => { '$ref' => '#/parameters/skipParam'}} }
let(:skipper) { true }
it "uses the parameters in the document" do
expect(resolve_params(metadata, self)).to eq([{name: "skipper", in: :path, value: true}])
end
end
end end
describe "#resolve_path", :swagger_object do describe "#resolve_path", :swagger_object do
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment