diff --git a/lib/pact_broker/api/resources/publish_contracts.rb b/lib/pact_broker/api/resources/publish_contracts.rb index 6cd026bb1..e73ce6f11 100644 --- a/lib/pact_broker/api/resources/publish_contracts.rb +++ b/lib/pact_broker/api/resources/publish_contracts.rb @@ -31,7 +31,7 @@ def malformed_request? end def process_post - handle_webhook_events do + handle_webhook_events(consumer_version_branch: parsed_contracts.branch) do results = contract_service.publish(parsed_contracts, base_url: base_url) response.body = decorator_class(:publish_contracts_results_decorator).new(results).to_json(decorator_options) end diff --git a/lib/pact_broker/api/resources/webhook_execution_methods.rb b/lib/pact_broker/api/resources/webhook_execution_methods.rb index 1370dbc62..86ee2e7c8 100644 --- a/lib/pact_broker/api/resources/webhook_execution_methods.rb +++ b/lib/pact_broker/api/resources/webhook_execution_methods.rb @@ -5,29 +5,15 @@ module PactBroker module Api module Resources module WebhookExecutionMethods - def webhook_execution_configuration - application_context.webhook_execution_configuration_creator.call(self) - end - - def webhook_options - { - database_connector: database_connector, - webhook_execution_configuration: webhook_execution_configuration - } - end - - def webhook_event_listener - @webhook_event_listener ||= PactBroker::Webhooks::EventListener.new(webhook_options) - end - - def handle_webhook_events + def handle_webhook_events(event_context = {}) + @webhook_event_listener = PactBroker::Webhooks::EventListener.new(webhook_options(event_context)) PactBroker::Events.subscribe(webhook_event_listener) do yield end end def schedule_triggered_webhooks - webhook_event_listener.schedule_triggered_webhooks + webhook_event_listener&.schedule_triggered_webhooks end def finish_request @@ -36,6 +22,26 @@ def finish_request end super end + + + def webhook_options(event_context = {}) + { + database_connector: database_connector, + webhook_execution_configuration: webhook_execution_configuration.with_webhook_context(event_context) + } + end + private :webhook_options + + def webhook_execution_configuration + application_context.webhook_execution_configuration_creator.call(self) + end + private :webhook_execution_configuration + + def webhook_event_listener + @webhook_event_listener + end + + private :webhook_event_listener end end end diff --git a/lib/pact_broker/webhooks/pact_and_verification_parameters.rb b/lib/pact_broker/webhooks/pact_and_verification_parameters.rb index f5ea41319..3a12b9f7a 100644 --- a/lib/pact_broker/webhooks/pact_and_verification_parameters.rb +++ b/lib/pact_broker/webhooks/pact_and_verification_parameters.rb @@ -137,10 +137,10 @@ def consumer_version_tags end def consumer_version_branch - if webhook_context[:consumer_version_branch] - webhook_context[:consumer_version_branch] + if webhook_context.key?(:consumer_version_branch) + webhook_context[:consumer_version_branch] || "" else - pact&.consumer_version&.branch || "" + pact&.consumer_version&.branch_names&.last || "" end end diff --git a/spec/integration/webhooks/contract_publication_spec.rb b/spec/integration/webhooks/contract_publication_spec.rb new file mode 100644 index 000000000..2bdf33bd4 --- /dev/null +++ b/spec/integration/webhooks/contract_publication_spec.rb @@ -0,0 +1,66 @@ +RSpec.describe "triggering a webhook for a contract publication" do + before do + td.create_global_webhook(event_names: ["contract_published"], body: webhook_body_template) + end + + let(:webhook_body_template) do + { + "consumer_version_number" => "${pactbroker.consumerVersionNumber}", + "consumer_version_branch" => "${pactbroker.consumerVersionBranch}", + "consumer_version_tags" => "${pactbroker.consumerVersionTags}", + } + end + + let(:expected_webhook_body) do + { + consumer_version_number: "1", + consumer_version_branch: "main", + consumer_version_tags: "a, b", + } + end + + let(:request_body_hash) do + { + :pacticipantName => "Foo", + :pacticipantVersionNumber => "1", + :branch => "main", + :tags => ["a", "b"], + :buildUrl => "http://ci/builds/1234", + :contracts => [ + { + :consumerName => "Foo", + :providerName => "Bar", + :specification => "pact", + :contentType => "application/json", + :content => encoded_contract + } + ] + } + end + + let(:rack_headers) do + { + "CONTENT_TYPE" => "application/json", + "HTTP_ACCEPT" => "application/hal+json", + "pactbroker.database_connector" => database_connector} + end + + let(:contract) { { consumer: { name: "Foo" }, provider: { name: "Bar" }, interactions: [] }.to_json } + let(:encoded_contract) { Base64.strict_encode64(contract) } + let(:path) { "/contracts/publish" } + + let!(:request) do + stub_request(:post, /http/).to_return(:status => 200) + end + + subject { post(path, request_body_hash.to_json, rack_headers) } + + let(:database_connector) { ->(&block) { block.call } } + + it { is_expected.to be_a_hal_json_success_response } + + it "passes through the correct parameters to the webhook" do + subject + expect(a_request(:post, /http/).with(body: expected_webhook_body)).to have_been_made + end +end diff --git a/spec/integration/webhooks/pact_publication_spec.rb b/spec/integration/webhooks/pact_publication_spec.rb index 0ea92e3f8..b7af4885b 100644 --- a/spec/integration/webhooks/pact_publication_spec.rb +++ b/spec/integration/webhooks/pact_publication_spec.rb @@ -11,7 +11,7 @@ let(:database_connector) { ->(&block) { block.call } } - subject { put("/pacts/provider/Bar/consumer/Foo/version/2", pact_content, { "CONTENT_TYPE" => "application/json", "pactbroker.database_connector" => database_connector}) } + subject { put("/pacts/provider/Bar/consumer/Foo/version/2", pact_content, { "CONTENT_TYPE" => "application/json", "pactbroker.database_connector" => database_connector }) } context "when there is a verification from the main branch of the provider" do before do diff --git a/spec/lib/pact_broker/webhooks/render_spec.rb b/spec/lib/pact_broker/webhooks/render_spec.rb index 9039a6f4f..bf5160885 100644 --- a/spec/lib/pact_broker/webhooks/render_spec.rb +++ b/spec/lib/pact_broker/webhooks/render_spec.rb @@ -75,7 +75,7 @@ module Webhooks end let(:consumer_version) do - double("version", tags: consumer_tags, branch: "consumer-branch") + double("version", tags: consumer_tags, branch_names: ["foo-branch","consumer-branch"]) end let(:provider_tags) do