pact_broker-client 1.53.0 → 1.57.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (33) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/test.yml +1 -1
  3. data/CHANGELOG.md +31 -0
  4. data/README.md +14 -2
  5. data/doc/pacts/markdown/Pact Broker Client - Pact Broker.md +222 -0
  6. data/lib/pact_broker/client/base_client.rb +7 -5
  7. data/lib/pact_broker/client/cli/matrix_commands.rb +3 -2
  8. data/lib/pact_broker/client/cli/pacticipant_commands.rb +2 -1
  9. data/lib/pact_broker/client/cli/version_selector_options_parser.rb +4 -0
  10. data/lib/pact_broker/client/cli/webhook_commands.rb +16 -1
  11. data/lib/pact_broker/client/deployments/record_release.rb +5 -1
  12. data/lib/pact_broker/client/deployments/record_undeployment.rb +1 -1
  13. data/lib/pact_broker/client/environments/environment_command.rb +7 -2
  14. data/lib/pact_broker/client/git.rb +15 -4
  15. data/lib/pact_broker/client/hal/entity.rb +2 -2
  16. data/lib/pact_broker/client/hal/http_client.rb +20 -1
  17. data/lib/pact_broker/client/hal/link.rb +7 -2
  18. data/lib/pact_broker/client/pacticipants/create.rb +2 -1
  19. data/lib/pact_broker/client/publish_pacts.rb +5 -1
  20. data/lib/pact_broker/client/version.rb +1 -1
  21. data/lib/pact_broker/client/webhooks/create.rb +4 -0
  22. data/script/can-i-deploy.sh +5 -0
  23. data/script/record-deployments-and-releases.sh +3 -3
  24. data/spec/lib/pact_broker/client/cli/broker_run_webhook_commands_spec.rb +55 -0
  25. data/spec/lib/pact_broker/client/cli/version_selector_options_parser_spec.rb +6 -0
  26. data/spec/lib/pact_broker/client/deployments/record_deployment_spec.rb +12 -1
  27. data/spec/lib/pact_broker/client/deployments/record_undeployment_spec.rb +1 -1
  28. data/spec/lib/pact_broker/client/git_spec.rb +46 -0
  29. data/spec/lib/pact_broker/client/hal/link_spec.rb +15 -0
  30. data/spec/pacts/pact_broker_client-pact_broker.json +234 -0
  31. data/spec/service_providers/webhooks_create_spec.rb +58 -0
  32. data/tasks/pact.rake +3 -1
  33. metadata +4 -3
@@ -2,6 +2,7 @@ require 'pact_broker/client/retry'
2
2
  require 'pact_broker/client/hal/authorization_header_redactor'
3
3
  require 'net/http'
4
4
  require 'json'
5
+ require 'openssl'
5
6
 
6
7
  module PactBroker
7
8
  module Client
@@ -62,13 +63,19 @@ module PactBroker
62
63
  def perform_request request, uri
63
64
  response = until_truthy_or_max_times(condition: ->(resp) { resp.code.to_i < 500 }) do
64
65
  http = Net::HTTP.new(uri.host, uri.port, :ENV)
65
- http.set_debug_output(output_stream) if verbose
66
+ http.set_debug_output(output_stream) if verbose?
66
67
  http.use_ssl = (uri.scheme == 'https')
67
68
  # Need to manually set the ca_file and ca_path for the pact-ruby-standalone.
68
69
  # The env vars seem to be picked up automatically in later Ruby versions.
69
70
  # See https://github.com/pact-foundation/pact-ruby-standalone/issues/57
70
71
  http.ca_file = ENV['SSL_CERT_FILE'] if ENV['SSL_CERT_FILE'] && ENV['SSL_CERT_FILE'] != ''
71
72
  http.ca_path = ENV['SSL_CERT_DIR'] if ENV['SSL_CERT_DIR'] && ENV['SSL_CERT_DIR'] != ''
