Skip to content

Commit

Permalink
feat: include test webhook request in execution response body
Browse files Browse the repository at this point in the history
  • Loading branch information
bethesque committed Jun 20, 2018
1 parent 460b194 commit 7518098
Show file tree
Hide file tree
Showing 7 changed files with 88 additions and 12 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,32 @@ class ErrorDecorator < BaseDecorator
property :backtrace
end

class HTTPRequestDecorator < BaseDecorator
property :headers, exec_context: :decorator
property :body, exec_context: :decorator
property :url, exec_context: :decorator

def headers
headers_hash = represented.to_hash
headers_hash.keys.each_with_object({}) do | name, new_headers_hash|
new_headers_hash[name] = headers_hash[name].join(", ")
end
end

def body
begin
::JSON.parse(represented.body)
rescue StandardError => e
represented.body
end
end

def url
(represented.uri || represented.path).to_s
end
end


class HTTPResponseDecorator < BaseDecorator
property :status, :getter => lambda { |_| code.to_i }
property :headers, exec_context: :decorator
Expand All @@ -33,6 +59,7 @@ def body
end

property :error, :extend => ErrorDecorator, if: lambda { |context| context[:options][:user_options][:show_response] }
property :request, :extend => HTTPRequestDecorator
property :response, :extend => HTTPResponseDecorator, if: lambda { |context| context[:options][:user_options][:show_response] }
property :response_hidden_message, as: :message, exec_context: :decorator, if: lambda { |context| !context[:options][:user_options][:show_response] }

Expand Down
2 changes: 1 addition & 1 deletion lib/pact_broker/domain/webhook.rb
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ def execute pact, verification, options
end

def to_s
"webhook for consumer=#{consumer_name} provider=#{provider_name} uuid=#{uuid} request=#{request}"
"webhook for consumer=#{consumer_name} provider=#{provider_name} uuid=#{uuid}"
end

def consumer_name
Expand Down
7 changes: 6 additions & 1 deletion lib/pact_broker/domain/webhook_execution_result.rb
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,8 @@ module Domain

class WebhookExecutionResult

def initialize response, logs, error = nil
def initialize request, response, logs, error = nil
@request = request
@response = response
@logs = logs
@error = error
Expand All @@ -14,6 +15,10 @@ def success?
!@response.nil? && @response.code.to_i < 300
end

def request
@request
end

def response
@response
end
Expand Down
25 changes: 18 additions & 7 deletions lib/pact_broker/domain/webhook_request.rb
Original file line number Diff line number Diff line change
Expand Up @@ -15,12 +15,10 @@ module PactBroker
module Domain

class WebhookRequestError < StandardError

def initialize message, response
super message
@response = response
end

end

class WebhookResponseWithUtf8SafeBody < SimpleDelegator
Expand All @@ -41,6 +39,18 @@ def unsafe_body?
end
end

class WebhookRequestWithRedactedHeaders < SimpleDelegator
def to_hash
__getobj__().to_hash.each_with_object({}) do | (key, values), new_hash |
new_hash[key] = redact?(key) ? ["**********"] : values
end
end

def redact? name
WebhookRequest::HEADERS_TO_REDACT.any?{ | pattern | name =~ pattern }
end
end

class WebhookRequest

include PactBroker::Logging
Expand Down Expand Up @@ -95,15 +105,15 @@ def execute_and_build_result pact, verification, options, logs, execution_logger
req = build_request(uri, pact, verification, execution_logger)
response = do_request(uri, req)
log_response(response, execution_logger, options)
result = WebhookExecutionResult.new(response, logs.string)
result = WebhookExecutionResult.new(WebhookRequestWithRedactedHeaders.new(req), response, logs.string)
log_completion_message(options, execution_logger, result.success?)
result
end

def handle_error_and_build_result e, options, logs, execution_logger
log_error(e, execution_logger, options)
log_completion_message(options, execution_logger, false)
WebhookExecutionResult.new(nil, logs.string, e)
WebhookExecutionResult.new(nil, nil, logs.string, e)
end

def build_request uri, pact, verification, execution_logger
Expand All @@ -123,11 +133,12 @@ def build_request uri, pact, verification, execution_logger
end

