From 9321c7356d07cd759276e85395733de2eb02182d Mon Sep 17 00:00:00 2001 From: Beth Skurrie Date: Fri, 19 Jan 2018 10:34:37 +1100 Subject: [PATCH] feat(consumer or provider webhooks): refactor webhooks resource classes and add consumer and provider webhook links to pact resource --- lib/pact_broker/api.rb | 6 +- .../api/decorators/pact_decorator.rb | 14 +++ .../pact_webhooks_status_decorator.rb | 2 +- lib/pact_broker/api/pact_broker_urls.rb | 8 ++ lib/pact_broker/api/resources/all_webhooks.rb | 2 - .../api/resources/pact_webhooks.rb | 13 --- lib/pact_broker/api/resources/webhooks.rb | 93 +++++++++++++++++++ ...pact_webhooks_spec.rb => webhooks_spec.rb} | 4 +- 8 files changed, 121 insertions(+), 21 deletions(-) create mode 100644 lib/pact_broker/api/resources/webhooks.rb rename spec/lib/pact_broker/api/resources/{pact_webhooks_spec.rb => webhooks_spec.rb} (98%) diff --git a/lib/pact_broker/api.rb b/lib/pact_broker/api.rb index c504add46..1b7be5ae8 100644 --- a/lib/pact_broker/api.rb +++ b/lib/pact_broker/api.rb @@ -55,9 +55,9 @@ module PactBroker add ['pacticipants', :pacticipant_name, 'labels', :label_name], Api::Resources::Label, {resource_name: "pacticipant_label"} # Webhooks - add ['webhooks', 'provider', :provider_name, 'consumer', :consumer_name ], Api::Resources::PactWebhooks, {resource_name: "consumer_and_provider_webhooks"} - add ['webhooks', 'provider', :provider_name], Api::Resources::PactWebhooks, {resource_name: "provider_webhooks"} - add ['webhooks', 'consumer', :consumer_name], Api::Resources::PactWebhooks, {resource_name: "consumer_webhooks"} + add ['webhooks', 'provider', :provider_name, 'consumer', :consumer_name ], Api::Resources::Webhooks, {resource_name: "consumer_and_provider_webhooks"} + add ['webhooks', 'provider', :provider_name], Api::Resources::Webhooks, {resource_name: "provider_webhooks"} + add ['webhooks', 'consumer', :consumer_name], Api::Resources::Webhooks, {resource_name: "consumer_webhooks"} add ['pacts', 'provider', :provider_name, 'consumer', :consumer_name, 'webhooks'], Api::Resources::PactWebhooks, {resource_name: "pact_webhooks"} add ['pacts', 'provider', :provider_name, 'consumer', :consumer_name, 'webhooks', 'status'], Api::Resources::PactWebhooksStatus, {resource_name: "pact_webhooks_status"} diff --git a/lib/pact_broker/api/decorators/pact_decorator.rb b/lib/pact_broker/api/decorators/pact_decorator.rb index bd9b03456..7f422f270 100644 --- a/lib/pact_broker/api/decorators/pact_decorator.rb +++ b/lib/pact_broker/api/decorators/pact_decorator.rb @@ -106,6 +106,20 @@ def to_hash(options = {}) } end + link :'pb:consumer-webhooks' do | options | + { + title: "Webhooks for all pacts with consumer #{represented.consumer.name}", + href: consumer_webhooks_url(represented.consumer, options.fetch(:base_url)) + } + end + + link :'pb:consumer-webhooks' do | options | + { + title: "Webhooks for all pacts with provider #{represented.provider.name}", + href: consumer_webhooks_url(represented.provider, options.fetch(:base_url)) + } + end + link :'pb:tag-prod-version' do | options | { title: "PUT to this resource to tag this consumer version as 'production'", diff --git a/lib/pact_broker/api/decorators/pact_webhooks_status_decorator.rb b/lib/pact_broker/api/decorators/pact_webhooks_status_decorator.rb index 2db45f3cf..eec973e4b 100644 --- a/lib/pact_broker/api/decorators/pact_webhooks_status_decorator.rb +++ b/lib/pact_broker/api/decorators/pact_webhooks_status_decorator.rb @@ -63,7 +63,7 @@ class PactWebhooksStatusDecorator < BaseDecorator link :'pb:pact-webhooks' do | context | { title: "Webhooks for the pact between #{context[:consumer_name]} and #{context[:provider_name]}", - href: webhooks_for_consumer_and_provider_url(fake_consumer(context), fake_provider(context), context.fetch(:base_url)) + href: webhooks_for_pact_url(fake_consumer(context), fake_provider(context), context.fetch(:base_url)) } end diff --git a/lib/pact_broker/api/pact_broker_urls.rb b/lib/pact_broker/api/pact_broker_urls.rb index 429b8a31a..b25d8d670 100644 --- a/lib/pact_broker/api/pact_broker_urls.rb +++ b/lib/pact_broker/api/pact_broker_urls.rb @@ -156,6 +156,14 @@ def webhooks_for_consumer_and_provider_url consumer, provider, base_url = '' "#{base_url}/webhooks/provider/#{url_encode(provider.name)}/consumer/#{url_encode(consumer.name)}" end + def consumer_webhooks_url consumer, base_url = '' + "#{base_url}/webhooks/consumer/#{url_encode(consumer.name)}" + end + + def provider_webhooks_url provider, base_url = '' + "#{base_url}/webhooks/provider/#{url_encode(provider.name)}" + end + def webhooks_for_pact_url consumer, provider, base_url = '' "#{base_url}/pacts/provider/#{url_encode(provider.name)}/consumer/#{url_encode(consumer.name)}/webhooks" end diff --git a/lib/pact_broker/api/resources/all_webhooks.rb b/lib/pact_broker/api/resources/all_webhooks.rb index 4f54c7ec9..da199612a 100644 --- a/lib/pact_broker/api/resources/all_webhooks.rb +++ b/lib/pact_broker/api/resources/all_webhooks.rb @@ -5,7 +5,6 @@ module PactBroker module Api module Resources - class AllWebhooks < BaseResource def content_types_provided @@ -23,7 +22,6 @@ def to_json def webhooks webhook_service.find_all end - end end end diff --git a/lib/pact_broker/api/resources/pact_webhooks.rb b/lib/pact_broker/api/resources/pact_webhooks.rb index 26a219ae4..d8f9009af 100644 --- a/lib/pact_broker/api/resources/pact_webhooks.rb +++ b/lib/pact_broker/api/resources/pact_webhooks.rb @@ -76,19 +76,6 @@ def next_uuid @next_uuid ||= webhook_service.next_uuid end - def consumer - @consumer ||= identifier_from_path[:consumer_name] && find_pacticipant(identifier_from_path[:consumer_name], "consumer") - end - - def provider - @provider ||= identifier_from_path[:provider_name] && find_pacticipant(identifier_from_path[:provider_name], "provider") - end - - def find_pacticipant name, role - pacticipant_service.find_pacticipant_by_name(name).tap do | pacticipant | - set_json_error_message("No #{role} with name '#{name}' found") if pacticipant.nil? - end - end end end diff --git a/lib/pact_broker/api/resources/webhooks.rb b/lib/pact_broker/api/resources/webhooks.rb new file mode 100644 index 000000000..0b0ecad66 --- /dev/null +++ b/lib/pact_broker/api/resources/webhooks.rb @@ -0,0 +1,93 @@ +require 'pact_broker/api/resources/base_resource' +require 'pact_broker/api/decorators/webhook_decorator' +require 'pact_broker/api/decorators/webhooks_decorator' +require 'pact_broker/api/contracts/webhook_contract' + +module PactBroker + module Api + module Resources + class Webhooks < BaseResource + + def allowed_methods + ["POST", "GET"] + end + + def content_types_provided + [["application/hal+json", :to_json]] + end + + def content_types_accepted + [["application/json", :from_json]] + end + + def resource_exists? + (identifier_from_path[:consumer_name].nil? || consumer) && + (identifier_from_path[:provider_name].nil? || provider) + end + + def malformed_request? + if request.post? + return invalid_json? || validation_errors?(webhook) + end + false + end + + def validation_errors? webhook + errors = webhook_service.errors(webhook) + + unless errors.empty? + response.headers['Content-Type'] = 'application/json;charset=utf-8' + response.body = { errors: errors.messages }.to_json + end + + !errors.empty? + end + + def create_path + webhook_url next_uuid, base_url + end + + def post_is_create? + true + end + + def from_json + saved_webhook = webhook_service.create next_uuid, webhook, consumer, provider + response.body = Decorators::WebhookDecorator.new(saved_webhook).to_json(user_options: { base_url: base_url }) + end + + def to_json + Decorators::WebhooksDecorator.new(webhooks).to_json(user_options: decorator_context(resource_title: 'Pact webhooks')) + end + + private + + def webhooks + webhook_service.find_by_consumer_and_provider consumer, provider + end + + def webhook + @webhook ||= Decorators::WebhookDecorator.new(PactBroker::Domain::Webhook.new).from_json(request_body) + end + + def next_uuid + @next_uuid ||= webhook_service.next_uuid + end + + def consumer + @consumer ||= identifier_from_path[:consumer_name] && find_pacticipant(identifier_from_path[:consumer_name], "consumer") + end + + def provider + @provider ||= identifier_from_path[:provider_name] && find_pacticipant(identifier_from_path[:provider_name], "provider") + end + + def find_pacticipant name, role + pacticipant_service.find_pacticipant_by_name(name).tap do | pacticipant | + set_json_error_message("No #{role} with name '#{name}' found") if pacticipant.nil? + end + end + end + end + end +end diff --git a/spec/lib/pact_broker/api/resources/pact_webhooks_spec.rb b/spec/lib/pact_broker/api/resources/webhooks_spec.rb similarity index 98% rename from spec/lib/pact_broker/api/resources/pact_webhooks_spec.rb rename to spec/lib/pact_broker/api/resources/webhooks_spec.rb index 59ada0698..969b3a238 100644 --- a/spec/lib/pact_broker/api/resources/pact_webhooks_spec.rb +++ b/spec/lib/pact_broker/api/resources/webhooks_spec.rb @@ -1,8 +1,8 @@ -require 'pact_broker/api/resources/pact_webhooks' +require 'pact_broker/api/resources/webhooks' module PactBroker::Api module Resources - describe PactWebhooks do + describe Webhooks do let(:webhook_service) { PactBroker::Webhooks::Service } let(:uuid) { '1483234k24DKFGJ45K' }