pact_broker-client 1.30.0 → 1.35.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: d7be73ef3705005ce0808a1d74dba560c4f590fce09871ae7597c06479ce2316
4
- data.tar.gz: ec3b757187ce7c60dbc4835933debbe68fa2f5fb2b08ffdb6f9e5cb7141943e1
3
+ metadata.gz: 1bf1176c39519652e60c6aab383a941a2dd5a1c8e968b746741a290e68c736e9
4
+ data.tar.gz: 04b1f3aa9f25b353e61eb558d393d108750cd97b4645fe81313b1d04dca33ba5
5
5
  SHA512:
6
- metadata.gz: 5f035fa2d68c909fc2d3865ebcd76be24ae9af0a0a4bc4cd0e2503f3a1da822456a6439b61364a83a73ff6e9021a5fa5caa24addeb4f9d9a10980ab33e1ffb74
7
- data.tar.gz: 2fe9a489c6c2824f1d218b693559bf1be1713d2989c62283979acc7ddda0684a0b60607fce0abd5d813dbb279c7ff5a4b5ca6bb186c79af3911855803f79837a
6
+ metadata.gz: cbb4fe27ce2979d3daea2c597ca7509b6d4136ac53d139a738fd672f30d114fcce23ce4f3ba3c108aef13ec88b9793715bf57ec05a2fda6255dfcd7ed9c99875
7
+ data.tar.gz: 443c3e2e5fb75bcbfa3850ce1498f859c45872145f813c50b260a9a7d28a32f5aa7618c1f55b0c798b34975ec7b35d7e44b0937c6bd2575dea1b86356eb8ca5b
@@ -0,0 +1,23 @@
1
+ name: Test
2
+
3
+ on: push
4
+
5
+ jobs:
6
+ test:
7
+ runs-on: "ubuntu-latest"
8
+ continue-on-error: ${{ matrix.experimental }}
9
+ strategy:
10
+ fail-fast: false
11
+ matrix:
12
+ ruby_version: ["2.2", "2.7"]
13
+ experimental: [false]
14
+ include:
15
+ - ruby_version: "3.0"
16
+ experimental: true
17
+ steps:
18
+ - uses: actions/checkout@v2
19
+ - uses: ruby/setup-ruby@v1
20
+ with:
21
+ ruby-version: ${{ matrix.ruby_version }}
22
+ - run: "bundle install"
23
+ - run: "bundle exec rake"
@@ -1,3 +1,49 @@
1
+ <a name="v1.35.0"></a>
2
+ ### v1.35.0 (2021-01-21)
3
+
4
+ #### Features
5
+
6
+ * **can-i-deploy**
7
+ * display links to verification results in the output of can-i-deploy when using text format ([976950d](/../../commit/976950d))
8
+
9
+ <a name="v1.34.0"></a>
10
+ ### v1.34.0 (2020-11-20)
11
+
12
+ #### Features
13
+
14
+ * **pact publish**
15
+ * strip new lines from version numbers and tags ([5842d24](/../../commit/5842d24))
16
+
17
+ * **publish**
18
+ * update output text when pact already exists and merging ([9b849d3](/../../commit/9b849d3))
19
+
20
+ <a name="v1.33.0"></a>
21
+ ### v1.33.0 (2020-11-10)
22
+
23
+ #### Features
24
+
25
+ * **publish**
26
+ * allow pacts to be merged on the server side ([bd80f10](/../../commit/bd80f10))
27
+
28
+ <a name="v1.32.0"></a>
29
+ ### v1.32.0 (2020-10-26)
30
+
31
+ #### Features
32
+
33
+ * Improve HTTP errors handling (#76) ([d8eaf16](/../../commit/d8eaf16))
34
+
35
+ #### Bug Fixes
36
+
37
+ * **list-latest-pact-versions**
38
+ * correct json output ([cf77666](/../../commit/cf77666))
39
+
40
+ <a name="v1.31.0"></a>
41
+ ### v1.31.0 (2020-10-22)
42
+
43
+ #### Features
44
+
45
+ * update thor dependancy (#75) ([2078f31](/../../commit/2078f31))
46
+
1
47
  <a name="v1.30.0"></a>
2
48
  ### v1.30.0 (2020-10-09)
3
49
 
data/README.md CHANGED
@@ -2,7 +2,9 @@
2
2
 
3
3
  A client for the Pact Broker. Publishes and retrieves pacts, verification results, pacticipants, pacticipant versions and tags. The functionality is available via a CLI, or via Ruby Rake tasks. You can also use the [Pact CLI Docker image](https://hub.docker.com/r/pactfoundation/pact-cli).
4
4
 
5
- [![Build Status](https://travis-ci.org/pact-foundation/pact_broker-client.svg?branch=master)](https://travis-ci.org/pact-foundation/pact_broker-client)
5
+ ![Build status](https://github.com/pact-foundation/pact_broker-client/workflows/Test/badge.svg)
6
+
7
+ [![Gem Version](https://badge.fury.io/rb/pact_broker-client.svg)](http://badge.fury.io/rb/pact_broker-client)
6
8
 
7
9
  ![Trigger update to docs.pact.io](https://github.com/pact-foundation/pact_broker-client/workflows/Trigger%20update%20to%20docs.pact.io/badge.svg)
8
10
 
@@ -16,9 +18,19 @@ Download the latest [pact-ruby-standalone][pact-ruby-standalone] package. You do
16
18
 
17
19
  Add `gem 'pact_broker-client'` to your Gemfile and run `bundle install`, or install the gem directly by running `gem install pact_broker-client`.
18
20
 
21
+ ## Connecting to a Pact Broker with a self signed certificate
22
+
23
+ To connect to a Pact Broker that uses custom SSL cerificates, set the environment variable `$SSL_CERT_FILE` or `$SSL_CERT_DIR` to a path that contains the appropriate certificate. Read more at https://docs.pact.io/pact_broker/advanced_topics/using-tls#for-non-jvm
24
+
19
25
  ## Usage - CLI
20
26
 
21
- To connect to a Pact Broker that uses custom SSL cerificates, set the environment variable `$SSL_CERT_FILE` or `$SSL_CERT_DIR` to a path that contains the appropriate certificate.
27
+ The Pact Broker base URL can be specified either using the environment variable `$PACT_BROKER_BASE_URL` or the `-b` or `--broker-base-url` parameters.
28
+
29
+ Pact Broker authentication can be performed either using basic auth or a bearer token.
30
+
31
+ Basic auth parameters can be specified using the `$PACT_BROKER_USERNAME` and `$PACT_BROKER_PASSWORD` environment variables, or the `-u` or `--broker-username` and `-p` or `--broker-password` parameters.
32
+
33
+ Authentication using a bearer token can be specified using the environment variable `$PACT_BROKER_TOKEN` or the `-k` or `--broker-token` parameters. This authentication system is used by [Pactflow](pactflow.io).
22
34
 
23
35
  ### publish
24
36
 
@@ -188,7 +200,7 @@ Can I deploy all the applications in my monorepo to prod?
188
200
  --pacticipant B --version a7e28207 \
189
201
  --pacticipant C --version a7e28207 \
190
202
  --to prod \
191
- --broker-base-url BROKER_BASE_URL
203
+ --broker-base-url BROKER_BASE_URL
192
204
 
193
205
  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.)
194
206
 
@@ -164,7 +164,12 @@ Pact Broker will respond with:
164
164
  },
165
165
  "verificationResult": {
166
166
  "verifiedAt": "2017-10-10T12:49:04+11:00",
167
- "success": true
167
+ "success": true,
168
+ "_links": {
169
+ "self": {
170
+ "href": "http://result"
171
+ }
172
+ }
168
173
  },
169
174
  "pact": {
170
175
  "createdAt": "2017-10-10T12:49:04+11:00"
@@ -185,7 +190,12 @@ Pact Broker will respond with:
185
190
  },
186
191
  "verificationResult": {
187
192
  "verifiedAt": "2017-10-10T12:49:04+11:00",
188
- "success": true
193
+ "success": true,
194
+ "_links": {
195
+ "self": {
196
+ "href": "http://result"
197
+ }
198
+ }
189
199
  },
190
200
  "pact": {
191
201
  "createdAt": "2017-10-10T12:49:04+11:00"
@@ -233,7 +243,12 @@ Pact Broker will respond with:
233
243
  },
234
244
  "verificationResult": {
235
245
  "verifiedAt": "2017-10-10T12:49:04+11:00",
236
- "success": true
246
+ "success": true,
247
+ "_links": {
248
+ "self": {
249
+ "href": "http://result"
250
+ }
251
+ }
237
252
  },
238
253
  "pact": {
239
254
  "createdAt": "2017-10-10T12:49:04+11:00"
@@ -281,7 +296,12 @@ Pact Broker will respond with:
281
296
  },
282
297
  "verificationResult": {
283
298
  "verifiedAt": "2017-10-10T12:49:04+11:00",
284
- "success": true
299
+ "success": true,
300
+ "_links": {
301
+ "self": {
302
+ "href": "http://result"
303
+ }
304
+ }
285
305
  },
286
306
  "pact": {
287
307
  "createdAt": "2017-10-10T12:49:04+11:00"
@@ -329,7 +349,12 @@ Pact Broker will respond with:
329
349
  },
330
350
  "verificationResult": {
331
351
  "verifiedAt": "2017-10-10T12:49:04+11:00",
332
- "success": true
352
+ "success": true,
353
+ "_links": {
354
+ "self": {
355
+ "href": "http://result"
356
+ }
357
+ }
333
358
  },
334
359
  "pact": {
335
360
  "createdAt": "2017-10-10T12:49:04+11:00"
@@ -413,7 +438,12 @@ Pact Broker will respond with:
413
438
  },
414
439
  "verificationResult": {
415
440
  "verifiedAt": "2017-10-10T12:49:04+11:00",
416
- "success": true
441
+ "success": true,
442
+ "_links": {
443
+ "self": {
444
+ "href": "http://result"
445
+ }
446
+ }
417
447
  },
418
448
  "pact": {
419
449
  "createdAt": "2017-10-10T12:49:04+11:00"
@@ -484,7 +514,12 @@ Pact Broker will respond with:
484
514
  },
485
515
  "verificationResult": {
486
516
  "verifiedAt": "2017-10-10T12:49:04+11:00",
487
- "success": true
517
+ "success": true,
518
+ "_links": {
519
+ "self": {
520
+ "href": "http://result"
521
+ }
522
+ }
488
523
  },
489
524
  "pact": {
490
525
  "createdAt": "2017-10-10T12:49:04+11:00"
@@ -735,7 +770,12 @@ Pact Broker will respond with:
735
770
  },
736
771
  "verificationResult": {
737
772
  "verifiedAt": "2017-10-10T12:49:04+11:00",
738
- "success": true
773
+ "success": true,
774
+ "_links": {
775
+ "self": {
776
+ "href": "http://result"
777
+ }
778
+ }
739
779
  },
740
780
  "pact": {
741
781
  "createdAt": "2017-10-10T12:49:04+11:00"
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'erb'
2
4
  require 'httparty'
3
5
  require 'pact_broker/client/error'
@@ -30,6 +32,12 @@ module PactBroker
30
32
  end
31
33
 
32
34
  class BaseClient
35
+ ERROR_CODE_MAPPING = {
36
+ 401 => "Authentication failed",
37
+ 403 => "Authorization failed (insufficient permissions)",
38
+ 409 => "Potential duplicate pacticipants"
39
+ }.freeze
40
+
33
41
  include UrlHelpers
34
42
  include HTTParty
35
43
  include StringToSymbol
@@ -69,14 +77,8 @@ module PactBroker
69
77
  yield response
70
78
  elsif response.code == 404
71
79
  nil
72
- elsif response.code == 403
73
- message = "Authorization failed (insufficient permissions)"
74
- if response.body && response.body.size > 0
75
- message = message + ": #{response.body}"
76
- end
77
- raise Error.new(message)
78
- elsif response.code == 401
79
- message = "Authentication failed"
80
+ elsif ERROR_CODE_MAPPING.key?(response.code)
81
+ message = ERROR_CODE_MAPPING.fetch(response.code)
80
82
  if response.body && response.body.size > 0
81
83
  message = message + ": #{response.body}"
82
84
  end
@@ -93,7 +95,7 @@ module PactBroker
93
95
  response.body
94
96
  end
95
97
  rescue
96
- raise Error.new(response.body)
98
+ raise Error.new("status=#{response.code} #{response.body}")
97
99
  end
98
100
  raise Error.new(error_message)
99
101
  end
@@ -50,6 +50,7 @@ module PactBroker
50
50
  method_option :broker_token, aliases: "-k", desc: "Pact Broker bearer token"
51
51
  method_option :tag, aliases: "-t", type: :array, banner: "TAG", desc: "Tag name for consumer version. Can be specified multiple times."
52
52
  method_option :tag_with_git_branch, aliases: "-g", type: :boolean, default: false, required: false, desc: "Tag consumer version with the name of the current git branch. Default: false"
53
+ method_option :merge, type: :boolean, default: false, require: false, desc: "If a pact already exists for this consumer version and provider, merge the contents. Useful when running Pact tests concurrently on different build nodes."
53
54
  method_option :verbose, aliases: "-v", type: :boolean, default: false, required: false, desc: "Verbose output. Default: false"
54
55
 
55
56
  def publish(*pact_files)
@@ -209,13 +210,14 @@ module PactBroker
209
210
 
210
211
  def publish_pacts pact_files
211
212
  require 'pact_broker/client/publish_pacts'
213
+ write_options = options[:merge] ? { write: :merge } : {}
212
214
 
213
215
  PactBroker::Client::PublishPacts.call(
214
216
  options.broker_base_url,
215
217
  file_list(pact_files),
216
218
  options.consumer_app_version,
217
219
  tags,
218
- pact_broker_client_options
220
+ pact_broker_client_options.merge(write_options)
219
221
  )
220
222
  end
221
223
 
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require_relative 'base_client'
2
4
  require 'pact_broker/client/matrix/resource'
3
5
 
@@ -39,7 +41,7 @@ module PactBroker
39
41
  response.body
40
42
  end
41
43
  rescue
42
- raise Error.new(response.body)
44
+ raise Error.new("status=#{response.code} #{response.body}")
43
45
  end
44
46
  raise Error.new(error_message)
45
47
  end
@@ -1,41 +1,74 @@
1
1
  require 'table_print'
2
+ require 'dig_rb'
2
3
 
3
4
  module PactBroker
4
5
  module Client
5
6
  class Matrix
6
7
  class TextFormatter
7
8
 
8
- Line = Struct.new(:consumer, :consumer_version, :provider, :provider_version, :success)
9
+ Line = Struct.new(:consumer, :consumer_version, :provider, :provider_version, :success, :ref)
9
10
 
10
11
  OPTIONS = [
11
12
  { consumer: {} },
12
13
  { consumer_version: {display_name: 'C.VERSION'} },
13
14
  { provider: {} },
14
15
  { provider_version: {display_name: 'P.VERSION'} },
15
- { success: {display_name: 'SUCCESS?'} }
16
+ { success: {display_name: 'SUCCESS?'} },
17
+ { ref: { display_name: 'RESULT#' }}
16
18
  ]
17
19
 
18
20
  def self.call(matrix)
19
21
  matrix_rows = matrix[:matrix]
20
22
  return "" if matrix_rows.size == 0
21
- data = matrix_rows.collect do | line |
23
+ verification_result_number = 0
24
+ data = matrix_rows.each_with_index.collect do | line |
25
+ has_verification_result_url = lookup(line, nil, :verificationResult, :_links, :self, :href)
26
+ if has_verification_result_url
27
+ verification_result_number += 1
28
+ end
22
29
  Line.new(
23
- lookup(line, :consumer, :name),
24
- lookup(line, :consumer, :version, :number),
25
- lookup(line, :provider, :name),
26
- lookup(line, :provider, :version, :number),
27
- lookup(line, :verificationResult, :success).to_s
30
+ lookup(line, "???", :consumer, :name),
31
+ lookup(line, "???", :consumer, :version, :number),
32
+ lookup(line, "???", :provider, :name) ,
33
+ lookup(line, "???", :provider, :version, :number),
34
+ (lookup(line, "???", :verificationResult, :success)).to_s,
35
+ has_verification_result_url ? verification_result_number : ""
28
36
  )
29
37
  end
30
38
 
31
39
  printer = TablePrint::Printer.new(data, OPTIONS)
32
- printer.table_print
40
+ printer.table_print + verification_result_urls_text(matrix)
33
41
  end
34
42
 
35
- def self.lookup line, *keys
43
+ def self.lookup line, default, *keys
36
44
  keys.reduce(line) { | line, key | line[key] }
37
45
  rescue NoMethodError
38
- "???"
46
+ default
47
+ end
48
+
49
+ def self.verification_results_urls_and_successes(matrix)
50
+ (matrix[:matrix] || []).collect do | row |
51
+ url = row.dig(:verificationResult, :_links, :self, :href)
52
+ if url
53
+ success = row.dig(:verificationResult, :success)
54
+ [url, success]
55
+ else
56
+ nil
57
+ end
58
+ end.compact
59
+ end
60
+
61
+ def self.verification_result_urls_text(matrix)
62
+ text = self.verification_results_urls_and_successes(matrix).each_with_index.collect do |(url, success), i|
63
+ status = success ? 'success' : 'failure'
64
+ "#{i+1}. #{url} (#{status})"
65
+ end.join("\n")
66
+
67
+ if text.size > 0
68
+ "\n\nVERIFICATION RESULTS\n--------------------\n#{text}"
69
+ else
70
+ text
71
+ end
39
72
  end
40
73
  end
41
74
  end
@@ -20,7 +20,7 @@ module PactBroker
20
20
 
21
21
  def call
22
22
  message = if output == 'json'
23
- versions_resource.response.body
23
+ versions_resource.response.raw_body
24
24
  else
25
25
  to_text(versions)
26
26
  end
@@ -16,8 +16,8 @@ module PactBroker
16
16
  def initialize pact_broker_base_url, pact_file_paths, consumer_version, tags, pact_broker_client_options={}
17
17
  @pact_broker_base_url = pact_broker_base_url
18
18
  @pact_file_paths = pact_file_paths
19
- @consumer_version = consumer_version
20
- @tags = tags
19
+ @consumer_version = consumer_version.respond_to?(:strip) ? consumer_version.strip : consumer_version
20
+ @tags = tags ? tags.collect{ |tag| tag.respond_to?(:strip) ? tag.strip : tag } : tags
21
21
  @pact_broker_client_options = pact_broker_client_options
22
22
  end
23
23
 
@@ -37,6 +37,10 @@ module PactBroker
37
37
  @pact_broker_client ||= PactBroker::Client::PactBrokerClient.new(base_url: pact_broker_base_url, client_options: pact_broker_client_options)
38
38
  end
39
39
 
40
+ def merge_on_server?
41
+ pact_broker_client_options[:write] == :merge
42
+ end
43
+
40
44
  def publish_pacts
41
45
  pact_files.group_by(&:pact_name).collect do | pact_name, pact_files |
42
46
  $stdout.puts "Merging #{pact_files.collect(&:path).join(", ")}" if pact_files.size > 1
@@ -77,13 +81,13 @@ module PactBroker
77
81
  versions = pact_broker_client.pacticipants.versions
78
82
  Retry.while_error do
79
83
  consumer_names.collect do | consumer_name |
80
- $stdout.puts "Tagging version #{consumer_version} of #{consumer_name} as #{tag.inspect}"
81
84
  versions.tag(pacticipant: consumer_name, version: consumer_version, tag: tag)
85
+ $stdout.puts "Tagged version #{consumer_version} of #{consumer_name} as #{tag.inspect}"
82
86
  true
83
87
  end
84
88
  end
85
89
  rescue => e
86
- $stderr.puts "Failed to tag versions due to error: #{e.class} - #{e}"
90
+ $stderr.puts "Failed to tag version due to error: #{e.class} - #{e}"
87
91
  false
88
92
  end
89
93
 
@@ -91,7 +95,11 @@ module PactBroker
91
95
  Retry.while_error do
92
96
  pacts = pact_broker_client.pacticipants.versions.pacts
93
97
  if pacts.version_published?(consumer: pact.consumer_name, provider: pact.provider_name, consumer_version: consumer_version)
94
- $stdout.puts ::Term::ANSIColor.yellow("A pact for this consumer version is already published. Overwriting. (Note: Overwriting pacts is not recommended as it can lead to race conditions. Best practice is to provide a unique consumer version number for each publication.)")
98
+ if merge_on_server?
99
+ $stdout.puts "A pact for this consumer version is already published. Merging contents."
100
+ else
101
+ $stdout.puts ::Term::ANSIColor.yellow("A pact for this consumer version is already published. Overwriting. (Note: Overwriting pacts is not recommended as it can lead to race conditions. Best practice is to provide a unique consumer version number for each publication.)")
102
+ end
95
103
  end
96
104
 
97
105
  latest_pact_url = pacts.publish(pact_hash: pact, consumer_version: consumer_version)
@@ -1,5 +1,5 @@
1
1
  module PactBroker
2
2
  module Client
3
- VERSION = '1.30.0'
3
+ VERSION = '1.35.0'
4
4
  end
5
5
  end
@@ -24,11 +24,13 @@ Gem::Specification.new do |gem|
24
24
  gem.add_runtime_dependency 'httparty', '~>0.18'
25
25
  gem.add_runtime_dependency 'term-ansicolor', '~> 1.7'
26
26
  gem.add_runtime_dependency 'table_print', '~> 1.5'
27
- gem.add_runtime_dependency 'thor', '~> 0.20'
27
+ gem.add_runtime_dependency 'thor', '>= 0.20', '< 2.0'
28
28
  gem.add_runtime_dependency 'rake', '~> 13.0' #For FileList
29
+ gem.add_runtime_dependency 'dig_rb', '~> 1.0'
29
30
 
30
31
  gem.add_development_dependency 'fakefs', '~> 0.4'
31
32
  gem.add_development_dependency 'webmock', '~> 3.0'
32
33
  gem.add_development_dependency 'conventional-changelog', '~>1.3'
33
34
  gem.add_development_dependency 'pact', '~> 1.16'
35
+ gem.add_development_dependency 'pact-support', '1.15.0'
34
36
  end
@@ -2,10 +2,11 @@ require 'pact_broker/client/base_client'
2
2
  module PactBroker
3
3
  module Client
4
4
  describe BaseClient do
5
- describe '#initialize' do
6
- subject { BaseClient.new(base_url: base_url) }
5
+ subject { BaseClient.new(base_url: base_url) }
6
+
7
+ let(:base_url) { 'http://pact_broker_base_url'}
7
8
 
8
- let(:base_url) { 'http://pact_broker_base_url'}
9
+ describe '#initialize' do
9
10
  let(:username) { 'pact_repo_username'}
10
11
  let(:password) { 'pact_repo_password'}
11
12
  let(:token) { '123456789' }
@@ -119,6 +120,63 @@ module PactBroker
119
120
  end
120
121
  end
121
122
  end
123
+
124
+ describe '#handle_response' do
125
+ let(:response) { double('Response', success?: true) }
126
+
127
+ it 'yields response object' do
128
+ expect { |block| subject.handle_response(response, &block) }.to yield_with_args(response)
129
+ end
130
+
131
+ context 'with 404 response' do
132
+ let(:response) { double('Response', success?: false, code: 404) }
133
+ it 'returns nil' do
134
+ expect(subject.handle_response(response)).to be_nil
135
+ end
136
+ end
137
+
138
+ context 'with 401 response' do
139
+ let(:response) { double('Response', success?: false, code: 401, body: 'body') }
140
+ it 'raise an exception with meaningful message' do
141
+ expect { subject.handle_response(response) }
142
+ .to raise_error(PactBroker::Client::Error, "Authentication failed: body")
143
+ end
144
+ end
145
+
146
+ context 'with 403 response' do
147
+ let(:response) { double('Response', success?: false, code: 403, body: 'body') }
148
+ it 'raise an exception with meaningful message' do
149
+ expect { subject.handle_response(response) }
150
+ .to raise_error(PactBroker::Client::Error, "Authorization failed (insufficient permissions): body")
151
+ end
152
+ end
153
+
154
+ context 'with 409 response' do
155
+ let(:response) { double('Response', success?: false, code: 409, body: 'body') }
156
+ it 'raise an exception with meaningful message' do
157
+ expect { subject.handle_response(response) }
158
+ .to raise_error(PactBroker::Client::Error, "Potential duplicate pacticipants: body")
159
+ end
160
+ end
161
+
162
+ context 'with unsuccessful JSON response' do
163
+ let(:response) do
164
+ double('Response', success?: false, code: 500, body: '{"errors": ["Internal server error"]}')
165
+ end
166
+ it 'raise an exception with meaningful message' do
167
+ expect { subject.handle_response(response) }
168
+ .to raise_error(PactBroker::Client::Error, "Internal server error")
169
+ end
170
+ end
171
+
172
+ context 'with unsucessful nono-JSON response ' do
173
+ let(:response) { double('Response', success?: false, code: 500, body: 'Internal server error') }
174
+ it 'raise an exception with meaningful message' do
175
+ expect { subject.handle_response(response) }
176
+ .to raise_error(PactBroker::Client::Error, "status=500 Internal server error")
177
+ end
178
+ end
179
+ end
122
180
  end
123
181
  end
124
- end
182
+ end
@@ -1,29 +1,54 @@
1
+ require 'pact_broker/client/matrix/resource'
1
2
  require 'pact_broker/client/matrix/text_formatter'
2
3
 
3
4
  module PactBroker
4
5
  module Client
5
6
  describe Matrix::TextFormatter do
6
- let(:matrix_lines) { JSON.parse(File.read('spec/support/matrix.json'), symbolize_names: true)[:matrix] }
7
+ let(:matrix) { PactBroker::Client::Matrix::Resource.new(JSON.parse(File.read('spec/support/matrix.json'), symbolize_names: true)) }
7
8
  let(:expected_matrix_lines) { File.read('spec/support/matrix.txt') }
8
9
 
9
10
  # SublimeText removes whitespace from the end of files when you save them,
10
11
  # so removing trailing whitespace before comparing
11
- subject { Matrix::TextFormatter.call(matrix: matrix_lines).split("\n").collect(&:strip).join("\n") }
12
+ def strip_trailing_whitespace(text)
13
+ text.split("\n").collect(&:strip).join("\n")
14
+ end
15
+
16
+ subject { strip_trailing_whitespace(Matrix::TextFormatter.call(matrix)) }
12
17
 
13
18
  context "with valid data" do
14
19
  it "it has the right text" do
15
- expect(subject).to eq expected_matrix_lines
20
+ expect(subject).to start_with expected_matrix_lines
16
21
  end
17
22
  end
18
23
 
19
24
  context "with invalid data" do
20
25
  let(:expected_matrix_lines) { File.read('spec/support/matrix_error.txt') }
21
- let(:matrix_lines) { [{}] }
26
+ let(:matrix) { PactBroker::Client::Matrix::Resource.new(matrix: [{}]) }
22
27
 
23
28
  it "doesn't blow up" do
24
29
  expect(subject).to eq expected_matrix_lines
25
30
  end
26
31
  end
32
+
33
+ context "when some rows have a verification result URL and some don't" do
34
+ let(:matrix_lines) do
35
+ line_creator = -> { JSON.parse(File.read('spec/support/matrix.json'), symbolize_names: true)[:matrix].first }
36
+ line_1 = line_creator.call
37
+ line_2 = line_creator.call
38
+ line_3 = line_creator.call
39
+ line_2[:verificationResult] = nil
40
+ line_3[:verificationResult][:success] = false
41
+ [line_1, line_2, line_3]
42
+ end
43
+
44
+ let(:matrix) { PactBroker::Client::Matrix::Resource.new(matrix: matrix_lines) }
45
+
46
+ let(:expected_matrix_lines) { File.read('spec/support/matrix_with_results.txt') }
47
+
48
+ it "only provides a result number for the lines that have a result URL" do
49
+ expect(subject).to eq expected_matrix_lines
50
+ end
51
+ end
27
52
  end
28
53
  end
29
54
  end
@@ -62,12 +62,12 @@ module PactBroker
62
62
  end
63
63
 
64
64
  context "when publishing is successful" do
65
-
66
65
  it "puts the location of the latest pact" do
67
66
  allow($stdout).to receive(:puts)
68
67
  expect($stdout).to receive(:puts).with(/#{latest_pact_url}/)
69
68
  subject.call
70
69
  end
70
+
71
71
  it "returns true" do
72
72
  expect(subject.call).to be true
73
73
  end
@@ -142,6 +142,15 @@ module PactBroker
142
142
  end
143
143
  end
144
144
 
145
+ context "when consumer_version has a new line" do
146
+ let(:consumer_version) { "1\n" }
147
+
148
+ it "strips the new line" do
149
+ expect(pacts_client).to receive(:publish).with(pact_hash: pact_hash, consumer_version: "1")
150
+ subject.call
151
+ end
152
+ end
153
+
145
154
  context "when pact_broker_base_url is blank" do
146
155
  let(:pact_broker_base_url) { " " }
147
156
  it "raises a validation errror" do
@@ -164,6 +173,16 @@ module PactBroker
164
173
  subject.call
165
174
  end
166
175
 
176
+ context "when the tag has a new line on the end of it" do
177
+ let(:tags) { ["foo\n"] }
178
+
179
+ it "strips the newline" do
180
+ expect(pact_versions_client).to receive(:tag).with({pacticipant: "Consumer",
181
+ version: consumer_version, tag: "foo"})
182
+ subject.call
183
+ end
184
+ end
185
+
167
186
  context "when an error occurs tagging the pact" do
168
187
 
169
188
  before do
@@ -221,7 +221,12 @@
221
221
  },
222
222
  "verificationResult": {
223
223
  "verifiedAt": "2017-10-10T12:49:04+11:00",
224
- "success": true
224
+ "success": true,
225
+ "_links": {
226
+ "self": {
227
+ "href": "http://result"
228
+ }
229
+ }
225
230
  },
226
231
  "pact": {
227
232
  "createdAt": "2017-10-10T12:49:04+11:00"
@@ -271,7 +276,12 @@
271
276
  },
272
277
  "verificationResult": {
273
278
  "verifiedAt": "2017-10-10T12:49:04+11:00",
274
- "success": true
279
+ "success": true,
280
+ "_links": {
281
+ "self": {
282
+ "href": "http://result"
283
+ }
284
+ }
275
285
  },
276
286
  "pact": {
277
287
  "createdAt": "2017-10-10T12:49:04+11:00"
@@ -321,7 +331,12 @@
321
331
  },
322
332
  "verificationResult": {
323
333
  "verifiedAt": "2017-10-10T12:49:04+11:00",
324
- "success": true
334
+ "success": true,
335
+ "_links": {
336
+ "self": {
337
+ "href": "http://result"
338
+ }
339
+ }
325
340
  },
326
341
  "pact": {
327
342
  "createdAt": "2017-10-10T12:49:04+11:00"
@@ -418,7 +433,12 @@
418
433
  },
419
434
  "verificationResult": {
420
435
  "verifiedAt": "2017-10-10T12:49:04+11:00",
421
- "success": true
436
+ "success": true,
437
+ "_links": {
438
+ "self": {
439
+ "href": "http://result"
440
+ }
441
+ }
422
442
  },
423
443
  "pact": {
424
444
  "createdAt": "2017-10-10T12:49:04+11:00"
@@ -439,7 +459,12 @@
439
459
  },
440
460
  "verificationResult": {
441
461
  "verifiedAt": "2017-10-10T12:49:04+11:00",
442
- "success": true
462
+ "success": true,
463
+ "_links": {
464
+ "self": {
465
+ "href": "http://result"
466
+ }
467
+ }
443
468
  },
444
469
  "pact": {
445
470
  "createdAt": "2017-10-10T12:49:04+11:00"
@@ -492,7 +517,12 @@
492
517
  },
493
518
  "verificationResult": {
494
519
  "verifiedAt": "2017-10-10T12:49:04+11:00",
495
- "success": true
520
+ "success": true,
521
+ "_links": {
522
+ "self": {
523
+ "href": "http://result"
524
+ }
525
+ }
496
526
  },
497
527
  "pact": {
498
528
  "createdAt": "2017-10-10T12:49:04+11:00"
@@ -542,7 +572,12 @@
542
572
  },
543
573
  "verificationResult": {
544
574
  "verifiedAt": "2017-10-10T12:49:04+11:00",
545
- "success": true
575
+ "success": true,
576
+ "_links": {
577
+ "self": {
578
+ "href": "http://result"
579
+ }
580
+ }
546
581
  },
547
582
  "pact": {
548
583
  "createdAt": "2017-10-10T12:49:04+11:00"
@@ -592,7 +627,12 @@
592
627
  },
593
628
  "verificationResult": {
594
629
  "verifiedAt": "2017-10-10T12:49:04+11:00",
595
- "success": true
630
+ "success": true,
631
+ "_links": {
632
+ "self": {
633
+ "href": "http://result"
634
+ }
635
+ }
596
636
  },
597
637
  "pact": {
598
638
  "createdAt": "2017-10-10T12:49:04+11:00"
@@ -20,7 +20,12 @@
20
20
  },
21
21
  "verificationResult": {
22
22
  "verifiedAt": "2017-10-10T12:49:04+11:00",
23
- "success": true
23
+ "success": true,
24
+ "_links": {
25
+ "self": {
26
+ "href": "http://result"
27
+ }
28
+ }
24
29
  },
25
30
  "pact": {
26
31
  "createdAt": "2017-10-10T12:49:04+11:00"
@@ -1,3 +1,3 @@
1
- CONSUMER | C.VERSION | PROVIDER | P.VERSION | SUCCESS?
2
- ---------|-----------|----------|-----------|---------
3
- Foo | 4 | Bar | 5 | true
1
+ CONSUMER | C.VERSION | PROVIDER | P.VERSION | SUCCESS? | RESULT#
2
+ ---------|-----------|----------|-----------|----------|--------
3
+ Foo | 4 | Bar | 5 | true | 1
@@ -1,3 +1,3 @@
1
- CONSUMER | C.VERSION | PROVIDER | P.VERSION | SUCCESS?
2
- ---------|-----------|----------|-----------|---------
3
- ??? | ??? | ??? | ??? | ???
1
+ CONSUMER | C.VERSION | PROVIDER | P.VERSION | SUCCESS? | RESULT#
2
+ ---------|-----------|----------|-----------|----------|--------
3
+ ??? | ??? | ??? | ??? | ??? |
@@ -0,0 +1,10 @@
1
+ CONSUMER | C.VERSION | PROVIDER | P.VERSION | SUCCESS? | RESULT#
2
+ ---------|-----------|----------|-----------|----------|--------
3
+ Foo | 4 | Bar | 5 | true | 1
4
+ Foo | 4 | Bar | 5 | ??? |
5
+ Foo | 4 | Bar | 5 | false | 2
6
+
7
+ VERIFICATION RESULTS
8
+ --------------------
9
+ 1. http://result (success)
10
+ 2. http://result (failure)
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: pact_broker-client
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.30.0
4
+ version: 1.35.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Beth Skurrie
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2020-10-09 00:00:00.000000000 Z
11
+ date: 2021-01-21 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: httparty
@@ -56,16 +56,22 @@ dependencies:
56
56
  name: thor
57
57
  requirement: !ruby/object:Gem::Requirement
58
58
  requirements:
59
- - - "~>"
59
+ - - ">="
60
60
  - !ruby/object:Gem::Version
61
61
  version: '0.20'
62
+ - - "<"
63
+ - !ruby/object:Gem::Version
64
+ version: '2.0'
62
65
  type: :runtime
63
66
  prerelease: false
64
67
  version_requirements: !ruby/object:Gem::Requirement
65
68
  requirements:
66
- - - "~>"
69
+ - - ">="
67
70
  - !ruby/object:Gem::Version
68
71
  version: '0.20'
72
+ - - "<"
73
+ - !ruby/object:Gem::Version
74
+ version: '2.0'
69
75
  - !ruby/object:Gem::Dependency
70
76
  name: rake
71
77
  requirement: !ruby/object:Gem::Requirement
@@ -80,6 +86,20 @@ dependencies:
80
86
  - - "~>"
81
87
  - !ruby/object:Gem::Version
82
88
  version: '13.0'
89
+ - !ruby/object:Gem::Dependency
90
+ name: dig_rb
91
+ requirement: !ruby/object:Gem::Requirement
92
+ requirements:
93
+ - - "~>"
94
+ - !ruby/object:Gem::Version
95
+ version: '1.0'
96
+ type: :runtime
97
+ prerelease: false
98
+ version_requirements: !ruby/object:Gem::Requirement
99
+ requirements:
100
+ - - "~>"
101
+ - !ruby/object:Gem::Version
102
+ version: '1.0'
83
103
  - !ruby/object:Gem::Dependency
84
104
  name: fakefs
85
105
  requirement: !ruby/object:Gem::Requirement
@@ -136,6 +156,20 @@ dependencies:
136
156
  - - "~>"
137
157
  - !ruby/object:Gem::Version
138
158
  version: '1.16'
159
+ - !ruby/object:Gem::Dependency
160
+ name: pact-support
161
+ requirement: !ruby/object:Gem::Requirement
162
+ requirements:
163
+ - - '='
164
+ - !ruby/object:Gem::Version
165
+ version: 1.15.0
166
+ type: :development
167
+ prerelease: false
168
+ version_requirements: !ruby/object:Gem::Requirement
169
+ requirements:
170
+ - - '='
171
+ - !ruby/object:Gem::Version
172
+ version: 1.15.0
139
173
  description: Client for the Pact Broker. Publish, retrieve and query pacts and verification
140
174
  results.
141
175
  email:
@@ -146,10 +180,10 @@ extensions: []
146
180
  extra_rdoc_files: []
147
181
  files:
148
182
  - ".github/workflows/release_gem.yml"
183
+ - ".github/workflows/test.yml"
149
184
  - ".github/workflows/trigger_pact_docs_update.yml"
150
185
  - ".gitignore"
151
186
  - ".rspec"
152
- - ".travis.yml"
153
187
  - CHANGELOG.md
154
188
  - Dockerfile
155
189
  - Gemfile
@@ -271,6 +305,7 @@ files:
271
305
  - spec/support/matrix.json
272
306
  - spec/support/matrix.txt
273
307
  - spec/support/matrix_error.txt
308
+ - spec/support/matrix_with_results.txt
274
309
  - spec/support/pacticipant_get.json
275
310
  - spec/support/pacticipants_list.json
276
311
  - spec/support/pacts_latest_list.json
@@ -295,7 +330,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
295
330
  - !ruby/object:Gem::Version
296
331
  version: '0'
297
332
  requirements: []
298
- rubygems_version: 3.1.4
333
+ rubygems_version: 3.2.6
299
334
  signing_key:
300
335
  specification_version: 4
301
336
  summary: See description
@@ -350,6 +385,7 @@ test_files:
350
385
  - spec/support/matrix.json
351
386
  - spec/support/matrix.txt
352
387
  - spec/support/matrix_error.txt
388
+ - spec/support/matrix_with_results.txt
353
389
  - spec/support/pacticipant_get.json
354
390
  - spec/support/pacticipants_list.json
355
391
  - spec/support/pacts_latest_list.json
@@ -1,11 +0,0 @@
1
- language: ruby
2
- rvm:
3
- - 2.2.4
4
- - 2.4.1
5
-
6
- # before_install:
7
- # - (git show-ref | grep $(git log --pretty=%h -1) | sed 's|.*/\(.*\)|\1|' | sort -u | grep -v HEAD) || true
8
- # - (git show -s --pretty=%d HEAD) || true
9
- # - (git for-each-ref --format='%(objectname) %(refname:short)' refs/heads | awk "/^$(git rev-parse HEAD)/ {print \$2}") || true
10
- # - (git show -s --pretty=%D HEAD | tr -s ', ' '\n' | grep -v HEAD | head -n1) || true
11
- # - (git name-rev --name-only HEAD) || true