Skip to content

Commit

Permalink
feat: add ${pactbroker.consumerVersionNumber} to webhook templates
Browse files Browse the repository at this point in the history
  • Loading branch information
bethesque committed Jun 7, 2018
1 parent 690e39b commit d525527
Show file tree
Hide file tree
Showing 5 changed files with 85 additions and 66 deletions.
1 change: 1 addition & 0 deletions lib/pact_broker/doc/views/webhooks.markdown
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@ A request body can be specified as well.
The following variables may be used in the request parameters or body, and will be replaced with their appropriate values at runtime.

`${pactbroker.pactUrl}`: the "permalink" URL to the newly published pact (the URL specifying the consumer version URL, rather than the "/latest" format.)
`${pactbroker.consumerVersionNumber}`: the version number of the most recent consumer version associated with the pact content.

Example usage:

Expand Down
22 changes: 4 additions & 18 deletions lib/pact_broker/domain/webhook_request.rb
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,10 @@
require 'pact_broker/messages'
require 'net/http'
require 'pact_broker/webhooks/redact_logs'
require 'pact_broker/webhooks/render'
require 'pact_broker/api/pact_broker_urls'
require 'pact_broker/build_http_options'
require 'cgi'

module PactBroker

Expand Down Expand Up @@ -91,11 +93,7 @@ def build_request uri, pact, execution_logger
req.basic_auth(username, password) if username

unless body.nil?
if String === body
req.body = gsub_body(pact, body)
else
req.body = gsub_body(pact, body.to_json)
end
req.body = PactBroker::Webhooks::Render.call(String === body ? body : body.to_json, pact)
end

execution_logger.info req.body
Expand Down Expand Up @@ -150,26 +148,14 @@ def http_request(uri)
end

def build_uri pact
URI(gsub_url(pact, url))
URI(PactBroker::Webhooks::Render.call(url, pact){ | value | CGI::escape(value)} )
end

def url_with_credentials pact
u = build_uri(pact)
u.userinfo = "#{CGI::escape username}:#{display_password}" if username
u
end

def gsub_body pact, body
base_url = PactBroker.configuration.base_url
body.gsub('${pactbroker.pactUrl}', PactBroker::Api::PactBrokerUrls.pact_url(base_url, pact))
end

def gsub_url pact, url
base_url = PactBroker.configuration.base_url
pact_url = PactBroker::Api::PactBrokerUrls.pact_url(base_url, pact)
escaped_pact_url = CGI::escape(pact_url)
url.gsub('${pactbroker.pactUrl}', escaped_pact_url)
end
end
end
end
23 changes: 23 additions & 0 deletions lib/pact_broker/webhooks/render.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
module PactBroker
module Webhooks
class Render
def self.call(body, pact, verification = nil, &escaper)
base_url = PactBroker.configuration.base_url
params = {
'${pactbroker.pactUrl}' => PactBroker::Api::PactBrokerUrls.pact_url(base_url, pact),
'${pactbroker.consumerVersionNumber}' => pact.consumer_version_number
}

if escaper
params.keys.each do | key |
params[key] = escaper.call(params[key])
end
end

params.inject(body) do | body, (key, value) |
body.gsub(key, value)
end
end
end
end
end
69 changes: 21 additions & 48 deletions spec/lib/pact_broker/domain/webhook_request_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,9 @@ module Domain
allow(PactBroker.logger).to receive(:info).and_call_original
allow(PactBroker.logger).to receive(:debug).and_call_original
allow(PactBroker.logger).to receive(:warn).and_call_original
allow(PactBroker::Webhooks::Render).to receive(:call) do | content, pact, verification, &block |
content
end
end

let(:username) { nil }
Expand Down Expand Up @@ -57,51 +60,37 @@ module Domain
describe "execute" do
let!(:http_request) do
stub_request(:post, "http://example.org/hook").
with(:headers => {'Content-Type'=>'text/plain'}, :body => 'body').
with(:headers => {'Content-Type'=>'text/plain'}, :body => request_body).
to_return(:status => 200, :body => "respbod", :headers => {'Content-Type' => 'text/foo, blah'})
end

