Skip to content

Commit

Permalink
fix: set missing provider branch name parameter for contract_requirin…
Browse files Browse the repository at this point in the history
…g_verification_published webhooks
  • Loading branch information
bethesque committed Oct 15, 2021
1 parent cb9f003 commit 777ccdd
Show file tree
Hide file tree
Showing 9 changed files with 187 additions and 47 deletions.
40 changes: 20 additions & 20 deletions lib/pact_broker/pacts/selector.rb
Original file line number Diff line number Diff line change
Expand Up @@ -136,83 +136,83 @@ def in_environment?
end

def self.overall_latest
Selector.new(latest: true)
new(latest: true)
end

def self.for_main_branch
Selector.new(main_branch: true)
new(main_branch: true)
end

def self.latest_for_tag(tag)
Selector.new(latest: true, tag: tag)
new(latest: true, tag: tag)
end

def self.latest_for_branch(branch)
Selector.new(latest: true, branch: branch)
new(latest: true, branch: branch)
end

def self.latest_for_tag_with_fallback(tag, fallback_tag)
Selector.new(latest: true, tag: tag, fallback_tag: fallback_tag)
new(latest: true, tag: tag, fallback_tag: fallback_tag)
end

def self.latest_for_branch_with_fallback(branch, fallback_branch)
Selector.new(latest: true, branch: branch, fallback_branch: fallback_branch)
new(latest: true, branch: branch, fallback_branch: fallback_branch)
end

def self.all_for_tag(tag)
Selector.new(tag: tag)
new(tag: tag)
end

def self.all_for_tag_and_consumer(tag, consumer)
Selector.new(tag: tag, consumer: consumer)
new(tag: tag, consumer: consumer)
end

def self.latest_for_tag_and_consumer(tag, consumer)
Selector.new(latest: true, tag: tag, consumer: consumer)
new(latest: true, tag: tag, consumer: consumer)
end

def self.latest_for_branch_and_consumer(branch, consumer)
Selector.new(latest: true, branch: branch, consumer: consumer)
new(latest: true, branch: branch, consumer: consumer)
end

def self.latest_for_consumer(consumer)
Selector.new(latest: true, consumer: consumer)
new(latest: true, consumer: consumer)
end

def self.for_currently_deployed(environment_name = nil)
Selector.new( { currently_deployed: true, environment_name: environment_name }.compact )
new( { currently_deployed: true, environment_name: environment_name }.compact )
end

def self.for_currently_supported(environment_name = nil)
Selector.new( { currently_supported: true, environment_name: environment_name }.compact )
new( { currently_supported: true, environment_name: environment_name }.compact )
end

def self.for_currently_deployed_and_consumer(consumer)
Selector.new(currently_deployed: true, consumer: consumer)
new(currently_deployed: true, consumer: consumer)
end

def self.for_currently_deployed_and_environment_and_consumer(environment_name, consumer)
Selector.new(currently_deployed: true, environment_name: environment_name, consumer: consumer)
new(currently_deployed: true, environment_name: environment_name, consumer: consumer)
end

def self.for_currently_supported_and_environment_and_consumer(environment_name, consumer)
Selector.new(currently_supported: true, environment_name: environment_name, consumer: consumer)
new(currently_supported: true, environment_name: environment_name, consumer: consumer)
end

def self.for_environment(environment_name)
Selector.new(environment_name: environment_name)
new(environment_name: environment_name)
end

def self.for_environment_and_consumer(environment_name, consumer)
Selector.new(environment_name: environment_name, consumer: consumer)
new(environment_name: environment_name, consumer: consumer)
end

def self.from_hash hash
Selector.new(hash)
new(hash)
end

def for_consumer(consumer)
Selector.new(to_h.merge(consumer: consumer))
self.class.new(to_h.merge(consumer: consumer))
end

def latest_for_main_branch?
Expand Down
7 changes: 5 additions & 2 deletions lib/pact_broker/verifications/required_verification.rb
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
module PactBroker
module Verifications
class RequiredVerification
attr_reader :provider_version, :provider_version_descriptions
attr_reader :provider_version, :provider_version_selectors, :provider_version_descriptions

def initialize(attributes = {})
attributes.each do | (name, value) |
Expand All @@ -10,7 +10,9 @@ def initialize(attributes = {})
end

def == other
provider_version == other.provider_version && provider_version_descriptions == other.provider_version_descriptions
provider_version == other.provider_version &&
provider_version_selectors == other.provider_version_selectors &&
provider_version_descriptions == other.provider_version_descriptions
end

