Skip to content

Commit

Permalink
feat: add endpoint to return latest pact for consumer, provider and c…
Browse files Browse the repository at this point in the history
…onsumer branch
  • Loading branch information
bethesque committed Jul 28, 2023
1 parent b26ddb4 commit f77086e
Show file tree
Hide file tree
Showing 6 changed files with 52 additions and 3 deletions.
1 change: 1 addition & 0 deletions lib/pact_broker/api.rb
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@ def self.build_api(application_context = PactBroker::ApplicationContext.default_
# Latest pacts
add ["pacts", "provider", :provider_name, "consumer", :consumer_name, "latest"], Api::Resources::LatestPact, {resource_name: "latest_pact_publication"}
add ["pacts", "provider", :provider_name, "consumer", :consumer_name, "latest", :tag], Api::Resources::LatestPact, {resource_name: "latest_tagged_pact_publication"}
add ["pacts", "provider", :provider_name, "consumer", :consumer_name, "branch", :branch_name, "latest"], Api::Resources::LatestPact, {resource_name: "latest_pact_publication_for_branch"}
add ["pacts", "provider", :provider_name], Api::Resources::ProviderPacts, {resource_name: "provider_pact_publications"}
add ["pacts", "provider", :provider_name, "tag", :tag], Api::Resources::ProviderPacts, {resource_name: "tagged_provider_pact_publications"}
add ["pacts", "provider", :provider_name, "consumer", :consumer_name, "latest-untagged"], Api::Resources::LatestPact, {resource_name: "latest_untagged_pact_publication", tag: :untagged}
Expand Down
6 changes: 5 additions & 1 deletion lib/pact_broker/pacts/pact_publication_dataset_module.rb
Original file line number Diff line number Diff line change
Expand Up @@ -132,10 +132,14 @@ def for_branch_heads(branch_name)
.remove_overridden_revisions_from_complete_query
end

# The pact that belongs to the branch head.
# May return nil if the branch head does not have a pact published for it.
def latest_for_consumer_branch(branch_name)
for_branch_heads(branch_name)
end

# The latest pact that belongs to a version on the specified branch (might not be the version that is the branch head)
# Always returns a pact, if any pacts exist for this branch.
def old_latest_for_consumer_branch(branch_name)
branch_versions_join = {
Sequel[:pact_publications][:consumer_version_id] => Sequel[:branch_versions][:version_id]
Expand All @@ -148,7 +152,7 @@ def old_latest_for_consumer_branch(branch_name)

max_orders = join(:branch_versions, branch_versions_join)
.join(:branches, branches_join)
.select_group(:consumer_id, :provider_id, Sequel[:branches][:name].as(:branch_name))
.select_group(Sequel[:pact_publications][:consumer_id], Sequel[:pact_publications][:provider_id], Sequel[:branches][:name].as(:branch_name))
.select_append{ max(consumer_version_order).as(latest_consumer_version_order) }

max_join = {
Expand Down
4 changes: 3 additions & 1 deletion lib/pact_broker/pacts/repository.rb
Original file line number Diff line number Diff line change
Expand Up @@ -200,7 +200,7 @@ def find_latest_pacts
.sort
end

def find_latest_pact(consumer_name, provider_name, tag = nil)
def find_latest_pact(consumer_name, provider_name, tag = nil, branch_name = nil)
query = scope_for(PactPublication)
.eager_for_domain_with_content
.select_all_qualified
Expand All @@ -211,6 +211,8 @@ def find_latest_pact(consumer_name, provider_name, tag = nil)
query = query.untagged
elsif tag
query = query.for_consumer_version_tag_all_revisions(tag)
elsif branch_name
query = query.old_latest_for_consumer_branch(branch_name)
end
query.latest_by_consumer_version_order.all.collect(&:to_domain_with_content)[0]
end
Expand Down
2 changes: 1 addition & 1 deletion lib/pact_broker/pacts/service.rb
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ module Service
extend SquashPactsForVerification

def find_latest_pact params
pact_repository.find_latest_pact(params[:consumer_name], params[:provider_name], params[:tag])
pact_repository.find_latest_pact(params[:consumer_name], params[:provider_name], params[:tag], params[:branch_name])
end

def search_for_latest_pact params
Expand Down
22 changes: 22 additions & 0 deletions spec/features/get_latest_pact_for_branch.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
describe "retrieving the latest pact for a branch" do
let(:path) { "/pacts/provider/Provider/consumer/Consumer/branch/main/latest" }
let(:json_response_body) { JSON.parse(subject.body, symbolize_names: true) }

subject { get(path) }

before do
td.create_consumer("Consumer")
.create_provider("Provider")
.create_consumer_version("1", branch: "main")
.create_pact
.create_consumer_version("2", branch: "main")
.create_pact
.create_consumer_version("3", branch: "foo")
.create_pact
.create_consumer_version("4", branch: "main")
end

it "returns the latest pact for the branch" do
expect(json_response_body[:_links][:self][:href]).to end_with("2")
end
end
20 changes: 20 additions & 0 deletions spec/lib/pact_broker/pacts/repository_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -965,6 +965,26 @@ module Pacts
end
end
end

context "with a branch specified" do
before do
td.create_consumer("Consumer")
.create_provider("Provider")
.create_consumer_version("1.0.0", branch: "main")
.create_pact
.create_consumer_version("1.2.3", branch: "main")
.create_pact
.create_consumer_version("2.3.4", branch: "main")
.create_consumer_version("4", branch: "foo")
.create_pact
end

subject { Repository.new.find_latest_pact("Consumer", "Provider", nil, "main") }

it "returns the latest pact that belongs to a version on the specified branch" do
expect(subject.consumer_version.number).to eq("1.2.3")
end
end
end

describe "search_for_latest_pact" do
Expand Down

0 comments on commit f77086e

Please sign in to comment.