pact_broker-client 1.23.0 → 1.24.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -2,7 +2,7 @@ Returns exit code 0 or 1, indicating whether or not the specified application (p
2
2
 
3
3
  The environment variables PACT_BROKER_BASE_URL, PACT_BROKER_USERNAME and PACT_BROKER_PASSWORD may be used instead of their respective command line options.
4
4
 
5
- There are two ways to use `can-i-deploy`. The first (recommended and most common) approach is to specify just the application version you want to deploy and let the Pact Broker work out the dependencies for you. The second approach is to specify each application version explicitly. This would generally only be used if there were limitations that stopped you being able to use the first approach.
5
+ There are two ways to use `can-i-deploy`. The first (recommended and most commonly used) approach is to specify just the application version you want to deploy and let the Pact Broker work out the dependencies for you. The second approach is to specify each application version explicitly. This would generally only be used if there were limitations that stopped you being able to use the first approach.
6
6
 
7
7
  #### Specifying an application version
8
8
 
@@ -13,12 +13,13 @@ To specify an application (pacticipant) version you need to provide:
13
13
  * `--version VERSION` to specify a known application version (recommended)
14
14
  * `--latest` to specify the latest version
15
15
  * `--latest TAG` to specify the latest version that has a particular tag
16
+ * `--all TAG` to specify all the versions that have a particular tag (eg. "all prod" versions). This would be used when ensuring you have backwards compatiblity with all production mobile clients for a provider. Note, when using this option, you need to specify dependency explicitly (see the second usage option).
16
17
 
17
18
  Using a specific version is the easiest way to ensure you get an accurate response that won't be affected by race conditions.
18
19
 
19
20
  #### Recommended usage - allowing the Pact Broker to automatically determine the dependencies
20
21
 
21
- If you would like the Pact Broker to calculate the dependencies for you when you want to deploy an application into a given environment, you will need to let the Broker know what application versions are in that environment. To do this, the relevant application version resource in the Broker will need to be "tagged" with the name of the environment during the deployment process:
22
+ Prerequisite: if you would like the Pact Broker to calculate the dependencies for you when you want to deploy an application into a given environment, you will need to let the Broker know which version of each application is in that environment. To do this, the relevant application version resource in the Broker will need to be "tagged" with the name of the environment during the deployment process:
22
23
 
23
24
  $ pact-broker create-version-tag --pacticipant Foo --version 173153ae0 --tag test
24
25
 
@@ -56,13 +57,20 @@ Can I deploy the latest version of the application Foo that has the tag "test" t
56
57
 
57
58
 
58
59
 
59
- #### Alternate usage - specifying all dependencies explicitly
60
+ #### Alternate usage - specifying dependencies explicitly
60
61
 
61
- If you are unable to use tags, or there is some other limitation that stops you from using the recommended approach, you can specify each of the application versions explictly. You can specify as many application versions as you like.
62
+ If you are unable to use tags, or there is some other limitation that stops you from using the recommended approach, you can specify one or more of the dependencies explictly. You must also do this if you want to use the `--all TAG` option for any of the pacticipants.
62
63
 
63
- $ pact-broker can-i-deploy --pacticipant PACTICIPANT_1 [--version VERSION_1 | --latest [TAG]] \
64
- --pacticipant PACTICIPANT_2 [--version VERSION_2 | --latest [TAG_2]] \
65
- --to ENVIRONMENT \
64
+ You can specify as many application versions as you like, and you can even specify multiple versions of the same application (repeat the `--pacticipant` name and supply a different version.)
65
+
66
+ You can use explictly declared dependencies with or without the `--to ENVIRONMENT`. For example, if you declare two (or more) application versions with no `--to ENVIRONMENT`, then only the applications you specify will be taken into account when determining if it is safe to deploy. If you declare two (or more) application versions _as well as_ a `--to ENVIRONMENT`, then the Pact Broker will work out what integrations your declared applications will have in that environment when determining if it safe to deploy. When using this script for a production release, and you are using tags, it is always the most future-proof option to use the `--to` if possible, as it will catch any newly added consumers or providers.
67
+
68
+ If you are finding that your dependencies are not being automatically included when you supply multiple pacticipant versions, please upgrade to the latest version of the Pact Broker, as this is a more recently added feature.
69
+
70
+
71
+ $ pact-broker can-i-deploy --pacticipant PACTICIPANT_1 [--version VERSION_1 | --latest [TAG_1] | --all TAG_1] \
72
+ --pacticipant PACTICIPANT_2 [--version VERSION_2 | --latest [TAG_2] | --all TAG_2] \
73
+ [--to ENVIRONMENT] \
66
74
  --broker-base-url BROKER_BASE_URL
67
75
 
68
76
  Examples:
@@ -82,3 +90,11 @@ Can I deploy the latest version of Foo with tag "master" and the latest version
82
90
  --pacticipant Bar --latest master \
83
91
  --broker-base-url BROKER_BASE_URL
84
92
 
93
+
94
+ Mobile provider use case - can I deploy version b80e7b1b of Bar, all versions of Foo with tag "prod", and the latest version tagged "prod" of any other automatically calculated dependencies together? (Eg. where Bar is a provider and Foo is a mobile consumer with multiple versions in production, and Bar also has its own providers it needs to be compatible with.)
95
+
96
+
97
+ $ pact-broker can-i-deploy --pacticipant Bar --version b80e7b1b \
98
+ --pacticipant Foo --all prod \
99
+ --to prod \
100
+ --broker-base-url BROKER_BASE_URL
@@ -0,0 +1 @@
1
+ Create a curl command that executes the request that you want your webhook to execute, then replace "curl" with "pact-broker create-or-update-webhook" and add the consumer, provider, event types and broker details. Note that the URL must be the first parameter when executing create-or-update-webhook and a uuid must also be provided. You can generate a valid UUID by using the `generate-uuid` command.
@@ -64,6 +64,36 @@ module PactBroker
64
64
  end
65
65
  new_argv.flatten
66
66
  end
67
+
68
+ # If you try and generate a uuid, and the PACT_BROKER_... env vars are set, it will cause
69
+ # generate_uuid to be called with parameters that it doesn't declare, and hence, throw an error.
70
+ # This is a dirty hack that stops that happening!
71
+ def self.ignored_and_hidden_potential_options_from_environment_variables
72
+ method_option :broker_base_url, hide: true
73
+ method_option :broker_username, hide: true
74
+ method_option :broker_password, hide: true
75
+ method_option :broker_token, hide: true
76
+ end
77
+
78
+ def self.shared_options_for_webhook_commands
79
+ method_option :request, banner: "METHOD", aliases: "-X", desc: "HTTP method", required: true
80
+ method_option :header, aliases: "-H", type: :array, desc: "Header"
81
+ method_option :data, aliases: "-d", desc: "Data"
82
+ method_option :user, aliases: "-u", desc: "Basic auth username and password eg. username:password"
83
+ method_option :consumer, desc: "Consumer name"
84
+ method_option :provider, desc: "Provider name"
85
+ method_option :broker_base_url, required: true, aliases: "-b", desc: "The base URL of the Pact Broker"
86
+ method_option :broker_username, desc: "Pact Broker basic auth username"
87
+ method_option :broker_password, aliases: "-p", desc: "Pact Broker basic auth password"
88
+ method_option :broker_token, aliases: "-k", desc: "Pact Broker bearer token"
89
+ method_option :description, desc: "The description of the webhook"
90
+ method_option :contract_content_changed, type: :boolean, desc: "Trigger this webhook when the pact content changes"
91
+ method_option :contract_published, type: :boolean, desc: "Trigger this webhook when a pact is published"
92
+ method_option :provider_verification_published, type: :boolean, desc: "Trigger this webhook when a provider verification result is published"
93
+ method_option :provider_verification_failed, type: :boolean, desc: "Trigger this webhook when a failed provider verification result is published"
94
+ method_option :provider_verification_succeeded, type: :boolean, desc: "Trigger this webhook when a successful provider verification result is published"
95
+ method_option :verbose, aliases: "-v", type: :boolean, default: false, required: false, desc: "Verbose output. Default: false"
96
+ end
67
97
  end
68
98
  end
69
99
  end
@@ -1,5 +1,5 @@
1
1
  module PactBroker
2
2
  module Client
3
- VERSION = '1.23.0'
3
+ VERSION = '1.24.0'
4
4
  end
5
5
  end
@@ -8,8 +8,8 @@ module PactBroker
8
8
  module Client
9
9
  module Webhooks
10
10
  class Create
11
-
12
11
  WEBHOOKS_WITH_OPTIONAL_PACTICICPANTS_NOT_SUPPORTED = "This version of the Pact Broker requires that both consumer and provider are specified for a webhook. Please upgrade your broker to >= 2.22.0 to create a webhook with optional consumer and provider."
12
+ CREATING_WEBHOOK_WITH_UUID_NOT_SUPPORTED = "This version of the Pact Broker does not support creating webhooks with a specified UUID. Please upgrade your broker to >= 2.49.0 or use the create-webhook command."
13
13
 
14
14
  attr_reader :params, :pact_broker_base_url, :basic_auth_options, :verbose
15
15
 
@@ -24,7 +24,7 @@ module PactBroker
24
24
  end
25
25
 
26
26
  def call
27
- if params.consumer && params.provider
27
+ if params.consumer && params.provider && !params.uuid
28
28
  create_webhook_with_consumer_and_provider
29
29
  else
30
30
  create_webhook_with_optional_consumer_and_provider
@@ -41,10 +41,19 @@ module PactBroker
41
41
  end
42
42
 
43
43
  def create_webhook_with_optional_consumer_and_provider
44
- webhook_entity = index_link.get!._link("pb:webhooks").post(request_body_with_optional_consumer_and_provider)
44
+ index_entity = index_link.get!
45
+ if params.uuid
46
+ if index_entity.can?("pb:webhook")
47
+ webhook_entity = index_entity._link("pb:webhook").expand(uuid: params.uuid).put(request_body_with_optional_consumer_and_provider)
48
+ else
49
+ return error_result(CREATING_WEBHOOK_WITH_UUID_NOT_SUPPORTED)
50
+ end
51
+ else
52
+ webhook_entity = index_entity._link("pb:webhooks").post(request_body_with_optional_consumer_and_provider)
53
+ end
45
54
 
46
55
  if webhook_entity.response.status == 405
47
- raise PactBroker::Client::Error.new(WEBHOOKS_WITH_OPTIONAL_PACTICICPANTS_NOT_SUPPORTED)
56
+ return error_result(WEBHOOKS_WITH_OPTIONAL_PACTICICPANTS_NOT_SUPPORTED)
48
57
  end
49
58
 
50
59
  handle_response(webhook_entity)
@@ -62,7 +71,7 @@ module PactBroker
62
71
  username: params.username,
63
72
  password: params.password
64
73
  }
