From a086ffecd44253b923827fc9704622ca5898823a Mon Sep 17 00:00:00 2001 From: Beth Skurrie Date: Tue, 4 Jun 2019 16:11:34 +1000 Subject: [PATCH] fix(matrix): ensure unrelated dependencies are not included in a matrix result when three pacticipants each have dependencies on each other --- lib/pact_broker/matrix/row.rb | 15 +++++++++++- .../lib/pact_broker/matrix/repository_spec.rb | 24 +++++++++++++++++++ 2 files changed, 38 insertions(+), 1 deletion(-) diff --git a/lib/pact_broker/matrix/row.rb b/lib/pact_broker/matrix/row.rb index 2a166a503..373ef344b 100644 --- a/lib/pact_broker/matrix/row.rb +++ b/lib/pact_broker/matrix/row.rb @@ -53,7 +53,8 @@ def where_consumer_and_provider_in selectors ), Sequel.|( *QueryHelper.provider_and_maybe_provider_version_match_any_selector_or_verification_is_missing(selectors) - ) + ), + QueryHelper.either_consumer_or_provider_was_specified_in_query(selectors) ) } end @@ -94,6 +95,18 @@ def self.provider_and_maybe_provider_version_match_any_selector_or_verification_ provider_verification_is_missing_for_matching_selector(s) } end + + # Some selecters are specified in the query, others are implied (when only one pacticipant is specified, + # the integrations are automatically worked out, and the selectors for these are of type :implied ) + # When there are 3 pacticipants that each have dependencies on each other (A->B, A->C, B->C), the query + # to deploy C (implied A, implied B, specified C) was returning the A->B row because it matched the + # implied selectors as well. + # This extra filter makes sure that every row that is returned actually matches one of the specified + # selectors. + def self.either_consumer_or_provider_was_specified_in_query(selectors) + specified_pacticipant_ids = selectors.select{ |s| s[:type] == :specified }.collect{ |s| s[:pacticipant_id] } + Sequel.|({ consumer_id: specified_pacticipant_ids } , { provider_id: specified_pacticipant_ids }) + end end def where_consumer_or_provider_is s diff --git a/spec/lib/pact_broker/matrix/repository_spec.rb b/spec/lib/pact_broker/matrix/repository_spec.rb index 4ba690321..9bb2b3e32 100644 --- a/spec/lib/pact_broker/matrix/repository_spec.rb +++ b/spec/lib/pact_broker/matrix/repository_spec.rb @@ -1035,6 +1035,30 @@ def shorten_rows rows expect(subject.rows.first.consumer_version_number).to eq "2" end end + + describe "deploying a provider when there is a three way dependency between 3 pacticipants" do + before do + # A->B, A->C, B->C, deploying C + td.create_pact_with_hierarchy("B", "1", "C") + .create_verification(provider_version: "10") + .create_consumer("A") + .create_consumer_version("2") + .create_pact + .create_verification(provider_version: "10") + .use_provider("B") + .create_pact + end + + let(:selectors) { [ { pacticipant_name: "C", pacticipant_version_number: "10" } ] } + let(:options) { { latestby: "cvp", limit: "100", latest: true} } + let(:rows) { Repository.new.find(selectors, options) } + + subject { shorten_rows(rows) } + + it "only includes rows that involve the specified pacticipant" do + expect(subject.all?{ | row | row.include?("C") } ).to be true + end + end end end end