pact_broker 2.45.0 → 2.46.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (34) hide show
  1. checksums.yaml +4 -4
  2. data/.travis.yml +0 -13
  3. data/CHANGELOG.md +21 -0
  4. data/lib/db.rb +7 -1
  5. data/lib/pact_broker/api/contracts/verifiable_pacts_json_query_schema.rb +1 -1
  6. data/lib/pact_broker/api/contracts/verifiable_pacts_query_schema.rb +1 -1
  7. data/lib/pact_broker/api/decorators/triggered_webhook_decorator.rb +9 -1
  8. data/lib/pact_broker/api/decorators/verifiable_pact_decorator.rb +24 -16
  9. data/lib/pact_broker/api/decorators/verifiable_pacts_query_decorator.rb +1 -1
  10. data/lib/pact_broker/api/resources/base_resource.rb +1 -1
  11. data/lib/pact_broker/api/resources/triggered_webhook_logs.rb +1 -1
  12. data/lib/pact_broker/app.rb +7 -2
  13. data/lib/pact_broker/configuration.rb +1 -5
  14. data/lib/pact_broker/matrix/repository.rb +2 -2
  15. data/lib/pact_broker/pacts/pact_publication.rb +53 -0
  16. data/lib/pact_broker/pacts/pact_version.rb +16 -6
  17. data/lib/pact_broker/pacts/repository.rb +81 -27
  18. data/lib/pact_broker/pacts/verifiable_pact_messages.rb +30 -0
  19. data/lib/pact_broker/repositories/helpers.rb +4 -0
  20. data/lib/pact_broker/test/test_data_builder.rb +4 -0
  21. data/lib/pact_broker/version.rb +1 -1
  22. data/pact_broker.gemspec +1 -1
  23. data/script/generate-certificates-for-webooks-certificate-spec.rb +8 -0
  24. data/script/release.sh +4 -3
  25. data/script/seed-for-webhook-test.rb +59 -0
  26. data/spec/lib/pact_broker/api/contracts/verifiable_pacts_json_query_schema_spec.rb +1 -1
  27. data/spec/lib/pact_broker/api/contracts/verifiable_pacts_query_schema_spec.rb +1 -1
  28. data/spec/lib/pact_broker/api/decorators/triggered_webhook_decorator_spec.rb +1 -1
  29. data/spec/lib/pact_broker/api/decorators/verifiable_pact_decorator_spec.rb +24 -2
  30. data/spec/lib/pact_broker/api/resources/base_resource_spec.rb +23 -1
  31. data/spec/lib/pact_broker/pacts/repository_find_for_verification_spec.rb +55 -12
  32. data/spec/support/verification_job.rb +2 -0
  33. metadata +5 -5
  34. data/lib/rack/pact_broker/store_base_url.rb +0 -14
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: '018d04fa3d6dbb44832534462f7fbb54d033ffdbabd390ed155507ee126b51d4'
4
- data.tar.gz: 404a22118fe03caa9dc0891b610aaf92211cb7f3417a465ed7ed80a6f27abb94
3
+ metadata.gz: e4afa0b6a3444f1fdf6ea852bed8016f63cccd1a5373aa0903be0d206f528bc6
4
+ data.tar.gz: cd86a0d032bb39ffe2f4318116cc9e51886fc3d3e84bf8c537d6bae5ee0f9d52
5
5
  SHA512:
6
- metadata.gz: 1f6e74be59f0704398d686b4de7f6ca8b3fda020b8ba7ba92c9743ead1b580cda709631bf03f325024b92755b6ee50eb969f961e5d97203a36f506101ee9456a
7
- data.tar.gz: 9a3a640ce7ac8f942de1150d1641c29db951cc9947371bfd0bdd6d1dd7139e3a815fba0fd400b247e344737cb30447eae856cc0f157e25a934d53e2d49a342c1
6
+ metadata.gz: 217a6da9c4b27d6959695eefa1c6b8c13526c827222d114cb6527d20fc9fceec194498ffa84ee6f10e574f96a353429bfdacf18f6b6494826e12aea5d58fc7ba
7
+ data.tar.gz: 1632aac1111449205a45ca9367093d2e4557e75a163a8c516248486f7a7e884cbf9205302ba8c5e1f4c01c8ff604bbebdaeef6729a1bc03e9dd97ec7f0afa850
data/.travis.yml CHANGED
@@ -27,16 +27,3 @@ script:
27
27
  - bundle exec rake
28
28
  - if [ "$DATABASE_ADAPTER" == "postgres" ]; then ./cc-test-reporter after-build --exit-code $TRAVIS_TEST_RESULT || true; fi
29
29
  # - if [ ! -z "$(ruby --version | grep '2\.4\.')" ]; then ./script/db-spec.sh; fi
30
- jobs:
31
- include:
32
- - stage: gem release
33
- before_script: echo ""
34
- script: echo "Deploying to rubygems.org ..."
35
- deploy:
36
- provider: rubygems
37
- api_key:
38
- secure: AzTHDbKRr1ZO4E2mRyvU054Tx8c2cZbKkoDBZjSAQ2CY3E7oH137NTAIGd4BthH/E9mbEXtGpZIDfWPbaOcUJQ5Bz24CWTKmGyic6FrPhJnOW5CKVSLGCDPzpmqHULv/GTN16YN0Dh1HLeGYZzlHlxT0+4AVvbvBAleHrAFeJs8=
39
- gem: pact_broker
40
- on:
41
- tags: true
42
- repo: pact-foundation/pact_broker
data/CHANGELOG.md CHANGED
@@ -1,3 +1,24 @@
1
+ <a name="v2.46.0"></a>
2
+ ### v2.46.0 (2020-01-30)
3
+
4
+
5
+ #### Features
6
+
7
+ * allow the base URL of the application to be set for the API ([73bd4c44](/../../commit/73bd4c44))
8
+ * correct logs relation to pb:logs in the triggered webhooks resource ([89ea1a58](/../../commit/89ea1a58))
9
+
10
+ * **pacts for verification**
11
+ * add pre and post verification messages that can be displayed to the user based on whether or not the verification has passed or failed ([bb079858](/../../commit/bb079858))
12
+ * allow all versions for a particular tag to be verified (eg. all prod versions of a mobile consumer) ([e16feef6](/../../commit/e16feef6))
13
+ * optimise queries for determining which provider version tags are pending ([b4e1461a](/../../commit/b4e1461a))
14
+
15
+
16
+ #### Bug Fixes
17
+
18
+ * **pacts for verification**
19
+ * set includePendingStatus to false by default ([9b3162ac](/../../commit/9b3162ac))
20
+
21
+
1
22
  <a name="v2.45.0"></a>
2
23
  ### v2.45.0 (2020-01-30)
3
24
 
data/lib/db.rb CHANGED
@@ -25,11 +25,17 @@ module DB
25
25
  # pool, as noted in the documentation for the extension.
26
26
  #
27
27
  def self.connect db_credentials
