Commit 7b919204 by andrew morton Committed by GitHub

Merge pull request #24 from drewish/allow-optional-params

Don't require optional parameters to have value
parents 251f26f6 160af2e8
...@@ -12,6 +12,8 @@ module RSpec ...@@ -12,6 +12,8 @@ module RSpec
data[value] data[value]
end end
##
# Look up parameter or definition references.
def resolve_ref(ref) def resolve_ref(ref)
unless %r{#/(?<location>parameters|definitions)/(?<name>.+)} =~ ref unless %r{#/(?<location>parameters|definitions)/(?<name>.+)} =~ ref
raise ArgumentError, "Invalid reference: #{ref}" raise ArgumentError, "Invalid reference: #{ref}"
......
...@@ -4,10 +4,17 @@ module RSpec ...@@ -4,10 +4,17 @@ module RSpec
class RequestBuilder class RequestBuilder
attr_reader :metadata, :instance attr_reader :metadata, :instance
##
# Creates a new RequestBuilder from the Example class's +metadata+ hash
# and a test +instance+ that we can use to populate the parameter
# values.
def initialize(metadata, instance) def initialize(metadata, instance)
@metadata, @instance = metadata, instance @metadata, @instance = metadata, instance
end end
##
# Finds the Document associated with this request so things like schema
# and parameter references can be resolved.
def document def document
@document ||= begin @document ||= begin
name = metadata[:swagger_document] name = metadata[:swagger_document]
...@@ -27,6 +34,9 @@ module RSpec ...@@ -27,6 +34,9 @@ module RSpec
Array(metadata[:swagger_operation][:consumes]).presence || Array(document[:consumes]) Array(metadata[:swagger_operation][:consumes]).presence || Array(document[:consumes])
end end
##
# Returns parameters defined in the operation and path item. Providing
# a +location+ will limit the parameters by their `in` value.
def parameters location = nil def parameters location = nil
path_item = metadata[:swagger_path_item] || {} path_item = metadata[:swagger_path_item] || {}
operation = metadata[:swagger_operation] || {} operation = metadata[:swagger_operation] || {}
...@@ -39,12 +49,10 @@ module RSpec ...@@ -39,12 +49,10 @@ module RSpec
end end
def parameter_values location def parameter_values location
# Don't bother looking at the full parameter bodies since all we need values = parameters(location).
# are location and name which are in the key. map{ |_, p| p['$ref'] ? document.resolve_ref(p['$ref']) : p }.
values = parameters(location) select{ |p| p[:required] || instance.respond_to?(p[:name]) }.
.keys map{ |p| [p[:name], instance.send(p[:name])] }
.map{ |k| k.split('&').last }
.map{ |name| [name, instance.send(name)] }
Hash[values] Hash[values]
end end
......
...@@ -3,7 +3,7 @@ module RSpec ...@@ -3,7 +3,7 @@ module RSpec
# Version information for RSpec Swagger. # Version information for RSpec Swagger.
module Swagger module Swagger
module Version module Version
STRING = '0.1.2' STRING = '0.1.3'
end end
end end
end end
......
...@@ -98,15 +98,19 @@ RSpec.describe RSpec::Rails::Swagger::RequestBuilder do ...@@ -98,15 +98,19 @@ RSpec.describe RSpec::Rails::Swagger::RequestBuilder do
describe '#parameters' do describe '#parameters' do
subject { described_class.new(metadata, double('instance')) } subject { described_class.new(metadata, double('instance')) }
let(:metadata) { { let(:metadata) do
swagger_path_item: { parameters: { {
swagger_path_item: {
parameters: {
'path&petId' => { name: 'petId', in: :path, description: 'path' }, 'path&petId' => { name: 'petId', in: :path, description: 'path' },
'query&site' => { name: 'site', in: :query } 'query&site' => { name: 'site', in: :query }
} }, }
swagger_operation: { parameters: { },
'path&petId' => { name: 'petId', in: :path, description: 'op' } swagger_operation: {
} }, parameters: { 'path&petId' => { name: 'petId', in: :path, description: 'op' } }
} } }
}
end
it 'merges values from the path and operation' do it 'merges values from the path and operation' do
expect(subject.parameters).to eq({ expect(subject.parameters).to eq({
...@@ -116,6 +120,56 @@ RSpec.describe RSpec::Rails::Swagger::RequestBuilder do ...@@ -116,6 +120,56 @@ RSpec.describe RSpec::Rails::Swagger::RequestBuilder do
end end
end end
describe '#parameter_values' do
subject { described_class.new(metadata, instance) }
let(:metadata) do
{
swagger_operation: {
parameters: {
"query&date" => { "$ref" => "#/parameters/filter_date" },
"query&subscriber" => { name: "subscriber", type: :string, in: :query, required: required }
}
}
}
end
let(:instance) { double('instance') }
before do
expect(subject).to receive_message_chain(:document, :resolve_ref) do
{ name: "date", type: :integer, in: :query, required: required }
end
end
context 'required parameters' do
let(:required) { true }
it 'includes defined values' do
allow(instance).to receive(:date) { 10 }
allow(instance).to receive(:subscriber) { false }
expect(subject.parameter_values(:query)).to eq({ 'date' => 10, 'subscriber' => false })
end
it 'undefined cause errors' do
expect{ subject.parameter_values(:query) }.to raise_exception(RSpec::Mocks::MockExpectationError)
end
end
context 'optional parameters' do
let(:required) { false }
it 'includes defined values' do
allow(instance).to receive(:date) { 27 }
allow(instance).to receive(:subscriber) { true }
expect(subject.parameter_values(:query)).to eq({ 'date' => 27, 'subscriber' => true })
end
it 'ommits undefined values' do
expect(subject.parameter_values(:query)).to eq({})
end
end
end
describe '#headers' do describe '#headers' do
subject { described_class.new(double('metadata'), instance) } subject { described_class.new(double('metadata'), instance) }
let(:instance) { double('instance') } let(:instance) { double('instance') }
...@@ -170,7 +224,7 @@ RSpec.describe RSpec::Rails::Swagger::RequestBuilder do ...@@ -170,7 +224,7 @@ RSpec.describe RSpec::Rails::Swagger::RequestBuilder do
context 'with header params' do context 'with header params' do
it 'returns them in a string' do it 'returns them in a string' do
expect(subject).to receive(:parameters).with(:header) { { expect(subject).to receive(:parameters).with(:header) { {
'header&X-Magic' => { same: :here } 'header&X-Magic' => { name: 'X-Magic', in: :header }
} } } }
expect(instance).to receive('X-Magic'.to_sym) { :pickles } expect(instance).to receive('X-Magic'.to_sym) { :pickles }
...@@ -221,7 +275,7 @@ RSpec.describe RSpec::Rails::Swagger::RequestBuilder do ...@@ -221,7 +275,7 @@ RSpec.describe RSpec::Rails::Swagger::RequestBuilder do
context 'with query params' do context 'with query params' do
it 'returns them in a string' do it 'returns them in a string' do
expect(subject).to receive(:parameters).with(:query) { { expect(subject).to receive(:parameters).with(:query) { {
'query&site' => { same: :here } 'query&site' => { name: 'site', in: :query }
} } } }
expect(instance).to receive(:site) { :pickles } expect(instance).to receive(:site) { :pickles }
......
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