pact_broker 2.59.1 → 2.62.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 +53 -0
- data/README.md +1 -1
- data/db/migrations/20200922_add_event_to_triggered_webhook.rb +5 -0
- data/lib/pact_broker/api/contracts/verifiable_pacts_json_query_schema.rb +10 -3
- data/lib/pact_broker/api/contracts/verifiable_pacts_query_schema.rb +1 -0
- data/lib/pact_broker/api/decorators/triggered_webhook_decorator.rb +1 -0
- data/lib/pact_broker/api/decorators/verifiable_pact_decorator.rb +5 -5
- data/lib/pact_broker/api/pact_broker_urls.rb +9 -2
- data/lib/pact_broker/api/resources/all_webhooks.rb +1 -6
- data/lib/pact_broker/api/resources/can_i_deploy.rb +0 -4
- data/lib/pact_broker/api/resources/default_base_resource.rb +9 -0
- data/lib/pact_broker/api/resources/error_handler.rb +2 -4
- data/lib/pact_broker/api/resources/error_test.rb +4 -2
- data/lib/pact_broker/api/resources/group.rb +0 -4
- data/lib/pact_broker/api/resources/index.rb +11 -8
- data/lib/pact_broker/api/resources/integration.rb +0 -4
- data/lib/pact_broker/api/resources/integrations.rb +0 -4
- data/lib/pact_broker/api/resources/label.rb +0 -8
- data/lib/pact_broker/api/resources/latest_pact.rb +1 -5
- data/lib/pact_broker/api/resources/latest_pacts.rb +1 -5
- data/lib/pact_broker/api/resources/latest_verifications_for_consumer_version.rb +0 -4
- data/lib/pact_broker/api/resources/matrix.rb +4 -0
- data/lib/pact_broker/api/resources/matrix_for_consumer_and_provider.rb +4 -0
- data/lib/pact_broker/api/resources/metrics.rb +4 -0
- data/lib/pact_broker/api/resources/pact.rb +4 -8
- data/lib/pact_broker/api/resources/pact_content_diff.rb +4 -0
- data/lib/pact_broker/api/resources/pact_triggered_webhooks.rb +5 -1
- data/lib/pact_broker/api/resources/pact_versions.rb +5 -1
- data/lib/pact_broker/api/resources/pact_webhooks.rb +5 -1
- data/lib/pact_broker/api/resources/pact_webhooks_status.rb +5 -1
- data/lib/pact_broker/api/resources/pacticipant.rb +5 -9
- data/lib/pact_broker/api/resources/pacticipants.rb +0 -4
- data/lib/pact_broker/api/resources/pacticipants_for_label.rb +4 -0
- data/lib/pact_broker/api/resources/previous_distinct_pact_version.rb +4 -9
- data/lib/pact_broker/api/resources/provider_pacts.rb +1 -5
- data/lib/pact_broker/api/resources/provider_pacts_for_verification.rb +8 -6
- data/lib/pact_broker/api/resources/relationships.rb +4 -2
- data/lib/pact_broker/api/resources/tag.rb +5 -5
- data/lib/pact_broker/api/resources/tagged_pact_versions.rb +5 -2
- data/lib/pact_broker/api/resources/triggered_webhook_logs.rb +7 -5
- data/lib/pact_broker/api/resources/verification.rb +5 -5
- data/lib/pact_broker/api/resources/verification_triggered_webhooks.rb +6 -12
- data/lib/pact_broker/api/resources/verifications.rb +5 -5
- data/lib/pact_broker/api/resources/version.rb +5 -5
- data/lib/pact_broker/api/resources/versions.rb +5 -2
- data/lib/pact_broker/api/resources/webhook.rb +4 -0
- data/lib/pact_broker/api/resources/webhook_execution.rb +4 -0
- data/lib/pact_broker/api/resources/webhooks.rb +5 -1
- data/lib/pact_broker/app.rb +1 -1
- data/lib/pact_broker/badges/service.rb +1 -1
- data/lib/pact_broker/certificates/service.rb +2 -2
- data/lib/pact_broker/configuration.rb +21 -1
- data/lib/pact_broker/db.rb +14 -0
- data/lib/pact_broker/db/table_dependency_calculator.rb +45 -0
- data/lib/pact_broker/doc/views/provider-pacts-for-verification.markdown +78 -0
- data/lib/pact_broker/domain/pact.rb +9 -0
- data/lib/pact_broker/domain/webhook_request.rb +3 -1
- data/lib/pact_broker/matrix/deployment_status_summary.rb +1 -1
- data/lib/pact_broker/pacts/build_verifiable_pact_notices.rb +7 -4
- data/lib/pact_broker/pacts/content.rb +30 -5
- data/lib/pact_broker/pacts/repository.rb +25 -31
- data/lib/pact_broker/pacts/selector.rb +8 -0
- data/lib/pact_broker/test/test_data_builder.rb +1 -1
- data/lib/pact_broker/version.rb +1 -1
- data/lib/pact_broker/webhooks/job.rb +8 -2
- data/lib/pact_broker/webhooks/repository.rb +3 -2
- data/lib/pact_broker/webhooks/service.rb +2 -2
- data/lib/pact_broker/webhooks/triggered_webhook.rb +1 -3
- data/lib/pact_broker/webhooks/webhook_event.rb +1 -2
- data/script/seed.rb +39 -17
- data/spec/features/get_provider_pacts_for_verification_spec.rb +8 -0
- data/spec/lib/pact_broker/api/contracts/verifiable_pacts_json_query_schema_spec.rb +23 -4
- data/spec/lib/pact_broker/api/decorators/pact_webhooks_status_decorator_spec.rb +2 -1
- data/spec/lib/pact_broker/api/decorators/triggered_webhook_decorator_spec.rb +3 -1
- data/spec/lib/pact_broker/api/pact_broker_urls_spec.rb +15 -0
- data/spec/lib/pact_broker/api/resources/default_base_resource_spec.rb +10 -5
- data/spec/lib/pact_broker/api/resources/error_handler_spec.rb +18 -1
- data/spec/lib/pact_broker/api/resources/provider_pacts_for_verification_spec.rb +1 -1
- data/spec/lib/pact_broker/api/resources/verification_triggered_webhooks_spec.rb +0 -1
- data/spec/lib/pact_broker/badges/service_spec.rb +1 -1
- data/spec/lib/pact_broker/certificates/service_spec.rb +3 -3
- data/spec/lib/pact_broker/pacts/content_spec.rb +90 -0
- data/spec/lib/pact_broker/pacts/repository_find_for_verification_fallback_spec.rb +14 -0
- data/spec/lib/pact_broker/pacts/repository_find_for_verification_spec.rb +62 -0
- data/spec/lib/pact_broker/webhooks/job_spec.rb +19 -1
- data/spec/lib/pact_broker/webhooks/repository_spec.rb +3 -2
- data/spec/lib/pact_broker/webhooks/service_spec.rb +2 -2
- data/spec/support/database_cleaner.rb +1 -5
- data/tasks/database.rb +1 -0
- data/tasks/database/table_dependency_calculator.rb +4 -41
- metadata +5 -2
@@ -6,7 +6,6 @@ module PactBroker
|
|
6
6
|
module Api
|
7
7
|
module Resources
|
8
8
|
class Versions < BaseResource
|
9
|
-
|
10
9
|
def content_types_provided
|
11
10
|
[["application/hal+json", :to_json]]
|
12
11
|
end
|
@@ -24,7 +23,11 @@ module PactBroker
|
|
24
23
|
end
|
25
24
|
|
26
25
|
def versions
|
27
|
-
pacticipant_service.find_all_pacticipant_versions_in_reverse_order pacticipant_name
|
26
|
+
@versions ||= pacticipant_service.find_all_pacticipant_versions_in_reverse_order pacticipant_name
|
27
|
+
end
|
28
|
+
|
29
|
+
def policy_name
|
30
|
+
:'versions::versions'
|
28
31
|
end
|
29
32
|
end
|
30
33
|
end
|
@@ -50,10 +50,14 @@ module PactBroker
|
|
50
50
|
Decorators::WebhooksDecorator.new(webhooks).to_json(decorator_options(resource_title: 'Pact webhooks'))
|
51
51
|
end
|
52
52
|
|
53
|
+
def policy_name
|
54
|
+
:'webhooks::webhooks'
|
55
|
+
end
|
56
|
+
|
53
57
|
private
|
54
58
|
|
55
59
|
def webhooks
|
56
|
-
webhook_service.find_by_consumer_and_provider
|
60
|
+
webhook_service.find_by_consumer_and_provider(consumer, provider)
|
57
61
|
end
|
58
62
|
|
59
63
|
def webhook
|
data/lib/pact_broker/app.rb
CHANGED
@@ -227,7 +227,7 @@ module PactBroker
|
|
227
227
|
|
228
228
|
def configure_sucker_punch
|
229
229
|
SuckerPunch.exception_handler = -> (ex, klass, args) do
|
230
|
-
PactBroker.
|
230
|
+
PactBroker.logger.warn("Unhandled Suckerpunch error for #{klass}.perform(#{args.inspect})", ex)
|
231
231
|
end
|
232
232
|
end
|
233
233
|
|
@@ -100,7 +100,7 @@ module PactBroker
|
|
100
100
|
logger.warn "Timeout retrieving badge from #{uri} #{e.class} - #{e.message}"
|
101
101
|
nil
|
102
102
|
rescue StandardError => e
|
103
|
-
|
103
|
+
logger.warn("Error retrieving badge from #{uri}", e)
|
104
104
|
nil
|
105
105
|
end
|
106
106
|
end
|
@@ -18,7 +18,7 @@ module PactBroker
|
|
18
18
|
logger.debug("Loading certificate #{certificate.subject} in to cert store")
|
19
19
|
cert_store.add_cert(certificate)
|
20
20
|
rescue StandardError => e
|
21
|
-
|
21
|
+
logger.warn("Error adding certificate object #{certificate.to_s} to store", e)
|
22
22
|
end
|
23
23
|
end
|
24
24
|
cert_store
|
@@ -31,7 +31,7 @@ module PactBroker
|
|
31
31
|
begin
|
32
32
|
OpenSSL::X509::Certificate.new(c)
|
33
33
|
rescue StandardError => e
|
34
|
-
|
34
|
+
logger.warn("Error creating certificate object from certificate #{certificate.uuid} '#{certificate.description}'", e)
|
35
35
|
nil
|
36
36
|
end
|
37
37
|
end
|
@@ -31,12 +31,19 @@ module PactBroker
|
|
31
31
|
:webhook_host_whitelist,
|
32
32
|
:base_equality_only_on_content_that_affects_verification_results,
|
33
33
|
:seed_example_data,
|
34
|
-
:badge_provider_mode
|
34
|
+
:badge_provider_mode,
|
35
|
+
:warning_error_class_names,
|
36
|
+
:base_url,
|
37
|
+
:log_dir,
|
38
|
+
:allow_missing_migration_files,
|
39
|
+
:auto_migrate_db_data,
|
40
|
+
:use_rack_protection
|
35
41
|
]
|
36
42
|
|
37
43
|
attr_accessor :base_url, :log_dir, :database_connection, :auto_migrate_db, :auto_migrate_db_data, :allow_missing_migration_files, :example_data_seeder, :seed_example_data, :use_hal_browser, :html_pact_renderer, :use_rack_protection
|
38
44
|
attr_accessor :validate_database_connection_config, :enable_diagnostic_endpoints, :version_parser, :sha_generator
|
39
45
|
attr_accessor :use_case_sensitive_resource_names, :order_versions_by_date
|
46
|
+
attr_accessor :warning_error_class_names
|
40
47
|
attr_accessor :check_for_potential_duplicate_pacticipant_names
|
41
48
|
attr_accessor :webhook_retry_schedule
|
42
49
|
attr_reader :webhook_http_method_whitelist, :webhook_scheme_whitelist, :webhook_host_whitelist
|
@@ -115,6 +122,7 @@ module PactBroker
|
|
115
122
|
require 'pact_broker/api/resources/default_base_resource'
|
116
123
|
PactBroker::Api::Resources::DefaultBaseResource
|
117
124
|
}
|
125
|
+
config.warning_error_class_names = ['Sequel::ForeignKeyConstraintViolation']
|
118
126
|
config
|
119
127
|
end
|
120
128
|
|
@@ -126,6 +134,12 @@ module PactBroker
|
|
126
134
|
@custom_logger = logger
|
127
135
|
end
|
128
136
|
|
137
|
+
def log_configuration
|
138
|
+
SAVABLE_SETTING_NAMES.sort.each do | setting |
|
139
|
+
logger.info "PactBroker.configuration.#{setting}=#{PactBroker.configuration.send(setting).inspect}"
|
140
|
+
end
|
141
|
+
end
|
142
|
+
|
129
143
|
def self.default_html_pact_render
|
130
144
|
lambda { |pact, options|
|
131
145
|
require 'pact_broker/api/renderers/html_pact_renderer'
|
@@ -228,6 +242,12 @@ module PactBroker
|
|
228
242
|
@webhook_host_whitelist = parse_space_delimited_string_list_property('webhook_host_whitelist', webhook_host_whitelist)
|
229
243
|
end
|
230
244
|
|
245
|
+
def warning_error_classes
|
246
|
+
warning_error_class_names.collect do | class_name |
|
247
|
+
Object.const_get(class_name)
|
248
|
+
end
|
249
|
+
end
|
250
|
+
|
231
251
|
private
|
232
252
|
|
233
253
|
def parse_space_delimited_string_list_property property_name, property_value
|
data/lib/pact_broker/db.rb
CHANGED
@@ -3,6 +3,7 @@ require 'pact_broker/db/validate_encoding'
|
|
3
3
|
require 'pact_broker/db/migrate'
|
4
4
|
require 'pact_broker/db/migrate_data'
|
5
5
|
require 'pact_broker/db/version'
|
6
|
+
require 'pact_broker/db/table_dependency_calculator'
|
6
7
|
|
7
8
|
Sequel.datetime_class = DateTime
|
8
9
|
|
@@ -31,6 +32,19 @@ module PactBroker
|
|
31
32
|
Sequel::TimestampMigrator.is_current?(database_connection, PactBroker::DB::MIGRATIONS_DIR, options)
|
32
33
|
end
|
33
34
|
|
35
|
+
def self.truncate database_connection, options = {}
|
36
|
+
exceptions = options[:except] || []
|
37
|
+
TableDependencyCalculator.call(database_connection).each do | table_name |
|
38
|
+
if !exceptions.include?(table_name)
|
39
|
+
begin
|
40
|
+
database_connection[table_name].truncate
|
41
|
+
rescue StandardError => e
|
42
|
+
puts "Could not truncate table #{table_name}"
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
34
48
|
def self.version database_connection
|
35
49
|
PactBroker::DB::Version.call(database_connection)
|
36
50
|
end
|
@@ -0,0 +1,45 @@
|
|
1
|
+
module PactBroker
|
2
|
+
module DB
|
3
|
+
|
4
|
+
# Returns a list of the tables in the database in the order in which
|
5
|
+
# they can be truncated or dropped
|
6
|
+
class TableDependencyCalculator
|
7
|
+
|
8
|
+
def self.call connection
|
9
|
+
new(connection).call
|
10
|
+
end
|
11
|
+
|
12
|
+
def initialize connection
|
13
|
+
@connection = connection
|
14
|
+
end
|
15
|
+
|
16
|
+
def call
|
17
|
+
ordered_table_names = []
|
18
|
+
dependencies = @connection
|
19
|
+
.tables
|
20
|
+
.collect{|it| @connection.foreign_key_list(it)
|
21
|
+
.collect{|fk| {from: it, to: fk[:table]} } }
|
22
|
+
.flatten
|
23
|
+
.uniq
|
24
|
+
table_names = @connection.tables - [:schema_migrations, :schema_info]
|
25
|
+
check(table_names, dependencies, ordered_table_names)
|
26
|
+
ordered_table_names
|
27
|
+
end
|
28
|
+
|
29
|
+
def deps_on table_name, deps
|
30
|
+
deps.select{ | d| d[:to] == table_name }.collect{ |d| d[:from] }
|
31
|
+
end
|
32
|
+
|
33
|
+
def check table_names, deps, ordered_table_names
|
34
|
+
return if table_names.size == 0
|
35
|
+
remaining_dependencies = deps_on(table_names.first, deps) - ordered_table_names
|
36
|
+
if remaining_dependencies.size == 0
|
37
|
+
ordered_table_names << table_names.first
|
38
|
+
check(table_names[1..-1], deps, ordered_table_names)
|
39
|
+
else
|
40
|
+
check((remaining_dependencies + table_names).uniq, deps, ordered_table_names)
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
@@ -0,0 +1,78 @@
|
|
1
|
+
# Provider pacts for verification
|
2
|
+
|
3
|
+
Path: `/pacts/provider/{provider}/for-verification`
|
4
|
+
|
5
|
+
Allowed methods: `POST`
|
6
|
+
|
7
|
+
Content type: `application/hal+json`
|
8
|
+
|
9
|
+
Returns a deduplicated list of pacts to be verified by the specified provider.
|
10
|
+
|
11
|
+
### Body
|
12
|
+
|
13
|
+
Example: This data structure represents the way a user might specify "I want to verify the latest 'master' pact, all 'prod' pacts, and when I publish the verification results, I'm going to tag the provider version with 'master'"
|
14
|
+
|
15
|
+
{
|
16
|
+
"consumerVersionSelectors": [
|
17
|
+
{
|
18
|
+
"tag": "master",
|
19
|
+
"latest": true
|
20
|
+
},{
|
21
|
+
"tag": "prod"
|
22
|
+
}
|
23
|
+
],
|
24
|
+
"providerVersionTags": ["master"],
|
25
|
+
"includePendingStatus": true,
|
26
|
+
"includeWipPactsSince": "2020-01-01"
|
27
|
+
}
|
28
|
+
|
29
|
+
|
30
|
+
`consumerVersionSelectors.tag`: the tag name(s) of the consumer versions to get the pacts for.
|
31
|
+
|
32
|
+
`consumerVersionSelectors.fallbackTag`: the name of the tag to fallback to if the specified `tag` does not exist. This is useful when the consumer and provider use matching branch names to coordinate the development of new features.
|
33
|
+
|
34
|
+
`consumerVersionSelectors.latest`: true. If the latest flag is omitted, *all* the pacts with the specified tag will be returned. (This might seem a bit weird, but it's done this way to match the syntax used for the matrix query params. See https://docs.pact.io/selectors)
|
35
|
+
|
36
|
+
`consumerVersionSelectors.consumer`: allows a selector to only be applied to a certain consumer. This is used when there is an API that has multiple consumers, one of which is a deployed service, and one of which is a mobile consumer. The deployed service only needs the latest production pact verified, where as the mobile consumer may want all the production pacts verified.
|
37
|
+
|
38
|
+
`providerVersionTags`: the tag name(s) for the provider application version that will be published with the verification results. This is used by the Broker to determine whether or not a particular pact is in pending state or not. This parameter can be specified multiple times.
|
39
|
+
|
40
|
+
`includePendingStatus`: true|false (default false). When true, a pending boolean will be added to the verificationProperties in the response, and an extra message will appear in the notices array to indicate why this pact is/is not in pending state. This will allow your code to handle the response based on only what is present in the response, and not have to do ifs based on the user's options together with the response. As requested in the "pacts for verification" issue, please print out these messages in the tests if possible. If not possible, perhaps create a separate task which will list the pact URLs and messages for debugging purposes.
|
41
|
+
|
42
|
+
`includeWipPactsSince`: Date string. The date from which to include the "work in progress" pacts. See https://docs.pact.io/wip for more information on work in progress pacts.
|
43
|
+
|
44
|
+
### Response body
|
45
|
+
|
46
|
+
`pending` flag and the "pending reason" notice will only be included if `includePendingStatus` is set to true.
|
47
|
+
|
48
|
+
|
49
|
+
{
|
50
|
+
"_embedded": {
|
51
|
+
"pacts": [
|
52
|
+
{
|
53
|
+
"verificationProperties": {
|
54
|
+
"notices": [
|
55
|
+
{
|
56
|
+
"text": "This pact is being verified because it is the pact for the latest version of Foo tagged with 'dev'",
|
57
|
+
"when": "before_verification"
|
58
|
+
}
|
59
|
+
],
|
60
|
+
"pending": false
|
61
|
+
},
|
62
|
+
"_links": {
|
63
|
+
"self": {
|
64
|
+
"href": "http://localhost:9292/pacts/provider/Bar/consumer/Foo/pact-version/0e3369199f4008231946e0245474537443ccda2a",
|
65
|
+
"name": "Pact between Foo (v1.0.0) and Bar"
|
66
|
+
}
|
67
|
+
}
|
68
|
+
}
|
69
|
+
]
|
70
|
+
},
|
71
|
+
"_links": {
|
72
|
+
"self": {
|
73
|
+
"href": "http://localhost:9292/pacts/provider/Bar/for-verification",
|
74
|
+
"title": "Pacts to be verified"
|
75
|
+
}
|
76
|
+
}
|
77
|
+
}
|
78
|
+
|
@@ -1,5 +1,6 @@
|
|
1
1
|
require 'pact_broker/db'
|
2
2
|
require 'pact_broker/json'
|
3
|
+
require 'pact_broker/pacts/content'
|
3
4
|
|
4
5
|
=begin
|
5
6
|
This class most accurately represents a PactPublication
|
@@ -76,6 +77,14 @@ module PactBroker
|
|
76
77
|
JSON.parse(json_content, PACT_PARSING_OPTIONS)
|
77
78
|
end
|
78
79
|
|
80
|
+
def content_object
|
81
|
+
@content_object ||= begin
|
82
|
+
PactBroker::Pacts::Content.from_json(json_content)
|
83
|
+
rescue
|
84
|
+
PactBroker::Pacts::Content.new
|
85
|
+
end
|
86
|
+
end
|
87
|
+
|
79
88
|
def pact_publication_id
|
80
89
|
id
|
81
90
|
end
|
@@ -59,7 +59,9 @@ module PactBroker
|
|
59
59
|
|
60
60
|
def http_request
|
61
61
|
@http_request ||= begin
|
62
|
-
req = Net::HTTP.const_get(method.capitalize).new(
|
62
|
+
req = Net::HTTP.const_get(method.capitalize).new(uri.request_uri)
|
63
|
+
req.delete("accept-encoding")
|
64
|
+
req.delete("user-agent")
|
63
65
|
headers.each_pair { | name, value | req[name] = value }
|
64
66
|
req.basic_auth(username, password) if username && username.size > 0
|
65
67
|
req.body = body unless body.nil?
|
@@ -195,7 +195,7 @@ module PactBroker
|
|
195
195
|
InteractionsMissingVerifications.new(selector_for(row.consumer_name), selector_for(row.provider_name), row.verification.interactions_missing_test_results)
|
196
196
|
end
|
197
197
|
rescue StandardError => e
|
198
|
-
|
198
|
+
logger.warn("Error determining if there were missing interaction verifications", e)
|
199
199
|
nil
|
200
200
|
end
|
201
201
|
end.compact.tap { |it| report_missing_interaction_verifications(it) if it.any? }
|
@@ -7,10 +7,13 @@ module PactBroker
|
|
7
7
|
def self.call(verifiable_pact, pact_url, options)
|
8
8
|
messages = VerifiablePactMessages.new(verifiable_pact, pact_url)
|
9
9
|
|
10
|
-
notices = [
|
11
|
-
|
12
|
-
|
13
|
-
|
10
|
+
notices = []
|
11
|
+
|
12
|
+
if options[:deprecated]
|
13
|
+
append_notice(notices, 'before_verification', 'WARNING - this version of the Pact library uses a beta version of the API which will be removed in the future. Please upgrade your Pact library. See https://docs.pact.io/pact_broker/advanced_topics/provider_verification_results/#pacts-for-verification for minimum required versions.')
|
14
|
+
end
|
15
|
+
|
16
|
+
append_notice(notices, 'before_verification', messages.inclusion_reason)
|
14
17
|
|
15
18
|
if options[:include_pending_status]
|
16
19
|
append_notice(notices, 'before_verification', messages.pending_reason)
|
@@ -32,15 +32,22 @@ module PactBroker
|
|
32
32
|
end
|
33
33
|
|
34
34
|
def interactions_missing_test_results
|
35
|
-
|
35
|
+
return [] unless messages_or_interactions
|
36
|
+
messages_or_interactions.reject do | interaction |
|
36
37
|
interaction['tests']&.any?
|
37
38
|
end
|
38
39
|
end
|
39
40
|
|
40
41
|
def with_test_results(test_results)
|
41
|
-
|
42
|
-
if
|
43
|
-
tests =
|
42
|
+
# new format
|
43
|
+
if test_results.is_a?(Array)
|
44
|
+
tests = test_results
|
45
|
+
else
|
46
|
+
# old format
|
47
|
+
tests = test_results && test_results['tests']
|
48
|
+
if tests.nil? || !tests.is_a?(Array) || tests.empty?
|
49
|
+
tests = []
|
50
|
+
end
|
44
51
|
end
|
45
52
|
|
46
53
|
new_pact_hash = pact_hash.dup
|
@@ -66,6 +73,12 @@ module PactBroker
|
|
66
73
|
Content.from_hash(new_pact_hash)
|
67
74
|
end
|
68
75
|
|
76
|
+
def interaction_ids
|
77
|
+
messages_or_interaction_or_empty_array.collect do | interaction |
|
78
|
+
interaction['_id']
|
79
|
+
end.compact
|
80
|
+
end
|
81
|
+
|
69
82
|
# Half thinking this belongs in GenerateSha
|
70
83
|
def content_that_affects_verification_results
|
71
84
|
if interactions || messages
|
@@ -91,6 +104,10 @@ module PactBroker
|
|
91
104
|
messages || interactions
|
92
105
|
end
|
93
106
|
|
107
|
+
def messages_or_interaction_or_empty_array
|
108
|
+
messages_or_interactions || []
|
109
|
+
end
|
110
|
+
|
94
111
|
def pact_specification_version
|
95
112
|
maybe_pact_specification_version_1 = pact_hash['metadata']['pactSpecification']['version'] rescue nil
|
96
113
|
maybe_pact_specification_version_2 = pact_hash['metadata']['pact-specification']['version'] rescue nil
|
@@ -129,7 +146,15 @@ module PactBroker
|
|
129
146
|
end
|
130
147
|
|
131
148
|
def test_is_for_interaction(interaction, test)
|
132
|
-
test.is_a?(Hash) && interaction.is_a?(Hash) &&
|
149
|
+
test.is_a?(Hash) && interaction.is_a?(Hash) && ( interaction_ids_match(interaction, test) || description_and_state_match(interaction, test))
|
150
|
+
end
|
151
|
+
|
152
|
+
def interaction_ids_match(interaction, test)
|
153
|
+
interaction['_id'] && interaction['_id'] == test['interactionId']
|
154
|
+
end
|
155
|
+
|
156
|
+
def description_and_state_match(interaction, test)
|
157
|
+
test['interactionDescription'] && test['interactionDescription'] == interaction['description'] && test['interactionProviderState'] == interaction['providerState']
|
133
158
|
end
|
134
159
|
end
|
135
160
|
end
|
@@ -405,42 +405,37 @@ module PactBroker
|
|
405
405
|
SelectedPact.new(pact_publication.to_domain, Selectors.create_for_overall_latest)
|
406
406
|
end
|
407
407
|
else
|
408
|
-
|
408
|
+
selectors_for_overall_latest = consumer_version_selectors.select(&:overall_latest?)
|
409
|
+
selectors_for_overall_latest.flat_map do | selector |
|
410
|
+
query = scope_for(LatestPactPublications).provider(provider_name)
|
411
|
+
query = query.consumer(selector.consumer) if selector.consumer
|
412
|
+
query.collect do | latest_pact_publication |
|
413
|
+
pact_publication = PactPublication.find(id: latest_pact_publication.id)
|
414
|
+
resolved_selector = selector.consumer ? Selector.latest_for_consumer(selector.consumer) : Selector.overall_latest
|
415
|
+
SelectedPact.new(pact_publication.to_domain, Selectors.new(resolved_selector))
|
416
|
+
end
|
417
|
+
end
|
409
418
|
end
|
410
419
|
end
|
411
420
|
|
412
421
|
def find_pacts_for_which_the_latest_version_for_the_tag_is_required(provider_name, consumer_version_selectors)
|
413
422
|
# The tags for which only the latest version is specified
|
414
|
-
|
423
|
+
selectors = consumer_version_selectors.select(&:latest_for_tag?)
|
415
424
|
|
416
|
-
|
417
|
-
|
418
|
-
|
419
|
-
|
420
|
-
.
|
421
|
-
.
|
422
|
-
.
|
423
|
-
|
424
|
-
|
425
|
-
|
426
|
-
|
427
|
-
end
|
428
|
-
else
|
429
|
-
[]
|
425
|
+
selectors.flat_map do | selector |
|
426
|
+
query = scope_for(LatestTaggedPactPublications).where(tag_name: selector.tag).provider(provider_name)
|
427
|
+
query = query.consumer(selector.consumer) if selector.consumer
|
428
|
+
query.all.collect do | latest_tagged_pact_publication |
|
429
|
+
pact_publication = PactPublication.find(id: latest_tagged_pact_publication.id)
|
430
|
+
resolved_pact = selector.consumer ? Selector.latest_for_tag_and_consumer(selector.tag, selector.consumer) : Selector.latest_for_tag(selector.tag)
|
431
|
+
SelectedPact.new(
|
432
|
+
pact_publication.to_domain,
|
433
|
+
Selectors.new(resolved_pact)
|
434
|
+
)
|
435
|
+
end
|
430
436
|
end
|
431
437
|
end
|
432
438
|
|
433
|
-
def create_selected_pact(pact_publications)
|
434
|
-
selector_tag_names = pact_publications.collect(&:tag_name)
|
435
|
-
selectors = Selectors.create_for_latest_of_each_tag(selector_tag_names)
|
436
|
-
last_pact_publication = pact_publications.sort_by(&:consumer_version_order).last
|
437
|
-
pact_publication = scope_for(PactPublication).find(id: last_pact_publication.id)
|
438
|
-
SelectedPact.new(
|
439
|
-
pact_publication.to_domain,
|
440
|
-
selectors
|
441
|
-
)
|
442
|
-
end
|
443
|
-
|
444
439
|
def create_fallback_selected_pact(pact_publications, consumer_version_selectors)
|
445
440
|
selector_tag_names = pact_publications.collect(&:tag_name)
|
446
441
|
selectors = Selectors.create_for_latest_fallback_of_each_tag(selector_tag_names)
|
@@ -454,10 +449,9 @@ module PactBroker
|
|
454
449
|
|
455
450
|
def find_pacts_for_which_the_latest_version_for_the_fallback_tag_is_required(provider_name, selectors)
|
456
451
|
selectors.collect do | selector |
|
457
|
-
scope_for(LatestTaggedPactPublications)
|
458
|
-
|
459
|
-
|
460
|
-
.all
|
452
|
+
query = scope_for(LatestTaggedPactPublications).provider(provider_name).where(tag_name: selector.fallback_tag)
|
453
|
+
query = query.consumer(selector.consumer) if selector.consumer
|
454
|
+
query.all
|
461
455
|
.collect do | latest_tagged_pact_publication |
|
462
456
|
pact_publication = unscoped(PactPublication).find(id: latest_tagged_pact_publication.id)
|
463
457
|
SelectedPact.new(
|