28
+ # Keep this conifiguration in sync with lib/pact_broker/app.rb#configure_database_connection
28
29
  Sequel.datetime_class = DateTime
29
30
  # logger = Logger.new($stdout)
30
31
  con = Sequel.connect(db_credentials.merge(:logger => logger, :pool_class => Sequel::ThreadedConnectionPool, :encoding => 'utf8'))
31
32
  con.extension(:connection_validator)
32
33
  con.extension(:pagination)
34
+ con.extend_datasets do
35
+ def any?
36
+ !empty?
37
+ end
38
+ end
33
39
  con.pool.connection_validation_timeout = -1 #Check the connection on every request
34
40
  con.timezone = :utc
35
41
  con.run("SET sql_mode='STRICT_TRANS_TABLES';") if db_credentials[:adapter].to_s =~ /mysql/
@@ -49,7 +55,7 @@ module DB
49
55
  end
50
56
 
51
57
  def self.mysql?
52
- PACT_BROKER_DB.adapter_scheme.to_s =~ /mysql/
58
+ !!(PACT_BROKER_DB.adapter_scheme.to_s =~ /mysql/)
53
59
  end
54
60
 
55
61
  PACT_BROKER_DB ||= connection_for_env ENV.fetch('RACK_ENV')
@@ -18,7 +18,7 @@ module PactBroker
18
18
  optional(:consumerVersionSelectors).each do
19
19
  schema do
20
20
  required(:tag).filled(:str?)
21
- required(:latest).filled(included_in?: [true])
21
+ optional(:latest).filled(included_in?: [true, false])
22
22
  end
23
23
  end
24
24
  optional(:includePendingStatus).filled(included_in?: [true, false])
@@ -17,7 +17,7 @@ module PactBroker
17
17
  optional(:consumer_version_selectors).each do
18
18
  schema do
19
19
  required(:tag).filled(:str?)
20
- required(:latest).filled(included_in?: ["true"])
20
+ optional(:latest).filled(included_in?: ["true", "false"])
21
21
  end
22
22
  end
23
23
  optional(:include_pending_status).filled(included_in?: ["true", "false"])
@@ -12,7 +12,7 @@ module PactBroker
12
12
 
13
13
  property :created_at, as: :triggeredAt
14
14
 
15
- link :logs do | context |
15
+ link :'pb:logs' do | context |
16
16
  {
17
17
  href: triggered_webhook_logs_url(represented, context[:base_url]),
18
18
  title: "Webhook execution logs",
@@ -20,6 +20,14 @@ module PactBroker
20
20
  }
21
21
  end
22
22
 
23
+ link :logs do | context |
24
+ {
25
+ href: triggered_webhook_logs_url(represented, context[:base_url]),
26
+ title: "DEPRECATED - Use pb:logs",
27
+ name: represented.request_description
28
+ }
29
+ end
30
+
23
31
  link :'pb:webhook' do | context |