73
+ if disable_ssl_verification?
74
+ if verbose?
75
+ $stdout.puts("SSL verification is disabled")
76
+ end
77
+ http.verify_mode = OpenSSL::SSL::VERIFY_NONE
78
+ end
72
79
  http.start do |http|
73
80
  http.request request
74
81
  end
@@ -115,6 +122,14 @@ module PactBroker
115
122
  AuthorizationHeaderRedactor.new($stdout)
116
123
  end
117
124
 
125
+ def verbose?
126
+ verbose || ENV["VERBOSE"] == "true"
127
+ end
128
+
129
+ def disable_ssl_verification?
130
+ ENV['PACT_DISABLE_SSL_VERIFICATION'] == 'true' || ENV['PACT_BROKER_DISABLE_SSL_VERIFICATION'] == 'true'
131
+ end
132
+
118
133
  class Response < SimpleDelegator
119
134
  def body
120
135
  bod = raw_body
@@ -129,6 +144,10 @@ module PactBroker
129
144
  __getobj__().to_hash
130
145
  end
131
146
 
147
+ def header(name)
148
+ __getobj__()[name]
149
+ end
150
+
132
151
  def raw_body
133
152
  __getobj__().body
134
153
  end
@@ -86,11 +86,16 @@ module PactBroker
86
86
  private
87
87
 
88
88
  def wrap_response(href, http_response)
89
- require 'pact_broker/client/hal/entity' # avoid circular reference
89
+ require "pact_broker/client/hal/entity" # avoid circular reference
90
90
  if http_response.success?
91
91
  Entity.new(href, http_response.body, @http_client, http_response)
92
92
  else
93
- ErrorEntity.new(href, http_response.raw_body, @http_client, http_response)
93
+ body = begin
94
+ http_response.header("Content-Type") && http_response.header("Content-Type").include?("json") ? http_response.body : http_response.raw_body
95
+ rescue
96
+ http_response.raw_body
97
+ end
98
+ ErrorEntity.new(href, body, @http_client, http_response)
94
99
  end
95
100
  end
96
101
 
@@ -38,7 +38,8 @@ module PactBroker
38
38
  {
39
39
  name: params[:name],
40
40
  repositoryUrl: params[:repository_url],
41
- displayName: params[:display_name]
41
+ displayName: params[:display_name],
42
+ mainBranch: params[:main_branch]
42
43
  }.compact
43
44
  end
44
45
  end
@@ -86,7 +86,11 @@ module PactBroker
86
86
  "Successfully published pacts"
87
87
  end
88
88
  else
89
- ::Term::ANSIColor.red(response_entity.response.body.to_s)
89
+ if response_entity.notices
90
+ PactBroker::Client::ColorizeNotices.call(response_entity.notices.collect{ |n| OpenStruct.new(n) } )
91
+ else
92
+ ::Term::ANSIColor.red(response_entity.response.raw_body)
93
+ end
90
94
  end
91
95
  end.join("\n")
92
96
  end
@@ -1,5 +1,5 @@
1
1
  module PactBroker
2
2
  module Client
3
- VERSION = '1.53.0'
3
+ VERSION = '1.57.0'
4
4
  end
5
5
  end
@@ -81,10 +81,14 @@ module PactBroker
81
81
 
82
82
  if params.consumer
83
83
  body[:consumer] = { name: params.consumer }
84
+ elsif params.consumer_label
85
+ body[:consumer] = { label: params.consumer_label }
84
86
  end
85
87
 
86
88
  if params.provider
87
89
  body[:provider] = { name: params.provider }
90
+ elsif params.provider_label
91
+ body[:provider] = { label: params.provider_label }
88
92
  end
89
93
 
90
94
  if params.team_uuid