execution_logger.info(req.body) if req.body
logger.info "Making webhook #{uuid} request #{method.upcase} URI=#{uri} headers=#{headers_to_log} (body in debug logs)"
logger.debug "body=#{req.body}"
req
end

def do_request uri, req
logger.info "Making webhook #{uuid} request #{to_s}"
options = PactBroker::BuildHttpOptions.call(uri)
response = Net::HTTP.start(uri.hostname, uri.port, :ENV, options) do |http|
http.request req
Expand All @@ -149,8 +160,8 @@ def response_body_hidden_message
end

def log_response_to_application_logger response
logger.info "Received response for webhook #{uuid} status=#{response.code}"
logger.debug "headers=#{response.to_hash}"
logger.info "Received response for webhook #{uuid} status=#{response.code} (headers and body in debug logs)"
logger.debug "headers=#{response.to_hash} "
logger.debug "body=#{response.unsafe_body}"
end

Expand Down
2 changes: 1 addition & 1 deletion script/seed.rb
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@
.create_global_webhook(method: 'GET', url: "http://example.org?consumer=${pactbroker.consumerName}&provider=${pactbroker.providerName}")
.create_certificate(path: 'spec/fixtures/certificates/self-signed.badssl.com.pem')
.create_consumer("Bethtest")
.create_verification_webhook(method: 'POST', url: "http://localhost:9292", body: webhook_body)
.create_verification_webhook(method: 'POST', url: "http://localhost:9292", body: webhook_body, username: "foo", password: "bar")
.create_consumer("Foo")
.create_label("microservice")
.create_provider("Bar")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,15 @@ module Decorators

describe "to_json" do

let(:webhook_execution_result) { PactBroker::Domain::WebhookExecutionResult.new(response, logs, error)}
let(:webhook_execution_result) { PactBroker::Domain::WebhookExecutionResult.new(request, response, logs, error)}
let(:logs) { "logs" }
let(:headers) { { "Something" => ["blah", "thing"]} }
let(:request) do
req = Net::HTTP::Get.new("http://example.org?foo=bar")
req['Foo'] = ['bar', 'wiffle']
req.body = { foo: 'bar' }.to_json
req
end
let(:response) { double('http_response', code: '200', body: response_body, to_hash: headers) }
let(:response_body) { 'body' }
let(:error) { nil }
Expand Down Expand Up @@ -43,6 +49,32 @@ module Decorators
end
end

context "when there is a request" do
it "includes the request URL" do
expect(subject[:request][:url]).to eq "http://example.org?foo=bar"
end

it "includes the request headers" do
expect(subject[:request][:headers][:'foo']).to eq "bar, wiffle"
end

context "when the request body is JSON" do
it "includes the request body as JSON" do
expect(subject[:request][:body]).to include( foo: 'bar' )
end
end

context "when the request body is not json" do
before do
request.body = "<xml></xml>"
end

it "includes the request body as a String" do
expect(subject[:request][:body]).to eq "<xml></xml>"
end
end
end

context "when there is a response" do
it "includes the response code" do
expect(subject[:response][:status]).to eq 200
Expand All @@ -51,6 +83,7 @@ module Decorators
it "includes the response headers" do
expect(subject[:response][:headers]).to eq :'Something' => "blah, thing"
end

it "includes the response body" do
expect(subject[:response][:body]).to eq response_body
end
Expand Down
2 changes: 1 addition & 1 deletion spec/support/test_data_builder.rb
Original file line number Diff line number Diff line change
Expand Up @@ -294,7 +294,7 @@ def create_triggered_webhook params = {}
def create_webhook_execution params = {}
params.delete(:comment)
logs = params[:logs] || "logs"
webhook_execution_result = PactBroker::Domain::WebhookExecutionResult.new(OpenStruct.new(code: "200"), logs, nil)
webhook_execution_result = PactBroker::Domain::WebhookExecutionResult.new(nil, OpenStruct.new(code: "200"), logs, nil)
@webhook_execution = PactBroker::Webhooks::Repository.new.create_execution @triggered_webhook, webhook_execution_result
created_at = params[:created_at] || @pact.created_at + Rational(1, 86400)
set_created_at_if_set created_at, :webhook_executions, {id: @webhook_execution.id}
Expand Down

0 comments on commit 7518098

Please sign in to comment.