24
32
  {
25
33
  href: webhook_url(represented.webhook_uuid, context[:base_url]),
@@ -30,25 +30,33 @@ module PactBroker
30
30
  property :notices, getter: -> (context) { context[:decorator].notices(context[:options][:user_options]) }
31
31
  property :noteToDevelopers, getter: -> (_) { "Please print out the text from the 'notices' rather than using the inclusionReason and the pendingReason fields. These will be removed when this API moves out of beta."}
32
32
 
33
- def inclusion_reason(pact_url)
34
- PactBroker::Pacts::VerifiablePactMessages.new(represented, pact_url).inclusion_reason
35
- end
36
-
37
- def pending_reason(pact_url)
38
- PactBroker::Pacts::VerifiablePactMessages.new(represented, pact_url).pending_reason
39
- end
40
-
41
33
  def notices(user_options)
34
+ # TODO move this out of the decorator
42
35
  pact_url = pact_version_url(represented, user_options[:base_url])
43
- mess = [{
44
- timing: 'pre_verification',
45
- text: inclusion_reason(pact_url)
36
+ messages = PactBroker::Pacts::VerifiablePactMessages.new(represented, pact_url)
37
+
38
+ the_notices = [{
39
+ when: 'before_verification',
40
+ text: messages.inclusion_reason
46
41
  }]
47
- mess << {
48
- timing: 'pre_verification',
49
- text: pending_reason(pact_url)
50
- } if user_options[:include_pending_status]
51
- mess
42
+
43
+ if user_options[:include_pending_status]
44
+ append_notice(the_notices, 'before_verification', messages.pending_reason)
45
+ append_notice(the_notices, 'after_verification:success_true_published_false', messages.verification_success_true_published_false)
46
+ append_notice(the_notices, 'after_verification:success_false_published_false', messages.verification_success_false_published_false)
47
+ append_notice(the_notices, 'after_verification:success_true_published_true', messages.verification_success_true_published_true)
48
+ append_notice(the_notices, 'after_verification:success_false_published_true', messages.verification_success_false_published_true)
49
+ end
50
+ the_notices
51
+ end
52
+
53
+ def append_notice the_notices, the_when, text
54
+ if text
55
+ the_notices << {
56
+ when: the_when,
57
+ text: text
58
+ }
59
+ end
52
60
  end
53
61
  end
54
62
 
@@ -19,7 +19,7 @@ module PactBroker
19
19
  }
20
20
  end
21
21
 
22
- property :include_pending_status, default: true,
22
+ property :include_pending_status, default: false,
23
23
  setter: ->(fragment:, represented:, **) {
24
24
  represented.include_pending_status = (fragment == 'true' || fragment == true)
25
25
  }
@@ -59,7 +59,7 @@ module PactBroker
59
59
  alias_method :path_info, :identifier_from_path
60
60
 
61
61
  def base_url
62
- request.base_uri.to_s.chomp('/')
62
+ PactBroker.configuration.base_url || request.base_uri.to_s.chomp('/')
63
63
  end
64
64
 
65
65
  def charsets_provided
@@ -26,7 +26,7 @@ module PactBroker
26
26
 
27
27
  def triggered_webhook
28
28
  @triggered_webhook ||= begin
29
- criteria = {webhook_uuid: identifier_from_path[:uuid], trigger_uuid: identifier_from_path[:trigger_uuid]}
29
+ criteria = { webhook_uuid: identifier_from_path[:uuid], trigger_uuid: identifier_from_path[:trigger_uuid] }
30
30
  PactBroker::Webhooks::TriggeredWebhook.where(criteria).single_record
31
31
  end
32
32
  end
@@ -4,7 +4,6 @@ require 'pact_broker/project_root'
4
4
  require 'pact_broker/logging/default_formatter'
5
5
  require 'rack-protection'
6
6
  require 'rack/hal_browser'
7
- require 'rack/pact_broker/store_base_url'
8
7
  require 'rack/pact_broker/add_pact_broker_version_header'
9
8
  require 'rack/pact_broker/convert_file_extension_to_accept_header'
10
9
  require 'rack/pact_broker/database_transaction'
@@ -106,11 +105,18 @@ module PactBroker
106
105
  end
107
106
 
108
107
  def configure_database_connection
108
+ # Keep this configuration in sync with lib/db.rb
109
109
  PactBroker::DB.connection = configuration.database_connection
110
110
  PactBroker::DB.connection.timezone = :utc
111
+ PactBroker::DB.connection.extend_datasets do
112
+ def any?
113
+ !empty?
114
+ end
115
+ end
111
116
  PactBroker::DB.validate_connection_config if configuration.validate_database_connection_config
112
117
  PactBroker::DB.set_mysql_strict_mode_if_mysql
113
118
  PactBroker::DB.connection.extension(:pagination)
119
+
114
120
  Sequel.datetime_class = DateTime
115
121
  Sequel.database_timezone = :utc # Store all dates in UTC, assume any date without a TZ is UTC
116
122
  Sequel.application_timezone = :local # Convert dates to localtime when retrieving from database
@@ -152,7 +158,6 @@ module PactBroker
152
158
  end
153
159
  @app_builder.use Rack::PactBroker::InvalidUriProtection
154
160
  @app_builder.use Rack::PactBroker::ResetThreadData
155
- @app_builder.use Rack::PactBroker::StoreBaseURL
156
161
  @app_builder.use Rack::PactBroker::AddPactBrokerVersionHeader
157
162
  @app_builder.use Rack::PactBroker::AddVaryHeader
158
163
  @app_builder.use Rack::Static, :urls => ["/stylesheets", "/css", "/fonts", "/js", "/javascripts", "/images"], :root => PactBroker.project_root.join("public")
@@ -33,7 +33,7 @@ module PactBroker
33
33
  :seed_example_data
34
34
  ]
35
35
 
36
- attr_accessor :log_dir, :database_connection, :auto_migrate_db, :auto_migrate_db_data, :example_data_seeder, :seed_example_data, :use_hal_browser, :html_pact_renderer, :use_rack_protection
36
+ attr_accessor :base_url, :log_dir, :database_connection, :auto_migrate_db, :auto_migrate_db_data, :example_data_seeder, :seed_example_data, :use_hal_browser, :html_pact_renderer, :use_rack_protection
37
37
  attr_accessor :validate_database_connection_config, :enable_diagnostic_endpoints, :version_parser, :sha_generator
38
38
  attr_accessor :use_case_sensitive_resource_names, :order_versions_by_date
39
39
  attr_accessor :check_for_potential_duplicate_pacticipant_names
@@ -176,10 +176,6 @@ module PactBroker
176
176
  self.enable_public_badge_access = enable_badge_resources
177
177
  end
178
178
 
179
- def base_url
180
- ENV['PACT_BROKER_BASE_URL']
181
- end
182
-
183
179
  def save_to_database
184
180
  # Can't require a Sequel::Model class before the connection has been set
185
181
  require 'pact_broker/config/save'
@@ -97,9 +97,9 @@ module PactBroker
97
97
 
98
98
  private
99
99
 
100
- # If one of the specified pacticipants is a consumer, then that provider is required to be deployed
100
+ # If a specified pacticipant is a consumer, then its provider is required to be deployed
101
101
  # to the same environment before the consumer can be deployed.
102
- # If one of the specified pacticipants is a provider, then the provider may be deployed
102
+ # If a specified pacticipant is a provider only, then it may be deployed
103
103
  # without the consumer being present.
104
104
  def is_a_row_for_this_integration_required?(specified_pacticipant_names, consumer_name)
105
105
  specified_pacticipant_names.include?(consumer_name)
@@ -25,10 +25,63 @@ module PactBroker
25
25
  dataset_module do
26
26
  include PactBroker::Repositories::Helpers
27
27
 
28
+ def remove_overridden_revisions
29
+ join(:latest_pact_publication_ids_for_consumer_versions, { Sequel[:lp][:pact_publication_id] => Sequel[:pact_publications][:id] }, { table_alias: :lp})
30
+ end
31
+
32
+ def join_consumer_versions(table_alias = :cv)
33
+ join(:versions, { Sequel[:pact_publications][:consumer_version_id] => Sequel[table_alias][:id] }, { table_alias: table_alias })
34
+ end
35
+
36
+ def join_consumer_version_tags(table_alias = :ct)
37
+ join(:tags, { Sequel[table_alias][:version_id] => Sequel[:pact_publications][:consumer_version_id]}, { table_alias: table_alias })
38
+ end
39
+
40
+ def join_consumer_version_tags_with_names(consumer_version_tag_names)
41
+ join(:tags, {
42
+ Sequel[:ct][:version_id] => Sequel[:pact_publications][:consumer_version_id],
43
+ Sequel[:ct][:name] => consumer_version_tag_names
44
+ }, {
45
+ table_alias: :ct
46
+ })
47
+ end
48
+
49
+ def join_providers(table_alias = :providers)
50
+ join(:pacticipants, { Sequel[:pact_publications][:provider_id] => Sequel[table_alias][:id] }, { table_alias: table_alias })
51
+ end
52
+
53
+ def join_consumers(table_alias = :consumers)
54
+ join(:pacticipants, { Sequel[:pact_publications][:consumer_id] => Sequel[table_alias][:id] }, { table_alias: table_alias })
55
+ end
56
+
57
+ def join_pact_versions
58
+ join(:pact_versions, { Sequel[:pact_publications][:pact_version_id] => Sequel[:pact_versions][:id] })
59
+ end
60
+
61
+ def eager_load_pact_versions
62
+ eager(:pact_versions)
63
+ end
64
+
28
65
  def tag tag_name
29
66
  filter = name_like(Sequel.qualify(:tags, :name), tag_name)
30
67
  join(:tags, {version_id: :consumer_version_id}).where(filter)
31
68
  end
69
+
70
+ def provider_name_like(name)
71
+ where(name_like(Sequel[:providers][:name], name))
72
+ end
73
+
74
+ def consumer_version_tag(tag)
75
+ where(Sequel[:ct][:name] => tag)
76
+ end
77
+
78
+ def order_by_consumer_name
79
+ order_append_ignore_case(Sequel[:consumers][:name])
80
+ end
81
+
82
+ def order_by_consumer_version_order
83
+ order_append(Sequel[:cv][:order])
84
+ end
32
85
  end
33
86
 
34
87
  def before_create
@@ -52,21 +52,31 @@ module PactBroker
52
52
 
53
53
  def select_provider_tags_with_successful_verifications(tags)
54
54
  tags.select do | tag |
55
+ verifications_join = {
56
+ Sequel[:verifications][:pact_version_id] => Sequel[:pact_versions][:id],
57
+ Sequel[:verifications][:success] => true
58
+ }
59
+ tags_join = {
60
+ Sequel[:tags][:version_id] => Sequel[:versions][:id],
61
+ Sequel[:tags][:name] => tag
62
+ }
55
63
  PactVersion.where(Sequel[:pact_versions][:id] => id)
56
- .join(:verifications, Sequel[:verifications][:pact_version_id] => Sequel[:pact_versions][:id])
64
+ .join(:verifications, verifications_join)
57
65
  .join(:versions, Sequel[:versions][:id] => Sequel[:verifications][:provider_version_id])
58
- .join(:tags, Sequel[:tags][:version_id] => Sequel[:versions][:id])
59
- .where(Sequel[:tags][:name] => tag)
60
- .where(Sequel[:verifications][:success] => true)
66
+ .join(:tags, tags_join)
61
67
  .any?
62
68
  end
63
69
  end
64
70
 
65
71
  def verified_successfully_by_any_provider_version?
72
+ verifications_join = {
73
+ Sequel[:verifications][:pact_version_id] => Sequel[:pact_versions][:id],
74
+ Sequel[:verifications][:pact_version_id] => id,
75
+ Sequel[:verifications][:success] => true
76
+ }
66
77
  PactVersion.where(Sequel[:pact_versions][:id] => id)
67
- .join(:verifications, Sequel[:verifications][:pact_version_id] => Sequel[:pact_versions][:id])
78
+ .join(:verifications, verifications_join)
68
79
  .join(:versions, Sequel[:versions][:id] => Sequel[:verifications][:provider_version_id])
69
- .where(Sequel[:verifications][:success] => true)
70
80
  .any?
71
81
  end
72
82
 
@@ -13,6 +13,7 @@ require 'pact_broker/pacts/parse'
13
13
  require 'pact_broker/matrix/head_row'
14
14
  require 'pact_broker/pacts/latest_pact_publication_id_for_consumer_version'
15
15
  require 'pact_broker/pacts/verifiable_pact'
16
+ require 'pact_broker/repositories/helpers'
16
17
 
17
18
  module PactBroker
18
19
  module Pacts
@@ -20,6 +21,7 @@ module PactBroker
20
21
 
21
22
  include PactBroker::Logging
22
23
  include PactBroker::Repositories
24
+ include PactBroker::Repositories::Helpers
23
25
 
24
26
  def create params
25
27
  pact_version = find_or_create_pact_version(
@@ -125,36 +127,60 @@ module PactBroker
125
127
  end
126
128
  end
127
129
 
130
+ def find_all_pact_versions_for_provider_with_tags provider_name, consumer_version_tag_names
131
+ provider = pacticipant_repository.find_by_name(provider_name)
132
+
133
+ PactPublication
134
+ .select_all_qualified
135
+ .select_append(Sequel[:cv][:order].as(:consumer_version_order))
136
+ .remove_overridden_revisions
137
+ .join_consumer_versions(:cv)
138
+ .join_consumer_version_tags_with_names(consumer_version_tag_names)
139
+ .where(provider: provider)
140
+ .eager(:consumer)
141
+ .eager(:consumer_version)
142
+ .eager(:provider)
143
+ .eager(:pact_version)
144
+ .all
145
+ .group_by(&:pact_version_id)
146
+ .values
147
+ .collect{ | pacts| pacts.sort_by{|pact| pact.values.fetch(:consumer_version_order) }.last }
148
+ .collect(&:to_domain)
149
+ end
150
+
128
151
  # To find the work in progress pacts for this verification execution:
129
152
  # For each provider tag that will be applied to this verification result (usually there will just be one, but
130
153
  # we have to allow for multiple tags),
131
154
  # find the head pacts (the pacts that are the latest for their tag) that have been successfully
132
155
  # verified against the provider tag.
133
156
  # Then, find all the head pacts, and remove the ones that have been successfully verified by ALL
134
- # of the provider tags supplied.
157
+ # of the provider tags supplied, and the ones that were published before the include_wip_pacts_since date.
135
158
  # Then, for all of the head pacts that are remaining (these are the WIP ones) work out which
136
159
  # provider tags they are pending for.
137
- # Don't include pact publications that were created
160
+ # Don't include pact publications that were created before the provider tag was first used
161
+ # (that is, before the provider's git branch was created).
138
162
  def find_wip_pact_versions_for_provider provider_name, provider_tags_names = [], options = {}
163
+ # TODO not sure about this
139
164
  return [] if provider_tags_names.empty?
140
165
 
141
166
  provider = pacticipant_repository.find_by_name(provider_name)
142
167
 
143
- # Hash of provider tag names => list of head pacts
144
- successfully_verified_head_pacts_for_provider_tags = find_successfully_verified_head_pacts_by_provider_tag(provider_name, provider_tags_names, options)
168
+ # Hash of provider tag name => list of head pacts that have been successfully verified by that tag
169
+ successfully_verified_head_pacts_for_provider_tags = find_successfully_verified_head_pacts_by_provider_tag(provider.id, provider_tags_names, options)
170
+ # Create hash of provider tag name => list of pact publication ids
145
171
  successfully_verified_head_pact_publication_ids_for_each_provider_tag = successfully_verified_head_pacts_for_provider_tags.each_with_object({}) do | (provider_tag_name, head_pacts), hash |
146
- hash[provider_tag_name] = head_pacts.collect(&:id)
172
+ hash[provider_tag_name] = head_pacts.collect(&:id).uniq
147
173
  end
148
174
 
149
- # list of pact_publication_ids that are NOT work in progress
150
- head_pact_publication_ids_successully_verified_by_all_provider_tags = successfully_verified_head_pacts_for_provider_tags.values.collect{ |head_pacts| head_pacts.collect(&:id) }.reduce(:&)
175
+ # list of head pact_publication_ids that are NOT work in progress because they've been verified by all of the provider version tags supplied
176
+ non_wip_pact_publication_ids = successfully_verified_head_pacts_for_provider_tags.values.collect{ |head_pacts| head_pacts.collect(&:id) }.reduce(:&)
151
177
 
152
- pact_publication_ids = find_head_pacts_that_have_not_been_successfully_verified_by_all_provider_tags(
153
- provider_name,
154
- head_pact_publication_ids_successully_verified_by_all_provider_tags,
178
+ wip_pact_publication_ids = find_head_pacts_that_have_not_been_successfully_verified_by_all_provider_tags(
179
+ provider.id,
180
+ non_wip_pact_publication_ids,
155
181
  options)
156
182
 
157
- pacts = AllPactPublications.where(id: pact_publication_ids).order_ignore_case(:consumer_name).order_append(:consumer_version_order)
183
+ wip_pacts = AllPactPublications.where(id: wip_pact_publication_ids).order_ignore_case(:consumer_name).order_append(:consumer_version_order)
158
184
 
159
185
  # The first instance (by date) of each provider tag with that name
160
186
  provider_tag_collection = PactBroker::Domain::Tag
@@ -166,7 +192,7 @@ module PactBroker
166
192
  .where(name: provider_tags_names)
167
193
  .all
168
194
 
169
- pacts.collect do | pact|
195
+ wip_pacts.collect do | pact|
170
196
  pending_tag_names = find_provider_tags_for_which_pact_publication_id_is_pending(pact, successfully_verified_head_pact_publication_ids_for_each_provider_tag)
171
197
  pre_existing_tag_names = find_provider_tag_names_that_were_first_used_before_pact_published(pact, provider_tag_collection)
172
198
 
@@ -313,13 +339,33 @@ module PactBroker
313
339
 
314
340
  # Returns a list of Domain::Pact objects the represent pact publications
315
341
  def find_for_verification(provider_name, consumer_version_selectors)
342
+ find_pacts_for_which_the_latest_version_or_latest_version_for_the_tag_is_required(provider_name, consumer_version_selectors) +
343
+ find_pacts_for_which_all_versions_for_the_tag_are_required(provider_name, consumer_version_selectors)
344
+ end
345
+
346
+ private
347
+
348
+ def find_pacts_for_which_the_latest_version_or_latest_version_for_the_tag_is_required(provider_name, consumer_version_selectors)
349
+ # The tags for which only the latest version is specified
316
350
  latest_tags = consumer_version_selectors.any? ?
317
351
  consumer_version_selectors.select(&:latest).collect(&:tag) :
318
352
  nil
353
+
319
354
  find_latest_pact_versions_for_provider(provider_name, latest_tags)
320
355
  end
321
356
 
322
- private
357
+ def find_pacts_for_which_all_versions_for_the_tag_are_required(provider_name, consumer_version_selectors)
358
+ # The tags for which all versions are specified
359
+ all_tags = consumer_version_selectors.any? ?
360
+ consumer_version_selectors.reject(&:latest).collect(&:tag) :
361
+ nil
362
+
363
+ if all_tags
364
+ find_all_pact_versions_for_provider_with_tags(provider_name, all_tags)
365
+ else
366
+ []
367
+ end
368
+ end
323
369
 
324
370
  def find_previous_distinct_pact_by_sha pact
325
371
  current_pact_content_sha =
@@ -389,27 +435,35 @@ module PactBroker
389
435
  end
390
436
  end
391
437
 
392
- def find_head_pacts_that_have_not_been_successfully_verified_by_all_provider_tags(provider_name, pact_publication_ids_successfully_verified_by_all_provider_tags, options)
438
+ def find_head_pacts_that_have_not_been_successfully_verified_by_all_provider_tags(provider_id, pact_publication_ids_successfully_verified_by_all_provider_tags, options)
393
439
  # Exclude the head pacts that have been successfully verified by all the specified provider tags
394
- pact_publication_ids = LatestTaggedPactPublications
395
- .provider(provider_name)
396
- .exclude(id: pact_publication_ids_successfully_verified_by_all_provider_tags)
440
+ LatestTaggedPactPublications
441
+ .where(provider_id: provider_id)
397
442
  .where(Sequel.lit('latest_tagged_pact_publications.created_at > ?', options.fetch(:include_wip_pacts_since)))
443
+ .exclude(id: pact_publication_ids_successfully_verified_by_all_provider_tags)
398
444
  .select_for_subquery(:id)
399
445
  end
400
446
 
401
- # Find the head pacts that have been successfully verified by a provider version with the specified tags
402
- # Returns a Hash of provider_tag => LatestTaggedPactPublications with only id and tag_name populated
403
- def find_successfully_verified_head_pacts_by_provider_tag(provider_name, provider_tags, options)
447
+ # Find the head pacts that have been successfully verified by a provider version with the specified
448
+ # provider version tags.
449
+ # Returns a Hash of provider_tag => LatestTaggedPactPublications with only pact publication id and tag_name populated
450
+ # This is the list of pacts we are EXCLUDING from the WIP list because they have already been verified successfully
451
+ def find_successfully_verified_head_pacts_by_provider_tag(provider_id, provider_tags, options)
404
452
  provider_tags.compact.each_with_object({}) do | provider_tag, hash |
453
+ verifications_join = {
454
+ pact_version_id: :pact_version_id,
455
+ Sequel[:verifications][:success] => true,
456
+ Sequel[:verifications][:provider_id] => provider_id
457
+ }
458
+ tags_join = {
459
+ Sequel[:verifications][:provider_version_id] => Sequel[:provider_tags][:version_id],
460
+ Sequel[:provider_tags][:name] => provider_tag
461
+ }
405
462
  head_pacts = LatestTaggedPactPublications
406
- .join(:verifications, { pact_version_id: :pact_version_id })
407
- .join(:tags, { Sequel[:verifications][:provider_version_id] => Sequel[:provider_tags][:version_id] }, {table_alias: :provider_tags})
408
- .where(Sequel[:provider_tags][:name] => provider_tag)
409
- .provider(provider_name)
410
- .where(Sequel[:verifications][:success] => true)
411
- .or(Sequel.lit('latest_tagged_pact_publications.created_at < ?', options.fetch(:include_wip_pacts_since)))
412
- .select(Sequel[:latest_tagged_pact_publications][:id].as(:id), :tag_name)
463
+ .select(Sequel[:latest_tagged_pact_publications][:id].as(:id))
464
+ .join(:verifications, verifications_join)
465
+ .join(:tags, tags_join, { table_alias: :provider_tags } )
466
+ .where(Sequel[:latest_tagged_pact_publications][:provider_id] => provider_id)
413
467
  .all
414
468
  hash[provider_tag] = head_pacts
415
469
  end
@@ -35,6 +35,28 @@ module PactBroker
35
35
  end
36
36
  end
37
37
 
38
+ def verification_success_true_published_false
39
+ if pending?
40
+ "This pact is still in pending state for #{pending_provider_tags_description} as the successful verification results #{with_these_tags}have not yet been published."
41
+ end
42
+ end
43
+
44
+ def verification_success_true_published_true
45
+ if pending?
46
+ "This pact is no longer in pending state for #{pending_provider_tags_description}, as a successful verification result #{with_these_tags}has been published. If a verification for a version with fails in the future, it will fail the build. #{READ_MORE_PENDING}"
47
+ end
48
+ end
49
+
50
+ def verification_success_false_published_false
51
+ if pending?
52
+ "This pact is still in pending state for #{pending_provider_tags_description} as a successful verification result #{with_these_tags}has not yet been published"
53
+ end
54
+ end
55
+
56
+ def verification_success_false_published_true
57
+ verification_success_false_published_false
58
+ end
59
+
38
60
  private
39
61
 
40
62
  attr_reader :verifiable_pact, :pact_version_url
@@ -77,6 +99,14 @@ module PactBroker
77
99
  else "a version of #{provider_name} with tag #{join(non_pending_provider_tags)}"
78
100
  end
79
101
  end
102
+
103
+ def with_these_tags
104
+ case pending_provider_tags.size
105
+ when 0 then ""
106
+ when 1 then "with this tag "
107
+ else "with these tags "
108
+ end
109
+ end
80
110
  end
81
111
  end
82
112
  end
@@ -23,6 +23,10 @@ module PactBroker
23
23
  order(Sequel.function(:lower, column_name))
24
24
  end
25
25
 
26
+ def order_append_ignore_case column_name = :name
27
+ order_append(Sequel.function(:lower, column_name))
28
+ end
29
+
26
30
  def mysql?
27
31
  Sequel::Model.db.adapter_scheme.to_s =~ /mysql/
28
32
  end
@@ -252,6 +252,10 @@ module PactBroker
252
252
  create_webhook(parameters.merge(consumer: nil, provider: nil))
253
253
  end
254
254
 
255
+ def create_global_contract_content_changed_webhook parameters = {}
256
+ create_webhook(parameters.merge(consumer: nil, provider: nil, event_names: [PactBroker::Webhooks::WebhookEvent::CONTRACT_CONTENT_CHANGED]))
257
+ end
258
+
255
259
  def create_global_verification_webhook parameters = {}
256
260
  create_webhook(parameters.merge(consumer: nil, provider: nil, event_names: [PactBroker::Webhooks::WebhookEvent::VERIFICATION_PUBLISHED]))
257
261
  end
@@ -1,3 +1,3 @@
1
1
  module PactBroker
2
- VERSION = '2.45.0'
2
+ VERSION = '2.46.0'
3
3
  end
data/pact_broker.gemspec CHANGED
@@ -48,7 +48,7 @@ Gem::Specification.new do |gem|
48
48
  gem.add_runtime_dependency 'roar', '~> 1.1'
49
49
  gem.add_runtime_dependency 'reform', '~> 2.2'
50
50
  gem.add_runtime_dependency 'dry-validation', '~> 0.10.5'
51
- gem.add_runtime_dependency 'sequel', '~> 5.6'
51
+ gem.add_runtime_dependency 'sequel', '~> 5.28'
52
52
  gem.add_runtime_dependency 'webmachine', '1.5.0'
53
53
  gem.add_runtime_dependency 'semver2', '~> 3.4.2'
54
54
  gem.add_runtime_dependency 'rack', '>= 2.0.8', '~>2.0'
@@ -1,4 +1,12 @@
1
1
  #Code to generate certificates
2
+
3
+ # To generate a self signed CA certificate for use in a server:
4
+ # root_ca.add_extension(ef.create_extension("basicConstraints","CA:TRUE",true))
5
+ # root_ca.add_extension(ef.create_extension("keyUsage","keyCertSign, cRLSign", true))
6
+ # root_ca.add_extension(ef.create_extension("subjectKeyIdentifier","hash",false))
7
+ # root_ca.add_extension(ef.create_extension("authorityKeyIdentifier","keyid:always",false))
8
+ # root_ca.add_extension(ef.create_extension("keyUsage","digitalSignature", true))
9
+
2
10
  require 'openssl'
3
11
 
4
12
  root_key = OpenSSL::PKey::RSA.new 2048 # the CA's public/private key
data/script/release.sh CHANGED
@@ -5,6 +5,7 @@ bundle exec rake generate_changelog
5
5
  git add CHANGELOG.md lib/pact_broker/version.rb
6
6
  VERSION=$(ruby -r ./lib/pact_broker/version.rb -e "puts PactBroker::VERSION")
7
7
  git commit -m "chore(release): version ${VERSION}"
8
- git tag -a v${VERSION} -m "chore(release): version ${VERSION}"
9
- git push origin v${VERSION}
10
- git push origin master
8
+ bundle exec rake release
9
+ # git tag -a v${VERSION} -m "chore(release): version ${VERSION}"
10
+ # git push origin v${VERSION}
11
+ # git push origin master
@@ -0,0 +1,59 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ raise "Please supply database path" unless ARGV[0]
4
+
5
+ $LOAD_PATH.unshift './lib'
6
+ $LOAD_PATH.unshift './spec'
7
+ $LOAD_PATH.unshift './tasks'
8
+ ENV['RACK_ENV'] = 'development'
9
+ require 'sequel'
10
+ require 'logger'
11
+ DATABASE_CREDENTIALS = {logger: Logger.new($stdout), adapter: "sqlite", database: ARGV[0], :encoding => 'utf8'}.tap { |it| puts it }
12
+ #DATABASE_CREDENTIALS = {adapter: "postgres", database: "pact_broker", username: 'pact_broker', password: 'pact_broker', :encoding => 'utf8'}
13
+
14
+ connection = Sequel.connect(DATABASE_CREDENTIALS)
15
+ connection.timezone = :utc
16
+ # Uncomment these lines to open a pry session for inspecting the database
17
+
18
+ require 'pact_broker/db'
19
+ PactBroker::DB.connection = connection
20
+ require 'pact_broker'
21
+ require 'support/test_data_builder'
22
+
23
+ require 'database/table_dependency_calculator'
24
+ PactBroker::Database::TableDependencyCalculator.call(connection).each do | table_name |
25
+ connection[table_name].delete
26
+ end
27
+
28
+ webhook_body = {
29
+ 'pactUrl' => '${pactbroker.pactUrl}',
30
+ 'verificationResultUrl' => '${pactbroker.verificationResultUrl}',
31
+ 'consumerVersionNumber' => '${pactbroker.consumerVersionNumber}',
32
+ 'providerVersionNumber' => '${pactbroker.providerVersionNumber}',
33
+ 'providerVersionTags' => '${pactbroker.providerVersionTags}',
34
+ 'consumerVersionTags' => '${pactbroker.consumerVersionTags}',
35
+ 'consumerName' => '${pactbroker.consumerName}',
36
+ 'providerName' => '${pactbroker.providerName}',
37
+ 'githubVerificationStatus' => '${pactbroker.githubVerificationStatus}'
38
+ }
39
+
40
+ # .create_global_webhook(
41
+ # method: 'POST',
42
+ # url: "http://localhost:9292/pact-changed-webhook",
43
+ # body: webhook_body.to_json,
44
+ # username: "foo",
45
+ # password: "bar")
46
+
47
+ PactBroker.configuration.base_equality_only_on_content_that_affects_verification_results = false
48
+
49
+ TestDataBuilder.new
50
+ .create_global_contract_content_changed_webhook(
51
+ method: 'POST',
52
+ url: "http://localhost:9292/pact-changed-webhook",
53
+ body: webhook_body.to_json,
54
+ username: "foo",
55
+ password: "bar")
56
+ .create_global_verification_webhook(
57
+ method: 'POST',
58
+ url: "http://localhost:9292/verification-published-webhook",
59
+ body: webhook_body.to_json)
@@ -57,7 +57,7 @@ module PactBroker
57
57
  }]
58
58
  end
59
59
 
60
- it { is_expected.to have_key(:consumerVersionSelectors) }
60
+ it { is_expected.to be_empty }
61
61
  end
62
62
 
63
63
  context "when includeWipPactsSince key exists" do
@@ -51,7 +51,7 @@ module PactBroker
51
51
  }]
