Skip to content

Commit e60460e

Browse files
committed
feat: add consumer and provider objects to webhook resource
1 parent 3d94bdc commit e60460e

File tree

6 files changed

+173
-2
lines changed

6 files changed

+173
-2
lines changed

lib/pact_broker/api/contracts/webhook_contract.rb

+35
Original file line numberDiff line numberDiff line change
@@ -26,10 +26,45 @@ def validate(*)
2626
config.messages_file = File.expand_path("../../../locale/en.yml", __FILE__)
2727
end
2828

29+
optional(:consumer)
30+
optional(:provider)
2931
required(:request).filled
3032
optional(:events).maybe(min_size?: 1)
3133
end
3234

35+
property :consumer do
36+
property :name
37+
38+
validation do
39+
configure do
40+
config.messages_file = File.expand_path("../../../locale/en.yml", __FILE__)
41+
42+
def pacticipant_exists?(name)
43+
!!PactBroker::Pacticipants::Service.find_pacticipant_by_name(name)
44+
end
45+
end
46+
47+
required(:name).filled(:pacticipant_exists?)
48+
end
49+
50+
end
51+
52+
property :provider do
53+
property :name
54+
55+
validation do
56+
configure do
57+
config.messages_file = File.expand_path("../../../locale/en.yml", __FILE__)
58+
59+
def pacticipant_exists?(name)
60+
!!PactBroker::Pacticipants::Service.find_pacticipant_by_name(name)
61+
end
62+
end
63+
64+
required(:name).filled(:pacticipant_exists?)
65+
end
66+
end
67+
3368
property :request do
3469
property :url
3570
property :http_method

lib/pact_broker/api/decorators/webhook_decorator.rb

+8
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,14 @@ class WebhookEventDecorator < BaseDecorator
1616
property :name
1717
end
1818

19+
property :consumer, :class => PactBroker::Domain::Pacticipant do
20+
property :name
21+
end
22+
23+
property :provider, :class => PactBroker::Domain::Pacticipant do
24+
property :name
25+
end
26+
1927
property :request, :class => PactBroker::Domain::WebhookRequest, extend: WebhookRequestDecorator
2028
collection :events, :class => PactBroker::Webhooks::WebhookEvent, extend: WebhookEventDecorator
2129

lib/pact_broker/locale/en.yml

+1
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ en:
88
name_in_path_matches_name_in_pact?: "does not match %{left} name in path ('%{right}')."
99
valid_consumer_version_number?: "Consumer version number '%{value}' cannot be parsed to a version number. The expected format (unless this configuration has been overridden) is a semantic version. eg. 1.3.0 or 2.0.4.rc1"
1010
non_templated_host?: "cannot have a template parameter in the host"
11+
pacticipant_exists?: "does not match an existing pacticipant"
1112

1213
pact_broker:
1314
messages:
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
{
2+
"events": [{
3+
"name": "something_happened"
4+
}],
5+
"consumer": {
6+
"name": "Foo"
7+
},
8+
"provider": {
9+
"name": "Bar"
10+
},
11+
"request": {
12+
"method": "POST",
13+
"url": "HTTPS://some.url",
14+
"username": "username",
15+
"password": "password",
16+
"headers": {
17+
"Accept": "application/json"
18+
},
19+
"body": {
20+
"a" : "body"
21+
}
22+
}
23+
}

spec/lib/pact_broker/api/contracts/webhook_contract_spec.rb

+98-2
Original file line numberDiff line numberDiff line change
@@ -6,14 +6,16 @@ module PactBroker
66
module Api
77
module Contracts
88
describe WebhookContract do
9-
let(:json) { load_fixture 'webhook_valid.json' }
9+
let(:json) { load_fixture 'webhook_valid_with_pacticipants.json' }
1010
let(:hash) { JSON.parse(json) }
1111
let(:webhook) { PactBroker::Api::Decorators::WebhookDecorator.new(Domain::Webhook.new).from_json(json) }
1212
let(:subject) { WebhookContract.new(webhook) }
1313
let(:matching_hosts) { ['foo'] }
14+
let(:consumer) { double("consumer") }
15+
let(:provider) { double("provider") }
1416