@@ -0,0 +1,5 @@
1
+ bundle exec bin/pact-broker publish spec/pacts/pact_broker_client-pact_broker.json \
2
+ --consumer-app-version 1.2.26 \
3
+ --branch main
4
+
5
+ bundle exec bin/pact-broker can-i-deploy --pacticipant "Pact Broker Client" --branch "main"
@@ -6,12 +6,12 @@ bundle exec bin/pact-broker can-i-deploy --pacticipant Foo --version 2 --to-envi
6
6
 
7
7
  bundle exec bin/pact-broker record-deployment --pacticipant Foo --version 2 --environment test
8
8
  bundle exec bin/pact-broker record-deployment --pacticipant Foo --version 2 --environment test --target customer-1
9
- bundle exec bin/pact-broker record-deployment --pacticipant Foo --version 2 --environment test --target customer-1
9
+ bundle exec bin/pact-broker record-deployment --pacticipant Foo --version 2 --environment test --application-instance customer-1
10
10
 
11
- bundle exec bin/pact-broker record-undeployment --pacticipant Foo --environment test --target customer-2
11
+ bundle exec bin/pact-broker record-undeployment --pacticipant Foo --environment test --application-instance customer-2
12
12
  bundle exec bin/pact-broker record-undeployment --pacticipant Foo --environment test
13
13
  bundle exec bin/pact-broker record-undeployment --pacticipant Foo --environment test
14
- bundle exec bin/pact-broker record-undeployment --pacticipant Foo --environment test --target customer-1
14
+ bundle exec bin/pact-broker record-undeployment --pacticipant Foo --environment test --application-instance customer-1
15
15
 
16
16
  bundle exec bin/pact-broker record-release --pacticipant Foo --version 2 --environment test
17
17
  bundle exec bin/pact-broker record-support-ended --pacticipant Foo --version 2 --environment test
@@ -49,7 +49,9 @@ module PactBroker
49
49
  password: "password",
50
50
  body: "data",
51
51
  consumer: "consumer",
52
+ consumer_label: nil,
52
53
  provider: "provider",
54
+ provider_label: nil,
53
55
  events: ["contract_content_changed"],
54
56
  team_uuid: "1234"
55
57
  }.tap { |it| Pact::Fixture.add_fixture(:create_webhook_params, it) }
@@ -223,6 +225,59 @@ module PactBroker
223
225
  expect { subject }.to raise_error(WebhookCreationError, /foo/)
224
226
  end
225
227
  end
228
+
229
+ end
230
+
231
+ context "when both consumer name and label options are specified" do
232
+ before do
233
+ options_hash[:consumer_label] = "consumer_label"
234
+ broker.options = OpenStruct.new(options_hash)
235
+ end
236
+
237
+ it "raises a WebhookCreationError" do
238
+ expect { subject }.to raise_error(
239
+ WebhookCreationError,
240
+ "Consumer name (--consumer) and label (--consumer_label) options are mutually exclusive"
241
+ )
242
+ end
243
+ end
244
+
245
+ context "when both provider name and label options are specified" do
246
+ before do
247
+ options_hash[:provider_label] = "provider_label"
248
+ broker.options = OpenStruct.new(options_hash)
249
+ end
250
+
251
+ it "raises a WebhookCreationError" do
252
+ expect { subject }.to raise_error(
253
+ WebhookCreationError,
254
+ "Provider name (--provider) and label (--provider_label) options are mutually exclusive"
255
+ )
256
+ end
257
+ end
258
+
259
+ context "when participant labels are specified" do
260
+ before do
261
+ options_hash.delete(:consumer)
262
+ options_hash.delete(:provider)
263
+ options_hash.merge!(consumer_label: 'consumer_label', provider_label: 'provider_label')
264
+ expected_params.merge!(
265
+ consumer: nil,
266
+ consumer_label: 'consumer_label',
267
+ provider: nil,
268
+ provider_label: 'provider_label'
269
+ )
270
+
271
+ broker.options = OpenStruct.new(options_hash)
272
+ end
273
+
274
+ it "calls PactBroker::Client::Webhooks::Create with participant labels in params" do
275
+ expect(PactBroker::Client::Webhooks::Create).to receive(:call) do | params, _, _ |
276
+ expect(params).to eq expected_params
277
+ command_result
278
+ end
279
+ subject
280
+ end
226
281
  end