52
52
  end
53
53
 
54
- it { is_expected.to have_key(:consumer_version_selectors) }
54
+ it { is_expected.to be_empty }
55
55
  end
56
56
 
57
57
  context "when include_wip_pacts_since key exists" do
@@ -43,7 +43,7 @@ module PactBroker
43
43
  subject { JSON.parse(json, symbolize_names: true) }
44
44
 
45
45
  it "includes a link to the logs" do
46
- expect(subject[:_links][:logs][:href]).to eq logs_url
46
+ expect(subject[:_links][:'pb:logs'][:href]).to eq logs_url
47
47
  end
48
48
 
49
49
  it "includes a link to the webhook" do
@@ -8,6 +8,10 @@ module PactBroker
8
8
  allow_any_instance_of(PactBroker::Api::PactBrokerUrls).to receive(:pact_version_url).and_return('/pact-version-url')
9
9
  allow_any_instance_of(PactBroker::Pacts::VerifiablePactMessages).to receive(:inclusion_reason).and_return("the inclusion reason")
10
10
  allow_any_instance_of(PactBroker::Pacts::VerifiablePactMessages).to receive(:pending_reason).and_return(pending_reason)
11
+ allow_any_instance_of(PactBroker::Pacts::VerifiablePactMessages).to receive(:verification_success_true_published_false).and_return('verification_success_true_published_false')
12
+ allow_any_instance_of(PactBroker::Pacts::VerifiablePactMessages).to receive(:verification_success_false_published_false).and_return('verification_success_false_published_false')
13
+ allow_any_instance_of(PactBroker::Pacts::VerifiablePactMessages).to receive(:verification_success_true_published_true).and_return('verification_success_true_published_true')
14
+ allow_any_instance_of(PactBroker::Pacts::VerifiablePactMessages).to receive(:verification_success_false_published_true).and_return('verification_success_false_published_true')
11
15
  end
