Skip to content

Commit

Permalink
feat: include tag and consumer version number in metadata parameter o…
Browse files Browse the repository at this point in the history
…f verification creation URL when verifying latest pact for a tag
  • Loading branch information
bethesque committed Feb 23, 2020
1 parent 13cb20b commit 3b59e82
Show file tree
Hide file tree
Showing 7 changed files with 89 additions and 25 deletions.
13 changes: 8 additions & 5 deletions lib/pact_broker/api/pact_broker_urls.rb
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
require 'erb'
require 'pact_broker/pacts/metadata'

module PactBroker
module Api
module PactBrokerUrls

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

extend self
Expand Down Expand Up @@ -59,13 +61,14 @@ def pact_version_url_with_metadata pact, base_url = ''
end

def build_webhook_metadata(pact)
Base64.strict_encode64(Rack::Utils.build_nested_query(
consumer_version_number: pact.consumer_version_number,
consumer_version_tags: pact.consumer_version_tag_names
))
encode_webhook_metadata(build_metadata_for_webhook_triggered_by_pact_publication(pact))
end

def parse_webhook_metadata(metadata)
def encode_webhook_metadata(metadata)
Base64.strict_encode64(Rack::Utils.build_nested_query(metadata))
end

def decode_webhook_metadata(metadata)
if metadata
Rack::Utils.parse_nested_query(Base64.strict_decode64(metadata)).each_with_object({}) do | (k, v), new_hash |
new_hash[k.to_sym] = v
Expand Down
8 changes: 6 additions & 2 deletions lib/pact_broker/api/resources/latest_pact.rb
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
require 'pact_broker/api/resources/base_resource'
require 'pact_broker/configuration'
require 'pact_broker/api/decorators/extended_pact_decorator'
require 'pact_broker/pacts/metadata'

module PactBroker
module Api
Expand All @@ -25,11 +26,11 @@ def resource_exists?

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

def to_extended_json
PactBroker::Api::Decorators::ExtendedPactDecorator.new(pact).to_json(user_options: decorator_context(metadata: identifier_from_path[:metadata]))
PactBroker::Api::Decorators::ExtendedPactDecorator.new(pact).to_json(user_options: decorator_context(metadata: metadata))
end

def to_html
Expand All @@ -44,6 +45,9 @@ def pact
@pact ||= pact_service.find_latest_pact(identifier_from_path)
end

def metadata
@metadata ||= encode_webhook_metadata(PactBroker::Pacts::Metadata.build_metadata_for_latest_pact(pact, identifier_from_path))
end
end
end
end
Expand Down
2 changes: 1 addition & 1 deletion lib/pact_broker/api/resources/verifications.rb
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ def update_matrix_after_request?
end

def metadata
PactBrokerUrls.parse_webhook_metadata(identifier_from_path[:metadata])
PactBrokerUrls.decode_webhook_metadata(identifier_from_path[:metadata])
end

def webhook_options
Expand Down
37 changes: 37 additions & 0 deletions lib/pact_broker/pacts/metadata.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
module PactBroker
module Pacts
module Metadata
extend self

# When verifying a pact at /.../latest/TAG, this stores the
# tag and the current consumer version number in the
# metadata parameter of the URL for publishing the verification results.
# This is part of ensuring that verification results webhooks
# go back to the correct consumer version number (eg for git statuses)
def build_metadata_for_latest_pact(pact, selection_parameters)
if selection_parameters[:tag]
{
consumer_version_tags: selection_parameters[:tag],
consumer_version_number: pact.consumer_version_number
}
else
{
consumer_version_number: pact.consumer_version_number
}
end
end

# When a pact is published, and a webhook is triggered, this stores
# the current tags and consumer version number in the metadata parameter of the
# pact version URL that is made available in the webhook template
# parameters. This is part of ensuring that verification results webhooks
# go back to the correct consumer version number (eg for git statuses)
def build_metadata_for_webhook_triggered_by_pact_publication(pact)
{
consumer_version_number: pact.consumer_version_number,
consumer_version_tags: pact.consumer_version_tag_names
}
end
end
end
end
6 changes: 3 additions & 3 deletions spec/lib/pact_broker/api/pact_broker_urls_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -107,14 +107,14 @@ module Api
end