1517
def valid_webhook_with
16-
hash = load_json_fixture 'webhook_valid.json'
18+
hash = load_json_fixture 'webhook_valid_with_pacticipants.json'
1719
yield hash
1820
hash.to_json
1921
end
@@ -23,6 +25,8 @@ def valid_webhook_with
2325
PactBroker.configuration.webhook_http_method_whitelist = webhook_http_method_whitelist
2426
PactBroker.configuration.webhook_host_whitelist = webhook_host_whitelist
2527
allow(PactBroker::Webhooks::CheckHostWhitelist).to receive(:call).and_return(whitelist_matches)
28+
allow(PactBroker::Pacticipants::Service).to receive(:find_pacticipant_by_name).with("Foo").and_return(consumer)
29+
allow(PactBroker::Pacticipants::Service).to receive(:find_pacticipant_by_name).with("Bar").and_return(provider)
2630
subject.validate(hash)
2731
end
2832

@@ -36,6 +40,98 @@ def valid_webhook_with
3640
end
3741
end
3842

43+
context "with a nil consumer name" do
44+
let(:json) do
45+
valid_webhook_with do |hash|
46+
hash['consumer']['name'] = nil
47+
end
48+
end
49+
50+
it "contains an error" do
51+
expect(subject.errors[:'consumer.name']).to eq ["can't be blank"]
52+
end
53+
end
54+
55+
context "with no consumer name key" do
56+
let(:json) do
57+
valid_webhook_with do |hash|
58+
hash['consumer'].delete('name')
59+
end
60+
end
61+
62+
# I'd prefer this to be "is missing". Isn't the whole point of dry validation
63+
# that you can distingush between keys being missing and values being missing? FFS.
64+
it "contains an error" do
65+
expect(subject.errors[:'consumer.name']).to eq ["can't be blank"]
66+
end
67+
end
68+
69+
context "with no consumer" do
70+
let(:json) do
71+
valid_webhook_with do |hash|
72+
hash.delete('consumer')
73+
end
74+
end
75+
76+
it "contains no errors" do
77+
expect(subject.errors).to be_empty
78+
end
79+
end
80+
81+
context "with a consumer name that doesn't match any existing consumer" do
82+
let(:consumer) { nil }
83+
84+
it "contains no errors" do
85+
expect(subject.errors[:'consumer.name']).to eq ["does not match an existing pacticipant"]
86+
end
87+
end
88+
89+
context "with a nil provider name" do
90+
let(:json) do
91+
valid_webhook_with do |hash|
92+
hash['provider']['name'] = nil
93+
end
94+
end
95+
96+
it "contains an error" do
97+
expect(subject.errors[:'provider.name']).to eq ["can't be blank"]
98+
end
99+
end
100+
101+
context "with no provider name key" do
102+
let(:json) do
103+
valid_webhook_with do |hash|
104+
hash['provider'].delete('name')
105+
end
106+
end
107+
108+
# I'd prefer this to be "is missing". Isn't the whole point of dry validation
109+
# that you can distingush between keys being missing and values being missing? FFS.
110+
it "contains an error" do
111+
expect(subject.errors[:'provider.name']).to eq ["can't be blank"]
112+
end
113+
end
114+
115+
context "with no provider" do
116+
let(:json) do
117+
valid_webhook_with do |hash|
118+
hash.delete('provider')
119+
end
120+
end
121+
122+
it "contains no errors" do
123+
expect(subject.errors).to be_empty
124+
end
125+
end
126+
127+
context "with a provider name that doesn't match any existing provider" do
128+
let(:provider) { nil }
129+
130+
it "contains no errors" do
131+
expect(subject.errors[:'provider.name']).to eq ["does not match an existing pacticipant"]
132+
end
133+
end
134+
39135
context "with no request defined" do
40136
let(:json) { {}.to_json }
41137

spec/lib/pact_broker/api/decorators/webhook_decorator_spec.rb

+8
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,14 @@ module Decorators
4646
expect(parsed_json[:request]).to eq request
4747
end
4848

49+
it 'includes the consumer' do
50+
expect(parsed_json[:consumer]).to eq name: "Consumer"
51+
end
52+
53+
it 'includes the provider' do
54+
expect(parsed_json[:provider]).to eq name: "Provider"
55+
end
56+
4957
it 'includes a link to the consumer' do
5058
expect(parsed_json[:_links][:'pb:consumer'][:name]).to eq 'Consumer'
5159
expect(parsed_json[:_links][:'pb:consumer'][:href]).to eq 'http://example.org/pacticipants/Consumer'

0 commit comments

Comments
 (0)