12
16
  let(:pending_reason) { "the pending reason" }
13
17
  let(:expected_hash) do
@@ -16,9 +20,23 @@ module PactBroker
16
20
  "pending" => true,
17
21
  "notices" => [
18
22
  {
23
+ "when" => "before_verification",
19
24
  "text" => "the inclusion reason"
20
- }, {
25
+ },{
26
+ "when" => "before_verification",
21
27
  "text" => pending_reason
28
+ },{
29
+ "when" => "after_verification:success_true_published_false",
30
+ "text" => "verification_success_true_published_false"
31
+ },{
32
+ "when" => "after_verification:success_false_published_false",
33
+ "text" => "verification_success_false_published_false"
34
+ },{
35
+ "when" => "after_verification:success_true_published_true",
36
+ "text" => "verification_success_true_published_true"
37
+ },{
38
+ "when" => "after_verification:success_false_published_true",
39
+ "text" => "verification_success_false_published_true"
22
40
  }
23
41
  ]
24
42
  },
@@ -60,7 +78,7 @@ module PactBroker
60
78
  end
61
79
 
62
80
  it "creates the inclusion message" do
63
- expect(PactBroker::Pacts::VerifiablePactMessages).to receive(:new).twice.with(pact, '/pact-version-url').and_call_original
81
+ expect(PactBroker::Pacts::VerifiablePactMessages).to receive(:new).with(pact, '/pact-version-url').and_call_original
64
82
  subject