227
282
  end
228
283
  end
@@ -69,6 +69,12 @@ module PactBroker
69
69
  ],[
70
70
  ["--version", "2"],
71
71
  [{ pacticipant: nil, version: "2" }]
72
+ ],[
73
+ ["--pacticipant", "Foo", "--branch", "main"],
74
+ [{ pacticipant: "Foo", branch: "main", latest: true }]
75
+ ],[
76
+ ["--branch", "main"],
77
+ [{ pacticipant: nil, branch: "main", latest: true }]
72
78
  ]
73
79
  ]
74
80
 
@@ -44,8 +44,9 @@ module PactBroker
44
44
  let(:record_deployment_body_hash) do
45
45
  { "some" => "response" }
46
46
  end
47
+ let(:index_headers) { { "Content-Type" => "application/hal+json" } }
47
48
  let!(:index_request) do
48
- stub_request(:get, broker_base_url).to_return(status: 200, body: index_body_hash.to_json, headers: { "Content-Type" => "application/hal+json" } )
49
+ stub_request(:get, broker_base_url).to_return(status: 200, body: index_body_hash.to_json, headers: index_headers )
49
50
  end
50
51
  let!(:version_request) do
51
52
  stub_request(:get, broker_base_url + "/pacticipants/Foo/versions/1").to_return(status: 200, body: version_body_hash.to_json, headers: { "Content-Type" => "application/hal+json" } )
@@ -89,10 +90,20 @@ module PactBroker
89
90
  "_links" => {}
90
91
  }
91
92
  end
93
+
92
94
  it "returns an error response" do
93
95
  expect(subject.success).to be false
94
96
  expect(subject.message).to include "does not support"
95
97
  end
98
+
99
+ context "when the server is Pactflow" do
100
+ let(:index_headers) { { "Content-Type" => "application/hal+json", "Pactflow-Something" => "foo" } }
101
+
102
+ it "returns an error response" do
103
+ expect(subject.message).to include "permission"
104
+ expect(subject.message).to include "does not support"
105
+ end
106
+ end
96
107
  end
97
108
 
98
109
  context "when the specified version does not exist" do
@@ -174,7 +174,7 @@ module PactBroker
174
174
 
175
175
  context "when a target is provided and there is no deployed version with a matching target" do
176
176
  let(:application_instance) { "wrong" }
177
- let(:expected_message) { "Foo is not currently deployed to application instance 'wrong' in test environment. Please omit the application instance to undeploy from the anonymous instance or specify one of the following application instances to record the undeployment from: customer-1." }
177
+ let(:expected_message) { "Foo is not currently deployed to application instance 'wrong' in test environment. Please omit the application instance or specify one of the following application instances to record the undeployment from: customer-1." }
178
178
 
179
179
  its(:success) { is_expected.to be false }
180
180
  its(:message) { is_expected.to include expected_message }
@@ -35,6 +35,16 @@ module PactBroker
35
35
  end
36
36
  end
37
37
 
38
+ context "when the branch starts with refs/heads/" do
39
+ before do
40
+ allow(ENV).to receive(:[]).with("GITHUB_REF").and_return("refs/heads/feature-x")
41
+ end
42
+
43
+ it "trims off the refs/heads/" do
44
+ expect(subject).to eq "feature-x"
45
+ end
46
+ end
47
+
38
48
  context "when there is one environment variable ending with _BRANCH" do
39
49
  before do
40
50
  allow(ENV).to receive(:keys).and_return(%w{FOO_BRANCH BAR_BRANCH BLAH})
