Skip to content

Commit

Permalink
feat: include relations for each consumer version that a pact version…
Browse files Browse the repository at this point in the history
… belongs to when retrieved using the URL from the 'pacts for verification' response
  • Loading branch information
bethesque committed Oct 10, 2021
1 parent a727da8 commit 3458c9e
Show file tree
Hide file tree
Showing 6 changed files with 155 additions and 3 deletions.
12 changes: 12 additions & 0 deletions lib/pact_broker/api/decorators/pact_decorator.rb
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,18 @@ def to_hash(options = {})
}
end

links :'pb:consumer-versions' do | options |
if options[:consumer_versions]
options[:consumer_versions].collect do | consumer_version |
{
title: "Consumer version",
name: consumer_version.number,
href: version_url(options.fetch(:base_url), consumer_version)
}
end
end
end

link :'pb:provider' do | options |
{
title: "Provider",
Expand Down
34 changes: 32 additions & 2 deletions lib/pact_broker/api/resources/metadata_resource_methods.rb
Original file line number Diff line number Diff line change
Expand Up @@ -11,13 +11,43 @@ def pact_params
@pact_params ||= PactBroker::Pacts::PactParams.from_request(request, maybe_params_with_consumer_version_number.merge(path_info))
end

def maybe_params_with_consumer_version_number
metadata.slice(:consumer_version_number)
def maybe_consumer_version_number_param
if metadata[:consumer_version_number]
metadata.slice(:consumer_version_number)
elsif metadata_consumer_version_numbers&.any?
{
consumer_version_number: consumer_versions_from_metadata.last&.number
}
else
{}
end
end

def metadata
@metadata ||= PactBroker::Pacts::Metadata.parse_metadata(PactBrokerUrls.decode_pact_metadata(identifier_from_path[:metadata]))
end

def metadata_consumer_version_numbers
@metadata_consumer_version_numbers ||= begin
if metadata[:consumer_version_selectors].is_a?(Array)
metadata[:consumer_version_selectors].collect{ | selector | selector[:consumer_version_number] }.compact.uniq
elsif metadata[:consumer_version_number]
[metadata[:consumer_version_number]]
else
nil
end
end
end

def consumer_versions_from_metadata
@consumer_versions_from_metadata ||= begin
if metadata_consumer_version_numbers
metadata_consumer_version_numbers.collect do | consumer_version_number |
version_service.find_by_pacticipant_name_and_number(pacticipant_name: identifier_from_path[:consumer_name], pacticipant_version_number: consumer_version_number)
end.compact.sort_by(&:order)
end
end
end
end
end
end
Expand Down
4 changes: 4 additions & 0 deletions lib/pact_broker/api/resources/pact_version.rb
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,10 @@ class PactVersion < Pact
def allowed_methods
["GET", "OPTIONS"]
end

def decorator_options(options)
super(options.merge(consumer_versions: consumer_versions_from_metadata&.reverse))
end
end
end
end
Expand Down
1 change: 1 addition & 0 deletions lib/pact_broker/test/http_test_data_builder.rb
Original file line number Diff line number Diff line change
Expand Up @@ -224,6 +224,7 @@ def create_webhook_for_event(uuid: nil, url: "https://postman-echo.com/post", bo
puts "Creating #{webhook_prefix}webhook for contract changed event with uuid #{uuid}"
uuid ||= SecureRandom.uuid
default_body = {
"pactUrl" => "${pactbroker.pactUrl}",
"eventName" => "${pactbroker.eventName}",
"consumerName" => "${pactbroker.consumerName}",
"consumerVersionNumber" => "${pactbroker.consumerVersionNumber}",
Expand Down
2 changes: 1 addition & 1 deletion script/data/branches.rb
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
.publish_contract(consumer: "branch-consumer", provider: "branch-provider", consumer_version: "1", content_id: "1111", branch: "main")
.publish_contract(consumer: "branch-consumer", provider: "branch-provider", consumer_version: "1", content_id: "1111", branch: "feat/x")
.publish_contract(consumer: "branch-consumer", provider: "branch-provider", consumer_version: "2", content_id: "1111", branch: "feat/x")
.get_pacts_for_verification(provider: "branch-provider", enable_pending: false)
.get_pacts_for_verification(provider: "branch-provider", enable_pending: false, consumer_version_selectors: [ { branch: "main" }, { branch: "feat/x" }])
.verify_pact(
provider_version_branch: "main",
provider_version: "1",
Expand Down
105 changes: 105 additions & 0 deletions spec/integration/pact_metdata_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
RSpec.describe "the consumer version relations in the pact version resource" do
context "when requested with no metadata" do
before do
td.create_pact_with_hierarchy("Foo", "1", "Bar")
.create_consumer_version("2")
.republish_same_pact
end

let(:pact_version_url) { PactBroker::Api::PactBrokerUrls.pact_version_url(td.and_return(:pact)) }

subject { get(pact_version_url) }


it "includes the consumer version of the latest version that published the pact" do
body = JSON.parse(subject.body)
consumer_version_relation = body["_links"]["pb:consumer-version"]
expect(consumer_version_relation).to include("name" => "2")

consumer_versions_relations = body["_links"]["pb:consumer-versions"]
expect(consumer_versions_relations).to be nil
end
end
context "for a pact published webhook" do
before do
td.create_global_webhook(event_names: ["contract_published"], body: { "pact_url" => "${pactbroker.pactUrl}" })
.create_consumer("Foo")
.create_provider("Bar")
.create_consumer_version("1")
.create_pact(json_content: pact_content)
end

let(:database_connector) { ->(&block) { block.call } }
let(:pact_content) { td.random_json_content("Foo", "Bar") }

let!(:webhook_request) do
stub_request(:post, /http/).to_return(:status => 200)
end

let(:publish_pact) { put("/pacts/provider/Bar/consumer/Foo/version/2", pact_content, { "CONTENT_TYPE" => "application/json", "pactbroker.database_connector" => database_connector }) }

let(:pact_version_response) do
publish_pact
pact_url = PactBroker::Webhooks::Execution.last.logs.scan(/(http:\/\/example.org\/pacts.*?)"/).last.last
get(pact_url)
end

it "includes the consumer version of the version that just published the pact" do
body = JSON.parse(pact_version_response.body)

consumer_version_relation = body["_links"]["pb:consumer-version"]
expect(consumer_version_relation).to include("name" => "2")

consumer_versions_relations = body["_links"]["pb:consumer-versions"]
expect(consumer_versions_relations.size).to eq 1
expect(consumer_versions_relations).to contain_hash("name" => "2")
end
end

context "for pacts for verification" do
before do
json_content = td.random_json_content("Foo", "Bar")
td.create_consumer("Foo")
.create_provider("Bar")
.create_consumer_version("1", branch: "main")
.create_pact(json_content: json_content)
.create_consumer_version("2", branch: "feat/x")
.create_pact(json_content: json_content)
.create_consumer_version("2", branch: "feat/y")
.create_pact(json_content: json_content)
.create_consumer_version("3", branch: "feat/z")
end

let(:pacts_for_verification_request_body) do
{
consumerVersionSelectors: [ { branch: "main" }, { branch: "feat/x" }, { branch: "feat/y" } ],
}.to_json
end

let(:rack_headers) do
{
"HTTP_ACCEPT" => "application/hal+json"
}
end

let(:pacts_for_verification) do
response = post("/pacts/provider/Bar/for-verification", pacts_for_verification_request_body, rack_headers)
JSON.parse(response.body)["_embedded"]["pacts"]
end

let(:pact_version_url) do
pacts_for_verification[0]["_links"]["self"]["href"]
end

it "includes links for all the consumer versions for which it was selected" do
body = JSON.parse(get(pact_version_url).body)
consumer_version_relation = body["_links"]["pb:consumer-version"]
expect(consumer_version_relation).to include("name" => "2")

consumer_versions_relations = body["_links"]["pb:consumer-versions"]
expect(consumer_versions_relations.size).to eq 2
expect(consumer_versions_relations).to contain_hash("name" => "2")
expect(consumer_versions_relations).to contain_hash("name" => "1")
end
end
end

0 comments on commit 3458c9e

Please sign in to comment.