65
83
  end
66
84
 
@@ -76,6 +94,10 @@ module PactBroker
76
94
  expect(subject['verificationProperties']).to_not have_key('pendingReason')
77
95
  expect(notices).to_not include(pending_reason)
78
96
  end
97
+
98
+ it "does not include the pending notices" do
99
+ expect(subject['verificationProperties']['notices'].size).to eq 1
100
+ end
79
101
  end
80
102
 
81
103
  context "when wip is true" do
@@ -4,7 +4,7 @@ module PactBroker
4
4
  module Api
5
5
  module Resources
6
6
  describe BaseResource do
7
- let(:request) { double('request', uri: uri).as_null_object }
7
+ let(:request) { double('request', uri: uri, base_uri: URI("http://example.org/")).as_null_object }
8
8
  let(:response) { double('response') }
9
9
  let(:uri) { URI('http://example.org/path?query') }
10
10
 
@@ -19,6 +19,28 @@ module PactBroker
19
19
  expect(subject.headers['Access-Control-Allow-Methods']).to eq "GET, OPTIONS"
20
20
  end
21
21
  end
22
+
23
+ describe "base_url" do
24
+ context "when PactBroker.configuration.base_url is not nil" do
25
+ before do
26
+ allow(PactBroker.configuration).to receive(:base_url).and_return("http://foo")
27
+ end
28
+
29
+ it "returns the configured base URL" do
30
+ expect(subject.base_url).to eq "http://foo"
31
+ end
32
+ end
33
+
34
+ context "when PactBroker.configuration.base_url is nil" do
35
+ before do
36
+ allow(PactBroker.configuration).to receive(:base_url).and_return(nil)
37
+ end
38
+
39
+ it "returns the base URL from the request" do
40
+ expect(subject.base_url).to eq "http://example.org"
41
+ end
42
+ end
43
+ end
22
44
  end
