Skip to content

Commit 3b59e82

Browse files
committed
feat: include tag and consumer version number in metadata parameter of verification creation URL when verifying latest pact for a tag
1 parent 13cb20b commit 3b59e82

File tree

7 files changed

+89
-25
lines changed

7 files changed

+89
-25
lines changed

lib/pact_broker/api/pact_broker_urls.rb

+8-5
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,11 @@
11
require 'erb'
2+
require 'pact_broker/pacts/metadata'
23

34
module PactBroker
45
module Api
56
module PactBrokerUrls
67

8+
include PactBroker::Pacts::Metadata
79
# TODO make base_url the last and optional argument for all methods, defaulting to ''
810

911
extend self
@@ -59,13 +61,14 @@ def pact_version_url_with_metadata pact, base_url = ''
5961
end
6062

6163
def build_webhook_metadata(pact)
62-
Base64.strict_encode64(Rack::Utils.build_nested_query(
63-
consumer_version_number: pact.consumer_version_number,
64-
consumer_version_tags: pact.consumer_version_tag_names
65-
))
64+
encode_webhook_metadata(build_metadata_for_webhook_triggered_by_pact_publication(pact))
6665
end
6766

68-
def parse_webhook_metadata(metadata)
67+
def encode_webhook_metadata(metadata)
68+
Base64.strict_encode64(Rack::Utils.build_nested_query(metadata))
69+
end
70+
71+
def decode_webhook_metadata(metadata)
6972
if metadata
7073
Rack::Utils.parse_nested_query(Base64.strict_decode64(metadata)).each_with_object({}) do | (k, v), new_hash |
7174
new_hash[k.to_sym] = v

lib/pact_broker/api/resources/latest_pact.rb

+6-2
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
require 'pact_broker/api/resources/base_resource'
22
require 'pact_broker/configuration'
33
require 'pact_broker/api/decorators/extended_pact_decorator'
4+
require 'pact_broker/pacts/metadata'
45

56
module PactBroker
67
module Api
@@ -25,11 +26,11 @@ def resource_exists?
2526

2627
def to_json
2728
response.headers['X-Pact-Consumer-Version'] = pact.consumer_version_number
28-
PactBroker::Api::Decorators::PactDecorator.new(pact).to_json(user_options: { base_url: base_url })
29+
PactBroker::Api::Decorators::PactDecorator.new(pact).to_json(user_options: decorator_context(metadata: metadata))
2930
end
3031

3132
def to_extended_json
32-
PactBroker::Api::Decorators::ExtendedPactDecorator.new(pact).to_json(user_options: decorator_context(metadata: identifier_from_path[:metadata]))
33+
PactBroker::Api::Decorators::ExtendedPactDecorator.new(pact).to_json(user_options: decorator_context(metadata: metadata))
3334
end
3435

3536
def to_html
@@ -44,6 +45,9 @@ def pact
4445
@pact ||= pact_service.find_latest_pact(identifier_from_path)
4546
end
4647

48+
def metadata
49+
@metadata ||= encode_webhook_metadata(PactBroker::Pacts::Metadata.build_metadata_for_latest_pact(pact, identifier_from_path))
50+
end
4751
end
4852
end
4953
end

lib/pact_broker/api/resources/verifications.rb

+1-1
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,7 @@ def update_matrix_after_request?
7272
end
7373

7474
def metadata
75-
PactBrokerUrls.parse_webhook_metadata(identifier_from_path[:metadata])
75+
PactBrokerUrls.decode_webhook_metadata(identifier_from_path[:metadata])
7676
end
7777

7878
def webhook_options

lib/pact_broker/pacts/metadata.rb

+37
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
module PactBroker
2+
module Pacts
3+
module Metadata
4+
extend self
5+
6+
# When verifying a pact at /.../latest/TAG, this stores the
7+
# tag and the current consumer version number in the
8+
# metadata parameter of the URL for publishing the verification results.
9+
# This is part of ensuring that verification results webhooks
10+
# go back to the correct consumer version number (eg for git statuses)
11+
def build_metadata_for_latest_pact(pact, selection_parameters)
12+
if selection_parameters[:tag]
13+
{
14+
consumer_version_tags: selection_parameters[:tag],
15+
consumer_version_number: pact.consumer_version_number
16+
}
17+
else
18+
{
19+
consumer_version_number: pact.consumer_version_number
20+
}
21+
end
22+
end
23+
24+
# When a pact is published, and a webhook is triggered, this stores
25+
# the current tags and consumer version number in the metadata parameter of the
26+
# pact version URL that is made available in the webhook template
27+
# parameters. This is part of ensuring that verification results webhooks
28+
# go back to the correct consumer version number (eg for git statuses)
29+
def build_metadata_for_webhook_triggered_by_pact_publication(pact)
30+
{
31+
consumer_version_number: pact.consumer_version_number,
32+
consumer_version_tags: pact.consumer_version_tag_names
33+
}
34+
end
35+
end
36+
end
37+
end

spec/lib/pact_broker/api/pact_broker_urls_spec.rb

+3-3
Original file line numberDiff line numberDiff line change
@@ -107,14 +107,14 @@ module Api
107107
end
108108

