pact_broker-client 1.41.0 → 1.46.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (93) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/test.yml +21 -0
  3. data/CHANGELOG.md +57 -0
  4. data/README.md +69 -48
  5. data/doc/pacts/markdown/Pact Broker Client - Pact Broker.md +79 -102
  6. data/doc/pacts/markdown/Pact Broker Client - Pactflow.md +94 -0
  7. data/doc/pacts/markdown/README.md +1 -0
  8. data/lib/pact_broker/client/backports.rb +9 -0
  9. data/lib/pact_broker/client/base_command.rb +98 -0
  10. data/lib/pact_broker/client/can_i_deploy.rb +40 -5
  11. data/lib/pact_broker/client/cli/broker.rb +18 -160
  12. data/lib/pact_broker/client/cli/custom_thor.rb +12 -16
  13. data/lib/pact_broker/client/cli/deployment_commands.rb +94 -0
  14. data/lib/pact_broker/client/cli/environment_commands.rb +70 -0
  15. data/lib/pact_broker/client/cli/pacticipant_commands.rb +53 -0
  16. data/lib/pact_broker/client/cli/webhook_commands.rb +122 -0
  17. data/lib/pact_broker/client/deployments.rb +4 -0
  18. data/lib/pact_broker/client/deployments/record_deployment.rb +38 -0
  19. data/lib/pact_broker/client/deployments/record_release.rb +99 -0
  20. data/lib/pact_broker/client/deployments/record_support_ended.rb +103 -0
  21. data/lib/pact_broker/client/deployments/record_undeployment.rb +127 -0
  22. data/lib/pact_broker/client/describe_text_formatter.rb +23 -0
  23. data/lib/pact_broker/client/environments.rb +6 -0
  24. data/lib/pact_broker/client/environments/create_environment.rb +31 -0
  25. data/lib/pact_broker/client/environments/delete_environment.rb +27 -0
  26. data/lib/pact_broker/client/environments/describe_environment.rb +26 -0
  27. data/lib/pact_broker/client/environments/environment_command.rb +66 -0
  28. data/lib/pact_broker/client/environments/list_environments.rb +30 -0
  29. data/lib/pact_broker/client/environments/text_formatter.rb +30 -0
  30. data/lib/pact_broker/client/environments/update_environment.rb +31 -0
  31. data/lib/pact_broker/client/generate_display_name.rb +27 -0
  32. data/lib/pact_broker/client/hal/entity.rb +31 -6
  33. data/lib/pact_broker/client/hal/http_client.rb +8 -2
  34. data/lib/pact_broker/client/hal/link.rb +8 -0
  35. data/lib/pact_broker/client/hal_client_methods.rb +1 -3
  36. data/lib/pact_broker/client/matrix/text_formatter.rb +21 -13
  37. data/lib/pact_broker/client/pacticipants.rb +6 -0
  38. data/lib/pact_broker/client/pacticipants/create.rb +24 -34
  39. data/lib/pact_broker/client/pacticipants/describe.rb +33 -0
  40. data/lib/pact_broker/client/pacticipants/list.rb +34 -0
  41. data/lib/pact_broker/client/pacticipants/text_formatter.rb +41 -0
  42. data/lib/pact_broker/client/string_refinements.rb +56 -0
  43. data/lib/pact_broker/client/version.rb +1 -1
  44. data/lib/pact_broker/client/versions.rb +4 -1
  45. data/lib/pact_broker/client/versions/describe.rb +3 -1
  46. data/lib/pact_broker/client/versions/formatter.rb +3 -1
  47. data/lib/pact_broker/client/versions/json_formatter.rb +5 -3
  48. data/lib/pact_broker/client/versions/text_formatter.rb +3 -1
  49. data/lib/pact_broker/client/webhooks/create.rb +14 -8
  50. data/pact-broker-client.gemspec +1 -0
  51. data/script/record-deployments-and-releases.sh +18 -0
  52. data/script/webhook-commands.sh +12 -0
  53. data/spec/fixtures/approvals/can_i_deploy_failure_dry_run.approved.txt +7 -0
  54. data/spec/fixtures/approvals/can_i_deploy_success_dry_run.approved.txt +7 -0
  55. data/spec/fixtures/approvals/describe_environment.approved.txt +7 -0
  56. data/spec/fixtures/approvals/describe_pacticipant.approved.txt +2 -0
  57. data/spec/fixtures/approvals/list_environments.approved.txt +3 -0
  58. data/spec/integration/describe_environment_spec.rb +31 -0
  59. data/spec/lib/pact_broker/client/can_i_deploy_spec.rb +62 -2
  60. data/spec/lib/pact_broker/client/cli/broker_can_i_deploy_spec.rb +17 -4
  61. data/spec/lib/pact_broker/client/cli/broker_publish_spec.rb +1 -1
  62. data/spec/lib/pact_broker/client/cli/broker_run_webhook_commands_spec.rb +7 -5
  63. data/spec/lib/pact_broker/client/deployments/record_deployment_spec.rb +204 -0
  64. data/spec/lib/pact_broker/client/deployments/record_support_ended_spec.rb +208 -0
  65. data/spec/lib/pact_broker/client/deployments/record_undeployment_spec.rb +219 -0
  66. data/spec/lib/pact_broker/client/environments/delete_environment_spec.rb +120 -0
  67. data/spec/lib/pact_broker/client/environments/describe_environment_spec.rb +89 -0
  68. data/spec/lib/pact_broker/client/environments/update_environment_spec.rb +167 -0
  69. data/spec/lib/pact_broker/client/generate_display_name_spec.rb +39 -0
  70. data/spec/lib/pact_broker/client/hal/entity_spec.rb +2 -2
  71. data/spec/lib/pact_broker/client/pacticipants/create_spec.rb +2 -2
  72. data/spec/pacts/pact_broker_client-pact_broker.json +88 -108
  73. data/spec/pacts/pact_broker_client-pactflow.json +118 -0
  74. data/spec/service_providers/create_environment_spec.rb +78 -0
  75. data/spec/service_providers/list_environments_spec.rb +77 -0
  76. data/spec/service_providers/pact_broker_client_matrix_ignore_spec.rb +1 -1
  77. data/spec/service_providers/pact_broker_client_register_repository_spec.rb +2 -2
  78. data/spec/service_providers/pact_helper.rb +15 -10
  79. data/spec/service_providers/pactflow_webhooks_create_spec.rb +86 -0
  80. data/spec/service_providers/pacticipants_create_spec.rb +5 -4
  81. data/spec/service_providers/publish_pacts_spec.rb +3 -1
  82. data/spec/service_providers/record_deployment_spec.rb +14 -32
  83. data/spec/service_providers/record_release_spec.rb +132 -0
  84. data/spec/service_providers/record_undeployment_spec.rb +166 -0
  85. data/spec/service_providers/webhooks_create_spec.rb +1 -1
  86. data/spec/spec_helper.rb +15 -2
  87. data/spec/support/approvals.rb +1 -1
  88. data/spec/support/shared_context.rb +2 -1
  89. data/tasks/pact.rake +21 -1
  90. metadata +82 -7
  91. data/lib/pact_broker/client/versions/record_deployment.rb +0 -109
  92. data/lib/pact_broker/client/versions/record_undeployment.rb +0 -102
  93. data/spec/lib/pact_broker/client/versions/record_deployment_spec.rb +0 -82
