Skip to content

Commit

Permalink
fix: when the latest version for a tag does not have a pact, do not r…
Browse files Browse the repository at this point in the history
…eturn a pact for the 'latest tag' selector

Fixes: #494
  • Loading branch information
bethesque committed Sep 9, 2021
1 parent ece9c17 commit 374c77c
Show file tree
Hide file tree
Showing 4 changed files with 131 additions and 2 deletions.
25 changes: 25 additions & 0 deletions lib/pact_broker/pacts/pact_publication_dataset_module.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

module PactBroker
module Pacts
# rubocop: disable Metrics/ModuleLength
module PactPublicationDatasetModule
include PactPublicationSelectorDatasetModule

Expand Down Expand Up @@ -187,6 +188,29 @@ def latest_for_consumer_tag(tag_name)
.remove_overridden_revisions_from_complete_query
end

# The pacts for the latest versions with the specified tag (new logic)
# NOT the latest pact that belongs to a version with the specified tag.
def for_latest_consumer_versions_with_tag(tag_name)
head_tags = PactBroker::Domain::Tag
.select_group(:pacticipant_id, :name)
.select_append{ max(version_order).as(:latest_version_order) }
.where(name: tag_name)

head_tags_join = {
Sequel[:pact_publications][:consumer_id] => Sequel[:head_tags][:pacticipant_id],
Sequel[:pact_publications][:consumer_version_order] => Sequel[:head_tags][:latest_version_order]
}

base_query = self
if no_columns_selected?
base_query = base_query.select_all_qualified.select_append(Sequel[:head_tags][:name].as(:tag_name))
end

base_query
.join(head_tags, head_tags_join, { table_alias: :head_tags })
.remove_overridden_revisions_from_complete_query
end

def verified_before_date(date)
where { Sequel[:verifications][:execution_date] < date }
end
Expand Down Expand Up @@ -311,5 +335,6 @@ def no_columns_selected?
opts[:select].nil?
end
end
# rubocop: enable Metrics/ModuleLength
end
end
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ def for_provider_and_consumer_version_selector provider, selector
# Do the "latest" logic last so that the provider/consumer criteria get included in the "latest" query before the join, rather than after
query = query.latest_for_main_branches if selector.latest_for_main_branch?
query = query.latest_for_consumer_branch(selector.branch) if selector.latest_for_branch?
query = query.latest_for_consumer_tag(selector.tag) if selector.latest_for_tag?
query = query.for_latest_consumer_versions_with_tag(selector.tag) if selector.latest_for_tag?
query = query.overall_latest if selector.overall_latest?
query
end
Expand Down
25 changes: 25 additions & 0 deletions script/data/issue-494.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
#!/usr/bin/env ruby
begin

$LOAD_PATH << "#{Dir.pwd}/lib"
require "pact_broker/test/http_test_data_builder"
base_url = ENV["PACT_BROKER_BASE_URL"] || "http://localhost:9292"

provider_name = "issue-494-provider"
consumer_name = "issue-494-consumer"

td = PactBroker::Test::HttpTestDataBuilder.new(base_url)
td.delete_pacticipant(consumer_name)
.delete_pacticipant(provider_name)
.publish_contract(consumer: consumer_name, provider: provider_name, consumer_version: "1", content_id: "1111", tag: "test")
.create_tag(pacticipant: consumer_name, version: "2", tag: "test")
.get_pacts_for_verification(
provider: provider_name,
consumer_version_selectors: [{ tag: "test", latest: true }]
)

rescue StandardError => e
puts "#{e.class} #{e.message}"
puts e.backtrace
exit 1
end
Original file line number Diff line number Diff line change
Expand Up @@ -246,7 +246,7 @@ module Pacts

subject { PactPublication.latest_for_consumer_tag("main") }

it "returns the latest pacts for the tags with the specified name (for any consumer/provider)" do
it "returns the pacts for the latest versions with the specified tags with the specified name (for any consumer/provider)" do
all = subject.all.sort_by{ |pact_publication| pact_publication.consumer_version.order }
expect(all.size).to eq 2
expect(all.first.consumer.name).to eq "Foo"
Expand All @@ -262,6 +262,85 @@ module Pacts
expect(subject.all.first.values.keys.sort).to eq (PactPublication.columns + [:tag_name]).sort
end

context "when the latest version with the tag does not have a pact" do
before do
td.use_consumer("Foo")
.create_consumer_version("12", tag_names: ["main"])
.use_consumer("Foo2")
.create_consumer_version("12", tag_names: ["main"])
end

it "returns the latest pact that belongs to a version with the specified tag" do
expect(subject.all.size).to eq 2
end
end

context "when columns are already selected" do
subject { PactPublication.select(Sequel[:pact_publications][:id]).latest_for_consumer_tag("main") }

it "does not override them" do
expect(subject.all.first.values.keys).to eq [:id]
end
end

context "when chained" do
it "works" do
all = PactPublication.for_provider(td.find_pacticipant("Bar")).latest_for_consumer_tag("main").all
expect(all.first.provider.name).to eq "Bar"
end
end
end

describe "for_latest_consumer_versions_with_tag" do
before do
td.create_consumer("Foo")
.create_provider("Bar")
.create_consumer_version("1", tag_names: ["main"])
.create_pact
.create_consumer_version("2", tag_names: ["main"])
.create_pact
.revise_pact
.create_consumer_version("3", tag_names: ["feat/x"])
.create_pact
.create_consumer("Foo2")
.create_provider("Bar2")
.create_consumer_version("10", tag_names: ["main"])
.create_pact
.create_consumer_version("11", tag_names: ["main"])
.create_pact
end

subject { PactPublication.for_latest_consumer_versions_with_tag("main") }

it "returns the pacts for the latest versions with the specified tags with the specified name (for any consumer/provider)" do
all = subject.all.sort_by{ |pact_publication| pact_publication.consumer_version.order }
expect(all.size).to eq 2
expect(all.first.consumer.name).to eq "Foo"
expect(all.first.provider.name).to eq "Bar"
expect(all.first.consumer_version.number).to eq "2"

expect(all.last.consumer.name).to eq "Foo2"
expect(all.last.provider.name).to eq "Bar2"
expect(all.last.consumer_version.number).to eq "11"
end

it "does not return extra columns" do
expect(subject.all.first.values.keys.sort).to eq (PactPublication.columns + [:tag_name]).sort
end

context "when the latest version with the tag does not have a pact" do
before do
td.use_consumer("Foo")
.create_consumer_version("12", tag_names: ["main"])
.use_consumer("Foo2")
.create_consumer_version("12", tag_names: ["main"])
end

it "returns an empty list" do
expect(subject.all).to eq []
end
end

context "when columns are already selected" do
subject { PactPublication.select(Sequel[:pact_publications][:id]).latest_for_consumer_tag("main") }

Expand Down

0 comments on commit 374c77c

Please sign in to comment.