pact 1.41.2 → 1.42.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +9 -0
- data/lib/pact/cli/run_pact_verification.rb +11 -5
- data/lib/pact/hal/http_client.rb +5 -2
- data/lib/pact/hal/link.rb +19 -1
- data/lib/pact/pact_broker.rb +10 -4
- data/lib/pact/pact_broker/fetch_pact_uris_for_verification.rb +96 -0
- data/lib/pact/provider/configuration/pact_verification_from_broker.rb +22 -4
- data/lib/pact/provider/configuration/service_provider_dsl.rb +1 -1
- data/lib/pact/provider/pact_uri.rb +6 -4
- data/lib/pact/provider/rspec.rb +7 -5
- data/lib/pact/version.rb +1 -1
- metadata +3 -3
- data/lib/pact/pact_broker/fetch_pending_pacts.rb +0 -58
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: e4b327f444ffe97e8a904aa40ccdf20086de7507
|
4
|
+
data.tar.gz: 4885272ca8b7b4eb1e3ebd8d5f995ec50fbb96b5
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 3e26230cf9736addab312532d9ca89bf519872b08d5a2b9a0934f4b033ca815b0c09c20f96b68fd43912621c634f6a0ca03dfc05b4475dfe6d229674c6c13f0b
|
7
|
+
data.tar.gz: 5765ee8272e673040156be5cea50512bbfa613e93424260bb556bc412dded504ea25d3608f4a743bcb42b2febe4995cfe35e368c953f397c607d0ca73bb44df7
|
data/CHANGELOG.md
CHANGED
@@ -44,15 +44,17 @@ module Pact
|
|
44
44
|
end
|
45
45
|
|
46
46
|
def run_specs
|
47
|
-
exit_code = if options[:pact_uri]
|
48
|
-
|
47
|
+
exit_code = if options[:pact_uri].is_a?(String)
|
48
|
+
run_with_pact_url_string
|
49
|
+
elsif options[:pact_uri]
|
50
|
+
run_with_pact_uri_object # from pact-provider-verifier
|
49
51
|
else
|
50
|
-
|
52
|
+
run_with_configured_pacts_from_pact_helper
|
51
53
|
end
|
52
54
|
exit exit_code
|
53
55
|
end
|
54
56
|
|
55
|
-
def
|
57
|
+
def run_with_pact_url_string
|
56
58
|
pact_repository_uri_options = {}
|
57
59
|
pact_repository_uri_options[:username] = options[:pact_broker_username] if options[:pact_broker_username]
|
58
60
|
pact_repository_uri_options[:password] = options[:pact_broker_password] if options[:pact_broker_password]
|
@@ -61,7 +63,11 @@ module Pact
|
|
61
63
|
Pact::Provider::PactSpecRunner.new([pact_uri], pact_spec_options).run
|
62
64
|
end
|
63
65
|
|
64
|
-
def
|
66
|
+
def run_with_pact_uri_object
|
67
|
+
Pact::Provider::PactSpecRunner.new([options[:pact_uri]], pact_spec_options).run
|
68
|
+
end
|
69
|
+
|
70
|
+
def run_with_configured_pacts_from_pact_helper
|
65
71
|
pact_urls = Pact.provider_world.pact_urls
|
66
72
|
raise "Please configure a pact to verify" if pact_urls.empty?
|
67
73
|
Pact::Provider::PactSpecRunner.new(pact_urls, pact_spec_options).run
|
data/lib/pact/hal/http_client.rb
CHANGED
@@ -1,6 +1,7 @@
|
|
1
1
|
require 'pact/retry'
|
2
2
|
require 'pact/hal/authorization_header_redactor'
|
3
3
|
require 'net/http'
|
4
|
+
require 'rack'
|
4
5
|
|
5
6
|
module Pact
|
6
7
|
module Hal
|
@@ -15,9 +16,11 @@ module Pact
|
|
15
16
|
end
|
16
17
|
|
17
18
|
def get href, params = {}, headers = {}
|
18
|
-
query = params.collect{ |(key, value)| "#{CGI::escape(key)}=#{CGI::escape(value)}" }.join("&")
|
19
19
|
uri = URI(href)
|
20
|
-
|
20
|
+
if params && params.any?
|
21
|
+
existing_params = Rack::Utils.parse_nested_query(uri.query)
|
22
|
+
uri.query = Rack::Utils.build_nested_query(existing_params.merge(params))
|
23
|
+
end
|
21
24
|
perform_request(create_request(uri, 'Get', nil, headers), uri)
|
22
25
|
end
|
23
26
|
|
data/lib/pact/hal/link.rb
CHANGED
@@ -40,6 +40,10 @@ module Pact
|
|
40
40
|
wrap_response(href, @http_client.get(href, payload, headers))
|
41
41
|
end
|
42
42
|
|
43
|
+
def get!(*args)
|
44
|
+
get(*args).assert_success!
|
45
|
+
end
|
46
|
+
|
43
47
|
def put(payload = nil, headers = {})
|
44
48
|
wrap_response(href, @http_client.put(href, payload ? payload.to_json : nil, headers))
|
45
49
|
end
|
@@ -51,11 +55,25 @@ module Pact
|
|
51
55
|
def expand(params)
|
52
56
|
expanded_url = expand_url(params, href)
|
53
57
|
new_attrs = @attrs.merge('href' => expanded_url)
|
54
|
-
Link.new(new_attrs,
|
58
|
+
Link.new(new_attrs, http_client)
|
59
|
+
end
|
60
|
+
|
61
|
+
def with_query(query)
|
62
|
+
if query && query.any?
|
63
|
+
uri = URI(href)
|
64
|
+
existing_query_params = Rack::Utils.parse_nested_query(uri.query)
|
65
|
+
uri.query = Rack::Utils.build_nested_query(existing_query_params.merge(query))
|
66
|
+
new_attrs = attrs.merge('href' => uri.to_s)
|
67
|
+
Link.new(new_attrs, http_client)
|
68
|
+
else
|
69
|
+
self
|
70
|
+
end
|
55
71
|
end
|
56
72
|
|
57
73
|
private
|
58
74
|
|
75
|
+
attr_reader :attrs, :http_client
|
76
|
+
|
59
77
|
def wrap_response(href, http_response)
|
60
78
|
require 'pact/hal/entity' # avoid circular reference
|
61
79
|
if http_response.success?
|
data/lib/pact/pact_broker.rb
CHANGED
@@ -1,19 +1,25 @@
|
|
1
1
|
require 'pact/pact_broker/fetch_pacts'
|
2
|
-
require 'pact/pact_broker/
|
2
|
+
require 'pact/pact_broker/fetch_pact_uris_for_verification'
|
3
|
+
require 'pact/provider/pact_uri'
|
3
4
|
|
4
5
|
#
|
5
|
-
# @public
|
6
|
+
# @public Used by Pact Provider Verifier
|
6
7
|
#
|
7
8
|
module Pact
|
8
9
|
module PactBroker
|
9
10
|
extend self
|
10
11
|
|
12
|
+
# Keep for backwards compatibility with pact-provider-verifier < 1.23.1
|
11
13
|
def fetch_pact_uris *args
|
12
14
|
Pact::PactBroker::FetchPacts.call(*args).collect(&:uri)
|
13
15
|
end
|
14
16
|
|
15
|
-
def
|
16
|
-
Pact::PactBroker::
|
17
|
+
def fetch_pact_uris_for_verification *args
|
18
|
+
Pact::PactBroker::FetchPactURIsForVerification.call(*args)
|
19
|
+
end
|
20
|
+
|
21
|
+
def build_pact_uri(*args)
|
22
|
+
Pact::Provider::PactURI.new(*args)
|
17
23
|
end
|
18
24
|
end
|
19
25
|
end
|
@@ -0,0 +1,96 @@
|
|
1
|
+
require 'pact/hal/entity'
|
2
|
+
require 'pact/hal/http_client'
|
3
|
+
require 'pact/provider/pact_uri'
|
4
|
+
require 'pact/errors'
|
5
|
+
require 'pact/pact_broker/fetch_pacts'
|
6
|
+
|
7
|
+
module Pact
|
8
|
+
module PactBroker
|
9
|
+
class FetchPactURIsForVerification
|
10
|
+
attr_reader :provider, :consumer_version_selectors, :provider_version_tags, :broker_base_url, :http_client_options, :http_client
|
11
|
+
|
12
|
+
PACTS_FOR_VERIFICATION_RELATION = 'beta:provider-pacts-for-verification'.freeze
|
13
|
+
PACTS = 'pacts'.freeze
|
14
|
+
HREF = 'href'.freeze
|
15
|
+
LINKS = '_links'.freeze
|
16
|
+
SELF = 'self'.freeze
|
17
|
+
EMBEDDED = '_embedded'.freeze
|
18
|
+
|
19
|
+
def initialize(provider, consumer_version_selectors, provider_version_tags, broker_base_url, http_client_options)
|
20
|
+
@provider = provider
|
21
|
+
@consumer_version_selectors = consumer_version_selectors
|
22
|
+
@provider_version_tags = provider_version_tags
|
23
|
+
@http_client_options = http_client_options
|
24
|
+
@broker_base_url = broker_base_url
|
25
|
+
@http_client = Pact::Hal::HttpClient.new(http_client_options)
|
26
|
+
end
|
27
|
+
|
28
|
+
def self.call(provider, consumer_version_selectors, provider_version_tags, broker_base_url, http_client_options)
|
29
|
+
new(provider, consumer_version_selectors, provider_version_tags, broker_base_url, http_client_options).call
|
30
|
+
end
|
31
|
+
|
32
|
+
def call
|
33
|
+
if index.can?(PACTS_FOR_VERIFICATION_RELATION)
|
34
|
+
log_message
|
35
|
+
pacts_for_verification
|
36
|
+
else
|
37
|
+
# Fall back to old method of fetching pacts
|
38
|
+
consumer_version_tags = consumer_version_selectors.collect{ | selector | selector[:tag] }
|
39
|
+
FetchPacts.call(provider, consumer_version_tags, broker_base_url, http_client_options)
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
private
|
44
|
+
|
45
|
+
def index
|
46
|
+
@index_entity ||= Pact::Hal::Link.new({ "href" => broker_base_url }, http_client).get.assert_success!
|
47
|
+
end
|
48
|
+
|
49
|
+
def pacts_for_verification
|
50
|
+
pacts_for_verification_entity.response.body[EMBEDDED][PACTS].collect do | pact |
|
51
|
+
metadata = {
|
52
|
+
pending: pact["verificationProperties"]["pending"],
|
53
|
+
pending_reason: pact["verificationProperties"]["pendingReason"],
|
54
|
+
inclusion_reason: pact["verificationProperties"]["inclusionReason"],
|
55
|
+
}
|
56
|
+
Pact::Provider::PactURI.new(pact[LINKS][SELF][HREF], http_client_options, metadata)
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
def pacts_for_verification_entity
|
61
|
+
index
|
62
|
+
._link(PACTS_FOR_VERIFICATION_RELATION)
|
63
|
+
.expand(provider: provider)
|
64
|
+
.with_query(query)
|
65
|
+
.get!
|
66
|
+
end
|
67
|
+
|
68
|
+
def query
|
69
|
+
q = {}
|
70
|
+
if consumer_version_selectors&.any?
|
71
|
+
q["consumer_version_selectors"] = consumer_version_selectors
|
72
|
+
end
|
73
|
+
|
74
|
+
if provider_version_tags&.any?
|
75
|
+
q["provider_version_tags"] = provider_version_tags
|
76
|
+
end
|
77
|
+
q
|
78
|
+
end
|
79
|
+
|
80
|
+
def log_message
|
81
|
+
latest = consumer_version_selectors&.any? ? "" : "latest "
|
82
|
+
message = "INFO: Fetching #{latest}pacts for #{provider} from #{broker_base_url}"
|
83
|
+
if consumer_version_selectors&.any?
|
84
|
+
desc = consumer_version_selectors.collect do |selector|
|
85
|
+
all_or_latest = selector[:all] ? "all" : "latest"
|
86
|
+
# TODO support fallback
|
87
|
+
name = selector[:fallback] ? "#{selector[:tag]} (or #{selector[:fallback]} if not found)" : selector[:tag]
|
88
|
+
"#{all_or_latest} #{name}"
|
89
|
+
end.join(", ")
|
90
|
+
message << " for tags: #{desc}"
|
91
|
+
end
|
92
|
+
Pact.configuration.output_stream.puts message
|
93
|
+
end
|
94
|
+
end
|
95
|
+
end
|
96
|
+
end
|
@@ -1,6 +1,6 @@
|
|
1
1
|
require 'pact/shared/dsl'
|
2
2
|
require 'pact/provider/world'
|
3
|
-
require 'pact/pact_broker/
|
3
|
+
require 'pact/pact_broker/fetch_pact_uris_for_verification'
|
4
4
|
require 'pact/errors'
|
5
5
|
|
6
6
|
module Pact
|
@@ -14,10 +14,11 @@ module Pact
|
|
14
14
|
# in parent scope, it will clash with these ones,
|
15
15
|
# so put an underscore in front of the name to be safer.
|
16
16
|
|
17
|
-
attr_accessor :_provider_name, :_pact_broker_base_url, :_consumer_version_tags, :_basic_auth_options, :_verbose
|
17
|
+
attr_accessor :_provider_name, :_pact_broker_base_url, :_consumer_version_tags, :_provider_version_tags, :_basic_auth_options, :_verbose
|
18
18
|
|
19
|
-
def initialize(provider_name)
|
19
|
+
def initialize(provider_name, provider_version_tags)
|
20
20
|
@_provider_name = provider_name
|
21
|
+
@_provider_version_tags = provider_version_tags
|
21
22
|
@_consumer_version_tags = []
|
22
23
|
@_verbose = false
|
23
24
|
end
|
@@ -45,10 +46,27 @@ module Pact
|
|
45
46
|
private
|
46
47
|
|
47
48
|
def create_pact_verification
|
48
|
-
fetch_pacts = Pact::PactBroker::
|
49
|
+
fetch_pacts = Pact::PactBroker::FetchPactURIsForVerification.new(
|
50
|
+
_provider_name,
|
51
|
+
consumer_version_selectors,
|
52
|
+
_provider_version_tags,
|
53
|
+
_pact_broker_base_url,
|
54
|
+
_basic_auth_options.merge(verbose: _verbose)
|
55
|
+
)
|
56
|
+
|
49
57
|
Pact.provider_world.add_pact_uri_source fetch_pacts
|
50
58
|
end
|
51
59
|
|
60
|
+
def consumer_version_selectors
|
61
|
+
# TODO support "all"
|
62
|
+
_consumer_version_tags.collect do | tag |
|
63
|
+
{
|
64
|
+
tag: tag,
|
65
|
+
latest: true
|
66
|
+
}
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
52
70
|
def validate
|
53
71
|
raise Pact::Error.new("Please provide a pact_broker_base_url from which to retrieve the pacts") unless _pact_broker_base_url
|
54
72
|
end
|
@@ -1,17 +1,19 @@
|
|
1
1
|
module Pact
|
2
2
|
module Provider
|
3
3
|
class PactURI
|
4
|
-
attr_reader :uri, :options
|
4
|
+
attr_reader :uri, :options, :metadata
|
5
5
|
|
6
|
-
def initialize (uri, options=
|
6
|
+
def initialize (uri, options = nil, metadata = nil)
|
7
7
|
@uri = uri
|
8
|
-
@options = options
|
8
|
+
@options = options || {}
|
9
|
+
@metadata = metadata || {} # make sure it's not nil if nil is passed in
|
9
10
|
end
|
10
11
|
|
11
12
|
def == other
|
12
13
|
other.is_a?(PactURI) &&
|
13
14
|
uri == other.uri &&
|
14
|
-
options == other.options
|
15
|
+
options == other.options &&
|
16
|
+
metadata == other.metadata
|
15
17
|
end
|
16
18
|
|
17
19
|
def basic_auth?
|
data/lib/pact/provider/rspec.rb
CHANGED
@@ -21,11 +21,13 @@ module Pact
|
|
21
21
|
include ::RSpec::Core::DSL
|
22
22
|
|
23
23
|
def honour_pactfile pact_uri, pact_json, options
|
24
|
-
|
25
|
-
Pact.configuration.output_stream.puts
|
26
|
-
Pact.configuration.output_stream.puts
|
24
|
+
Pact.configuration.output_stream.puts "INFO: Reading pact at #{pact_uri}"
|
25
|
+
Pact.configuration.output_stream.puts("DEBUG: #{pact_uri.metadata[:inclusion_reason]}") if pact_uri.metadata[:inclusion_reason]
|
26
|
+
Pact.configuration.output_stream.puts("DEBUG: #{pact_uri.metadata[:pending_reason]}") if pact_uri.metadata[:pending_reason]
|
27
|
+
Pact.configuration.output_stream.puts "DEBUG: Filtering interactions by: #{options[:criteria]}" if options[:criteria] && options[:criteria].any?
|
27
28
|
consumer_contract = Pact::ConsumerContract.from_json(pact_json)
|
28
|
-
|
29
|
+
suffix = pact_uri.metadata[:pending] ? " [PENDING]": ""
|
30
|
+
::RSpec.describe "Verifying a pact between #{consumer_contract.consumer.name} and #{consumer_contract.provider.name}#{suffix}", pactfile_uri: pact_uri do
|
29
31
|
honour_consumer_contract consumer_contract, options.merge(pact_json: pact_json, pact_uri: pact_uri)
|
30
32
|
end
|
31
33
|
end
|
@@ -74,7 +76,7 @@ module Pact
|
|
74
76
|
pact_interaction: interaction,
|
75
77
|
pact_interaction_example_description: interaction_description_for_rerun_command(interaction),
|
76
78
|
pact_uri: options[:pact_uri],
|
77
|
-
pact_ignore_failures: options[:
|
79
|
+
pact_ignore_failures: options[:pact_uri].metadata[:pending]
|
78
80
|
}
|
79
81
|
|
80
82
|
describe description_for(interaction), metadata do
|
data/lib/pact/version.rb
CHANGED
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: pact
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.42.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- James Fraser
|
@@ -12,7 +12,7 @@ authors:
|
|
12
12
|
autorequire:
|
13
13
|
bindir: bin
|
14
14
|
cert_chain: []
|
15
|
-
date: 2019-09-
|
15
|
+
date: 2019-09-26 00:00:00.000000000 Z
|
16
16
|
dependencies:
|
17
17
|
- !ruby/object:Gem::Dependency
|
18
18
|
name: randexp
|
@@ -323,8 +323,8 @@ files:
|
|
323
323
|
- lib/pact/hal/http_client.rb
|
324
324
|
- lib/pact/hal/link.rb
|
325
325
|
- lib/pact/pact_broker.rb
|
326
|
+
- lib/pact/pact_broker/fetch_pact_uris_for_verification.rb
|
326
327
|
- lib/pact/pact_broker/fetch_pacts.rb
|
327
|
-
- lib/pact/pact_broker/fetch_pending_pacts.rb
|
328
328
|
- lib/pact/project_root.rb
|
329
329
|
- lib/pact/provider.rb
|
330
330
|
- lib/pact/provider/configuration.rb
|
@@ -1,58 +0,0 @@
|
|
1
|
-
require 'pact/hal/entity'
|
2
|
-
require 'pact/hal/http_client'
|
3
|
-
require 'pact/provider/pact_uri'
|
4
|
-
require 'pact/errors'
|
5
|
-
|
6
|
-
module Pact
|
7
|
-
module PactBroker
|
8
|
-
class FetchPendingPacts
|
9
|
-
attr_reader :provider, :tags, :broker_base_url, :http_client_options, :http_client, :index_entity
|
10
|
-
|
11
|
-
PENDING_PROVIDER_RELATION = 'beta:pending-provider-pacts'.freeze
|
12
|
-
WIP_PROVIDER_RELATION = 'beta:wip-provider-pacts'.freeze # deprecated
|
13
|
-
PACTS = 'pacts'.freeze
|
14
|
-
PB_PACTS = 'pb:pacts'.freeze
|
15
|
-
HREF = 'href'.freeze
|
16
|
-
|
17
|
-
def initialize(provider, broker_base_url, http_client_options)
|
18
|
-
@provider = provider
|
19
|
-
@http_client_options = http_client_options
|
20
|
-
@broker_base_url = broker_base_url
|
21
|
-
@http_client = Pact::Hal::HttpClient.new(http_client_options)
|
22
|
-
end
|
23
|
-
|
24
|
-
def self.call(provider, broker_base_url, http_client_options)
|
25
|
-
new(provider, broker_base_url, http_client_options).call
|
26
|
-
end
|
27
|
-
|
28
|
-
def call
|
29
|
-
if index.success?
|
30
|
-
pending_pacts_for_provider
|
31
|
-
else
|
32
|
-
raise Pact::Error.new("Error retrieving #{broker_base_url} status=#{index_entity.response.code} #{index_entity.response.raw_body}")
|
33
|
-
end
|
34
|
-
end
|
35
|
-
|
36
|
-
private
|
37
|
-
|
38
|
-
def index
|
39
|
-
@index_entity ||= Pact::Hal::Link.new({ "href" => broker_base_url }, http_client).get.assert_success!
|
40
|
-
end
|
41
|
-
|
42
|
-
def pending_pacts_for_provider
|
43
|
-
link = index_entity._link(WIP_PROVIDER_RELATION, PENDING_PROVIDER_RELATION)
|
44
|
-
if link
|
45
|
-
get_pact_urls(link.expand(provider: provider).get)
|
46
|
-
else
|
47
|
-
[]
|
48
|
-
end
|
49
|
-
end
|
50
|
-
|
51
|
-
def get_pact_urls(link_by_provider)
|
52
|
-
link_by_provider.fetch(PB_PACTS, PACTS).collect do |pact|
|
53
|
-
Pact::Provider::PactURI.new(pact[HREF], http_client_options)
|
54
|
-
end
|
55
|
-
end
|
56
|
-
end
|
57
|
-
end
|
58
|
-
end
|