65
- }
74
+ }.tap { |req| req[:description] = params.description if params.description }
66
75
  end
67
76
 
68
77
  def request_body_with_optional_consumer_and_provider
@@ -87,7 +96,7 @@ module PactBroker
87
96
  if webhook_entity.success?
88
97
  success_result(webhook_entity)
89
98
  else
90
- error_result(webhook_entity)
99
+ http_error_result(webhook_entity)
91
100
  end
92
101
  end
93
102
 
@@ -95,7 +104,11 @@ module PactBroker
95
104
  CommandResult.new(true, "Webhook #{webhook_entity._link('self').title_or_name.inspect} created")
96
105
  end
97
106
 
98
- def error_result(webhook_entity)
107
+ def error_result(message)
108
+ CommandResult.new(false, message)
109
+ end
110
+
111
+ def http_error_result(webhook_entity)
99
112
  CommandResult.new(false, "Error creating webhook. response status=#{webhook_entity.response.status} body=#{webhook_entity.response.raw_body}")
100
113
  end
101
114
 
@@ -0,0 +1,23 @@
1
+ require 'pact_broker/client/cli/broker'
2
+ require 'pact_broker/client/webhooks/create'
3
+
4
+ module PactBroker
5
+ module Client
6
+ module CLI
7
+ describe Broker do
8
+ describe "create_or_update_webhook" do
9
+
10
+ let(:broker) { Broker.new }
11
+
12
+ subject { broker.create_or_update_webhook "http://webhook" }
13
+
14
+ it "calls PactBroker::Client::Webhooks::Create with the webhook params" do
15
+ expect(broker).to receive(:run_webhook_commands).with("http://webhook")
16
+
17
+ subject
18
+ end
19
+ end
20
+ end
21
+ end
22
+ end
23
+ end
@@ -6,184 +6,16 @@ module PactBroker
6
6
  module CLI
