Commit 8c27e79d by andrew morton

Handle param refs

parent cdbca3a8
......@@ -72,45 +72,59 @@ module RSpec
def parameter name, attributes = {}
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
# TODO validate there are not both body and formData params
if attributes[:in] == :body
unless attributes[:schema].present?
raise ArgumentError, "Parameter is missing required 'schema' value."
end
validate_parameter! full_param
param = { '$ref' => ref }
key = parameter_key(full_param)
else
validate_type! attributes[:type]
end
validate_parameter! attributes
# Path attributes are always required
attributes[:required] = true if attributes[:in] == :path
# if name.respond_to?(:has_key?)
# param = { '$ref' => name.delete(:ref) || name.delete('ref') }
# end
param = { name: name.to_s }.merge(attributes)
key = parameter_key(param)
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_data = metadata[object_key] ||= {}
object_data[:parameters] ||= {}
end
params = object_data[:parameters] ||= {}
param = { name: name.to_s }.merge(attributes)
def validate_parameter! attributes
validate_location! attributes[:in]
# This key ensures uniqueness based on the 'name' and 'in' values.
param_key = "#{param[:in]}&#{param[:name]}"
params[param_key] = param
if attributes[:in].to_s == 'body'
unless attributes[:schema].present?
raise ArgumentError, "Parameter is missing required 'schema' value."
end
else
validate_type! attributes[:type]
end
end
private
def validate_location! location
unless location.present?
raise ArgumentError, "Parameter is missing required 'in' value."
end
locations = %i(query header path formData body)
unless locations.include? location
locations = %q(query header path formData body)
unless locations.include? location.to_s
raise ArgumentError, "Parameter has an invalid 'in' value. Try: #{locations}."
end
end
......@@ -120,8 +134,8 @@ module RSpec
raise ArgumentError, "Parameter is missing required 'type' value."
end
types = %i(string number integer boolean array file)
unless types.include?(type)
types = %q(string number integer boolean array file)
unless types.include? type.to_s
raise ArgumentError, "Parameter has an invalid 'type' value. Try: #{types}."
end
end
......@@ -230,9 +244,9 @@ module RSpec
operation = metadata[:swagger_operation] || {}
params = path_item.fetch(:parameters, {}).merge(operation.fetch(:parameters, {}))
# TODO resolve $refs
params.values.map do |p|
p.slice(:name, :in).merge(value: group_instance.send(p[:name]))
params.keys.map do |key|
location, name = key.split('&')
{name: name, in: location.to_sym, value: group_instance.send(name)}
end
end
......
......@@ -84,6 +84,7 @@ RSpec.describe RSpec::Swagger::Helpers::Parameters do
include RSpec::Swagger::Helpers::Parameters
attr_accessor :metadata
def describe *args ; end
def resolve_document *args ; end
end
end
subject { klass.new }
......@@ -91,13 +92,15 @@ RSpec.describe RSpec::Swagger::Helpers::Parameters do
describe "#parameter" do
before { subject.metadata = {swagger_object: :path_item} }
context "with parameters passed in" do
it "requires 'in' parameter" do
expect{ subject.parameter("name", foo: :bar) }.to raise_exception(ArgumentError)
end
it "validates 'in' parameter" do
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
end
......@@ -135,6 +138,22 @@ RSpec.describe RSpec::Swagger::Helpers::Parameters do
expect(subject.metadata[:swagger_path_item][:parameters].length).to eq 3
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
......@@ -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
# the test just by matching the filter metadata.
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
let(:params) { {"path&post_id" => {name: "post_id", in: :path}} }
......@@ -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}])
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
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