@@ -108,6 +118,42 @@ module PactBroker
108
118
  include_examples "when raise_error is false"
109
119
  end
110
120
  end
121
+
122
+ describe ".build_url" do
123
+ before do
124
+ allow(ENV).to receive(:[]).and_call_original
125
+ end
126
+
127
+ subject { Git.build_url }
128
+
129
+ context "when nothing is set" do
130
+ before do
131
+ allow(ENV).to receive(:[]).and_return(nil)
132
+ end
133
+
134
+ it { is_expected.to eq nil }
135
+ end
136
+
137
+ context "when BUILDKITE_BUILD_URL is set" do
138
+ before do
139
+ allow(ENV).to receive(:[]).and_return(nil)
140
+ allow(ENV).to receive(:[]).with("BUILDKITE_BUILD_URL").and_return("http://build")
141
+ end
142
+
143
+ it { is_expected.to eq "http://build" }
144
+ end
145
+
146
+ context "when the Github Actions env vars are set" do
147
+ before do
148
+ allow(ENV).to receive(:[]).and_return(nil)
149
+ allow(ENV).to receive(:[]).with("GITHUB_SERVER_URL").and_return("https://github.com")
150
+ allow(ENV).to receive(:[]).with("GITHUB_REPOSITORY").and_return("org/repo")
151
+ allow(ENV).to receive(:[]).with("GITHUB_RUN_ID").and_return("1")
152
+ end
153
+
154
+ it { is_expected.to eq "https://github.com/org/repo/actions/runs/1" }
155
+ end
156
+ end
111
157
  end
112
158
  end
113
159
  end
@@ -5,6 +5,10 @@ require 'pact_broker/client/hal/http_client'
5
5
  module PactBroker::Client
6
6
  module Hal
7
7
  describe Link do
8
+ before do
9
+ allow(response).to receive(:header).with("Content-Type").and_return(content_type)
10
+ end
11
+
8
12
  let(:http_client) do
9
13
  instance_double('PactBroker::Client::Hal::HttpClient', post: response)
10
14
  end
@@ -33,6 +37,8 @@ module PactBroker::Client
33
37
  }
34
38
  end
35
39
 
40
+ let(:content_type) { nil }
41
+
36
42
  subject { Link.new(attrs, http_client) }
37
43
 
38
44
  before do
@@ -67,6 +73,15 @@ module PactBroker::Client
67
73
  expect(PactBroker::Client::Hal::ErrorEntity).to receive(:new).with("http://foo/{bar}", response_body.to_json, http_client, response)
68
74
  do_run
69
75
  end
76
+
77
+ context "when a JSON error is returned" do
78
+ let(:content_type) { "application/json" }
79
+
80
+ it "parses the response body" do
81
+ expect(PactBroker::Client::Hal::ErrorEntity).to receive(:new).with("http://foo/{bar}", response_body, http_client, response)
82
+ do_run
83
+ end
84
+ end
70
85
  end
71
86
  end
72
87
 
@@ -1995,6 +1995,16 @@
1995
1995
  },