109109
it "builds the webhook metadata" do
110-
expect(PactBrokerUrls.parse_webhook_metadata(PactBrokerUrls.build_webhook_metadata(pact))).to eq (expected_metadata)
110+
expect(PactBrokerUrls.decode_webhook_metadata(PactBrokerUrls.build_webhook_metadata(pact))).to eq (expected_metadata)
111111
end
112112
end
113113

114-
describe "parse_webhook_metadata" do
114+
describe "decode_webhook_metadata" do
115115
context "when the metadata is nil" do
116116
it "returns an empty hash" do
117-
expect(PactBrokerUrls.parse_webhook_metadata(nil)).to eq({})
117+
expect(PactBrokerUrls.decode_webhook_metadata(nil)).to eq({})
118118
end
119119
end
120120
end

spec/lib/pact_broker/api/resources/latest_pact_spec.rb

+32-12
Original file line numberDiff line numberDiff line change
@@ -3,32 +3,27 @@
33
require 'rack/test'
44

55
module PactBroker::Api
6-
76
module Resources
8-
97
describe LatestPact do
10-
118
include Rack::Test::Methods
12-
13-
let(:app) { PactBroker::API }
14-
159
describe "GET" do
16-
1710
context "Accept: text/html" do
1811

19-
let(:path) { "/pacts/provider/provider_name/consumer/consumer_name/latest" }
12+
let(:path) { "/pacts/provider/provider_name/consumer/consumer_name/latest/prod" }
2013
let(:json_content) { 'json_content' }
21-
let(:pact) { double("pact", json_content: json_content)}
14+
let(:pact) { double("pact", json_content: json_content, consumer_version_number: '1') }
2215
let(:html) { 'html' }
2316
let(:pact_id_params) { {provider_name: "provider_name", consumer_name: "consumer_name"} }
2417
let(:html_options) { { base_url: 'http://example.org', badge_url: "http://example.org#{path}/badge.svg" } }
18+
let(:metadata) { double('metadata') }
19+
let(:accept) { "text/html" }
2520

2621
before do
2722
allow(PactBroker::Pacts::Service).to receive(:find_latest_pact).and_return(pact)
2823
allow(PactBroker.configuration.html_pact_renderer).to receive(:call).and_return(html)
2924
end
3025

31-
subject { get path ,{}, {'HTTP_ACCEPT' => "text/html"} }
26+
subject { get(path, nil, 'HTTP_ACCEPT' => accept) }
3227

3328
it "find the pact" do
3429
expect(PactBroker::Pacts::Service).to receive(:find_latest_pact).with(hash_including(pact_id_params))
@@ -40,6 +35,7 @@ module Resources
4035
subject
4136
end
4237

38+
4339
it "returns a HTML body" do
4440
subject
4541
expect(last_response.body).to eq html
@@ -50,10 +46,34 @@ module Resources
5046
expect(last_response.headers['Content-Type']).to eq 'text/html;charset=utf-8'
5147
end
5248

49+
context "when Accept is application/hal+json" do
50+
let(:accept) { "application/hal+json" }
51+
let(:decorator) { instance_double(PactBroker::Api::Decorators::PactDecorator, to_json: pact_json)}
52+
let(:pact_json) { { some: 'json' }.to_json }
53+
54+
before do
55+
allow(PactBroker::Api::Decorators::PactDecorator).to receive(:new).and_return(decorator)
56+
allow(PactBroker::Pacts::Metadata).to receive(:build_metadata_for_latest_pact).and_return(metadata)
57+
allow_any_instance_of(LatestPact).to receive(:encode_webhook_metadata).and_return('encoded metadata')
58+
end
59+
60+
it "builds the metadata" do
61+
expect(PactBroker::Pacts::Metadata).to receive(:build_metadata_for_latest_pact).with(pact, hash_including(tag: 'prod'))
62+
subject
63+
end
64+
65+
it "encodes the metadata" do
66+
expect_any_instance_of(LatestPact).to receive(:encode_webhook_metadata).with(metadata)
67+
subject
68+
end
69+
70+
it "renders the pact in JSON" do
71+
expect(decorator).to receive(:to_json).with(user_options: hash_including(metadata: 'encoded metadata'))
72+
expect(subject.body).to eq pact_json
73+
end
74+
end
5375
end
5476
end
55-
5677
end
5778
end
58-
5979
end

spec/lib/pact_broker/api/resources/verifications_spec.rb

+2-2
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ module Resources
2424
before do
2525
allow(PactBroker::Verifications::Service).to receive(:create).and_return(verification)
2626
allow(PactBroker::Verifications::Service).to receive(:errors).and_return(double(:errors, messages: ['errors'], empty?: errors_empty))
27-
allow(PactBrokerUrls).to receive(:parse_webhook_metadata).and_return(parsed_metadata)
27+
allow(PactBrokerUrls).to receive(:decode_webhook_metadata).and_return(parsed_metadata)
2828
allow_any_instance_of(Verifications).to receive(:webhook_execution_configuration).and_return(webhook_execution_configuration)
2929
allow(webhook_execution_configuration).to receive(:with_webhook_context).and_return(webhook_execution_configuration)
3030
end
@@ -65,7 +65,7 @@ module Resources
6565
end
6666

6767
it "parses the webhook metadata" do
68-
expect(PactBrokerUrls).to receive(:parse_webhook_metadata).with("abcd")
68+
expect(PactBrokerUrls).to receive(:decode_webhook_metadata).with("abcd")
6969
subject
7070
end
7171

0 commit comments

Comments
 (0)