7
7
  describe Broker do
8
8
  describe "create_webhook" do
9
- before do
10
- allow($stdout).to receive(:puts)
11
- allow(PactBroker::Client::Webhooks::Create).to receive(:call).and_return(command_result)
12
- broker.options = OpenStruct.new(options_hash)
13
- end
14
9
 
15
10
  let(:broker) { Broker.new }
16
- let(:data) { 'data' }
17
- let(:user) { "username:password" }
18
- let(:command_result) { double('command result', success: success, message: 'message') }
19
- let(:success) { true }
20
- let(:header) { ["Foo: bar", "Bar: foo"] }
21
-
22
- let(:options_hash) do
23
- {
24
- request: "POST",
25
- header: header,
26
- data: data,
27
- user: user,
28
- consumer: "consumer",
29
- provider: "provider",
30
- broker_base_url: "http://broker",
31
- broker_username: "username",
32
- broker_password: "password",
33
- broker_token: "token",
34
- contract_content_changed: true,
35
- verbose: true
36
- }
37
- end
38
-
39
- let(:expected_params) do
40
- {
41
- http_method: "POST",
42
- url: "http://webhook",
43
- headers: { "Foo" => "bar", "Bar" => "foo"},
44
- username: "username",
45
- password: "password",
46
- body: "data",
47
- consumer: "consumer",
48
- provider: "provider",
49
- events: ["contract_content_changed"]
50
- }.tap { |it| Pact::Fixture.add_fixture(:create_webhook_params, it) }
51
- end
52
11
 
