diff --git a/README.md b/README.md
index 64415d31..ae0a18e0 100644
--- a/README.md
+++ b/README.md
@@ -607,8 +607,12 @@ Options:
# Webhook basic auth username and password eg. username:password
[--consumer=CONSUMER]
# Consumer name
+ [--consumer-label=CONSUMER_LABEL]
+ # Consumer label
[--provider=PROVIDER]
# Provider name
+ [--provider-label=PROVIDER_LABEL]
+ # Provider label
[--description=DESCRIPTION]
# Webhook description
[--contract-content-changed], [--no-contract-content-changed]
@@ -663,8 +667,12 @@ Options:
# Webhook basic auth username and password eg. username:password
[--consumer=CONSUMER]
# Consumer name
+ [--consumer-label=CONSUMER_LABEL]
+ # Consumer label
[--provider=PROVIDER]
# Provider name
+ [--provider-label=PROVIDER_LABEL]
+ # Provider label
[--description=DESCRIPTION]
# Webhook description
[--contract-content-changed], [--no-contract-content-changed]
diff --git a/doc/pacts/markdown/Pact Broker Client - Pact Broker.md b/doc/pacts/markdown/Pact Broker Client - Pact Broker.md
index e2e1ce9d..82ccb0b2 100644
--- a/doc/pacts/markdown/Pact Broker Client - Pact Broker.md
+++ b/doc/pacts/markdown/Pact Broker Client - Pact Broker.md
@@ -64,10 +64,14 @@
* [A request to create a webhook with a JSON body for a consumer and provider](#a_request_to_create_a_webhook_with_a_JSON_body_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
+* [A request to create a webhook with a JSON body for a consumer specified by a label](#a_request_to_create_a_webhook_with_a_JSON_body_for_a_consumer_specified_by_a_label)
+
* [A request to create a webhook with a JSON body for a consumer that does not exist](#a_request_to_create_a_webhook_with_a_JSON_body_for_a_consumer_that_does_not_exist)
* [A request to create a webhook with a JSON body for a provider](#a_request_to_create_a_webhook_with_a_JSON_body_for_a_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
+* [A request to create a webhook with a JSON body for a provider specified by a label](#a_request_to_create_a_webhook_with_a_JSON_body_for_a_provider_specified_by_a_label)
+
* [A request to create a webhook with a non-JSON body for a consumer and provider](#a_request_to_create_a_webhook_with_a_non-JSON_body_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
* [A request to create a webhook with every possible event type](#a_request_to_create_a_webhook_with_every_possible_event_type_given_the_'Pricing_Service'_and_'Condor'_already_exist_in_the_pact-broker) given the 'Pricing Service' and 'Condor' already exist in the pact-broker
@@ -1089,6 +1093,14 @@ Pact Broker will respond with:
},
"body": {
"description": "a webhook",
+ "request": {
+ "body": "{\"some\":\"body\"}",
+ "events": [
+ {
+ "name": "contract_content_changed"
+ }
+ ]
+ },
"_links": {
"self": {
"href": "http://localhost:1234/some-url",
@@ -1222,6 +1234,14 @@ Pact Broker will respond with:
},
"body": {
"description": "a webhook",
+ "request": {
+ "body": "{\"some\":\"body\"}",
+ "events": [
+ {
+ "name": "contract_content_changed"
+ }
+ ]
+ },
"_links": {
"self": {
"href": "http://localhost:1234/some-url",
@@ -1276,6 +1296,14 @@ Pact Broker will respond with:
},
"body": {
"description": "a webhook",
+ "request": {
+ "body": "{\"some\":\"body\"}",
+ "events": [
+ {
+ "name": "contract_content_changed"
+ }
+ ]
+ },
"_links": {
"self": {
"href": "http://localhost:1234/some-url",
@@ -1327,6 +1355,76 @@ Pact Broker will respond with:
},
"body": {
"description": "a webhook",
+ "request": {
+ "body": "{\"some\":\"body\"}",
+ "events": [
+ {
+ "name": "contract_content_changed"
+ }
+ ]
+ },
+ "_links": {
+ "self": {
+ "href": "http://localhost:1234/some-url",
+ "title": "A title"
+ }
+ }
+ }
+}
+```
+
+Upon receiving **a request to create a webhook with a JSON body for a consumer specified by a label** from Pact Broker Client, with
+```json
+{
+ "method": "post",
+ "path": "/HAL-REL-PLACEHOLDER-PB-WEBHOOKS",
+ "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"
+ },
+ "consumer": {
+ "label": "consumer_label"
+ }
+ }
+}
+```
+Pact Broker will respond with:
+```json
+{
+ "status": 201,
+ "headers": {
+ "Content-Type": "application/hal+json;charset=utf-8"
+ },
+ "body": {
+ "description": "a webhook",
+ "request": {
+ "body": "{\"some\":\"body\"}",
+ "events": [
+ {
+ "name": "contract_content_changed"
+ }
+ ]
+ },
"_links": {
"self": {
"href": "http://localhost:1234/some-url",
@@ -1433,6 +1531,76 @@ Pact Broker will respond with:
},
"body": {
"description": "a webhook",
+ "request": {
+ "body": "{\"some\":\"body\"}",
+ "events": [
+ {
+ "name": "contract_content_changed"
+ }
+ ]
+ },
+ "_links": {
+ "self": {
+ "href": "http://localhost:1234/some-url",
+ "title": "A title"
+ }
+ }
+ }
+}
+```
+
+Upon receiving **a request to create a webhook with a JSON body for a provider specified by a label** from Pact Broker Client, with
+```json
+{
+ "method": "post",
+ "path": "/HAL-REL-PLACEHOLDER-PB-WEBHOOKS",
+ "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": {
+ "label": "provider_label"
+ }
+ }
+}
+```
+Pact Broker will respond with:
+```json
+{
+ "status": 201,
+ "headers": {
+ "Content-Type": "application/hal+json;charset=utf-8"
+ },
+ "body": {
+ "description": "a webhook",
+ "request": {
+ "body": "{\"some\":\"body\"}",
+ "events": [
+ {
+ "name": "contract_content_changed"
+ }
+ ]
+ },
"_links": {
"self": {
"href": "http://localhost:1234/some-url",
@@ -1482,6 +1650,14 @@ Pact Broker will respond with:
},
"body": {
"description": "a webhook",
+ "request": {
+ "body": "",
+ "events": [
+ {
+ "name": "contract_content_changed"
+ }
+ ]
+ },
"_links": {
"self": {
"href": "http://localhost:1234/some-url",
@@ -1545,6 +1721,26 @@ Pact Broker will respond with:
},
"body": {
"description": "a webhook",
+ "request": {
+ "body": "{\"some\":\"body\"}",
+ "events": [
+ {
+ "name": "contract_content_changed"
+ },
+ {
+ "name": "contract_published"
+ },
+ {
+ "name": "provider_verification_published"
+ },
+ {
+ "name": "provider_verification_succeeded"
+ },
+ {
+ "name": "provider_verification_failed"
+ }
+ ]
+ },
"_links": {
"self": {
"href": "http://localhost:1234/some-url",
@@ -2550,6 +2746,14 @@ Pact Broker will respond with:
},
"body": {
"description": "a webhook",
+ "request": {
+ "body": "{\"some\":\"body\"}",
+ "events": [
+ {
+ "name": "contract_content_changed"
+ }
+ ]
+ },
"_links": {
"self": {
"href": "http://localhost:1234/some-url",
diff --git a/lib/pact_broker/client/cli/webhook_commands.rb b/lib/pact_broker/client/cli/webhook_commands.rb
index 86017cbd..5c940a44 100644
--- a/lib/pact_broker/client/cli/webhook_commands.rb
+++ b/lib/pact_broker/client/cli/webhook_commands.rb
@@ -15,7 +15,9 @@ def self.shared_options_for_webhook_commands
method_option :data, aliases: "-d", desc: "Webhook payload (file or string)"
method_option :user, aliases: "-u", desc: "Webhook basic auth username and password eg. username:password"
method_option :consumer, desc: "Consumer name"
+ method_option :consumer_label, desc: "Consumer label, mutually exclusive with consumer name"
method_option :provider, desc: "Provider name"
+ method_option :provider_label, desc: "Provider label, mutually exclusive with provider name"
method_option :description, desc: "Webhook description"
method_option :contract_content_changed, type: :boolean, desc: "Trigger this webhook when the pact content changes"
method_option :contract_published, type: :boolean, desc: "Trigger this webhook when a pact is published"
@@ -70,6 +72,7 @@ def parse_webhook_events
end
def parse_webhook_options(webhook_url)
+ validate_mutual_exclusiveness_of_participant_name_and_label_options
events = parse_webhook_events
# TODO update for contract_requiring_verification_published when released
@@ -102,7 +105,9 @@ def parse_webhook_options(webhook_url)
password: password,
body: body,
consumer: options.consumer,
+ consumer_label: options.consumer_label,
provider: options.provider,
+ provider_label: options.provider_label,
events: events,
team_uuid: options.team_uuid
}
@@ -118,10 +123,20 @@ def run_webhook_commands webhook_url
rescue PactBroker::Client::Error => e
raise WebhookCreationError, "#{e.class} - #{e.message}"
end
+
+ def validate_mutual_exclusiveness_of_participant_name_and_label_options
+ if options.consumer && options.consumer_label
+ raise WebhookCreationError.new("Consumer name (--consumer) and label (--consumer_label) options are mutually exclusive")
+ end
+
+ if options.provider && options.provider_label
+ raise WebhookCreationError.new("Provider name (--provider) and label (--provider_label) options are mutually exclusive")
+ end
+ end
end
end
end
end
end
end
-end
\ No newline at end of file
+end
diff --git a/lib/pact_broker/client/webhooks/create.rb b/lib/pact_broker/client/webhooks/create.rb
index 5d97ebf4..f90381b2 100644
--- a/lib/pact_broker/client/webhooks/create.rb
+++ b/lib/pact_broker/client/webhooks/create.rb
@@ -81,10 +81,14 @@ def request_body_with_optional_consumer_and_provider
if params.consumer
body[:consumer] = { name: params.consumer }
+ elsif params.consumer_label
+ body[:consumer] = { label: params.consumer_label }
end
if params.provider
body[:provider] = { name: params.provider }
+ elsif params.provider_label
+ body[:provider] = { label: params.provider_label }
end
if params.team_uuid
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 22ac5442..7818becc 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
@@ -49,7 +49,9 @@ module CLI
password: "password",
body: "data",
consumer: "consumer",
+ consumer_label: nil,
provider: "provider",
+ provider_label: nil,
events: ["contract_content_changed"],
team_uuid: "1234"
}.tap { |it| Pact::Fixture.add_fixture(:create_webhook_params, it) }
@@ -223,6 +225,59 @@ module CLI
expect { subject }.to raise_error(WebhookCreationError, /foo/)
end
end
+
+ end
+
+ context "when both consumer name and label options are specified" do
+ before do
+ options_hash[:consumer_label] = "consumer_label"
+ broker.options = OpenStruct.new(options_hash)
+ end
+
+ it "raises a WebhookCreationError" do
+ expect { subject }.to raise_error(
+ WebhookCreationError,
+ "Consumer name (--consumer) and label (--consumer_label) options are mutually exclusive"
+ )
+ end
+ end
+
+ context "when both provider name and label options are specified" do
+ before do
+ options_hash[:provider_label] = "provider_label"
+ broker.options = OpenStruct.new(options_hash)
+ end
+
+ it "raises a WebhookCreationError" do
+ expect { subject }.to raise_error(
+ WebhookCreationError,
+ "Provider name (--provider) and label (--provider_label) options are mutually exclusive"
+ )
+ end
+ end
+
+ context "when participant labels are specified" do
+ before do
+ options_hash.delete(:consumer)
+ options_hash.delete(:provider)
+ options_hash.merge!(consumer_label: 'consumer_label', provider_label: 'provider_label')
+ expected_params.merge!(
+ consumer: nil,
+ consumer_label: 'consumer_label',
+ provider: nil,
+ provider_label: 'provider_label'
+ )
+
+ broker.options = OpenStruct.new(options_hash)
+ end
+
+ it "calls PactBroker::Client::Webhooks::Create with participant labels in params" do
+ expect(PactBroker::Client::Webhooks::Create).to receive(:call) do | params, _, _ |
+ expect(params).to eq expected_params
+ command_result
+ end
+ subject
+ 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 dfe19d95..c717934f 100644
--- a/spec/pacts/pact_broker_client-pact_broker.json
+++ b/spec/pacts/pact_broker_client-pact_broker.json
@@ -1995,6 +1995,14 @@
},
"body": {
"description": "a webhook",
+ "request": {
+ "body": "{\"some\":\"body\"}",
+ "events": [
+ {
+ "name": "contract_content_changed"
+ }
+ ]
+ },
"_links": {
"self": {
"href": "http://localhost:1234/some-url",
@@ -2067,6 +2075,26 @@
},
"body": {
"description": "a webhook",
+ "request": {
+ "body": "{\"some\":\"body\"}",
+ "events": [
+ {
+ "name": "contract_content_changed"
+ },
+ {
+ "name": "contract_published"
+ },
+ {
+ "name": "provider_verification_published"
+ },
+ {
+ "name": "provider_verification_succeeded"
+ },
+ {
+ "name": "provider_verification_failed"
+ }
+ ]
+ },
"_links": {
"self": {
"href": "http://localhost:1234/some-url",
@@ -2125,6 +2153,14 @@
},
"body": {
"description": "a webhook",
+ "request": {
+ "body": "",
+ "events": [
+ {
+ "name": "contract_content_changed"
+ }
+ ]
+ },
"_links": {
"self": {
"href": "http://localhost:1234/some-url",
@@ -2323,6 +2359,84 @@
},
"body": {
"description": "a webhook",
+ "request": {
+ "body": "{\"some\":\"body\"}",
+ "events": [
+ {
+ "name": "contract_content_changed"
+ }
+ ]
+ },
+ "_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 create a webhook with a JSON body for a consumer specified by a label",
+ "request": {
+ "method": "post",
+ "path": "/HAL-REL-PLACEHOLDER-PB-WEBHOOKS",
+ "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"
+ },
+ "consumer": {
+ "label": "consumer_label"
+ }
+ }
+ },
+ "response": {
+ "status": 201,
+ "headers": {
+ "Content-Type": "application/hal+json;charset=utf-8"
+ },
+ "body": {
+ "description": "a webhook",
+ "request": {
+ "body": "{\"some\":\"body\"}",
+ "events": [
+ {
+ "name": "contract_content_changed"
+ }
+ ]
+ },
"_links": {
"self": {
"href": "http://localhost:1234/some-url",
@@ -2442,6 +2556,84 @@
},
"body": {
"description": "a webhook",
+ "request": {
+ "body": "{\"some\":\"body\"}",
+ "events": [
+ {
+ "name": "contract_content_changed"
+ }
+ ]
+ },
+ "_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 create a webhook with a JSON body for a provider specified by a label",
+ "request": {
+ "method": "post",
+ "path": "/HAL-REL-PLACEHOLDER-PB-WEBHOOKS",
+ "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": {
+ "label": "provider_label"
+ }
+ }
+ },
+ "response": {
+ "status": 201,
+ "headers": {
+ "Content-Type": "application/hal+json;charset=utf-8"
+ },
+ "body": {
+ "description": "a webhook",
+ "request": {
+ "body": "{\"some\":\"body\"}",
+ "events": [
+ {
+ "name": "contract_content_changed"
+ }
+ ]
+ },
"_links": {
"self": {
"href": "http://localhost:1234/some-url",
@@ -2501,6 +2693,14 @@
},
"body": {
"description": "a webhook",
+ "request": {
+ "body": "{\"some\":\"body\"}",
+ "events": [
+ {
+ "name": "contract_content_changed"
+ }
+ ]
+ },
"_links": {
"self": {
"href": "http://localhost:1234/some-url",
@@ -2597,6 +2797,14 @@
},
"body": {
"description": "a webhook",
+ "request": {
+ "body": "{\"some\":\"body\"}",
+ "events": [
+ {
+ "name": "contract_content_changed"
+ }
+ ]
+ },
"_links": {
"self": {
"href": "http://localhost:1234/some-url",
@@ -2663,6 +2871,14 @@
},
"body": {
"description": "a webhook",
+ "request": {
+ "body": "{\"some\":\"body\"}",
+ "events": [
+ {
+ "name": "contract_content_changed"
+ }
+ ]
+ },
"_links": {
"self": {
"href": "http://localhost:1234/some-url",
diff --git a/spec/service_providers/webhooks_create_spec.rb b/spec/service_providers/webhooks_create_spec.rb
index ad9119d8..41a64880 100644
--- a/spec/service_providers/webhooks_create_spec.rb
+++ b/spec/service_providers/webhooks_create_spec.rb
@@ -54,6 +54,12 @@
headers: pact_broker_response_headers,
body: {
description: Pact.like("a webhook"),
+ request: {
+ body: body,
+ events: [
+ name: "contract_content_changed"
+ ]
+ },
_links: {
self: {
href: Pact.term('http://localhost:1234/some-url', %r{http://.*}),
@@ -92,6 +98,7 @@
before do
params.merge!(events: event_names)
request_body.merge!("events" => event_names.map{ |event_name| { "name" => event_name } })
+ success_response[:body][:request].merge!(events: event_names.map{ |event_name| { "name" => event_name } })
pact_broker
.given("the 'Pricing Service' and 'Condor' already exist in the pact-broker")
@@ -207,6 +214,30 @@
end
end
+ context "when consumer is specified using a label" do
+ before do
+ params.delete(:consumer)
+ params.delete(:provider)
+ params.merge!(consumer_label: "consumer_label")
+ request_body["consumer"] = { "label" => "consumer_label" }
+ mock_pact_broker_index(self)
+
+ pact_broker
+ .upon_receiving("a request to create a webhook with a JSON body for a consumer specified by a label")
+ .with(
+ method: :post,
+ path: placeholder_path('pb:webhooks'),
+ headers: post_request_headers,
+ body: request_body)
+ .will_respond_with(success_response)
+ end
+
+ it "returns a CommandResult with success = true" do
+ expect(subject.success).to be true
+ expect(subject.message).to eq "Webhook \"a webhook\" created"
+ end
+ end
+
context "when only a consumer is specified and it does not exist" do
before do
params.delete(:provider)
@@ -257,6 +288,30 @@
end
end
+ context "when provider is specified using a label" do
+ before do
+ params.delete(:consumer)
+ params.delete(:provider)
+ params.merge!(provider_label: "provider_label")
+ request_body["provider"] = { "label" => "provider_label" }
+ mock_pact_broker_index(self)
+
+ pact_broker
+ .upon_receiving("a request to create a webhook with a JSON body for a provider specified by a label")
+ .with(
+ method: :post,
+ path: placeholder_path('pb:webhooks'),
+ headers: post_request_headers,
+ body: request_body)
+ .will_respond_with(success_response)
+ end
+
+ it "returns a CommandResult with success = true" do
+ expect(subject.success).to be true
+ expect(subject.message).to eq "Webhook \"a webhook\" created"
+ end
+ end
+
context "when neither consumer nor provider are specified" do
before do
params.delete(:consumer)