Skip to content

Commit

Permalink
refactor: parse pacts for verification selectors to Selector class
Browse files Browse the repository at this point in the history
  • Loading branch information
bethesque committed Feb 2, 2020
1 parent 59ec8c8 commit acf2e17
Show file tree
Hide file tree
Showing 9 changed files with 68 additions and 31 deletions.
13 changes: 2 additions & 11 deletions lib/pact_broker/api/decorators/verifiable_pact_decorator.rb
Original file line number Diff line number Diff line change
Expand Up @@ -7,20 +7,11 @@ module PactBroker
module Api
module Decorators
class VerifiablePactDecorator < BaseDecorator

# Allows a "flat" VerifiablePact to look like it has
# a nested verification_properties object for Reform
class Reshaper < SimpleDelegator
def verification_properties
__getobj__()
end
end

def initialize(verifiable_pact)
super(Reshaper.new(verifiable_pact))
super(verifiable_pact)
end

property :verification_properties, as: :verificationProperties do
nested :verificationProperties do
include PactBroker::Api::PactBrokerUrls

property :pending,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@
require_relative 'verifiable_pact_decorator'
require 'pact_broker/api/pact_broker_urls'
require 'pact_broker/hash_refinements'
require 'pact_broker/pacts/selector'
require 'pact_broker/pacts/selectors'

module PactBroker
module Api
Expand All @@ -11,7 +13,7 @@ class VerifiablePactsQueryDecorator < BaseDecorator

collection :provider_version_tags, default: []

