pact_broker 2.45.0 → 2.46.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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