Skip to content

Commit 679eec1

Browse files
committed
fix(matrix): ensure matrix for latest consumer version/provider version shows correct results when a pact is published, published again for the same version with different content, then published again for the same version with the original content.
1 parent 744250c commit 679eec1

File tree

7 files changed

+113
-7
lines changed

7 files changed

+113
-7
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
Sequel.migration do
2+
up do
3+
# Removes 'overwritten' pacts and verifications from the matrix
4+
# (ie. only show latest pact revision for each consumer version and
5+
# latest verification for each provider version)
6+
# Must include lines where verification_id is null so that we don't
7+
# lose the unverified pacts.
8+
# In this view there will be one row for each consumer version/provider version
9+
# This view used to be (stupidly) called latest_matrix
10+
create_or_replace_view(:latest_matrix_for_consumer_version_and_provider_version,
11+
"
12+
SELECT matrix.* FROM matrix
13+
inner join latest_pact_publication_revision_numbers lr
14+
on matrix.consumer_id = lr.consumer_id
15+
and matrix.provider_id = lr.provider_id
16+
and matrix.consumer_version_order = lr.consumer_version_order
17+
and matrix.pact_revision_number = lr.latest_revision_number
18+
INNER JOIN latest_verification_id_for_consumer_version_and_provider_version AS lv
19+
ON ((matrix.consumer_version_id = lv.consumer_version_id)
20+
AND (matrix.provider_version_id = lv.provider_version_id)
21+
AND ((matrix.verification_id = lv.latest_verification_id)))
22+
23+
UNION
24+
25+
select matrix.* from matrix
26+
inner join latest_pact_publication_revision_numbers lr
27+
on matrix.consumer_id = lr.consumer_id
28+
and matrix.provider_id = lr.provider_id
29+
and matrix.consumer_version_order = lr.consumer_version_order
30+
and matrix.pact_revision_number = lr.latest_revision_number
31+
where verification_id is null
32+
"
33+
)
34+
from(:materialized_head_matrix).delete
35+
from(:materialized_head_matrix).insert(from(:head_matrix).select_all)
36+
end
37+
38+
down do
39+
# revert to dodgey definition
40+
create_or_replace_view(:latest_matrix_for_consumer_version_and_provider_version,
41+
"SELECT matrix.* FROM matrix
42+
INNER JOIN latest_verification_id_for_consumer_version_and_provider_version AS lv
43+
ON ((matrix.consumer_version_id = lv.consumer_version_id)
44+
AND (matrix.provider_version_id = lv.provider_version_id)
45+
AND ((matrix.verification_id = lv.latest_verification_id)))
46+
47+
UNION
48+
49+
select matrix.* from matrix
50+
inner join latest_pact_publication_revision_numbers lr
51+
on matrix.consumer_id = lr.consumer_id
52+
and matrix.provider_id = lr.provider_id
53+
and matrix.consumer_version_order = lr.consumer_version_order
54+
and matrix.pact_revision_number = lr.latest_revision_number
55+
where verification_id is null
56+
"
57+
)
58+
end
59+
end

lib/pact_broker/index/service.rb

-3
Original file line numberDiff line numberDiff line change
@@ -14,9 +14,6 @@ class Service
1414
extend PactBroker::Services
1515
extend PactBroker::Logging
1616

17-
# Used when using table_print to output query results
18-
TP_COLS = [:consumer_name, :consumer_version_number, :consumer_version_id, :provider_name, :provider_id, :provider_version_number]
19-
2017
def self.find_index_items options = {}
2118
rows = []
2219
overall_latest_publication_ids = nil

lib/pact_broker/matrix/repository.rb

+5-2
Original file line numberDiff line numberDiff line change
@@ -20,16 +20,17 @@ class Repository
2020
GROUP_BY_PACT = [:consumer_name, :provider_name]
2121

2222
def refresh params
23+
PactBroker::Matrix::Row.refresh(params)
2324
PactBroker::Matrix::HeadRow.refresh(params)
2425
end
2526

2627
# Return the latest matrix row (pact/verification) for each consumer_version_number/provider_version_number
2728
def find selectors, options = {}
28-
# The group with the nil provider_version_numbers will be the results of the left outer join
29-
# that don't have verifications, so we need to include them all.
3029
lines = query_matrix(resolve_selectors(selectors, options), options)
3130
lines = apply_latestby(options, selectors, lines)
3231

