diff --git a/doc/pacts/markdown/Pact Broker Client - Pact Broker.md b/doc/pacts/markdown/Pact Broker Client - Pact Broker.md index ad8fe51c..8186af05 100644 --- a/doc/pacts/markdown/Pact Broker Client - Pact Broker.md +++ b/doc/pacts/markdown/Pact Broker Client - Pact Broker.md @@ -92,6 +92,8 @@ * [A request to tag the production version of Condor](#a_request_to_tag_the_production_version_of_Condor_given_'Condor'_exists_in_the_pact-broker) given 'Condor' exists in the pact-broker +* [A request to update a webhook](#a_request_to_update_a_webhook_given_a_webhook_with_the_uuid_696c5f93-1b7f-44bc-8d03-59440fcaa9a0_exists) given a webhook with the uuid 696c5f93-1b7f-44bc-8d03-59440fcaa9a0 exists + * [An invalid request to create a webhook for a consumer and provider](#an_invalid_request_to_create_a_webhook_for_a_consumer_and_provider_given_the_'Pricing_Service'_and_'Condor'_already_exist_in_the_pact-broker) given the 'Pricing Service' and 'Condor' already exist in the pact-broker #### Interactions @@ -766,6 +768,7 @@ Pact Broker will respond with: "Content-Type": "application/hal+json;charset=utf-8" }, "body": { + "description": "a webhook", "_links": { "self": { "href": "http://localhost:1234/some-url", @@ -864,6 +867,7 @@ Pact Broker will respond with: "Content-Type": "application/hal+json;charset=utf-8" }, "body": { + "description": "a webhook", "_links": { "self": { "href": "http://localhost:1234/some-url", @@ -917,6 +921,7 @@ Pact Broker will respond with: "Content-Type": "application/hal+json;charset=utf-8" }, "body": { + "description": "a webhook", "_links": { "self": { "href": "http://localhost:1234/some-url", @@ -967,6 +972,7 @@ Pact Broker will respond with: "Content-Type": "application/hal+json;charset=utf-8" }, "body": { + "description": "a webhook", "_links": { "self": { "href": "http://localhost:1234/some-url", @@ -1072,6 +1078,7 @@ Pact Broker will respond with: "Content-Type": "application/hal+json;charset=utf-8" }, "body": { + "description": "a webhook", "_links": { "self": { "href": "http://localhost:1234/some-url", @@ -1120,6 +1127,7 @@ Pact Broker will respond with: "Content-Type": "application/hal+json;charset=utf-8" }, "body": { + "description": "a webhook", "_links": { "self": { "href": "http://localhost:1234/some-url", @@ -1182,6 +1190,7 @@ Pact Broker will respond with: "Content-Type": "application/hal+json;charset=utf-8" }, "body": { + "description": "a webhook", "_links": { "self": { "href": "http://localhost:1234/some-url", @@ -1800,6 +1809,63 @@ Pact Broker will respond with: } } ``` + +Given **a webhook with the uuid 696c5f93-1b7f-44bc-8d03-59440fcaa9a0 exists**, upon receiving **a request to update a webhook** from Pact Broker Client, with +```json +{ + "method": "put", + "path": "/webhooks/696c5f93-1b7f-44bc-8d03-59440fcaa9a0", + "headers": { + "Content-Type": "application/json", + "Accept": "application/hal+json" + }, + "body": { + "description": "a webhook", + "events": [ + { + "name": "contract_content_changed" + } + ], + "request": { + "url": "https://webhook", + "method": "POST", + "headers": { + "Foo": "bar", + "Bar": "foo" + }, + "body": { + "some": "body" + }, + "username": "username", + "password": "password" + }, + "provider": { + "name": "Pricing Service" + }, + "consumer": { + "name": "Condor" + } + } +} +``` +Pact Broker will respond with: +```json +{ + "status": 200, + "headers": { + "Content-Type": "application/hal+json;charset=utf-8" + }, + "body": { + "description": "a webhook", + "_links": { + "self": { + "href": "http://localhost:1234/some-url", + "title": "A title" + } + } + } +} +``` Given **the 'Pricing Service' and 'Condor' already exist in the pact-broker**, upon receiving **an invalid request to create a webhook for a consumer and provider** from Pact Broker Client, with ```json diff --git a/lib/pact_broker/client/cli/broker.rb b/lib/pact_broker/client/cli/broker.rb index 56ad9d38..69fa6aca 100644 --- a/lib/pact_broker/client/cli/broker.rb +++ b/lib/pact_broker/client/cli/broker.rb @@ -249,6 +249,7 @@ def parse_webhook_options(webhook_url) { uuid: options.uuid, + description: options.description, http_method: options.request, url: webhook_url, headers: headers, diff --git a/lib/pact_broker/client/hal/entity.rb b/lib/pact_broker/client/hal/entity.rb index e78ec725..de21c9c0 100644 --- a/lib/pact_broker/client/hal/entity.rb +++ b/lib/pact_broker/client/hal/entity.rb @@ -6,11 +6,9 @@ module PactBroker module Client module Hal class RelationNotFoundError < ::PactBroker::Client::Error; end - class ErrorResponseReturned < ::PactBroker::Client::Error; end class Entity - def initialize(href, data, http_client, response = nil) @href = href @data = data @@ -71,7 +69,7 @@ def method_missing(method_name, *args, &block) elsif @links.key?(method_name) Link.new(@links[method_name], @client).run(*args) else - super + nil end end diff --git a/lib/pact_broker/client/webhooks/create.rb b/lib/pact_broker/client/webhooks/create.rb index 94c7fb11..42d22e8f 100644 --- a/lib/pact_broker/client/webhooks/create.rb +++ b/lib/pact_broker/client/webhooks/create.rb @@ -101,7 +101,13 @@ def handle_response(webhook_entity) end def success_result(webhook_entity) - CommandResult.new(true, "Webhook #{webhook_entity._link('self').title_or_name.inspect} created") + action = webhook_entity.response.status == 201 ? "created" : "updated" + name = if webhook_entity.description && webhook_entity.description.size > 0 + webhook_entity.description + else + webhook_entity._link('self').title_or_name + end + CommandResult.new(true, "Webhook #{name.inspect} #{action}") end def error_result(message) diff --git a/spec/lib/pact_broker/client/cli/broker_run_webhook_commands_spec.rb b/spec/lib/pact_broker/client/cli/broker_run_webhook_commands_spec.rb index 4f05a97a..cd7e9bcd 100644 --- a/spec/lib/pact_broker/client/cli/broker_run_webhook_commands_spec.rb +++ b/spec/lib/pact_broker/client/cli/broker_run_webhook_commands_spec.rb @@ -22,6 +22,7 @@ module CLI let(:options_hash) do { uuid: '9999', + description: "some webhook", request: "POST", header: header, data: data, @@ -39,6 +40,7 @@ module CLI let(:expected_params) do { uuid: '9999', + description: "some webhook", http_method: "POST", url: "http://webhook", headers: { "Foo" => "bar", "Bar" => "foo"}, diff --git a/spec/lib/pact_broker/client/hal/entity_spec.rb b/spec/lib/pact_broker/client/hal/entity_spec.rb index 935c5efb..ca1c3242 100644 --- a/spec/lib/pact_broker/client/hal/entity_spec.rb +++ b/spec/lib/pact_broker/client/hal/entity_spec.rb @@ -17,6 +17,7 @@ module Hal "name" => "Provider" } end + let(:pact_hash) do { "name" => "a name", diff --git a/spec/lib/pact_broker/client/webhooks/create_spec.rb b/spec/lib/pact_broker/client/webhooks/create_spec.rb index 450c4d17..5069eee6 100644 --- a/spec/lib/pact_broker/client/webhooks/create_spec.rb +++ b/spec/lib/pact_broker/client/webhooks/create_spec.rb @@ -70,6 +70,28 @@ module Webhooks expect(subject.message).to match /"some":"error"/ end end + + context "when there is an empty description returned" do + let!(:webhook_request) do + stub_request(:post, "http://broker/webhooks").to_return(status: 200, body: response_body.to_json, headers: { "Content-Type" => "application/hal+json" }) + end + + let(:response_body) do + { + description: "", + _links: { + self: { + href: "href", + title: "the title" + } + } + } + end + + it "uses the self title in the message instead" do + expect(subject.message).to include "the title" + end + end end end end diff --git a/spec/pacts/pact_broker_client-pact_broker.json b/spec/pacts/pact_broker_client-pact_broker.json index 18581aab..f18620cb 100644 --- a/spec/pacts/pact_broker_client-pact_broker.json +++ b/spec/pacts/pact_broker_client-pact_broker.json @@ -1287,6 +1287,7 @@ "Content-Type": "application/hal+json;charset=utf-8" }, "body": { + "description": "a webhook", "_links": { "self": { "href": "http://localhost:1234/some-url", @@ -1295,6 +1296,9 @@ } }, "matchingRules": { + "$.body.description": { + "match": "type" + }, "$.body._links.self.href": { "match": "regex", "regex": "http:\\/\\/.*" @@ -1355,6 +1359,7 @@ "Content-Type": "application/hal+json;charset=utf-8" }, "body": { + "description": "a webhook", "_links": { "self": { "href": "http://localhost:1234/some-url", @@ -1363,6 +1368,9 @@ } }, "matchingRules": { + "$.body.description": { + "match": "type" + }, "$.body._links.self.href": { "match": "regex", "regex": "http:\\/\\/.*" @@ -1409,6 +1417,7 @@ "Content-Type": "application/hal+json;charset=utf-8" }, "body": { + "description": "a webhook", "_links": { "self": { "href": "http://localhost:1234/some-url", @@ -1417,6 +1426,9 @@ } }, "matchingRules": { + "$.body.description": { + "match": "type" + }, "$.body._links.self.href": { "match": "regex", "regex": "http:\\/\\/.*" @@ -1590,6 +1602,7 @@ "Content-Type": "application/hal+json;charset=utf-8" }, "body": { + "description": "a webhook", "_links": { "self": { "href": "http://localhost:1234/some-url", @@ -1598,6 +1611,9 @@ } }, "matchingRules": { + "$.body.description": { + "match": "type" + }, "$.body._links.self.href": { "match": "regex", "regex": "http:\\/\\/.*" @@ -1705,6 +1721,7 @@ "Content-Type": "application/hal+json;charset=utf-8" }, "body": { + "description": "a webhook", "_links": { "self": { "href": "http://localhost:1234/some-url", @@ -1713,6 +1730,9 @@ } }, "matchingRules": { + "$.body.description": { + "match": "type" + }, "$.body._links.self.href": { "match": "regex", "regex": "http:\\/\\/.*" @@ -1760,6 +1780,7 @@ "Content-Type": "application/hal+json;charset=utf-8" }, "body": { + "description": "a webhook", "_links": { "self": { "href": "http://localhost:1234/some-url", @@ -1768,6 +1789,9 @@ } }, "matchingRules": { + "$.body.description": { + "match": "type" + }, "$.body._links.self.href": { "match": "regex", "regex": "http:\\/\\/.*" @@ -1852,6 +1876,73 @@ "Content-Type": "application/hal+json;charset=utf-8" }, "body": { + "description": "a webhook", + "_links": { + "self": { + "href": "http://localhost:1234/some-url", + "title": "A title" + } + } + }, + "matchingRules": { + "$.body.description": { + "match": "type" + }, + "$.body._links.self.href": { + "match": "regex", + "regex": "http:\\/\\/.*" + }, + "$.body._links.self.title": { + "match": "type" + } + } + } + }, + { + "description": "a request to update a webhook", + "providerState": "a webhook with the uuid 696c5f93-1b7f-44bc-8d03-59440fcaa9a0 exists", + "request": { + "method": "put", + "path": "/webhooks/696c5f93-1b7f-44bc-8d03-59440fcaa9a0", + "headers": { + "Content-Type": "application/json", + "Accept": "application/hal+json" + }, + "body": { + "description": "a webhook", + "events": [ + { + "name": "contract_content_changed" + } + ], + "request": { + "url": "https://webhook", + "method": "POST", + "headers": { + "Foo": "bar", + "Bar": "foo" + }, + "body": { + "some": "body" + }, + "username": "username", + "password": "password" + }, + "provider": { + "name": "Pricing Service" + }, + "consumer": { + "name": "Condor" + } + } + }, + "response": { + "status": 200, + "headers": { + "Content-Type": "application/hal+json;charset=utf-8" + }, + "body": { + "description": "a webhook", "_links": { "self": { "href": "http://localhost:1234/some-url", @@ -1860,6 +1951,9 @@ } }, "matchingRules": { + "$.body.description": { + "match": "type" + }, "$.body._links.self.href": { "match": "regex", "regex": "http:\\/\\/.*" diff --git a/spec/service_providers/webhooks_create_spec.rb b/spec/service_providers/webhooks_create_spec.rb index 274c9825..6ebfe1c3 100644 --- a/spec/service_providers/webhooks_create_spec.rb +++ b/spec/service_providers/webhooks_create_spec.rb @@ -47,11 +47,13 @@ } end + let(:response_status) { 201 } let(:success_response) do { - status: 201, + status: response_status, headers: pact_broker_response_headers, body: { + description: Pact.like("a webhook"), _links: { self: { href: Pact.term('http://localhost:1234/some-url', %r{http://.*}), @@ -82,7 +84,7 @@ it "returns a CommandResult with success = true" do expect(subject).to be_a PactBroker::Client::CommandResult expect(subject.success).to be true - expect(subject.message).to eq "Webhook \"A title\" created" + expect(subject.message).to eq "Webhook \"a webhook\" created" end end @@ -201,7 +203,7 @@ it "returns a CommandResult with success = true" do expect(subject.success).to be true - expect(subject.message).to eq "Webhook \"A title\" created" + expect(subject.message).to eq "Webhook \"a webhook\" created" end end @@ -282,23 +284,50 @@ request_body["provider"] = { "name" => "Pricing Service" } request_body["consumer"] = { "name" => "Condor" } mock_pact_broker_index_with_webhook_relation(self) - - pact_broker - .upon_receiving("a request to create a webhook with a JSON body and a uuid") - .given("the 'Pricing Service' and 'Condor' already exist in the pact-broker") - .with( - method: :put, - path: "/webhooks/#{uuid}", - headers: put_request_headers, - body: request_body) - .will_respond_with(success_response) end + let(:uuid) { '696c5f93-1b7f-44bc-8d03-59440fcaa9a0' } - it "returns a CommandResult with success = true" do - expect(subject).to be_a PactBroker::Client::CommandResult - expect(subject.success).to be true - expect(subject.message).to eq "Webhook \"A title\" created" + context "when the webhook does not already exist" do + before do + pact_broker + .upon_receiving("a request to create a webhook with a JSON body and a uuid") + .given("the 'Pricing Service' and 'Condor' already exist in the pact-broker") + .with( + method: :put, + path: "/webhooks/#{uuid}", + headers: put_request_headers, + body: request_body) + .will_respond_with(success_response) + end + + it "returns a CommandResult with success = true" do + expect(subject).to be_a PactBroker::Client::CommandResult + expect(subject.success).to be true + expect(subject.message).to eq "Webhook \"a webhook\" created" + end + end + + context "when the webhook does exist" do + before do + pact_broker + .upon_receiving("a request to update a webhook") + .given("a webhook with the uuid #{uuid} exists") + .with( + method: :put, + path: "/webhooks/#{uuid}", + headers: put_request_headers, + body: request_body) + .will_respond_with(success_response) + end + + let(:response_status) { 200 } + + it "returns a CommandResult with success = true" do + expect(subject).to be_a PactBroker::Client::CommandResult + expect(subject.success).to be true + expect(subject.message).to eq "Webhook \"a webhook\" updated" + end end end end