23
45
 
24
46
  ALL_RESOURCES = ObjectSpace.each_object(::Class).select {|klass| klass < BaseResource }
@@ -11,21 +11,35 @@ module PactBroker
11
11
  subject.find{ |pact| pact.consumer_version_number == consumer_version_number }
12
12
  end
13
13
 
14
+ def find_by_consumer_name_and_consumer_version_number(consumer_name, consumer_version_number)
15
+ subject.find{ |pact| pact.consumer_name == consumer_name && pact.consumer_version_number == consumer_version_number }
16
+ end
17
+
14
18
  before do
15
- td.create_pact_with_hierarchy("Foo", "bar-latest-prod", "Bar")
19
+ td.create_pact_with_hierarchy("Foo", "foo-latest-prod-version", "Bar")
16
20
  .create_consumer_version_tag("prod")
17
- .create_consumer_version("not-latest-dev", tag_names: ["dev"])
21
+ .create_consumer_version("not-latest-dev-version", tag_names: ["dev"])
18
22
  .comment("next pact not selected")
19
23
  .create_pact
20
- .create_consumer_version("bar-latest-dev", tag_names: ["dev"])
24
+ .create_consumer_version("foo-latest-dev-version", tag_names: ["dev"])
21
25
  .create_pact
22
26
  .create_consumer("Baz")
23
- .create_consumer_version("baz-latest-dev", tag_names: ["dev"])
27
+ .create_consumer_version("baz-latest-dev-version", tag_names: ["dev"])
24
28
  .create_pact
25
29
  end
26
30
 
27
31
  subject { Repository.new.find_for_verification("Bar", consumer_version_selectors) }
28
32
 