it "builds the webhook metadata" do
expect(PactBrokerUrls.parse_webhook_metadata(PactBrokerUrls.build_webhook_metadata(pact))).to eq (expected_metadata)
expect(PactBrokerUrls.decode_webhook_metadata(PactBrokerUrls.build_webhook_metadata(pact))).to eq (expected_metadata)
end
end

describe "parse_webhook_metadata" do
describe "decode_webhook_metadata" do
context "when the metadata is nil" do
it "returns an empty hash" do
expect(PactBrokerUrls.parse_webhook_metadata(nil)).to eq({})
expect(PactBrokerUrls.decode_webhook_metadata(nil)).to eq({})
end
end
end
Expand Down
44 changes: 32 additions & 12 deletions spec/lib/pact_broker/api/resources/latest_pact_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -3,32 +3,27 @@
require 'rack/test'

module PactBroker::Api

module Resources

describe LatestPact do

include Rack::Test::Methods

let(:app) { PactBroker::API }

describe "GET" do

context "Accept: text/html" do

let(:path) { "/pacts/provider/provider_name/consumer/consumer_name/latest" }
let(:path) { "/pacts/provider/provider_name/consumer/consumer_name/latest/prod" }
let(:json_content) { 'json_content' }
let(:pact) { double("pact", json_content: json_content)}
let(:pact) { double("pact", json_content: json_content, consumer_version_number: '1') }
let(:html) { 'html' }
let(:pact_id_params) { {provider_name: "provider_name", consumer_name: "consumer_name"} }
let(:html_options) { { base_url: 'http://example.org', badge_url: "http://example.org#{path}/badge.svg" } }
let(:metadata) { double('metadata') }
let(:accept) { "text/html" }

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

subject { get path ,{}, {'HTTP_ACCEPT' => "text/html"} }
subject { get(path, nil, 'HTTP_ACCEPT' => accept) }

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


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

context "when Accept is application/hal+json" do
let(:accept) { "application/hal+json" }
let(:decorator) { instance_double(PactBroker::Api::Decorators::PactDecorator, to_json: pact_json)}
let(:pact_json) { { some: 'json' }.to_json }

before do
allow(PactBroker::Api::Decorators::PactDecorator).to receive(:new).and_return(decorator)
allow(PactBroker::Pacts::Metadata).to receive(:build_metadata_for_latest_pact).and_return(metadata)
allow_any_instance_of(LatestPact).to receive(:encode_webhook_metadata).and_return('encoded metadata')
end

it "builds the metadata" do
expect(PactBroker::Pacts::Metadata).to receive(:build_metadata_for_latest_pact).with(pact, hash_including(tag: 'prod'))
subject
end

it "encodes the metadata" do
expect_any_instance_of(LatestPact).to receive(:encode_webhook_metadata).with(metadata)
subject
end

it "renders the pact in JSON" do
expect(decorator).to receive(:to_json).with(user_options: hash_including(metadata: 'encoded metadata'))
expect(subject.body).to eq pact_json
end
end
end
end

end
end

end
4 changes: 2 additions & 2 deletions spec/lib/pact_broker/api/resources/verifications_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ module Resources
before do
allow(PactBroker::Verifications::Service).to receive(:create).and_return(verification)
allow(PactBroker::Verifications::Service).to receive(:errors).and_return(double(:errors, messages: ['errors'], empty?: errors_empty))
allow(PactBrokerUrls).to receive(:parse_webhook_metadata).and_return(parsed_metadata)
allow(PactBrokerUrls).to receive(:decode_webhook_metadata).and_return(parsed_metadata)
allow_any_instance_of(Verifications).to receive(:webhook_execution_configuration).and_return(webhook_execution_configuration)
allow(webhook_execution_configuration).to receive(:with_webhook_context).and_return(webhook_execution_configuration)
end
Expand Down Expand Up @@ -65,7 +65,7 @@ module Resources
end

it "parses the webhook metadata" do
expect(PactBrokerUrls).to receive(:parse_webhook_metadata).with("abcd")
expect(PactBrokerUrls).to receive(:decode_webhook_metadata).with("abcd")
subject
end

Expand Down

0 comments on commit 3b59e82

Please sign in to comment.