pact_broker-client 1.30.0 → 1.35.0

Sign up to get free protection for your applications and to get access to all the features.
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