def + other
Expand All @@ -20,6 +22,7 @@ def + other

RequiredVerification.new(
provider_version: provider_version,
provider_version_selectors: provider_version_selectors + other.provider_version_selectors,
provider_version_descriptions: (provider_version_descriptions + other.provider_version_descriptions).uniq
)
end
Expand Down
21 changes: 14 additions & 7 deletions lib/pact_broker/verifications/service.rb
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@
require "pact_broker/hash_refinements"
require "pact_broker/events/publisher"
require "pact_broker/verifications/required_verification"
require "pact_broker/versions/selector"
require "pact_broker/versions/selectors"

module PactBroker
module Verifications
Expand Down Expand Up @@ -101,7 +103,7 @@ def delete_all_verifications_between(consumer_name, options)

def calculate_required_verifications_for_pact(pact)
pact_version = PactBroker::Pacts::PactVersion.for_pact_domain(pact)
required_verifications = required_verifications_for_main_branch(pact_version) +
required_verifications = required_verifications_for_main_branch(pact_version, pact.provider.main_branch) +
required_verifications_for_deployed_versions(pact_version) +
required_verifications_for_released_versions(pact_version)
required_verifications
Expand All @@ -126,19 +128,24 @@ def broadcast_events(verification, pact, event_context)
end
private :broadcast_events

def identify_required_verification(pact_version, provider_version, description)
def identify_required_verification(pact_version, provider_version, description, provider_version_selector)
any_verifications = PactBroker::Domain::Verification.where(pact_version_id: pact_version.id, provider_version_id: provider_version.id).any?
if !any_verifications
RequiredVerification.new(provider_version: provider_version, provider_version_descriptions: [description])
RequiredVerification.new(
provider_version: provider_version,
provider_version_selectors: PactBroker::Versions::Selectors.new(provider_version_selector),
provider_version_descriptions: [description]
)
end
end
private :identify_required_verification

def required_verifications_for_main_branch(pact_version)
def required_verifications_for_main_branch(pact_version, main_branch_name)
latest_version_from_main_branch = [version_service.find_latest_version_from_main_branch(pact_version.provider)].compact

latest_version_from_main_branch.collect do | main_branch_version |
identify_required_verification(pact_version, main_branch_version, "latest from main branch")
selector = PactBroker::Versions::Selector.for_main_branch.resolve_for_branch(main_branch_version, main_branch_name)
identify_required_verification(pact_version, main_branch_version, "latest from main branch", selector)
end.compact
end
private :required_verifications_for_main_branch
Expand All @@ -148,7 +155,7 @@ def required_verifications_for_deployed_versions(pact_version)
unscoped_service.find_currently_deployed_versions_for_pacticipant(pact_version.provider)
end
deployed_versions.collect do | deployed_version |
identify_required_verification(pact_version, deployed_version.version, "deployed in #{deployed_version.environment_name}")
identify_required_verification(pact_version, deployed_version.version, "deployed in #{deployed_version.environment_name}", PactBroker::Versions::Selector.for_currently_deployed)
end.compact
end
private :required_verifications_for_deployed_versions
Expand All @@ -158,7 +165,7 @@ def required_verifications_for_released_versions(pact_version)
unscoped_service.find_currently_supported_versions_for_pacticipant(pact_version.provider)
end
released_versions.collect do | released_version |
identify_required_verification(pact_version, released_version.version, "released in #{released_version.environment_name}")
identify_required_verification(pact_version, released_version.version, "released in #{released_version.environment_name}", PactBroker::Versions::Selector.for_currently_supported)
end.compact
end
private :required_verifications_for_released_versions
Expand Down
32 changes: 32 additions & 0 deletions lib/pact_broker/versions/selector.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
require "pact_broker/pacts/selector"
require "pact_broker/hash_refinements"

module PactBroker
module Versions
class Selector < PactBroker::Pacts::Selector
def resolve_for_branch(consumer_version, resolved_branch_name)
# Need to rename branch to branch_name
ResolvedSelector.new(self.to_h.merge({ resolved_branch_name: resolved_branch_name }.compact), consumer_version)
end
end

class ResolvedSelector < PactBroker::Pacts::ResolvedSelector
using PactBroker::HashRefinements

PROPERTY_NAMES = PactBroker::Pacts::Selector::PROPERTY_NAMES + [:version, :resolved_branch_name]