53
- subject { broker.create_webhook "http://webhook" }
12
+ subject { broker.create_webhook "http://webhook" }
54
13
 
55
14
  it "calls PactBroker::Client::Webhooks::Create with the webhook params" do
56
- expect(PactBroker::Client::Webhooks::Create).to receive(:call) do | params, _, _ |
57
- expect(params).to eq expected_params
58
- command_result
59
- end
60
- subject
61
- end
15
+ expect(broker).to receive(:run_webhook_commands).with("http://webhook")
62
16
 
63
- it "calls PactBroker::Client::Webhooks::Create with pact broker details" do
64
- expect(PactBroker::Client::Webhooks::Create).to receive(:call) do | _, broker_base_url, pact_broker_client_options |
65
- expect(broker_base_url).to eq "http://broker"
66
- expect(pact_broker_client_options).to eq(basic_auth: { username: "username", password: "password"}, token: "token", verbose: true)
67
- command_result
68
- end
69
17
  subject
70
18
  end
71
-
72
- context "when neither event type is selected" do
73
- before do
74
- options_hash.delete(:contract_content_changed)
75
- broker.options = OpenStruct.new(options_hash)
76
- end
77
-
78
- it "raises an error" do
79
- expect { subject }.to raise_error PactBroker::Client::Error, /You must select at least one/
80
- end
81
- end
82
-
83
- context "with no basic auth" do
84
- before do
85
- options_hash.delete(:broker_username)
86
- options_hash.delete(:broker_password)
87
- broker.options = OpenStruct.new(options_hash)
88
- end
89
-
90
- it "calls Webhooks::Create without basic auth" do
91
- expect(PactBroker::Client::Webhooks::Create).to receive(:call) do | _, _, pact_broker_client_options |
92
- expect(pact_broker_client_options).to eq(token: "token", verbose: true)
93
- command_result
94
- end
95
- subject
96
- end
97
- end
98
-
99
- context "when there are no headers specified" do
100
- let(:header) { nil }
101
-
102
- it "calls Webhooks::Create with an empty hash of headers" do
103
- expect(PactBroker::Client::Webhooks::Create).to receive(:call) do | params, _, _ |
104
- expect(params[:headers]).to eq({})
105
- command_result
106
- end
107
- subject
108
- end
109
- end
110
-
111
- context "when data is nil" do
112
- let(:data) { nil }
113
-
114
- it "alls Webhooks::Create with a nil body" do
115
- expect(PactBroker::Client::Webhooks::Create).to receive(:call) do | params, _, _ |
116
- expect(params[:body]).to be nil
117
- command_result
118
- end
119
- subject
120
- end
121
- end
122
-
123
- context "when a file reference is passed for the data" do
124
- before do
125
- FileUtils.mkdir_p "tmp"
126
- File.open("tmp/body.json", "w") { |file| file << "file" }
127
- end
128
-
129
- let(:data) { "@tmp/body.json" }
130
-
131
- it "reads the file and passes it in to the Webhooks::Create call" do
132
- expect(PactBroker::Client::Webhooks::Create).to receive(:call) do | params, _, _ |
133
- expect(params[:body]).to eq "file"
134
- command_result
135
- end
136
- subject
137
- end
138
-
139
- context "when the file is not found" do
140
-
141
- let(:data) { "@doesnotexist.json" }
142
-
143
- it "raises a PactBroker::Client::Error" do
144
- expect { subject }.to raise_error PactBroker::Client::Error, /Couldn't read data from file/
145
- end
146
- end
147
-
148
- context "when successful" do
149
- it "prints the message to stdout" do
150
- expect($stdout).to receive(:puts).with('message')
151
- subject
152
- end
153
- end
154
-
155
- context "when not successful" do
156
- let(:success) { false }
157
-
158
- it "prints the message to stderr" do
159
- expect($stdout).to receive(:puts).with('message')
160
- begin
161
- subject
162
- rescue SystemExit
163
- end
164
- end
165
-
166
- it "exits with code 1" do
167
- exited_with_error = false
168
- begin
169
- subject
170
- rescue SystemExit
171
- exited_with_error = true
172
- end
173
- expect(exited_with_error).to be true
174
- end
175
- end
176
-
177
- context "when a PactBroker::Client::Error is raised" do
178
- before do
179
- allow(PactBroker::Client::Webhooks::Create).to receive(:call).and_raise(PactBroker::Client::Error, "foo")
180
- end
181
-
182
- it "raises a WebhookCreationError which does not show an ugly stack trace" do
183
- expect { subject }.to raise_error(WebhookCreationError, /foo/)
184
- end
185
- end
186
- end
187
19
  end