@@ -32,7 +32,7 @@ module PactBroker::Client::CLI
32
32
  ["spec/support/cli_test_pacts/foo.json"],
33
33
  { number: "1.2.3", tags: [], version_required: false },
34
34
  {},
35
- {}
35
+ { pact_broker_base_url: 'http://pact-broker' }
36
36
  )
37
37
  invoke_broker
38
38
  end
@@ -33,7 +33,8 @@ module PactBroker
33
33
  broker_username: "username",
34
34
  broker_password: "password",
35
35
  contract_content_changed: true,
36
- verbose: true
36
+ verbose: true,
37
+ team_uuid: "1234"
37
38
  }
38
39
  end
39
40
 
@@ -49,7 +50,8 @@ module PactBroker
49
50
  body: "data",
50
51
  consumer: "consumer",
51
52
  provider: "provider",
52
- events: ["contract_content_changed"]
53
+ events: ["contract_content_changed"],
54
+ team_uuid: "1234"
53
55
  }.tap { |it| Pact::Fixture.add_fixture(:create_webhook_params, it) }
54
56
  end
55
57
 
@@ -66,7 +68,7 @@ module PactBroker
66
68
  it "calls PactBroker::Client::Webhooks::Create with pact broker details" do
67
69
  expect(PactBroker::Client::Webhooks::Create).to receive(:call) do | _, broker_base_url, pact_broker_client_options |
