Skip to content

Commit

Permalink
feat: add consumer_version_selectors to pact verification DSL, and co…
Browse files Browse the repository at this point in the history
…nvert consumer_version_tags to selectors
  • Loading branch information
bethesque committed Sep 26, 2020
1 parent 303077d commit 39e6c4a
Show file tree
Hide file tree
Showing 6 changed files with 122 additions and 19 deletions.
6 changes: 4 additions & 2 deletions lib/pact/pact_broker/fetch_pact_uris_for_verification.rb
Original file line number Diff line number Diff line change
Expand Up @@ -39,9 +39,11 @@ def call
log_message
pacts_for_verification
else
old_selectors = consumer_version_selectors.collect do | selector |
{ name: selector[:tag], all: !selector[:latest], fallback: selector[:fallbackTag]}
end
# Fall back to old method of fetching pacts
consumer_version_tags = consumer_version_selectors.collect{ | selector | selector[:tag] }
FetchPacts.call(provider, consumer_version_tags, broker_base_url, http_client_options)
FetchPacts.call(provider, old_selectors, broker_base_url, http_client_options)
end
end

Expand Down
1 change: 0 additions & 1 deletion lib/pact/pact_broker/pact_selection_description.rb
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ def pact_selection_description(provider, consumer_version_selectors, options, br
if consumer_version_selectors.any?
desc = consumer_version_selectors.collect do |selector|
all_or_latest = !selector[:latest] ? "all for tag" : "latest for tag"
# TODO support fallback
fallback = selector[:fallback] || selector[:fallbackTag]
name = fallback ? "#{selector[:tag]} (or #{fallback} if not found)" : selector[:tag]
"#{all_or_latest} #{name}"
Expand Down
39 changes: 33 additions & 6 deletions lib/pact/provider/configuration/pact_verification_from_broker.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
require 'pact/provider/world'
require 'pact/pact_broker/fetch_pact_uris_for_verification'
require 'pact/errors'
require 'pact/utils/string'

module Pact
module Provider
Expand All @@ -14,12 +15,13 @@ class PactVerificationFromBroker
# in parent scope, it will clash with these ones,
# so put an underscore in front of the name to be safer.

attr_accessor :_provider_name, :_pact_broker_base_url, :_consumer_version_tags, :_provider_version_tags, :_basic_auth_options, :_enable_pending, :_include_wip_pacts_since, :_verbose
attr_accessor :_provider_name, :_pact_broker_base_url, :_consumer_version_tags, :_provider_version_tags, :_basic_auth_options, :_enable_pending, :_include_wip_pacts_since, :_verbose, :_consumer_version_selectors

def initialize(provider_name, provider_version_tags)
@_provider_name = provider_name
@_provider_version_tags = provider_version_tags
@_consumer_version_tags = []
@_consumer_version_selectors = []
@_enable_pending = false
@_include_wip_pacts_since = nil
@_verbose = false
Expand All @@ -35,6 +37,10 @@ def consumer_version_tags consumer_version_tags
self._consumer_version_tags = *consumer_version_tags
end

def consumer_version_selectors consumer_version_selectors
self._consumer_version_selectors = *consumer_version_selectors
end

def enable_pending enable_pending
self._enable_pending = enable_pending
end
Expand Down Expand Up @@ -73,12 +79,33 @@ def create_pact_verification
end

def consumer_version_selectors
# TODO support "all"
convert_tags_to_selectors + convert_consumer_version_selectors
end

def convert_tags_to_selectors
_consumer_version_tags.collect do | tag |
{
tag: tag,
latest: true
}
if tag.is_a?(Hash)
{
tag: tag.fetch(:name),
latest: !tag[:all],
fallbackTag: tag[:fallback]
}
elsif tag.is_a?(String)
{
tag: tag,
latest: true
}
else
raise Pact::Error.new("The value supplied for consumer_version_tags must be a String or a Hash. Found #{tag.class}")
end
end
end

def convert_consumer_version_selectors
_consumer_version_selectors.collect do | selector |
selector.each_with_object({}) do | (key, value), new_selector |
new_selector[Pact::Utils::String.camelcase(key.to_s).to_sym] = value
end
end
end

Expand Down
35 changes: 35 additions & 0 deletions lib/pact/utils/string.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
# Can't use refinements because of Travelling Ruby

module Pact
module Utils
module String

extend self

# ripped from rubyworks/facets, thank you
def camelcase(string, *separators)
case separators.first
when Symbol, TrueClass, FalseClass, NilClass
first_letter = separators.shift
end

separators = ['_', '\s'] if separators.empty?

str = string.dup

separators.each do |s|
str = str.gsub(/(?:#{s}+)([a-z])/){ $1.upcase }
end

case first_letter
when :upper, true
str = str.gsub(/(\A|\s)([a-z])/){ $1 + $2.upcase }
when :lower, false
str = str.gsub(/(\A|\s)([A-Z])/){ $1 + $2.downcase }
end

str
end
end
end
end
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ module PactBroker
let(:provider) { "Foo"}
let(:broker_base_url) { "http://broker.org" }
let(:http_client_options) { {} }
let(:consumer_version_selectors) { [{ tag: "cmaster", latest: true}] }
let(:consumer_version_selectors) { [{ tag: "cmaster", latest: true, fallbackTag: 'blah' }] }
let(:provider_version_tags) { ["pmaster"] }

subject { FetchPactURIsForVerification.call(provider, consumer_version_selectors, provider_version_tags, broker_base_url, http_client_options)}
Expand Down Expand Up @@ -60,7 +60,7 @@ module PactBroker
end

it "calls the old fetch pacts code" do
expect(FetchPacts).to receive(:call).with(provider, ["cmaster"], broker_base_url, http_client_options)
expect(FetchPacts).to receive(:call).with(provider, [{ name: "cmaster", all: false, fallback: "blah" }], broker_base_url, http_client_options)
subject
end
end
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ module Configuration
}
end
let(:tags) { ['master'] }
let(:fetch_pacts) { double('FetchPacts') }

before do
allow(Pact::PactBroker::FetchPactURIsForVerification).to receive(:new).and_return(fetch_pacts)
Expand Down Expand Up @@ -82,8 +83,6 @@ module Configuration
end
end

let(:fetch_pacts) { double('FetchPacts') }

it "raises an error" do
expect { subject }.to raise_error Pact::Error, /Please provide a pact_broker_base_url/
end
Expand All @@ -97,8 +96,6 @@ module Configuration
end
end

let(:fetch_pacts) { double('FetchPacts') }

it "coerces the value into an array" do
expect(Pact::PactBroker::FetchPactURIsForVerification).to receive(:new).with(anything, [{ tag: "master", latest: true}], anything, anything, anything, anything)
subject
Expand All @@ -112,22 +109,65 @@ module Configuration
end
end

let(:fetch_pacts) { double('FetchPacts') }

it "creates an instance of FetchPacts with an emtpy array for the consumer_version_tags" do
expect(Pact::PactBroker::FetchPactURIsForVerification).to receive(:new).with(anything, [], anything, anything, anything, anything)
subject
end
end

context "when no verbose flag is provided" do
context "when the old format of selector is supplied to the consumer_verison_tags" do
let(:tags) { [{ name: 'main', all: true, fallback: 'fallback' }] }

subject do
PactVerificationFromBroker.build(provider_name, provider_version_tags) do
pact_broker_base_url base_url
consumer_version_tags tags
end
end

let(:fetch_pacts) { double('FetchPacts') }
it "converts them to selectors" do
expect(Pact::PactBroker::FetchPactURIsForVerification).to receive(:new).with(anything, [{ tag: "main", latest: false, fallbackTag: 'fallback'}], anything, anything, anything, anything)
subject
end
end

context "when an invalid class is used for the consumer_version_tags" do
let(:tags) { [true] }

subject do
PactVerificationFromBroker.build(provider_name, provider_version_tags) do
pact_broker_base_url base_url
consumer_version_tags tags
end
end

it "raises an error" do
expect { subject }.to raise_error Pact::Error, "The value supplied for consumer_version_tags must be a String or a Hash. Found TrueClass"
end
end

context "when consumer_version_selectors are provided" do
let(:tags) { [{ tag: 'main', latest: true, fallback_tag: 'fallback' }] }

subject do
PactVerificationFromBroker.build(provider_name, provider_version_tags) do
pact_broker_base_url base_url
consumer_version_selectors tags
end
end

it "converts the casing of the key names" do
expect(Pact::PactBroker::FetchPactURIsForVerification).to receive(:new).with(anything, [{ tag: "main", latest: true, fallbackTag: 'fallback'}], anything, anything, anything, anything)
subject
end
end

context "when no verbose flag is provided" do
subject do
PactVerificationFromBroker.build(provider_name, provider_version_tags) do
pact_broker_base_url base_url
end
end

it "creates an instance of FetchPactURIsForVerification with verbose: false" do
expect(Pact::PactBroker::FetchPactURIsForVerification).to receive(:new).with(anything, anything, anything, anything, hash_including(verbose: false), anything)
Expand Down

0 comments on commit 39e6c4a

Please sign in to comment.