188
20
  end
189
21
  end
@@ -0,0 +1,210 @@
1
+ require 'pact_broker/client/cli/broker'
2
+ require 'pact_broker/client/webhooks/create'
3
+
4
+ module PactBroker
5
+ module Client
6
+ module CLI
7
+ describe Broker do
8
+ describe "run_webhook_commands" do
9
+ before do
10
+ allow($stdout).to receive(:puts)
11
+ allow(PactBroker::Client::Webhooks::Create).to receive(:call).and_return(command_result)
12
+ broker.options = OpenStruct.new(options_hash)
13
+ end
14
+
15
+ let(:broker) { Broker.new }
16
+ let(:data) { 'data' }
17
+ let(:user) { "username:password" }
18
+ let(:command_result) { double('command result', success: success, message: 'message') }
19
+ let(:success) { true }
20
+ let(:header) { ["Foo: bar", "Bar: foo"] }
21
+
22
+ let(:options_hash) do
23
+ {
24
+ uuid: '9999',
25
+ request: "POST",
26
+ header: header,
27
+ data: data,
28
+ user: user,
29
+ consumer: "consumer",
30
+ provider: "provider",
31
+ broker_base_url: "http://broker",
32
+ broker_username: "username",
33
+ broker_password: "password",
34
+ broker_token: "token",
35
+ contract_content_changed: true,
36
+ verbose: true
37
+ }
38
+ end
39
+
40
+ let(:expected_params) do
41
+ {
42
+ uuid: '9999',
43
+ http_method: "POST",
44
+ url: "http://webhook",
45
+ headers: { "Foo" => "bar", "Bar" => "foo"},
46
+ username: "username",
47
+ password: "password",
48
+ body: "data",
49
+ consumer: "consumer",
50
+ provider: "provider",
51
+ events: ["contract_content_changed"]
52
+ }.tap { |it| Pact::Fixture.add_fixture(:create_webhook_params, it) }
53
+ end
54
+
55
+ subject { broker.run_webhook_commands "http://webhook" }
56
+
57
+ it "calls PactBroker::Client::Webhooks::Create with the webhook params" do
58
+ expect(PactBroker::Client::Webhooks::Create).to receive(:call) do | params, _, _ |
59
+ expect(params).to eq expected_params
60
+ command_result
61
+ end
62
+ subject
63
+ end
64
+
65
+ it "calls PactBroker::Client::Webhooks::Create with pact broker details" do
66
+ expect(PactBroker::Client::Webhooks::Create).to receive(:call) do | _, broker_base_url, pact_broker_client_options |
67
+ expect(broker_base_url).to eq "http://broker"
68
+ expect(pact_broker_client_options).to eq(basic_auth: { username: "username", password: "password"}, token: "token", verbose: true)
69
+ command_result
70
+ end
71
+ subject
72
+ end
73
+
74
+ context "when neither event type is selected" do
75
+ before do
76
+ options_hash.delete(:contract_content_changed)
77
+ broker.options = OpenStruct.new(options_hash)
78
+ end
79
+
80
+ it "raises an error" do
81
+ expect { subject }.to raise_error WebhookCreationError, /You must specify at least one/
82
+ end
83
+ end
84
+
85
+ context "with no basic auth" do
86
+ before do
87
+ options_hash.delete(:broker_username)
88
+ options_hash.delete(:broker_password)
89
+ broker.options = OpenStruct.new(options_hash)
90
+ end
91
+
92
+ it "calls Webhooks::Create without basic auth" do
93
+ expect(PactBroker::Client::Webhooks::Create).to receive(:call) do | _, _, pact_broker_client_options |
94
+ expect(pact_broker_client_options).to eq(token: "token", verbose: true)
95
+ command_result
96
+ end
97
+ subject
98
+ end
99
+ end
100
+
101
+ context "when there are no headers specified" do
102
+ let(:header) { nil }
103
+
104
+ it "calls Webhooks::Create with an empty hash of headers" do
105
+ expect(PactBroker::Client::Webhooks::Create).to receive(:call) do | params, _, _ |
106
+ expect(params[:headers]).to eq({})
107
+ command_result
108
+ end
109
+ subject
110
+ end
111
+ end
112
+
113
+ context "when data is nil" do
114
+ let(:data) { nil }
115
+
116
+ it "alls Webhooks::Create with a nil body" do
117
+ expect(PactBroker::Client::Webhooks::Create).to receive(:call) do | params, _, _ |
118
+ expect(params[:body]).to be nil
119
+ command_result
120
+ end
121
+ subject
122
+ end
123
+ end
124
+
125
+ context "when a uuid is provided" do
126
+ before do
127
+ options_hash.merge!(uuid: '9999')
128
+ expected_params.merge!(uuid: '9999')
129
+
130
+ broker.options = OpenStruct.new(options_hash)
131
+ end
132
+
133
+ it "calls PactBroker::Client::Webhooks::Create with uuid in params" do
134
+ expect(PactBroker::Client::Webhooks::Create).to receive(:call) do | params, _, _ |
135
+ expect(params).to eq expected_params
136
+ command_result
137
+ end
138
+ subject
139
+ end
140
+ end
141
+
142
+ context "when a file reference is passed for the data" do
143
+ before do
144
+ FileUtils.mkdir_p "tmp"
145
+ File.open("tmp/body.json", "w") { |file| file << "file" }
146
+ end
147
+
148
+ let(:data) { "@tmp/body.json" }
149
+
150
+ it "reads the file and passes it in to the Webhooks::Create call" do
151
+ expect(PactBroker::Client::Webhooks::Create).to receive(:call) do | params, _, _ |
152
+ expect(params[:body]).to eq "file"
153
+ command_result
154
+ end
155
+ subject
156
+ end
157
+
158
+ context "when the file is not found" do
159
+
160
+ let(:data) { "@doesnotexist.json" }
161
+
162
+ it "raises a WebhookCreationError" do
163
+ expect { subject }.to raise_error WebhookCreationError, /Couldn't read data from file/
164
+ end
165
+ end
166
+
167
+ context "when successful" do
168
+ it "prints the message to stdout" do
169
+ expect($stdout).to receive(:puts).with('message')
170
+ subject
171
+ end
172
+ end
173
+
174
+ context "when not successful" do
175
+ let(:success) { false }
176
+
177
+ it "prints the message to stderr" do
178
+ expect($stdout).to receive(:puts).with('message')
179
+ begin
180
+ subject
181
+ rescue SystemExit
182
+ end
183
+ end
184
+
185
+ it "exits with code 1" do
186
+ exited_with_error = false
187
+ begin
188
+ subject
189
+ rescue SystemExit
190
+ exited_with_error = true
191
+ end
192
+ expect(exited_with_error).to be true
193
+ end
194
+ end
195
+
196
+ context "when a PactBroker::Client::Error is raised" do
197
+ before do
198
+ allow(PactBroker::Client::Webhooks::Create).to receive(:call).and_raise(PactBroker::Client::Error, "foo")
199
+ end
200
+
201
+ it "raises a WebhookCreationError which does not show an ugly stack trace" do
202
+ expect { subject }.to raise_error(WebhookCreationError, /foo/)
203
+ end
204
+ end
205
+ end
206
+ end
207
+ end
208
+ end
209
+ end
210
+ end