describe "when the String body contains a ${pactbroker.pactUrl} parameter" do
let!(:http_request) do
stub_request(:post, "http://example.org/hook").
with(:headers => {'Content-Type'=>'text/plain'}, :body => "<xml><url>http://example.org/pact-url</url></xml>").
to_return(:status => 200)
end

let(:body) { "<xml><url>${pactbroker.pactUrl}</url></xml>" }
let(:request_body) { 'body' }

it "replaces the token with the live value" do
subject.execute(pact, options)
expect(http_request).to have_been_made
it "renders the url template" do
expect(PactBroker::Webhooks::Render).to receive(:call).with("http://example.org/hook", pact) do | content, pact, verification, &block |
expect(content).to eq "http://example.org/hook"
expect(pact).to be pact
expect(verification).to be nil
expect(block.call("foo bar")).to eq "foo+bar"
"http://example.org/hook"
end
subject.execute(pact, options)
end

describe "when the JSON body contains a ${pactbroker.pactUrl} parameter" do
let!(:http_request) do
stub_request(:post, "http://example.org/hook").
with(:headers => {'Content-Type'=>'text/plain'}, :body => '{"url":"http://example.org/pact-url"}').
to_return(:status => 200)
end

let(:body) { { url: '${pactbroker.pactUrl}' } }

it "replaces the token with the live value" do
context "when the body is a string" do
it "renders the body template with the String" do
expect(PactBroker::Webhooks::Render).to receive(:call).with('body', pact)
subject.execute(pact, options)
expect(http_request).to have_been_made
end
end

describe "when the URL contains a ${pactbroker.pactUrl} parameter" do
let!(:http_request) do
stub_request(:post, "http://example.org/hook?url=http%3A%2F%2Fexample.org%2Fpact-url").
to_return(:status => 200)
end

let(:url) { 'http://example.org/hook?url=${pactbroker.pactUrl}' }
context "when the body is an object" do
let(:body) { {"foo" => "bar"} }
let(:request_body) { '{"foo":"bar"}' }

it "replaces the token with the live value" do
it "renders the body template with JSON" do
expect(PactBroker::Webhooks::Render).to receive(:call).with(request_body, pact)
subject.execute(pact, options)
expect(http_request).to have_been_made
end
end

Expand Down Expand Up @@ -234,21 +223,6 @@ module Domain
end
end

context "when the request has a JSONable body" do
let(:body) { [{"some": "json"}] }

let!(:http_request) do
stub_request(:post, "http://example.org/hook").
with(:headers => {'Content-Type'=>'text/plain'}, :body => body.to_json).
to_return(:status => 200, :body => "respbod", :headers => {'Content-Type' => 'text/foo, blah'})
end

it "converts the body to JSON before submitting the request" do
subject.execute(pact, options)
expect(http_request).to have_been_made
end
end

context "when the request has a nil body" do
let(:body) { nil }

Expand All @@ -275,7 +249,6 @@ module Domain
end

context "when the request is not successful" do

let!(:http_request) do
stub_request(:post, "http://example.org/hook").
with(:headers => {'Content-Type'=>'text/plain'}, :body => 'body').
Expand Down
36 changes: 36 additions & 0 deletions spec/lib/pact_broker/webhooks/render_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
require 'pact_broker/webhooks/render'
require 'cgi'

module PactBroker
module Webhooks
describe Render do
describe "#call" do
before do
allow(PactBroker::Api::PactBrokerUrls).to receive(:pact_url).and_return("http://foo")
end

let(:body) do
"Foo ${pactbroker.pactUrl} ${pactbroker.consumerVersionNumber}"
end

let(:pact) do
instance_double("pact", consumer_version_number: "1.2.3+foo")
end

subject { Render.call(body, pact, nil) }

it { is_expected.to eq "Foo http://foo 1.2.3+foo" }

context "with an escaper" do
subject do
Render.call(body, pact, nil) do | value |
CGI.escape(value)
end
end

it { is_expected.to eq "Foo http%3A%2F%2Ffoo 1.2.3%2Bfoo" }
end
end
end
end
end

0 comments on commit d525527

Please sign in to comment.