33
+ context "when there are no selectors" do
34
+ let(:consumer_version_selectors) { [] }
35
+
36
+ it "returns the latest pact for each consumer" do
37
+ expect(subject.size).to eq 2
38
+ expect(find_by_consumer_name_and_consumer_version_number("Foo", "foo-latest-dev-version")).to_not be nil
39
+ expect(find_by_consumer_name_and_consumer_version_number("Baz", "baz-latest-dev-version")).to_not be nil
40
+ end
41
+ end
42
+
29
43
  context "when consumer tag names are specified" do
30
44
  let(:pact_selector_1) { double('selector', tag: 'dev', latest: true) }
31
45
  let(:pact_selector_2) { double('selector', tag: 'prod', latest: true) }
@@ -34,14 +48,43 @@ module PactBroker
34
48
  end
35
49
 
36
50
  it "returns the latest pact with the specified tags for each consumer" do
37
- expect(find_by_consumer_version_number("bar-latest-prod")).to_not be nil
38
- expect(find_by_consumer_version_number("bar-latest-dev")).to_not be nil
39
- expect(find_by_consumer_version_number("baz-latest-dev")).to_not be nil
51
+ expect(find_by_consumer_version_number("foo-latest-prod-version")).to_not be nil
52
+ expect(find_by_consumer_version_number("foo-latest-dev-version")).to_not be nil
53
+ expect(find_by_consumer_version_number("baz-latest-dev-version")).to_not be nil
40
54
  expect(subject.size).to eq 3
41
55
  end
42
56
 
43
57
  it "sets the latest_consumer_version_tag_names" do
44
- expect(find_by_consumer_version_number("bar-latest-prod").tag).to eq 'prod'
58
+ expect(find_by_consumer_version_number("foo-latest-prod-version").tag).to eq 'prod'
59
+ end
60
+
61
+ context "when all versions with a given tag are requested" do
62
+ before do
63
+ td.create_pact_with_hierarchy("Foo2", "prod-version-1", "Bar2")
64
+ .create_consumer_version_tag("prod")
65
+ .create_consumer_version("not-prod-version", tag_names: %w[master])
66
+ .create_pact
67
+ .create_consumer_version("prod-version-2", tag_names: %w[prod])
68
+ .create_pact
69
+ end
70
+
71
+ let(:consumer_version_selectors) { [pact_selector_1] }
72
+ let(:pact_selector_1) { double('selector', tag: 'prod', latest: nil) }
73
+
74
+ subject { Repository.new.find_for_verification("Bar2", consumer_version_selectors) }
75
+
76
+ it "returns all the versions with the specified tag" do
77
+ expect(subject.size).to be 2
78
+ expect(find_by_consumer_version_number("prod-version-1")).to_not be nil
79
+ expect(find_by_consumer_version_number("prod-version-2")).to_not be nil
80
+ end
81
+
82
+ it "dedupes them to ensure that each pact version is only verified once" do
83
+ td.create_consumer_version("prod-version-3", tag_names: %w[prod])
84
+ .republish_same_pact
85
+ expect(subject.size).to be 2
86
+ expect(subject.collect(&:consumer_version_number)).to eq %w[prod-version-1 prod-version-3]
87
+ end
45
88
  end
46
89
  end
47
90
 
@@ -49,14 +92,14 @@ module PactBroker
49
92
  let(:consumer_version_selectors) { [] }
50
93
 
51
94
  it "returns the latest pact for each provider" do
52
- expect(find_by_consumer_version_number("bar-latest-dev")).to_not be nil
53
- expect(find_by_consumer_version_number("baz-latest-dev")).to_not be nil
95
+ expect(find_by_consumer_version_number("foo-latest-dev-version")).to_not be nil
96
+ expect(find_by_consumer_version_number("baz-latest-dev-version")).to_not be nil
54
97
  expect(subject.size).to eq 2
55
98
  end
56
99
 
57
100
  it "does not set the tag name" do
58
- expect(find_by_consumer_version_number("bar-latest-dev").tag).to be nil
59
- expect(find_by_consumer_version_number("bar-latest-dev").overall_latest?).to be true
101
+ expect(find_by_consumer_version_number("foo-latest-dev-version").tag).to be nil
102
+ expect(find_by_consumer_version_number("foo-latest-dev-version").overall_latest?).to be true
60
103
  end
61
104
  end
62
105
  end
@@ -2,6 +2,8 @@ require 'sucker_punch'
2
2
  require 'faraday'
3
3
  require 'pact_broker/logging'
4
4
 
5
+
6
+ # Publishes verification results, as if they were triggered by a CI job
5
7
  module PactBroker
6
8
  class VerificationJob
7
9
  include SuckerPunch::Job
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: pact_broker
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.45.0
4
+ version: 2.46.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Bethany Skurrie
@@ -10,7 +10,7 @@ authors:
10
10
  autorequire:
11
11
  bindir: bin
12
12
  cert_chain: []
13
- date: 2020-01-29 00:00:00.000000000 Z
13
+ date: 2020-01-30 00:00:00.000000000 Z
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
16
  name: httparty
@@ -94,14 +94,14 @@ dependencies:
94
94
  requirements:
95
95
  - - "~>"
96
96
  - !ruby/object:Gem::Version
97
- version: '5.6'
97
+ version: '5.28'
98
98
  type: :runtime
99
99
  prerelease: false
100
100
  version_requirements: !ruby/object:Gem::Requirement
101
101
  requirements:
102
102
  - - "~>"
103
103
  - !ruby/object:Gem::Version
104
- version: '5.6'
104
+ version: '5.28'
105
105
  - !ruby/object:Gem::Dependency
106
106
  name: webmachine
107
107
  requirement: !ruby/object:Gem::Requirement
@@ -1147,7 +1147,6 @@ files:
1147
1147
  - lib/rack/pact_broker/no_auth.rb
1148
1148
  - lib/rack/pact_broker/request_target.rb
1149
1149
  - lib/rack/pact_broker/reset_thread_data.rb
1150
- - lib/rack/pact_broker/store_base_url.rb
1151
1150
  - lib/rack/pact_broker/ui_authentication.rb
1152
1151
  - lib/rack/pact_broker/ui_request_filter.rb
1153
1152
  - lib/webmachine/rack_adapter_monkey_patch.rb
@@ -1232,6 +1231,7 @@ files:
1232
1231
  - script/restart.sh
1233
1232
  - script/run-with-ssl.rb
1234
1233
  - script/seed-example-matrix.rb
1234
+ - script/seed-for-webhook-test.rb
1235
1235
  - script/seed-matrix.rb
1236
1236
  - script/seed.rb
1237
1237
  - script/update-hal-browser
@@ -1,14 +0,0 @@
1
- module Rack
2
- module PactBroker
3
- class StoreBaseURL
4
- def initialize app
5
- @app = app
6
- end
7
-
8
- def call(env)
9
- Thread.current[:pact_broker_thread_data].base_url ||= (ENV['PACT_BROKER_BASE_URL'] || ::Rack::Request.new(env).base_url)
10
- @app.call(env)
11
- end
12
- end
13
- end
14
- end