collection :consumer_version_selectors, default: [], class: OpenStruct do
collection :consumer_version_selectors, default: PactBroker::Pacts::Selectors.new, class: PactBroker::Pacts::Selector do
property :tag
property :latest,
setter: ->(fragment:, represented:, **) {
Expand All @@ -31,7 +33,11 @@ class VerifiablePactsQueryDecorator < BaseDecorator

def from_hash(hash)
# This handles both the snakecase keys from the GET query and the camelcase JSON POST body
super(hash&.snakecase_keys)
result = super(hash&.snakecase_keys)
if result.consumer_version_selectors && !result.consumer_version_selectors.is_a?(PactBroker::Pacts::Selectors)
result.consumer_version_selectors = PactBroker::Pacts::Selectors.new(result.consumer_version_selectors)
end
result
end
end
end
Expand Down
4 changes: 2 additions & 2 deletions lib/pact_broker/pacts/repository.rb
Original file line number Diff line number Diff line change
Expand Up @@ -207,7 +207,7 @@ def find_wip_pact_versions_for_provider provider_name, provider_tags_names = [],
pre_existing_pending_tags = pending_tag_names & pre_existing_tag_names

if pre_existing_pending_tags.any?
selectors = Selectors.create_for_overall_latest_of_each_tag(pact.head_tag_names)
selectors = Selectors.create_for_latest_of_each_tag(pact.head_tag_names)
VerifiablePact.new(pact.to_domain, selectors, true, pre_existing_pending_tags, [], nil, true)
end
end.compact
Expand Down Expand Up @@ -391,7 +391,7 @@ def find_pacts_for_which_the_latest_version_for_the_tag_is_required(provider_nam
.values
.collect do | pact_publications |
selector_tag_names = pact_publications.collect(&:tag_name)
selectors = Selectors.create_for_overall_latest_of_each_tag(selector_tag_names)
selectors = Selectors.create_for_latest_of_each_tag(selector_tag_names)
last_pact_publication = pact_publications.sort_by(&:consumer_version_order).last
pact_publication = PactPublication.find(id: last_pact_publication.id)
SelectedPact.new(
Expand Down
18 changes: 13 additions & 5 deletions lib/pact_broker/pacts/selector.rb
Original file line number Diff line number Diff line change
@@ -1,10 +1,22 @@
module PactBroker
module Pacts
class Selector < Hash
def initialize(options)
def initialize(options = {})
merge!(options)
end

def tag= tag
self[:tag] = tag
end

def latest= latest
self[:latest] = latest
end

def latest
self[:latest]
end

def self.overall_latest
Selector.new(latest: true)
end
Expand Down Expand Up @@ -56,10 +68,6 @@ def <=> other
def latest?
self[:latest]
end

def latest
self[:latest]
end
end
end
end
4 changes: 2 additions & 2 deletions lib/pact_broker/pacts/selectors.rb
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,15 @@
module PactBroker
module Pacts
class Selectors < Array
def initialize selectors
def initialize selectors = []
super(selectors)
end

def self.create_for_all_of_each_tag(tag_names)
Selectors.new(tag_names.collect{ | tag_name | Selector.all_for_tag(tag_name) })
end

def self.create_for_overall_latest_of_each_tag(tag_names)
def self.create_for_latest_of_each_tag(tag_names)
Selectors.new(tag_names.collect{ | tag_name | Selector.latest_for_tag(tag_name) })
end

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,10 @@ module Decorators
[{"tag" => "dev", "ignored" => "foo", "latest" => true}]
end

it "parses the consumer_version_selectors to a Selectors collection" do
expect(subject.consumer_version_selectors).to be_a(PactBroker::Pacts::Selectors)
end

context "when latest is not specified" do
let(:consumer_version_selectors) do
[{"tag" => "dev"}]
Expand All @@ -32,14 +36,14 @@ module Decorators
end

it "parses the latest as a boolean" do
expect(subject.consumer_version_selectors.first.latest).to be true
expect(subject.consumer_version_selectors.first).to eq PactBroker::Pacts::Selector.new(tag: "dev", latest: true)
end

context "when there are no consumer_version_selectors" do
let(:params) { {} }

it "returns an empty array" do
expect(subject.consumer_version_selectors).to eq []
expect(subject.consumer_version_selectors).to eq PactBroker::Pacts::Selectors.new
end
end

Expand Down Expand Up @@ -69,7 +73,7 @@ module Decorators
end

it "parses a string 'latest' to a boolean" do
expect(subject.consumer_version_selectors.first.latest).to be true
expect(subject.consumer_version_selectors.first).to eq PactBroker::Pacts::Selector.new(tag: "dev", latest: true)
end
end

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ module Resources
expect(PactBroker::Pacts::Service).to receive(:find_for_verification).with(
"Bar",
["master"],
[OpenStruct.new(tag: "dev", latest: true)],
PactBroker::Pacts::Selectors.new([PactBroker::Pacts::Selector.latest_for_tag("dev")]),
{
include_wip_pacts_since: DateTime.parse('2018-01-01'),
include_pending_status: true
Expand Down Expand Up @@ -77,7 +77,7 @@ module Resources
expect(PactBroker::Pacts::Service).to receive(:find_for_verification).with(
"Bar",
["master"],
[OpenStruct.new(tag: "dev", latest: true)],
PactBroker::Pacts::Selectors.new([PactBroker::Pacts::Selector.latest_for_tag("dev")]),
{
include_wip_pacts_since: DateTime.parse('2018-01-01'),
include_pending_status: true
Expand Down
28 changes: 28 additions & 0 deletions spec/lib/pact_broker/pacts/selector_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
require 'pact_broker/pacts/selector'

module PactBroker
module Pacts
describe Selector do
describe "<=>" do
let(:overall_latest_1) { Selector.overall_latest }
let(:overall_latest_2) { Selector.overall_latest }
let(:latest_for_tag_prod) { Selector.latest_for_tag('prod') }
let(:latest_for_tag_dev) { Selector.latest_for_tag('dev') }
let(:all_prod) { Selector.all_for_tag('prod') }
let(:all_dev) { Selector.all_for_tag('dev') }

let(:unsorted_selectors) do
[all_prod, all_dev, latest_for_tag_prod, overall_latest_1, overall_latest_1, latest_for_tag_dev]
end

let(:expected_sorted_selectors) do
[overall_latest_1, overall_latest_1, latest_for_tag_dev, latest_for_tag_prod, all_dev, all_prod]
end

it "sorts the selectors" do
expect(unsorted_selectors.sort).to eq(expected_sorted_selectors)
end
end
end
end
end
8 changes: 4 additions & 4 deletions spec/lib/pact_broker/pacts/verifiable_pact_messages_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -33,24 +33,24 @@ module Pacts
end

context "when there is 1 head consumer tags" do
let(:selectors) { Selectors.create_for_overall_latest_of_each_tag(%w[dev]) }
let(:selectors) { Selectors.create_for_latest_of_each_tag(%w[dev]) }
its(:inclusion_reason) { is_expected.to include "The pact at http://pact is being verified because it matches the following configured selection criterion: latest pact for a consumer version tagged 'dev'" }
its(:pact_description) { is_expected.to eq "Pact between Foo and Bar, consumer version 123, latest dev"}
end

context "when there are 2 head consumer tags" do
let(:selectors) { Selectors.create_for_overall_latest_of_each_tag(%w[dev prod]) }
let(:selectors) { Selectors.create_for_latest_of_each_tag(%w[dev prod]) }
its(:inclusion_reason) { is_expected.to include "The pact at http://pact is being verified because it matches the following configured selection criteria: latest pact for a consumer version tagged 'dev', latest pact for a consumer version tagged 'prod' (both have the same content)" }
end

context "when there are 3 head consumer tags" do
let(:selectors) { Selectors.create_for_overall_latest_of_each_tag(%w[dev prod feat-x]) }
let(:selectors) { Selectors.create_for_latest_of_each_tag(%w[dev prod feat-x]) }
its(:inclusion_reason) { is_expected.to include " (all have the same content)" }
end


context "when the pact is a WIP pact" do
let(:selectors) { Selectors.create_for_overall_latest_of_each_tag(%w[feat-x]) }
let(:selectors) { Selectors.create_for_latest_of_each_tag(%w[feat-x]) }
let(:wip) { true }
let(:pending) { true }
let(:pending_provider_tags) { %w[dev] }
Expand Down

0 comments on commit acf2e17

Please sign in to comment.