def initialize(properties = {}, version)
properties.without(*PROPERTY_NAMES).tap { |it| warn("WARN: Unsupported property for #{self.class.name}: #{it.keys.join(", ")} at #{caller[0..3]}") if it.any? }
merge!(properties.merge(version: version))
end

def resolved_branch_name
self[:resolved_branch_name]
end

def version
self[:version]
end
end
end
end
20 changes: 20 additions & 0 deletions lib/pact_broker/versions/selectors.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
require "pact_broker/pacts/selector"
require "pact_broker/versions/selector"

module PactBroker
module Versions
class Selectors < Array
def initialize *selectors
super([*selectors].flatten)
end

def + other
Selectors.new(super)
end

def sort
Selectors.new(super)
end
end
end
end
4 changes: 2 additions & 2 deletions lib/pact_broker/webhooks/pact_and_verification_parameters.rb
Original file line number Diff line number Diff line change
Expand Up @@ -171,8 +171,8 @@ def provider_version_number
end

def provider_version_branch
if webhook_context[:provider_version_branch]
webhook_context[:provider_version_branch]
if webhook_context.key?(:provider_version_branch)
webhook_context[:provider_version_branch] || ""
else
verification&.provider_version&.branch || ""
end
Expand Down
10 changes: 9 additions & 1 deletion lib/pact_broker/webhooks/trigger_service.rb
Original file line number Diff line number Diff line change
Expand Up @@ -135,13 +135,21 @@ def expand_events_for_required_verifications(event_name, pact, event_contexts)
required_verifications = verification_service.calculate_required_verifications_for_pact(pact)
event_contexts.flat_map do | event_context |
required_verifications.collect do | required_verification |
event_context.merge(provider_version_number: required_verification.provider_version.number, provider_version_descriptions: required_verification.provider_version_descriptions.uniq)
event_context.merge(
provider_version_number: required_verification.provider_version.number,
provider_version_branch: provider_version_branch_for_required_verification(required_verification, ),
provider_version_descriptions: required_verification.provider_version_descriptions.uniq
)
end
end
else
event_contexts
end
end

def provider_version_branch_for_required_verification(required_verification)
required_verification.provider_version_selectors.find(&:latest_for_main_branch?)&.resolved_branch_name || required_verification.provider_version.branch_versions.last&.branch_name
end
end
end
end
30 changes: 18 additions & 12 deletions spec/lib/pact_broker/verifications/service_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -112,12 +112,15 @@ module Verifications
end

it "returns the required verification for the main branch" do
expect(subject).to eq [
RequiredVerification.new(
expect(subject).to contain_exactly(
have_attributes(
provider_version: td.find_version("Bar", "1"),
provider_version_selectors: contain_exactly(
have_attributes(resolved_branch_name: "main", main_branch: true)
),
provider_version_descriptions: ["latest from main branch"]
)
]
)
end
end

Expand Down Expand Up @@ -153,6 +156,7 @@ module Verifications
expect(subject).to eq [
RequiredVerification.new(
provider_version: td.find_version("Bar", "1"),
provider_version_selectors: PactBroker::Versions::Selectors.new(PactBroker::Versions::Selector.for_currently_deployed),
provider_version_descriptions: ["deployed in test"]
)
]
Expand Down Expand Up @@ -193,6 +197,7 @@ module Verifications
expect(subject).to eq [
RequiredVerification.new(
provider_version: td.find_version("Bar", "1"),
provider_version_selectors: PactBroker::Versions::Selectors.new(PactBroker::Versions::Selector.for_currently_supported),
provider_version_descriptions: ["released in test"]
)
]
Expand Down Expand Up @@ -231,15 +236,16 @@ module Verifications
end

it "deduplicates the required versions" do
expect(subject).to eq [
RequiredVerification.new(
provider_version: td.find_version("Bar", "1"),
provider_version_descriptions: [
"latest from main branch",
"deployed in test",
"released in test"
])
]
expect(subject.size).to eq 1
expect(subject.first.provider_version).to eq td.find_version("Bar", "1")
expect(subject.first.provider_version_selectors[0]).to have_attributes(main_branch: true, resolved_branch_name: "main")
expect(subject.first.provider_version_selectors[1]).to eq PactBroker::Versions::Selector.for_currently_deployed
expect(subject.first.provider_version_selectors[2]).to eq PactBroker::Versions::Selector.for_currently_supported
expect(subject.first.provider_version_descriptions).to eq [
"latest from main branch",
"deployed in test",
"released in test"
]
end
end
end
Expand Down
Loading

0 comments on commit 777ccdd

Please sign in to comment.