pact_broker 2.19.1 → 2.19.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +20 -0
- data/README.md +0 -1
- data/db/migrations/000002_create_versions_table.rb +1 -1
- data/db/migrations/20180311_optimise_head_matrix.rb +1 -0
- data/db/migrations/20180523_create_latest_verifications_for_consumer_version_tags.rb +50 -0
- data/db/migrations/20180524_create_latest_verifications_for_consumer_and_provider.rb +46 -0
- data/lib/pact_broker/api/decorators/webhook_execution_result_decorator.rb +7 -3
- data/lib/pact_broker/configuration.rb +6 -1
- data/lib/pact_broker/domain/webhook_request.rb +12 -11
- data/lib/pact_broker/index/service.rb +14 -84
- data/lib/pact_broker/matrix/aggregated_row.rb +71 -0
- data/lib/pact_broker/matrix/head_row.rb +23 -0
- data/lib/pact_broker/matrix/repository.rb +0 -1
- data/lib/pact_broker/matrix/row.rb +15 -20
- data/lib/pact_broker/pacts/content.rb +66 -0
- data/lib/pact_broker/pacts/create_formatted_diff.rb +0 -1
- data/lib/pact_broker/pacts/diff.rb +3 -2
- data/lib/pact_broker/pacts/generate_sha.rb +24 -0
- data/lib/pact_broker/pacts/parse.rb +11 -0
- data/lib/pact_broker/pacts/repository.rb +4 -4
- data/lib/pact_broker/pacts/service.rb +4 -2
- data/lib/pact_broker/pacts/sort_content.rb +54 -0
- data/lib/pact_broker/verifications/latest_verification_for_consumer_and_provider.rb +26 -0
- data/lib/pact_broker/verifications/latest_verification_for_consumer_version_tag.rb +23 -0
- data/lib/pact_broker/version.rb +1 -1
- data/lib/pact_broker/versions/repository.rb +12 -3
- data/script/run-with-ssl.rb +44 -0
- data/spec/features/base_equality_only_on_content_that_affects_verification_results_spec.rb +34 -0
- data/spec/lib/pact_broker/api/decorators/webhook_execution_result_decorator_spec.rb +6 -2
- data/spec/lib/pact_broker/domain/{index_items_spec.rb → index_item_spec.rb} +0 -0
- data/spec/lib/pact_broker/domain/webhook_request_spec.rb +16 -5
- data/spec/lib/pact_broker/matrix/aggregated_row_spec.rb +79 -0
- data/spec/lib/pact_broker/matrix/head_row_spec.rb +55 -0
- data/spec/lib/pact_broker/matrix/row_spec.rb +22 -2
- data/spec/lib/pact_broker/pacts/content_spec.rb +166 -0
- data/spec/lib/pact_broker/pacts/create_formatted_diff_spec.rb +0 -3
- data/spec/lib/pact_broker/pacts/generate_sha_spec.rb +92 -0
- data/spec/lib/pact_broker/pacts/repository_spec.rb +47 -4
- data/spec/lib/pact_broker/pacts/sort_content_spec.rb +44 -0
- data/spec/lib/pact_broker/versions/repository_spec.rb +13 -5
- data/spec/spec_helper.rb +1 -0
- data/spec/support/foo-bar.json +34 -0
- data/spec/support/rspec_match_hash.rb +14 -17
- data/spec/support/test_data_builder.rb +5 -4
- metadata +26 -8
- data/lib/pact_broker/matrix/latest_row.rb +0 -10
- data/lib/pact_broker/pacts/sort_verifiable_content.rb +0 -41
- data/spec/lib/pact_broker/pacts/sort_verifiable_content_spec.rb +0 -25
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 6596910c63bcfb8363e958de4bb4bb698df0613e
|
4
|
+
data.tar.gz: 929b0ac8d06300c3a6226f4afb3af099f97c7476
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: aaf62c676cffcc46679e3cba55afd4234d74208577869803d76e670805b314d7e8a742525de8d3599aafa5f5769d50b62b76ee8464796766c42c92dc73807b36
|
7
|
+
data.tar.gz: 3cb076e57dcb8f23450ddd50e1b8f92f4161f79fd4541799296a5fdc0ed4671e13d1ba409eb0dfeff60c41cc86cc3472a304fb6e1068b6219a2359b3365799e7
|
data/CHANGELOG.md
CHANGED
@@ -1,3 +1,23 @@
|
|
1
|
+
<a name="v2.19.2"></a>
|
2
|
+
### v2.19.2 (2018-05-29)
|
3
|
+
|
4
|
+
|
5
|
+
#### Features
|
6
|
+
|
7
|
+
* load latest verification for consumer/provider via relationship rather than repository ([13b7c6e](/../../commit/13b7c6e))
|
8
|
+
* include more columns in latest_verifications_for_consumer_version_tags to avoid having to do extra queries for pact_versions and provider_versions ([e366af4](/../../commit/e366af4))
|
9
|
+
* optimise queries for index page with tags ([524e08d](/../../commit/524e08d))
|
10
|
+
* create view for latest verifications for consumer version tags ([eb67511](/../../commit/eb67511))
|
11
|
+
* log pact content as debug instead of info when publishing ([d116157](/../../commit/d116157))
|
12
|
+
* allow pact equality to be based only on the content that affects verification results ([bf8130f](/../../commit/bf8130f))
|
13
|
+
|
14
|
+
|
15
|
+
#### Bug Fixes
|
16
|
+
|
17
|
+
* temporarily redact webhook response body from UI for security purposes ([becf20c](/../../commit/becf20c))
|
18
|
+
* handle race condition causing unique constraint violation when creating pacticipant versions ([6c75ebd](/../../commit/6c75ebd))
|
19
|
+
|
20
|
+
|
1
21
|
<a name="v2.19.1"></a>
|
2
22
|
### v2.19.1 (2018-05-18)
|
3
23
|
|
data/README.md
CHANGED
@@ -4,7 +4,6 @@
|
|
4
4
|
[![Code Climate](https://codeclimate.com/github/pact-foundation/pact_broker/badges/gpa.svg)](https://codeclimate.com/github/pact-foundation/pact_broker)
|
5
5
|
[![Test Coverage](https://codeclimate.com/github/pact-foundation/pact_broker/badges/coverage.svg)](https://codeclimate.com/github/pact-foundation/pact_broker/coverage)
|
6
6
|
[![Issue Count](https://codeclimate.com/github/pact-foundation/pact_broker/badges/issue_count.svg)](https://codeclimate.com/github/pact-foundation/pact_broker)
|
7
|
-
[![Dependency Status](https://gemnasium.com/badges/github.com/pact-foundation/pact_broker.svg)](https://gemnasium.com/github.com/pact-foundation/pact_broker)
|
8
7
|
|
9
8
|
The Pact Broker is an application for sharing for consumer driven contracts and verification results. It is optimised for use with "pacts" (contracts created by the [Pact][pact-docs] framework), but can be used for any type of contract that can be serialized to JSON.
|
10
9
|
|
@@ -0,0 +1,50 @@
|
|
1
|
+
Sequel.migration do
|
2
|
+
up do
|
3
|
+
# The latest verification id for each consumer version tag
|
4
|
+
create_view(:latest_verification_ids_for_consumer_version_tags,
|
5
|
+
"select
|
6
|
+
pv.pacticipant_id as provider_id,
|
7
|
+
lpp.consumer_id,
|
8
|
+
t.name as consumer_version_tag_name,
|
9
|
+
max(v.id) as latest_verification_id
|
10
|
+
from verifications v
|
11
|
+
join latest_pact_publications_by_consumer_versions lpp
|
12
|
+
on v.pact_version_id = lpp.pact_version_id
|
13
|
+
join tags t
|
14
|
+
on lpp.consumer_version_id = t.version_id
|
15
|
+
join versions pv
|
16
|
+
on v.provider_version_id = pv.id
|
17
|
+
group by pv.pacticipant_id, lpp.consumer_id, t.name")
|
18
|
+
|
19
|
+
# The most recent verification for each consumer/consumer version tag/provider
|
20
|
+
latest_verifications = from(:verifications)
|
21
|
+
.select(
|
22
|
+
Sequel[:lv][:consumer_id],
|
23
|
+
Sequel[:lv][:provider_id],
|
24
|
+
Sequel[:lv][:consumer_version_tag_name],
|
25
|
+
Sequel[:pv][:sha].as(:pact_version_sha),
|
26
|
+
Sequel[:prv][:number].as(:provider_version_number),
|
27
|
+
Sequel[:prv][:order].as(:provider_version_order),
|
28
|
+
)
|
29
|
+
.select_append{ verifications.* }
|
30
|
+
.join(:latest_verification_ids_for_consumer_version_tags,
|
31
|
+
{
|
32
|
+
Sequel[:verifications][:id] => Sequel[:lv][:latest_verification_id],
|
33
|
+
}, { table_alias: :lv })
|
34
|
+
.join(:versions,
|
35
|
+
{
|
36
|
+
Sequel[:verifications][:provider_version_id] => Sequel[:prv][:id]
|
37
|
+
}, { table_alias: :prv })
|
38
|
+
.join(:pact_versions,
|
39
|
+
{
|
40
|
+
Sequel[:verifications][:pact_version_id] => Sequel[:pv][:id]
|
41
|
+
}, { table_alias: :pv })
|
42
|
+
|
43
|
+
create_or_replace_view(:latest_verifications_for_consumer_version_tags, latest_verifications)
|
44
|
+
end
|
45
|
+
|
46
|
+
down do
|
47
|
+
drop_view(:latest_verifications_for_consumer_version_tags)
|
48
|
+
drop_view(:latest_verification_ids_for_consumer_version_tags)
|
49
|
+
end
|
50
|
+
end
|
@@ -0,0 +1,46 @@
|
|
1
|
+
Sequel.migration do
|
2
|
+
up do
|
3
|
+
# The latest verification id for each consumer version tag
|
4
|
+
create_view(:latest_verification_ids_for_consumer_and_provider,
|
5
|
+
"select
|
6
|
+
pv.pacticipant_id as provider_id,
|
7
|
+
lpp.consumer_id,
|
8
|
+
max(v.id) as latest_verification_id
|
9
|
+
from verifications v
|
10
|
+
join latest_pact_publications_by_consumer_versions lpp
|
11
|
+
on v.pact_version_id = lpp.pact_version_id
|
12
|
+
join versions pv
|
13
|
+
on v.provider_version_id = pv.id
|
14
|
+
group by pv.pacticipant_id, lpp.consumer_id")
|
15
|
+
|
16
|
+
# The most recent verification for each consumer/consumer version tag/provider
|
17
|
+
latest_verifications = from(:verifications)
|
18
|
+
.select(
|
19
|
+
Sequel[:lv][:consumer_id],
|
20
|
+
Sequel[:lv][:provider_id],
|
21
|
+
Sequel[:pv][:sha].as(:pact_version_sha),
|
22
|
+
Sequel[:prv][:number].as(:provider_version_number),
|
23
|
+
Sequel[:prv][:order].as(:provider_version_order),
|
24
|
+
)
|
25
|
+
.select_append{ verifications.* }
|
26
|
+
.join(:latest_verification_ids_for_consumer_and_provider,
|
27
|
+
{
|
28
|
+
Sequel[:verifications][:id] => Sequel[:lv][:latest_verification_id],
|
29
|
+
}, { table_alias: :lv })
|
30
|
+
.join(:versions,
|
31
|
+
{
|
32
|
+
Sequel[:verifications][:provider_version_id] => Sequel[:prv][:id]
|
33
|
+
}, { table_alias: :prv })
|
34
|
+
.join(:pact_versions,
|
35
|
+
{
|
36
|
+
Sequel[:verifications][:pact_version_id] => Sequel[:pv][:id]
|
37
|
+
}, { table_alias: :pv })
|
38
|
+
|
39
|
+
create_or_replace_view(:latest_verifications_for_consumer_and_provider, latest_verifications)
|
40
|
+
end
|
41
|
+
|
42
|
+
down do
|
43
|
+
drop_view(:latest_verifications_for_consumer_and_provider)
|
44
|
+
drop_view(:latest_verification_ids_for_consumer_and_provider)
|
45
|
+
end
|
46
|
+
end
|
@@ -34,11 +34,15 @@ module PactBroker
|
|
34
34
|
represented.body
|
35
35
|
end
|
36
36
|
end
|
37
|
-
|
38
37
|
end
|
39
38
|
|
40
|
-
property :
|
41
|
-
property :
|
39
|
+
property :message, exec_context: :decorator
|
40
|
+
# property :error, :extend => ErrorDecorator
|
41
|
+
# property :response, :extend => HTTPResponseDecorator
|
42
|
+
|
43
|
+
def message
|
44
|
+
"Webhook response has been redacted temporarily for security purposes. Please see the Pact Broker application logs for the response body."
|
45
|
+
end
|
42
46
|
|
43
47
|
link :webhook do | options |
|
44
48
|
{
|
@@ -27,13 +27,14 @@ module PactBroker
|
|
27
27
|
]
|
28
28
|
|
29
29
|
attr_accessor :log_dir, :database_connection, :auto_migrate_db, :use_hal_browser, :html_pact_renderer
|
30
|
-
attr_accessor :validate_database_connection_config, :enable_diagnostic_endpoints, :version_parser
|
30
|
+
attr_accessor :validate_database_connection_config, :enable_diagnostic_endpoints, :version_parser, :sha_generator
|
31
31
|
attr_accessor :use_case_sensitive_resource_names, :order_versions_by_date
|
32
32
|
attr_accessor :check_for_potential_duplicate_pacticipant_names
|
33
33
|
attr_accessor :semver_formats
|
34
34
|
attr_accessor :enable_public_badge_access, :shields_io_base_url
|
35
35
|
attr_accessor :webhook_retry_schedule
|
36
36
|
attr_accessor :disable_ssl_verification
|
37
|
+
attr_accessor :base_equality_only_on_content_that_affects_verification_results
|
37
38
|
attr_reader :api_error_reporters
|
38
39
|
attr_writer :logger
|
39
40
|
|
@@ -51,6 +52,8 @@ module PactBroker
|
|
51
52
|
|
52
53
|
def self.default_configuration
|
53
54
|
require 'pact_broker/versions/parse_semantic_version'
|
55
|
+
require 'pact_broker/pacts/generate_sha'
|
56
|
+
|
54
57
|
config = Configuration.new
|
55
58
|
config.log_dir = File.expand_path("./log")
|
56
59
|
config.auto_migrate_db = true
|
@@ -62,6 +65,8 @@ module PactBroker
|
|
62
65
|
config.use_case_sensitive_resource_names = true
|
63
66
|
config.html_pact_renderer = default_html_pact_render
|
64
67
|
config.version_parser = PactBroker::Versions::ParseSemanticVersion
|
68
|
+
config.sha_generator = PactBroker::Pacts::GenerateSha
|
69
|
+
config.base_equality_only_on_content_that_affects_verification_results = false
|
65
70
|
# Not recommended to set this to true unless there is no way to
|
66
71
|
# consistently extract an orderable object from the consumer application version number.
|
67
72
|
config.order_versions_by_date = false
|
@@ -114,18 +114,19 @@ module PactBroker
|
|
114
114
|
execution_logger.info(" ")
|
115
115
|
logger.info "Received response for webhook #{uuid} status=#{response.code}"
|
116
116
|
execution_logger.info "HTTP/#{response.http_version} #{response.code} #{response.message}"
|
117
|
-
response.each_header do | header |
|
118
|
-
|
119
|
-
end
|
117
|
+
#response.each_header do | header |
|
118
|
+
# execution_logger.info "#{header.split("-").collect(&:capitalize).join('-')}: #{response[header]}"
|
119
|
+
#end
|
120
120
|
logger.debug "body=#{response.body}"
|
121
|
-
safe_body = nil
|
122
|
-
if response.body
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
end
|
128
|
-
execution_logger.info safe_body
|
121
|
+
# safe_body = nil
|
122
|
+
# if response.body
|
123
|
+
# safe_body = response.body.encode('UTF-8', 'binary', invalid: :replace, undef: :replace, replace: '')
|
124
|
+
# if response.body != safe_body
|
125
|
+
# execution_logger.debug "Note that invalid UTF-8 byte sequences were removed from response body before saving the logs"
|
126
|
+
# end
|
127
|
+
# end
|
128
|
+
#execution_logger.info safe_body
|
129
|
+
execution_logger.info "Webhook response has been redacted temporarily for security purposes. Please see the Pact Broker application logs for the response body."
|
129
130
|
end
|
130
131
|
|
131
132
|
def log_completion_message options, execution_logger, success
|
@@ -1,8 +1,8 @@
|
|
1
1
|
require 'pact_broker/repositories'
|
2
2
|
require 'pact_broker/logging'
|
3
3
|
require 'pact_broker/domain/index_item'
|
4
|
-
require 'pact_broker/matrix/latest_row'
|
5
4
|
require 'pact_broker/matrix/head_row'
|
5
|
+
require 'pact_broker/matrix/aggregated_row'
|
6
6
|
|
7
7
|
module PactBroker
|
8
8
|
|
@@ -14,107 +14,37 @@ module PactBroker
|
|
14
14
|
extend PactBroker::Logging
|
15
15
|
|
16
16
|
def self.find_index_items options = {}
|
17
|
-
rows = []
|
18
|
-
overall_latest_publication_ids = nil
|
19
|
-
|
20
17
|
rows = PactBroker::Matrix::HeadRow
|
21
18
|
.select_all_qualified
|
22
19
|
.eager(:latest_triggered_webhooks)
|
23
20
|
.eager(:webhooks)
|
24
|
-
.order(:consumer_name, :provider_name)
|
25
|
-
.eager(:consumer_version_tags)
|
26
|
-
.eager(:provider_version_tags)
|
27
21
|
|
28
22
|
if !options[:tags]
|
29
|
-
rows = rows.where(consumer_version_tag_name: nil)
|
30
|
-
|
31
|
-
end
|
32
|
-
|
33
|
-
if options[:tags]
|
23
|
+
rows = rows.where(consumer_version_tag_name: nil)
|
24
|
+
else
|
34
25
|
if options[:tags].is_a?(Array)
|
35
26
|
rows = rows.where(consumer_version_tag_name: options[:tags]).or(consumer_version_tag_name: nil)
|
36
27
|
end
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
# Smoosh all the rows with matching pact publications together
|
42
|
-
# and collect their consumer_head_tag_names
|
43
|
-
rows = rows
|
44
|
-
.group_by(&:pact_publication_id)
|
45
|
-
.values
|
46
|
-
.collect{|group| [group.last, group.collect{|r| r[:consumer_version_tag_name]}.compact] }
|
47
|
-
.collect{ |(row, tag_names)| row.consumer_head_tag_names = tag_names; row }
|
28
|
+
rows = rows.eager(:consumer_version_tags)
|
29
|
+
.eager(:provider_version_tags)
|
30
|
+
.eager(:latest_verification_for_consumer_version_tag)
|
48
31
|
end
|
32
|
+
rows = rows.all.group_by(&:pact_publication_id).values.collect{ | rows| Matrix::AggregatedRow.new(rows) }
|
49
33
|
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
if options[:tags]
|
54
|
-
tag_names = row.consumer_version_tags.collect(&:name)
|
55
|
-
end
|
56
|
-
|
57
|
-
overall_latest = overall_latest_publication_ids.include?(row.pact_publication_id)
|
58
|
-
latest_verification = if overall_latest
|
59
|
-
verification_repository.find_latest_verification_for row.consumer_name, row.provider_name
|
60
|
-
else
|
61
|
-
tag_names.collect do | tag_name |
|
62
|
-
verification_repository.find_latest_verification_for row.consumer_name, row.provider_name, tag_name
|
63
|
-
end.compact.sort do | v1, v2 |
|
64
|
-
# Some provider versions have nil orders, not sure why
|
65
|
-
# Sort by execution_date instead of order
|
66
|
-
v1.execution_date <=> v2.execution_date
|
67
|
-
end.last
|
68
|
-
end
|
69
|
-
|
70
|
-
index_items << PactBroker::Domain::IndexItem.create(
|
34
|
+
rows.sort.collect do | row |
|
35
|
+
# TODO simplify. Do we really need 3 layers of abstraction?
|
36
|
+
PactBroker::Domain::IndexItem.create(
|
71
37
|
row.consumer,
|
72
38
|
row.provider,
|
73
39
|
row.pact,
|
74
|
-
overall_latest
|
75
|
-
latest_verification,
|
40
|
+
row.overall_latest?,
|
41
|
+
row.latest_verification,
|
76
42
|
row.webhooks,
|
77
43
|
row.latest_triggered_webhooks,
|
78
|
-
row.consumer_head_tag_names,
|
79
|
-
row.provider_version_tags.select(&:latest?)
|
44
|
+
options[:tags] ? row.consumer_head_tag_names : [],
|
45
|
+
options[:tags] ? row.provider_version_tags.select(&:latest?) : []
|
80
46
|
)
|
81
47
|
end
|
82
|
-
|
83
|
-
index_items
|
84
|
-
end
|
85
|
-
|
86
|
-
def self.tags_for(pact, options)
|
87
|
-
if options[:tags] == true
|
88
|
-
tag_service.find_all_tag_names_for_pacticipant(pact.consumer_name)
|
89
|
-
elsif options[:tags].is_a?(Array)
|
90
|
-
options[:tags]
|
91
|
-
else
|
92
|
-
[]
|
93
|
-
end
|
94
|
-
end
|
95
|
-
|
96
|
-
def self.build_index_item_rows(pact, tags)
|
97
|
-
index_items = [build_latest_pact_index_item(pact, tags)]
|
98
|
-
tags.each do | tag |
|
99
|
-
index_items << build_index_item_for_tagged_pact(pact, tag)
|
100
|
-
end
|
101
|
-
index_items.compact
|
102
|
-
end
|
103
|
-
|
104
|
-
def self.build_latest_pact_index_item pact, tags
|
105
|
-
latest_verification = verification_service.find_latest_verification_for(pact.consumer, pact.provider)
|
106
|
-
webhooks = webhook_service.find_by_consumer_and_provider pact.consumer, pact.provider
|
107
|
-
triggered_webhooks = webhook_service.find_latest_triggered_webhooks pact.consumer, pact.provider
|
108
|
-
tag_names = pact.consumer_version_tag_names.select{ |name| tags.include?(name) }
|
109
|
-
PactBroker::Domain::IndexItem.create pact.consumer, pact.provider, pact, true, latest_verification, webhooks, triggered_webhooks, tag_names
|
110
|
-
end
|
111
|
-
|
112
|
-
def self.build_index_item_for_tagged_pact latest_pact, tag
|
113
|
-
pact = pact_service.find_latest_pact consumer_name: latest_pact.consumer_name, provider_name: latest_pact.provider_name, tag: tag
|
114
|
-
return nil unless pact
|
115
|
-
return nil if pact.id == latest_pact.id
|
116
|
-
verification = verification_repository.find_latest_verification_for pact.consumer_name, pact.provider_name, tag
|
117
|
-
PactBroker::Domain::IndexItem.create pact.consumer, pact.provider, pact, false, verification, [], [], [tag]
|
118
48
|
end
|
119
49
|
end
|
120
50
|
end
|
@@ -0,0 +1,71 @@
|
|
1
|
+
require 'pact_broker/verifications/repository'
|
2
|
+
|
3
|
+
# A collection of matrix rows with the same pact publication id
|
4
|
+
# It's basically a normalised view of a denormalised view :(
|
5
|
+
# A pact publication may be the overall latest, and/or the latest for a tag
|
6
|
+
module PactBroker
|
7
|
+
module Matrix
|
8
|
+
class AggregatedRow
|
9
|
+
extend Forwardable
|
10
|
+
|
11
|
+
delegate [:consumer, :consumer_name, :consumer_version, :consumer_version_number, :consumer_version_order, :consumer_version_tags] => :first_row
|
12
|
+
delegate [:provider, :provider_name, :provider_version, :provider_version_number, :provider_version_order, :provider_version_tags] => :first_row
|
13
|
+
delegate [:pact, :pact_version, :pact_revision_number, :webhooks, :latest_triggered_webhooks, :'<=>'] => :first_row
|
14
|
+
delegate [:verification_id, :verification] => :first_row
|
15
|
+
|
16
|
+
def initialize matrix_rows
|
17
|
+
@matrix_rows = matrix_rows
|
18
|
+
@first_row = matrix_rows.first
|
19
|
+
end
|
20
|
+
|
21
|
+
def overall_latest?
|
22
|
+
!!matrix_rows.find{ | row| row.consumer_version_tag_name.nil? }
|
23
|
+
end
|
24
|
+
|
25
|
+
# If this comes back nil, it won't be "cached", but it's a reasonably
|
26
|
+
# quick query, so it's probably ok.
|
27
|
+
def latest_verification
|
28
|
+
@latest_verification ||= begin
|
29
|
+
verification = matrix_rows.collect do | row|
|
30
|
+
row.verification || latest_verification_for_consumer_version_tag(row)
|
31
|
+
end.compact.sort{ |v1, v2| v1.id <=> v2.id }.last
|
32
|
+
|
33
|
+
if !verification && overall_latest?
|
34
|
+
overall_latest_verification
|
35
|
+
else
|
36
|
+
verification
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
# The list of tag names for which this pact publication is the most recent with that tag
|
42
|
+
# There could, however, be a later consumer version that does't have a pact (perhaps because it was deleted)
|
43
|
+
# that has the same tag.
|
44
|
+
# TODO show a warning when the data is "corrupted" as above.
|
45
|
+
def consumer_head_tag_names
|
46
|
+
matrix_rows.collect(&:consumer_version_tag_name).compact
|
47
|
+
end
|
48
|
+
|
49
|
+
private
|
50
|
+
|
51
|
+
attr_reader :matrix_rows
|
52
|
+
|
53
|
+
def latest_verification_for_consumer_version_tag row
|
54
|
+
row.latest_verification_for_consumer_version_tag if row.consumer_version_tag_name
|
55
|
+
end
|
56
|
+
|
57
|
+
def overall_latest_verification
|
58
|
+
# not eager loaded because it shouldn't be called that often
|
59
|
+
first_row.latest_verification_for_consumer_and_provider
|
60
|
+
end
|
61
|
+
|
62
|
+
def first_row
|
63
|
+
@first_row
|
64
|
+
end
|
65
|
+
|
66
|
+
def consumer_version_tag_names
|
67
|
+
matrix_rows.collect(&:consumer_version_tag_name)
|
68
|
+
end
|
69
|
+
end
|
70
|
+
end
|
71
|
+
end
|