1996
1996
  "body": {
1997
1997
  "description": "a webhook",
1998
+ "request": {
1999
+ "body": {
2000
+ "some": "body"
2001
+ }
2002
+ },
2003
+ "events": [
2004
+ {
2005
+ "name": "contract_content_changed"
2006
+ }
2007
+ ],
1998
2008
  "_links": {
1999
2009
  "self": {
2000
2010
  "href": "http://localhost:1234/some-url",
@@ -2067,6 +2077,28 @@
2067
2077
  },
2068
2078
  "body": {
2069
2079
  "description": "a webhook",
2080
+ "request": {
2081
+ "body": {
2082
+ "some": "body"
2083
+ }
2084
+ },
2085
+ "events": [
2086
+ {
2087
+ "name": "contract_content_changed"
2088
+ },
2089
+ {
2090
+ "name": "contract_published"
2091
+ },
2092
+ {
2093
+ "name": "provider_verification_published"
2094
+ },
2095
+ {
2096
+ "name": "provider_verification_succeeded"
2097
+ },
2098
+ {
2099
+ "name": "provider_verification_failed"
2100
+ }
2101
+ ],
2070
2102
  "_links": {
2071
2103
  "self": {
2072
2104
  "href": "http://localhost:1234/some-url",
@@ -2125,6 +2157,14 @@
2125
2157
  },
2126
2158
  "body": {
2127
2159
  "description": "a webhook",
2160
+ "request": {
2161
+ "body": "<xml></xml>"
2162
+ },
2163
+ "events": [
2164
+ {
2165
+ "name": "contract_content_changed"
2166
+ }
2167
+ ],
2128
2168
  "_links": {
2129
2169
  "self": {
2130
2170
  "href": "http://localhost:1234/some-url",
@@ -2323,6 +2363,88 @@
2323
2363
  },
2324
2364
  "body": {
2325
2365
  "description": "a webhook",
2366
+ "request": {
2367
+ "body": {
2368
+ "some": "body"
2369
+ }
2370
+ },
2371
+ "events": [
2372
+ {
2373
+ "name": "contract_content_changed"
2374
+ }
2375
+ ],
2376
+ "_links": {
2377
+ "self": {
2378
+ "href": "http://localhost:1234/some-url",
2379
+ "title": "A title"
2380
+ }
2381
+ }
2382
+ },
2383
+ "matchingRules": {
2384
+ "$.body.description": {
2385
+ "match": "type"
2386
+ },
2387
+ "$.body._links.self.href": {
2388
+ "match": "regex",
2389
+ "regex": "http:\\/\\/.*"
2390
+ },
2391
+ "$.body._links.self.title": {
2392
+ "match": "type"
2393
+ }
2394
+ }
2395
+ }
2396
+ },
2397
+ {
2398
+ "description": "a request to create a webhook with a JSON body for a consumer specified by a label",
2399
+ "request": {
2400
+ "method": "post",
2401
+ "path": "/HAL-REL-PLACEHOLDER-PB-WEBHOOKS",
2402
+ "headers": {
2403
+ "Content-Type": "application/json",
2404
+ "Accept": "application/hal+json"
2405
+ },
2406
+ "body": {
2407
+ "description": "a webhook",
2408
+ "events": [
2409
+ {
2410
+ "name": "contract_content_changed"
2411
+ }
2412
+ ],
2413
+ "request": {
2414
+ "url": "https://webhook",
2415
+ "method": "POST",
2416
+ "headers": {
2417
+ "Foo": "bar",
2418
+ "Bar": "foo"
2419
+ },
2420
+ "body": {
2421
+ "some": "body"
2422
+ },
2423
+ "username": "username",
2424
+ "password": "password"
2425
+ },
2426
+ "consumer": {
2427
+ "label": "consumer_label"
2428
+ }
2429
+ }
2430
+ },
2431
+ "response": {
2432
+ "status": 201,
2433
+ "headers": {
2434
+ "Content-Type": "application/hal+json;charset=utf-8"
2435
+ },
2436
+ "body": {
2437
+ "description": "a webhook",
2438
+ "request": {
2439
+ "body": {
2440
+ "some": "body"
2441
+ }
2442
+ },
2443
+ "events": [
2444
+ {
2445
+ "name": "contract_content_changed"
2446
+ }
2447
+ ],
2326
2448
  "_links": {
2327
2449
  "self": {
2328
2450
  "href": "http://localhost:1234/some-url",
@@ -2442,6 +2564,88 @@
2442
2564
  },
2443
2565
  "body": {
2444
2566
  "description": "a webhook",
2567
+ "request": {
2568
+ "body": {
2569
+ "some": "body"
2570
+ }
2571
+ },
2572
+ "events": [
2573
+ {
2574
+ "name": "contract_content_changed"
2575
+ }
2576
+ ],
2577
+ "_links": {
2578
+ "self": {
2579
+ "href": "http://localhost:1234/some-url",
2580
+ "title": "A title"
2581
+ }
2582
+ }
2583
+ },
2584
+ "matchingRules": {
2585
+ "$.body.description": {
2586
+ "match": "type"
2587
+ },
2588
+ "$.body._links.self.href": {
2589
+ "match": "regex",
2590
+ "regex": "http:\\/\\/.*"
2591
+ },
2592
+ "$.body._links.self.title": {
2593
+ "match": "type"
2594
+ }
2595
+ }
2596
+ }
2597
+ },
2598
+ {
2599
+ "description": "a request to create a webhook with a JSON body for a provider specified by a label",
2600
+ "request": {
2601
+ "method": "post",
2602
+ "path": "/HAL-REL-PLACEHOLDER-PB-WEBHOOKS",
2603
+ "headers": {
2604
+ "Content-Type": "application/json",
2605
+ "Accept": "application/hal+json"
2606
+ },
2607
+ "body": {
2608
+ "description": "a webhook",
2609
+ "events": [
2610
+ {
2611
+ "name": "contract_content_changed"
2612
+ }
2613
+ ],
2614
+ "request": {
2615
+ "url": "https://webhook",
2616
+ "method": "POST",
2617
+ "headers": {
2618
+ "Foo": "bar",
2619
+ "Bar": "foo"
2620
+ },
2621
+ "body": {
2622
+ "some": "body"
2623
+ },
2624
+ "username": "username",
2625
+ "password": "password"
2626
+ },
2627
+ "provider": {
2628
+ "label": "provider_label"
2629
+ }
2630
+ }
2631
+ },
2632
+ "response": {
2633
+ "status": 201,
2634
+ "headers": {
2635
+ "Content-Type": "application/hal+json;charset=utf-8"
2636
+ },
2637
+ "body": {
2638
+ "description": "a webhook",
2639
+ "request": {
2640
+ "body": {
2641
+ "some": "body"
2642
+ }
2643
+ },
2644
+ "events": [
2645
+ {
2646
+ "name": "contract_content_changed"
2647
+ }
2648
+ ],
2445
2649
  "_links": {
2446
2650
  "self": {
2447
2651
  "href": "http://localhost:1234/some-url",
@@ -2501,6 +2705,16 @@
2501
2705
  },
2502
2706
  "body": {
2503
2707
  "description": "a webhook",
2708
+ "request": {
2709
+ "body": {
2710
+ "some": "body"
2711
+ }
2712
+ },
2713
+ "events": [
2714
+ {
2715
+ "name": "contract_content_changed"
2716
+ }
2717
+ ],
2504
2718
  "_links": {
2505
2719
  "self": {
2506
2720
  "href": "http://localhost:1234/some-url",
@@ -2597,6 +2811,16 @@
2597
2811
  },
2598
2812
  "body": {
2599
2813
  "description": "a webhook",
2814
+ "request": {
2815
+ "body": {
2816
+ "some": "body"
2817
+ }
2818
+ },
2819
+ "events": [
2820
+ {
2821
+ "name": "contract_content_changed"
2822
+ }
2823
+ ],
2600
2824
  "_links": {
2601
2825
  "self": {
2602
2826
  "href": "http://localhost:1234/some-url",
@@ -2663,6 +2887,16 @@
2663
2887
  },
2664
2888
  "body": {
2665
2889
  "description": "a webhook",
2890
+ "request": {
2891
+ "body": {
2892
+ "some": "body"
2893
+ }
2894
+ },
2895
+ "events": [
2896
+ {
2897
+ "name": "contract_content_changed"
2898
+ }
2899
+ ],
2666
2900
  "_links": {
2667
2901
  "self": {
2668
2902
  "href": "http://localhost:1234/some-url",