32+
# This needs to be done after the latestby, so can't be done in the db unless
33+
# the latestby logic is moved to the db
3334
if options.key?(:success)
3435
lines = lines.select{ |l| options[:success].include?(l.success) }
3536
end
@@ -45,6 +46,8 @@ def apply_latestby options, selectors, lines
4546
when 'cp' then GROUP_BY_PACT
4647
end
4748

49+
# The group with the nil provider_version_numbers will be the results of the left outer join
50+
# that don't have verifications, so we need to include them all.
4851
lines.group_by{|line| group_by_columns.collect{|key| line.send(key) }}
4952
.values
5053
.collect{ | lines | lines.first.provider_version_number.nil? ? lines : lines.first }

lib/pact_broker/matrix/row.rb

+3
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,9 @@ module PactBroker
66
module Matrix
77
class Row < Sequel::Model(:materialized_matrix)
88

9+
# Used when using table_print to output query results
10+
TP_COLS = [:consumer_version_number, :consumer_version_id, :pact_revision_number, :provider_id, :provider_version_number, :verification_number]
11+
912
associate(:one_to_many, :latest_triggered_webhooks, :class => "PactBroker::Webhooks::LatestTriggeredWebhook", primary_key: :pact_publication_id, key: :pact_publication_id)
1013
associate(:one_to_many, :webhooks, :class => "PactBroker::Webhooks::Webhook", primary_key: [:consumer_id, :provider_id], key: [:consumer_id, :provider_id])
1114
associate(:one_to_many, :consumer_version_tags, :class => "PactBroker::Tags::TagWithLatestFlag", primary_key: :consumer_version_id, key: :version_id)

lib/pact_broker/pacts/pact_version.rb

+2-1
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,8 @@ def latest_consumer_version
2222
end
2323

2424
def latest_pact_publication
25-
PactBroker::Pacts::LatestPactPublicationsByConsumerVersion.where(pact_version_id: id).order(:consumer_version_order).last
25+
# This verification might be for an overwritten revision, so must use AllPactPublications
26+
PactBroker::Pacts::AllPactPublications.where(pact_version_id: id).order(:consumer_version_order).last
2627
end
2728

2829
def consumer_versions

spec/lib/pact_broker/matrix/repository_spec.rb

+41
Original file line numberDiff line numberDiff line change
@@ -248,6 +248,47 @@ def shorten_rows rows
248248
end
249249
end
250250

251+
describe "find" do
252+
describe "when a pact for a particular consumer version is published, then re-published with different content, then published again with the original content" do
253+
before do
254+
first_pact = td.create_pact_with_hierarchy("billy", "1", "bobby").and_return(:pact)
255+
td.create_verification(provider_version: "1")
256+
.revise_pact
257+
.revise_pact(first_pact.json_content)
258+
end
259+
260+
let(:selectors) { build_selectors('billy' => nil, 'bobby' => nil) }
261+
262+
subject { Repository.new.find(selectors, options) }
263+
264+
context "when latestby: cvpv" do
265+
let(:options) { { latestby: 'cvpv' } }
266+
267+
it "only includes the row for the latest revision" do
268+
expect(subject.size).to eq 1
269+
expect(subject).to contain_hash(pact_revision_number: 3)
270+
end
271+
end
272+
273+
context "when latestby: cvp" do
274+
let(:options) { { latestby: 'cvp' } }
275+
276+
it "only includes the row for the latest revision" do
277+
expect(subject.size).to eq 1
278+
expect(subject).to contain_hash(pact_revision_number: 3)
279+
end
280+
end
281+
282+
context "when latestby: nil" do
283+
let(:options) { {} }
284+
285+
it "includes all the rows" do
286+
expect(subject.size).to eq 3
287+
end
288+
end
289+
end
290+
end
291+
251292
describe "find" do
252293
let(:options) { {} }
253294

spec/support/test_data_builder.rb

+3-1
Original file line numberDiff line numberDiff line change
@@ -206,14 +206,16 @@ def create_pact params = {}
206206
self
207207
end
208208

209-
def create_same_pact params = {}
209+
def republish_same_pact params = {}
210210
last_pact_version = PactBroker::Pacts::PactVersion.order(:id).last
211211
create_pact json_content: last_pact_version.content
212+
self
212213
end
213214

214215
def revise_pact json_content = nil
215216
json_content = json_content ? json_content : {random: rand}.to_json
216217
@pact = PactBroker::Pacts::Repository.new.update(@pact.id, json_content: json_content)
218+
refresh_matrix
217219
self
218220
end
219221

0 commit comments

Comments
 (0)