68
70
  expect(broker_base_url).to eq "http://broker"
69
- expect(pact_broker_client_options).to eq(basic_auth: { username: "username", password: "password"}, verbose: true)
71
+ expect(pact_broker_client_options).to eq(pact_broker_base_url: 'http://broker', basic_auth: { username: "username", password: "password"}, verbose: true)
70
72
  command_result
71
73
  end
72
74
  subject
@@ -92,7 +94,7 @@ module PactBroker
92
94
 
93
95
  it "calls Webhooks::Create without basic auth" do
94
96
  expect(PactBroker::Client::Webhooks::Create).to receive(:call) do | _, _, pact_broker_client_options |
95
- expect(pact_broker_client_options).to eq(verbose: true)
97
+ expect(pact_broker_client_options).to eq(verbose: true, pact_broker_base_url: 'http://broker')
96
98
  command_result
97
99
  end
98
100
  subject
@@ -110,7 +112,7 @@ module PactBroker
110
112
  it "calls Webhooks::Create without basic auth" do
111
113
 
112
114
  expect(PactBroker::Client::Webhooks::Create).to receive(:call) do | _, _, pact_broker_client_options |
113
- expect(pact_broker_client_options).to eq(verbose: true, token: "token")
115
+ expect(pact_broker_client_options).to eq(verbose: true, token: "token", pact_broker_base_url: 'http://broker')
114
116
  command_result
115
117
  end
116
118
  subject
@@ -0,0 +1,204 @@
1
+ require 'pact_broker/client/deployments/record_deployment'
2
+
3
+ module PactBroker
4
+ module Client
5
+ module Deployments
6
+ describe RecordDeployment do
7
+ describe ".call" do
8
+ let(:broker_base_url) { "http://broker" }
9
+ let(:index_body_hash) do
10
+ {
11
+ _links: {
12
+ "pb:environments" => { href: "#{broker_base_url}/environments" },
13
+ "pb:pacticipant-version" => {
14
+ href: "#{broker_base_url}/pacticipants/{pacticipant}/versions/{version}"
15
+ }
16
+ }
17
+ }
18
+ end
19
+ let(:version_body_hash) do
20
+ {
21
+ "_links" => {
22
+ "pb:record-deployment" => [
23
+ {
24
+ name: "test",
25
+ href: "#{broker_base_url}/record-deployment"
26
+ }
27
+ ]
28
+ }
29
+ }
30
+ end
31
+ let(:environments_body_hash) do
32
+ {
33
+ "_links" => {
34
+ "pb:environments" => [
35
+ {
36
+ "name" => "test",
37
+ "href" => ""
38
+ }
39
+ ]
40
+ }
41
+
42
+ }
43
+ end
44
+ let(:record_deployment_body_hash) do
45
+ { "some" => "response" }
46
+ end
47
+ 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
+ end
50
+ let!(:version_request) do
51
+ 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" } )
52
+ end
53
+
54
+ let!(:environments_request) do
55
+ stub_request(:get, "http://broker/environments").
56
+ with(headers: { 'Accept'=>'application/hal+json' }).
57
+ to_return(status: 200, body: environments_body_hash.to_json, headers: { "Content-Type" => "application/hal+json" })
58
+ end
59
+ let!(:record_deployment_request) do
60
+ stub_request(:post, "http://broker/record-deployment").
61
+ to_return(status: 200, body: record_deployment_body_hash.to_json , headers: {})
62
+ end
63
+
64
+ let(:target) { "blue" }
65
+
66
+ let(:params) do
67
+ {
68
+ pacticipant_name: "Foo",
69
+ version_number: "1",
70
+ environment_name: "test",
71
+ target: target
72
+ }
73
+ end
74
+
75
+ let(:options) do
76
+ {
77
+ output: output,
78
+ verbose: true
79
+ }
80
+ end
81
+ let(:output) { "text" }
82
+ let(:pact_broker_client_options) { { pact_broker_base_url: broker_base_url} }
83
+
84
+ subject { RecordDeployment.call(params, options, pact_broker_client_options) }
85
+
86
+ context "when the pb:environments relation does not exist" do
87
+ let(:index_body_hash) do
88
+ {
89
+ "_links" => {}
90
+ }
91
+ end
92
+ it "returns an error response" do
93
+ expect(subject.success).to be false
94
+ expect(subject.message).to include "does not support"
95
+ end
96
+ end
97
+
98
+ context "when the specified version does not exist" do
99
+ let!(:version_request) do
100
+ stub_request(:get, broker_base_url + "/pacticipants/Foo/versions/1").to_return(status: 404)
101
+ end
102
+
103
+ it "returns an error response" do
104
+ expect(subject.success).to be false
105
+ expect(subject.message).to include "Foo version 1 not found"
106
+ end
107
+ end
108
+
109
+ context "when the pacticipant version does not support recording deployments" do
110
+ let(:version_body_hash) do
111
+ {
112
+ "_links" => {}
113
+ }
114
+ end
115
+ it "returns an error response" do
116
+ expect(subject.success).to be false
117
+ expect(subject.message).to include "does not support"
118
+ end
119
+ end
120
+
121
+ context "when the specified environment is not available for recording a deployment" do
122
+ let(:version_body_hash) do
123
+ {
124
+ "_links" => {
125
+ "pb:record-deployment" => [
126
+ {
127
+ "name" => "prod",
128
+ "href" => ""
129
+ }
130
+ ]
131
+ }
132
+ }
133
+ end
134
+
135
+ context "when the environment does not exist" do
136
+ let(:environments_body_hash) do
137
+ {
138
+ "_links" => {
139
+ "pb:environments" => [
140
+ {
141
+ "name" => "prod",
142
+ "href" => ""
143
+ },{
144
+ "name" => "uat",
145
+ "href" => ""
146
+ }
147
+ ]
148
+ }
149
+ }
150
+ end
151
+
152
+ it "returns an error response" do
153
+ expect(subject.success).to be false
154
+ expect(subject.message).to include "No environment found with name 'test'. Available options: prod"
155
+ end
156
+ end
157
+
158
+ context "when the environment does exist" do
159
+ it "returns an error response" do
160
+ expect(subject.success).to be false
161
+ expect(subject.message).to include "Environment 'test' is not an available option for recording a deployment of Foo. Available options: prod"
162
+ end
163
+ end
164
+ end
165
+
166
+ context "when the output is json" do
167
+ let(:output) { "json" }
168
+
169
+ it "returns the JSON payload" do
170
+ expect(JSON.parse(subject.message)).to eq record_deployment_body_hash
171
+ end
172
+ end
173
+
174
+ context "when the response headers contain Pactflow" do
175
+ before do
176
+ allow_any_instance_of(RecordDeployment).to receive(:check_if_command_supported)
177
+ allow_any_instance_of(RecordDeployment).to receive(:check_environment_exists)
178
+ allow_any_instance_of(RecordDeployment).to receive(:record_action)
179
+ allow_any_instance_of(RecordDeployment).to receive(:index_resource).and_return(index_resource)
180
+ end
181
+
182
+ let(:response_headers) { { "X-Pactflow-Sha" => "abc" } }
183
+
184
+ let(:index_resource) do
185
+ double('PactBroker::Client::Hal::Entity', response: double('response', headers: response_headers) )
186
+ end
187
+
188
+ it "indicates the API was Pactflow" do
189
+ expect(subject.message).to include "Recorded deployment of Foo version 1 to test environment (target blue) in Pactflow"
190
+ end
191
+
192
+ context "when target is nil" do
193
+ let(:target) { nil }
194
+
195
+ it "does not include the target in the result message" do
196
+ expect(subject.message).to include "Recorded deployment of Foo version 1 to test environment in"
197
+ end
198
+ end
199
+ end
200
+ end
201
+ end
202
+ end
203
+ end
204
+ end
@@ -0,0 +1,208 @@
1
+ require 'pact_broker/client/deployments/record_support_ended'
2
+
3
+ module PactBroker
4
+ module Client
5
+ module Deployments
6
+ describe RecordSupportEnded do
7
+ let(:params) do
8
+ {
9
+ pacticipant_name: "Foo",
10
+ version_number: version_number,
11
+ environment_name: "test"
12
+ }
13
+ end
14
+ let(:version_number) { "2" }
15
+ let(:output) { "text" }
16
+ let(:options) { { output: output, verbose: true } }
17
+ let(:pact_broker_base_url) { "http://broker" }
18
+ let(:pact_broker_client_options) { { pact_broker_base_url: pact_broker_base_url } }
19
+
20
+ let(:index_body_hash) do
21
+ {
22
+ _links: {
23
+ :'pb:environments' => {
24
+ href: environments_url
25
+ },
26
+ :'pb:pacticipant' => {
27
+ href: pacticipant_url
28
+ }
29
+ }
30
+ }
31
+ end
32
+
33
+ let(:environments_hash) do
34
+ {
35
+ _links: {
36
+ :'pb:environments' => [
37
+ {
38
+ name: "test",
39
+ href: test_environment_url
40
+ }
41
+ ]
42
+ }
43
+ }
44
+ end
45
+
46
+ let(:environment_hash) do
47
+ {
48
+ _links: {
49
+ :'pb:currently-supported-versions' => {
50
+ href: currently_supported_versions_url
51
+ }
52
+ }
53
+ }
54
+ end
55
+
56
+ let(:supported_versions_hash) do
57
+ {
58
+ _embedded: {
59
+ releasedVersions: [
60
+ {
61
+ number: "customer-1",
62
+ _links: {
63
+ self: {
64
+ href: supported_version_url_1
65
+ }
66
+ }
67
+ },
68
+ {
69
+ number: returned_target_2,
70
+ _links: {
71
+ self: {
72
+ href: supported_version_url_2
73
+ }
74
+ }
75
+ }
76
+ ]
77
+ }
78
+ }
79
+ end
80
+
81
+ let(:returned_target_2) { nil }
82
+ let(:supported_version_hash) do
83
+ {
84
+ _embedded: {
85
+ version: {
86
+ number: "2"
87
+ }
88
+ }
89
+ }
90
+ end
91
+
92
+ let(:environments_url) { "#{webmock_base_url}/environments" }
93
+ let(:test_environment_url) { "#{webmock_base_url}/environments/1234" }
94
+ let(:currently_supported_versions_url) { "#{webmock_base_url}/currently-deployed-versions" }
95
+ let(:supported_version_url_1) { "#{webmock_base_url}/deployed-version-1" }
96
+ let(:supported_version_url_2) { "#{webmock_base_url}/deployed-version-2" }
97
+ let(:pacticipant_url) { "#{webmock_base_url}/pacticipant" }
98
+
99
+ let(:webmock_base_url) { "http://broker" }
100
+
101
+ let!(:index_request) do
102
+ stub_request(:get, "http://broker").to_return(status: 200, body: index_body_hash.to_json, headers: { "Content-Type" => "application/hal+json" } )
103
+ end
104
+
105
+ let!(:environments_request) do
106
+ stub_request(:get, "http://broker/environments").to_return(status: 200, body: environments_hash.to_json, headers: { "Content-Type" => "application/hal+json" } )
107
+ end
108
+
109
+ let!(:environment_request) do
110
+ stub_request(:get, test_environment_url).to_return(status: 200, body: environment_hash.to_json, headers: { "Content-Type" => "application/hal+json" } )
111
+ end
112
+
113
+ let!(:supported_versions_request) do
114
+ stub_request(:get, currently_supported_versions_url + "?pacticipant=Foo&version=2").to_return(status: 200, body: supported_versions_hash.to_json, headers: { "Content-Type" => "application/hal+json" } )
115
+ end
116
+
117
+ let!(:supported_version_patch_request_1) do
118
+ stub_request(:patch, supported_version_url_1).with(body: { currentlySupported: false}.to_json).to_return(status: 200, body: supported_version_hash.to_json, headers: { "Content-Type" => "application/hal+json" })
119
+ end
120
+
121
+ let!(:supported_version_patch_request_2) do
122
+ stub_request(:patch, supported_version_url_2).with(body: { currentlySupported: false}.to_json).to_return(status: 200, body: supported_version_hash.to_json, headers: { "Content-Type" => "application/hal+json" })
123
+ end
124
+
125
+ let!(:pacticipant_request) do
126
+ stub_request(:get, pacticipant_url).to_return(status: pacticipant_request_status, body: {}.to_json, headers: { "Content-Type" => "application/hal+json" })
127
+ end
128
+
129
+ let(:pacticipant_request_status) { 200 }
130
+
131
+ subject { RecordSupportEnded.call(params, options, pact_broker_client_options) }
132
+
133
+ its(:success) { is_expected.to eq true }
134
+ its(:message) { is_expected.to include "Recorded support ended for Foo version 2 in test environment in the Pact Broker" }
135
+
136
+ context "when there is no pb:environments relation in the index" do
137
+ let(:index_body_hash) do
138
+ {
139
+ _links: {}
140
+ }
141
+ end
142
+
143
+ its(:success) { is_expected.to be false }
144
+ its(:message) { is_expected.to include "support" }
145
+ end
146
+
147
+ context "when output is json" do
148
+ let(:output) { "json" }
149
+ its(:message) { is_expected.to eq [supported_version_hash, supported_version_hash].to_json }
150
+ end
151
+
152
+ context "when there is an error returned from one of the supported version updates (there should only ever be one supported version, but testing just for the sake of it)" do
153
+ let!(:supported_version_patch_request_2) do
154
+ stub_request(:patch, supported_version_url_2).to_return(status: 400, body: { errors: { foo: ["some error"]}}.to_json, headers: { "Content-Type" => "application/hal+json" })
155
+ end
156
+
157
+ let(:returned_target_2) { "customer-1" }
158
+
159
+ its(:success) { is_expected.to be false }
160
+ its(:message) { is_expected.to include "Recorded" }
161
+ its(:message) { is_expected.to include "some error" }
162
+ end
163
+
164
+ context "when there is no currently-deployed-versions relation in the environment resource" do
165
+ let(:environment_hash) do
166
+ {
167
+ _links: {}
168
+ }
169
+ end
170
+
171
+ its(:success) { is_expected.to be false }
172
+ its(:message) { is_expected.to include "support" }
173
+ end
174
+
175
+ context "when there is no matching supported versions" do
176
+ let(:supported_versions_hash) do
177
+ {
178
+ _embedded: {
179
+ releasedVersions: []
180
+ }
181
+ }
182
+ end
183
+
184
+ let(:expected_message) { "Foo version 2 is not currently released in test environment. Cannot record support ended." }
185
+
186
+ its(:success) { is_expected.to be false }
187
+ its(:message) { is_expected.to include expected_message }
188
+
189
+ context "when there are no supported versions for the pacticipant" do
190
+ context "when the pacticipant does not exist" do
191
+ let(:pacticipant_request_status) { 404 }
192
+
193
+ its(:success) { is_expected.to be false }
194
+ its(:message) { is_expected.to include "No pacticipant with name 'Foo' found" }
195
+ end
196
+ end
197
+
198
+ context "when output is json" do
199
+ let(:output) { "json" }
200
+
201
+ its(:message) { is_expected.to eq({ error: { message: expected_message } }.to_json) }
202
+ end
203
+ end
204
+
205
+ end
206
+ end
207
+ end
208
+ end