pact_broker 2.47.1 → 2.48.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 (40) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +21 -0
  3. data/Dockerfile +0 -1
  4. data/README.md +1 -1
  5. data/lib/pact_broker/api/contracts/verifiable_pacts_json_query_schema.rb +11 -0
  6. data/lib/pact_broker/api/contracts/verifiable_pacts_query_schema.rb +1 -0
  7. data/lib/pact_broker/api/decorators/verifiable_pact_decorator.rb +4 -39
  8. data/lib/pact_broker/api/decorators/verifiable_pacts_query_decorator.rb +9 -2
  9. data/lib/pact_broker/api/decorators/version_decorator.rb +1 -1
  10. data/lib/pact_broker/api/resources/verification.rb +6 -1
  11. data/lib/pact_broker/pacts/build_verifiable_pact_notices.rb +35 -0
  12. data/lib/pact_broker/pacts/repository.rb +71 -17
  13. data/lib/pact_broker/pacts/selected_pact.rb +9 -18
  14. data/lib/pact_broker/pacts/selector.rb +66 -10
  15. data/lib/pact_broker/pacts/selectors.rb +44 -0
  16. data/lib/pact_broker/pacts/service.rb +2 -2
  17. data/lib/pact_broker/pacts/squash_pacts_for_verification.rb +4 -6
  18. data/lib/pact_broker/pacts/verifiable_pact.rb +3 -12
  19. data/lib/pact_broker/pacts/verifiable_pact_messages.rb +63 -11
  20. data/lib/pact_broker/test/test_data_builder.rb +6 -0
  21. data/lib/pact_broker/verifications/repository.rb +4 -0
  22. data/lib/pact_broker/verifications/service.rb +5 -0
  23. data/lib/pact_broker/version.rb +1 -1
  24. data/lib/pact_broker/webhooks/service.rb +4 -0
  25. data/spec/features/delete_verification_spec.rb +29 -0
  26. data/spec/lib/pact_broker/api/contracts/verifiable_pacts_json_query_schema_spec.rb +29 -0
  27. data/spec/lib/pact_broker/api/decorators/verifiable_pact_decorator_spec.rb +18 -40
  28. data/spec/lib/pact_broker/api/decorators/verifiable_pacts_query_decorator_spec.rb +20 -6
  29. data/spec/lib/pact_broker/api/decorators/version_decorator_spec.rb +4 -0
  30. data/spec/lib/pact_broker/api/resources/provider_pacts_for_verification_spec.rb +2 -2
  31. data/spec/lib/pact_broker/pacts/build_verifiable_pact_notices_spec.rb +76 -0
  32. data/spec/lib/pact_broker/pacts/repository_find_for_verification_fallback_spec.rb +73 -0
  33. data/spec/lib/pact_broker/pacts/repository_find_for_verification_spec.rb +10 -12
  34. data/spec/lib/pact_broker/pacts/selector_spec.rb +28 -0
  35. data/spec/lib/pact_broker/pacts/selectors_spec.rb +30 -0
  36. data/spec/lib/pact_broker/pacts/service_spec.rb +2 -2
  37. data/spec/lib/pact_broker/pacts/squash_pacts_for_verification_spec.rb +2 -5
  38. data/spec/lib/pact_broker/pacts/verifiable_pact_messages_spec.rb +32 -24
  39. data/spec/support/verification_job.rb +1 -0
  40. metadata +14 -2
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: e05cc047cbfe572f654468283eabb11b7adc91da8b802b6955ddb10b3114a3ec
4
- data.tar.gz: 2a70640b544c8ac35f82bfc1612c9285506691ebe4e71c7e8629f3bd64ca3882
3
+ metadata.gz: bdda99358c4d4d8ca43f6e53e0e314fd24f475f1ff85fd0511743d8982224bca
4
+ data.tar.gz: 4f61ab3a051164ac3db85d7eef44fa088053873b2381f4c4104f4822c47bd651
5
5
  SHA512:
6
- metadata.gz: ad822d40451b9821921ea72fd8363625197524c1aed51ecefcfeb7d69b0d3b5382a9b45147fa2bf11baef50e77fc798e4eb55b58d4cbb9490d583a7d85399e4f
7
- data.tar.gz: 946de38bcbf4e0d96fa54cbd8466bdbb49cc44a74a4e89d11b4ed8b1c4db2778594450b6599e11adfbcdbd6dd5b84893c19389a5b92f163dfefa6d716f949313
6
+ metadata.gz: e3d9f86596a6d4aa776c13f28e84af1976485dc9eff3bef98accf6e372d379cb591270354a252c88a6b2c08ac928391e2ddcf8ee19d3db6f9832a667b4a81184
7
+ data.tar.gz: d4b2273ab789165a3f0ca7ce8f5fdb2220814d222ea172fa02fe77d19ce6e9e251277a6c621483a41b6b9911ab207b6d59861a39d2168ecdf5b0db64d1477d9f
@@ -1,3 +1,24 @@
1
+ <a name="v2.48.0"></a>
2
+ ### v2.48.0 (2020-02-07)
3
+
4
+
5
+ #### Features
6
+
7
+ * **pacts for verification**
8
+ * include a short description of the pact's selectors in the response ([41c6d91f](/../../commit/41c6d91f))
9
+ * update inclusion reason to support fallback tag explanation ([43081170](/../../commit/43081170))
10
+ * allow a fallback tag to be specified ([113180c1](/../../commit/113180c1))
11
+ * update the inclusion notice text to handle 'all pacts for tag' ([59ec8c8a](/../../commit/59ec8c8a))
12
+
13
+ * support DELETE for verification results ([70392e53](/../../commit/70392e53))
14
+
15
+
16
+ #### Bug Fixes
17
+
18
+ * a url typo (#328) ([482264fa](/../../commit/482264fa))
19
+ * correct URL of tag relation in pacticipant version resource ([ec24e999](/../../commit/ec24e999))
20
+
21
+
1
22
  <a name="v2.47.1"></a>
2
23
  ### v2.47.1 (2020-02-01)
3
24
 
data/Dockerfile CHANGED
@@ -12,7 +12,6 @@ RUN apk update \
12
12
  "sqlite>=3.28" \
13
13
  "tzdata>=2019" \
14
14
  "mariadb-dev>=10.3" \
15
- "git" \
16
15
  && rm -rf /var/cache/apk/*
17
16
 
18
17
  WORKDIR /app
data/README.md CHANGED
@@ -12,7 +12,7 @@ The Pact Broker is an application for sharing for consumer driven contracts and
12
12
  <a href="https:/pactflow.io/?utm_source=github&utm_campaign=pact_broker_intro"><img src="docs/images/Pactflow logo - black small.png"></a>
13
13
  <br/>
14
14
 
15
- You can try out a Pact Broker for free at <a href="https:/pactflow.io/?utm_source=github&utm_campaign=pact_broker_intro"/>pactflow.io</a>. Built by a group of core Pact maintainers, Pactflow is a fork of the OSS Pact Broker with extra goodies like an improved UI, field level verification results and federated login.
15
+ You can try out a Pact Broker for free at <a href="https://pactflow.io/?utm_source=github&utm_campaign=pact_broker_intro"/>pactflow.io</a>. Built by a group of core Pact maintainers, Pactflow is a fork of the OSS Pact Broker with extra goodies like an improved UI, field level verification results and federated login.
16
16
 
17
17
  **Why do I need a Pact Broker?**
18
18
 
@@ -17,8 +17,19 @@ module PactBroker
17
17
  optional(:providerVersionTags).maybe(:array?)
18
18
  optional(:consumerVersionSelectors).each do
19
19
  schema do
20
+ # configure do
21
+ # def self.messages
22
+ # super.merge(en: { errors: { fallbackTagMustBeForLatest: 'can only be set if latest=true' }})
23
+ # end
24
+ # end
25
+
20
26
  required(:tag).filled(:str?)
21
27
  optional(:latest).filled(included_in?: [true, false])
28
+ optional(:fallbackTag).filled(:str?)
29
+
30
+ # rule(fallbackTagMustBeForLatest: [:fallbackTag, :latest]) do | fallback_tag, latest |
31
+ # fallback_tag.filled?.then(latest.eql?(true))
32
+ # end
22
33
  end
23
34
  end
24
35
  optional(:includePendingStatus).filled(included_in?: [true, false])
@@ -18,6 +18,7 @@ module PactBroker
18
18
  schema do
19
19
  required(:tag).filled(:str?)
20
20
  optional(:latest).filled(included_in?: ["true", "false"])
21
+ optional(:fallback_tag).filled(:str?)
21
22
  end
22
23
  end
23
24
  optional(:include_pending_status).filled(included_in?: ["true", "false"])
@@ -1,26 +1,15 @@
1
1
  require_relative 'base_decorator'
2
2
  require 'pact_broker/api/pact_broker_urls'
3
- require 'delegate'
4
- require 'pact_broker/pacts/verifiable_pact_messages'
3
+ require 'pact_broker/pacts/build_verifiable_pact_notices'
5
4
 
6
5
  module PactBroker
7
6
  module Api
8
7
  module Decorators
9
8
  class VerifiablePactDecorator < BaseDecorator
10
9
 
11
- # Allows a "flat" VerifiablePact to look like it has
12
- # a nested verification_properties object for Reform
13
- class Reshaper < SimpleDelegator
14
- def verification_properties
15
- __getobj__()
16
- end
17
- end
18
-
19
- def initialize(verifiable_pact)
20
- super(Reshaper.new(verifiable_pact))
21
- end
10
+ property :shortDescription, getter: -> (context) { PactBroker::Pacts::VerifiablePactMessages.new(context[:represented], nil).pact_version_short_description }
22
11
 
23
- property :verification_properties, as: :verificationProperties do
12
+ nested :verificationProperties do
24
13
  include PactBroker::Api::PactBrokerUrls
25
14
 
26
15
  property :pending,
@@ -31,32 +20,8 @@ module PactBroker
31
20
  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
21
 
33
22
  def notices(user_options)
34
- # TODO move this out of the decorator
35
23
  pact_url = pact_version_url(represented, user_options[:base_url])
36
- messages = PactBroker::Pacts::VerifiablePactMessages.new(represented, pact_url)
37
-
38
- the_notices = [{
39
- when: 'before_verification',
40
- text: messages.inclusion_reason
41
- }]
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
24
+ PactBroker::Pacts::BuildVerifiablePactNotices.call(represented, pact_url, include_pending_status: user_options[:include_pending_status])
60
25
  end
61
26
  end
62
27
 
@@ -2,6 +2,8 @@ require_relative 'base_decorator'
2
2
  require_relative 'verifiable_pact_decorator'
3
3
  require 'pact_broker/api/pact_broker_urls'
4
4
  require 'pact_broker/hash_refinements'
5
+ require 'pact_broker/pacts/selector'
6
+ require 'pact_broker/pacts/selectors'
5
7
 
6
8
  module PactBroker
7
9
  module Api
@@ -11,12 +13,13 @@ module PactBroker
11
13
 
12
14
  collection :provider_version_tags, default: []
13
15
 
14
- collection :consumer_version_selectors, default: [], class: OpenStruct do
16
+ collection :consumer_version_selectors, default: PactBroker::Pacts::Selectors.new, class: PactBroker::Pacts::Selector do
15
17
  property :tag
16
18
  property :latest,
17
19
  setter: ->(fragment:, represented:, **) {
18
20
  represented.latest = (fragment == 'true' || fragment == true)
19
21
  }
22
+ property :fallback_tag
20
23
  end
21
24
 
22
25
  property :include_pending_status, default: false,
@@ -31,7 +34,11 @@ module PactBroker
31
34
 
32
35
  def from_hash(hash)
33
36
  # This handles both the snakecase keys from the GET query and the camelcase JSON POST body
34
- super(hash&.snakecase_keys)
37
+ result = super(hash&.snakecase_keys)
38
+ if result.consumer_version_selectors && !result.consumer_version_selectors.is_a?(PactBroker::Pacts::Selectors)
39
+ result.consumer_version_selectors = PactBroker::Pacts::Selectors.new(result.consumer_version_selectors)
40
+ end
41
+ result
35
42
  end
36
43
  end
37
44
  end
@@ -28,7 +28,7 @@ module PactBroker
28
28
 
29
29
  link :'pb:tag' do | options |
30
30
  {
31
- href: pacticipant_url(options.fetch(:base_url), represented.pacticipant) + '/tags/{tag}',
31
+ href: version_url(options.fetch(:base_url), represented) + '/tags/{tag}',
32
32
  title: "Get, create or delete a tag for this pacticipant version",
33
33
  templated: true
34
34
  }
@@ -20,7 +20,7 @@ module PactBroker
20
20
  # Remember to update latest_verification_id_for_pact_version_and_provider_version
21
21
  # if/when DELETE is implemented
22
22
  def allowed_methods
23
- ["GET", "OPTIONS"]
23
+ ["GET", "OPTIONS", "DELETE"]
24
24
  end
25
25
 
26
26
  def resource_exists?
@@ -40,6 +40,11 @@ module PactBroker
40
40
  extended_decorator_for(verification).to_json(user_options: { base_url: base_url })
41
41
  end
42
42
 
43
+ def delete_resource
44
+ verification_service.delete(verification)
45
+ true
46
+ end
47
+
43
48
  private
44
49
 
45
50
  def verification
@@ -0,0 +1,35 @@
1
+ require 'pact_broker/pacts/verifiable_pact_messages'
2
+
3
+ module PactBroker
4
+ module Pacts
5
+ class BuildVerifiablePactNotices
6
+
7
+ def self.call(verifiable_pact, pact_url, options)
8
+ messages = VerifiablePactMessages.new(verifiable_pact, pact_url)
9
+
10
+ notices = [{
11
+ when: 'before_verification',
12
+ text: messages.inclusion_reason
13
+ }]
14
+
15
+ if options[:include_pending_status]
16
+ append_notice(notices, 'before_verification', messages.pending_reason)
17
+ append_notice(notices, 'after_verification:success_true_published_false', messages.verification_success_true_published_false)
18
+ append_notice(notices, 'after_verification:success_false_published_false', messages.verification_success_false_published_false)
19
+ append_notice(notices, 'after_verification:success_true_published_true', messages.verification_success_true_published_true)
20
+ append_notice(notices, 'after_verification:success_false_published_true', messages.verification_success_false_published_true)
21
+ end
22
+ notices
23
+ end
24
+
25
+ def self.append_notice notices, the_when, text
26
+ if text
27
+ notices << {
28
+ when: the_when,
29
+ text: text
30
+ }
31
+ end
32
+ end
33
+ end
34
+ end
35
+ end
@@ -16,6 +16,7 @@ require 'pact_broker/pacts/verifiable_pact'
16
16
  require 'pact_broker/repositories/helpers'
17
17
  require 'pact_broker/pacts/selected_pact'
18
18
  require 'pact_broker/pacts/selector'
19
+ require 'pact_broker/pacts/selectors'
19
20
 
20
21
  module PactBroker
21
22
  module Pacts
@@ -150,7 +151,7 @@ module PactBroker
150
151
  .collect do | pact_publications |
151
152
  selector_tag_names = pact_publications.collect{ | p| p.values.fetch(:consumer_version_tag_name) }
152
153
  latest_pact_publication = pact_publications.sort_by{ |p| p.values.fetch(:consumer_version_order) }.last
153
- selectors = selector_tag_names.collect{ | tag_name | Selector.one_of_tag(tag_name) }
154
+ selectors = Selectors.create_for_all_of_each_tag(selector_tag_names)
154
155
  SelectedPact.new(latest_pact_publication.to_domain, selectors)
155
156
  end
156
157
  end
@@ -206,7 +207,8 @@ module PactBroker
206
207
  pre_existing_pending_tags = pending_tag_names & pre_existing_tag_names
207
208
 
208
209
  if pre_existing_pending_tags.any?
209
- VerifiablePact.new(pact.to_domain, true, pre_existing_pending_tags, [], pact.head_tag_names, nil, true)
210
+ selectors = Selectors.create_for_latest_of_each_tag(pact.head_tag_names)
211
+ VerifiablePact.new(pact.to_domain, selectors, true, pre_existing_pending_tags, [], true)
210
212
  end
211
213
  end.compact
212
214
  end
@@ -349,16 +351,36 @@ module PactBroker
349
351
  selected_pacts = find_pacts_for_which_the_latest_version_is_required(provider_name, consumer_version_selectors) +
350
352
  find_pacts_for_which_the_latest_version_for_the_tag_is_required(provider_name, consumer_version_selectors) +
351
353
  find_pacts_for_which_all_versions_for_the_tag_are_required(provider_name, consumer_version_selectors)
354
+
355
+ selected_pacts = selected_pacts + find_pacts_for_fallback_tags(selected_pacts, provider_name, consumer_version_selectors)
356
+
352
357
  selected_pacts
353
358
  .group_by(&:pact_version_sha)
354
359
  .values
355
360
  .collect do | selected_pacts_for_pact_version_id |
356
361
  SelectedPact.merge(selected_pacts_for_pact_version_id)
357
362
  end
363
+
358
364
  end
359
365
 
360
366
  private
361
367
 
368
+ def find_pacts_for_fallback_tags(selected_pacts, provider_name, consumer_version_selectors)
369
+ # TODO at the moment, the validation doesn't stop fallback being used with 'all' selectors
370
+ selectors_with_fallback_tags = consumer_version_selectors.select(&:fallback_tag?)
371
+ selectors_missing_a_pact = selectors_with_fallback_tags.reject do | selector |
372
+ selected_pacts.any? do | selected_pact |
373
+ selected_pact.latest_for_tag?(selector.tag)
374
+ end
375
+ end
376
+
377
+ if selectors_missing_a_pact.any?
378
+ find_pacts_for_which_the_latest_version_for_the_fallback_tag_is_required(provider_name, selectors_missing_a_pact)
379
+ else
380
+ []
381
+ end
382
+ end
383
+
362
384
  def find_pacts_for_which_the_latest_version_is_required(provider_name, consumer_version_selectors)
363
385
  if consumer_version_selectors.empty?
364
386
  LatestPactPublications
@@ -366,7 +388,7 @@ module PactBroker
366
388
  .order_ignore_case(:consumer_name)
367
389
  .collect do | latest_pact_publication |
368
390
  pact_publication = PactPublication.find(id: latest_pact_publication.id)
369
- SelectedPact.new(pact_publication.to_domain, [Selector.overall_latest])
391
+ SelectedPact.new(pact_publication.to_domain, Selectors.create_for_overall_latest)
370
392
  end
371
393
  else
372
394
  []
@@ -375,38 +397,70 @@ module PactBroker
375
397
 
376
398
  def find_pacts_for_which_the_latest_version_for_the_tag_is_required(provider_name, consumer_version_selectors)
377
399
  # The tags for which only the latest version is specified
378
- latest_tags = consumer_version_selectors.select(&:latest).collect(&:tag).compact.uniq
400
+ tag_names = consumer_version_selectors.tag_names_of_selectors_for_latest_pacts
379
401
 
380
402
  # TODO make this an efficient query!
381
403
  # These are not yet de-duped. Should make the behaviour consistent between this and find_pacts_for_which_all_versions_for_the_tag_are_required ?
382
- if latest_tags.any?
404
+ if tag_names.any?
383
405
  LatestTaggedPactPublications
384
406
  .provider(provider_name)
385
- .order_ignore_case(:consumer_name)
386
- .where(tag_name: latest_tags)
407
+ .where(tag_name: tag_names)
387
408
  .all
388
409
  .group_by(&:pact_version_id)
389
410
  .values
390
411
  .collect do | pact_publications |
391
- selector_tag_names = pact_publications.collect(&:tag_name)
392
- last_pact_publication = pact_publications.sort_by(&:consumer_version_order).last
393
- pact_publication = PactPublication.find(id: last_pact_publication.id)
394
- SelectedPact.new(
395
- pact_publication.to_domain,
396
- selector_tag_names.collect{ | tag_name| Selector.latest_for_tag(tag_name) }
397
- )
412
+ create_selected_pact(pact_publications)
398
413
  end
399
414
  else
400
415
  []
401
416
  end
402
417
  end
403
418
 
419
+ def create_selected_pact(pact_publications)
420
+ selector_tag_names = pact_publications.collect(&:tag_name)
421
+ selectors = Selectors.create_for_latest_of_each_tag(selector_tag_names)
422
+ last_pact_publication = pact_publications.sort_by(&:consumer_version_order).last
423
+ pact_publication = PactPublication.find(id: last_pact_publication.id)
424
+ SelectedPact.new(
425
+ pact_publication.to_domain,
426
+ selectors
427
+ )
428
+ end
429
+
430
+ def create_fallback_selected_pact(pact_publications, consumer_version_selectors)
431
+ selector_tag_names = pact_publications.collect(&:tag_name)
432
+ selectors = Selectors.create_for_latest_fallback_of_each_tag(selector_tag_names)
433
+ last_pact_publication = pact_publications.sort_by(&:consumer_version_order).last
434
+ pact_publication = PactPublication.find(id: last_pact_publication.id)
435
+ SelectedPact.new(
436
+ pact_publication.to_domain,
437
+ selectors
438
+ )
439
+ end
440
+
441
+ def find_pacts_for_which_the_latest_version_for_the_fallback_tag_is_required(provider_name, selectors)
442
+ selectors.collect do | selector |
443
+ LatestTaggedPactPublications
444
+ .provider(provider_name)
445
+ .where(tag_name: selector.fallback_tag)
446
+ .all
447
+ .collect do | latest_tagged_pact_publication |
448
+ pact_publication = PactPublication.find(id: latest_tagged_pact_publication.id)
449
+ SelectedPact.new(
450
+ pact_publication.to_domain,
451
+ Selectors.new(selector)
452
+ )
453
+ end
454
+ end.flatten
455
+ end
456
+
457
+
404
458
  def find_pacts_for_which_all_versions_for_the_tag_are_required(provider_name, consumer_version_selectors)
405
459
  # The tags for which all versions are specified
406
- all_tags = consumer_version_selectors.reject(&:latest).collect(&:tag)
460
+ tag_names = consumer_version_selectors.tag_names_of_selectors_for_all_pacts
407
461
 
408
- if all_tags.any?
409
- find_all_pact_versions_for_provider_with_consumer_version_tags(provider_name, all_tags)
462
+ if tag_names.any?
463
+ find_all_pact_versions_for_provider_with_consumer_version_tags(provider_name, tag_names)
410
464
  else
411
465
  []
412
466
  end
@@ -11,31 +11,22 @@ module PactBroker
11
11
  @selectors = selectors
12
12
  end
13
13
 
14
- # might actually be, but this code doesn't know it.
15
- def overall_latest?
16
- selectors.any?(&:overall_latest?)
17
- end
18
-
19
- def latest_for_tag?
20
- selectors.any?(&:latest_for_tag?)
21
- end
22
-
23
14
  def self.merge(selected_pacts)
24
15
  latest_selected_pact = selected_pacts.sort_by(&:consumer_version_order).last
25
- selectors = selected_pacts.collect(&:selectors).flatten.uniq
16
+ selectors = selected_pacts.collect(&:selectors).reduce(&:+)
26
17
  SelectedPact.new(latest_selected_pact.pact, selectors)
27
18
  end
28
19
 
29
- def merge(other)
30
- if pact_version_sha != other.pact_version_sha
31
- raise "These two pacts do not have the same pact_version_sha. They cannot be merged. #{pact_version_sha} and #{other.pact_version_sha}"
32
- else
33
- SelectedPact.new()
34
- end
20
+ def tag_names_of_selectors_for_latest_pacts
21
+ selectors.tag_names_of_selectors_for_latest_pacts
22
+ end
23
+
24
+ def overall_latest?
25
+ selectors.overall_latest?
35
26
  end
36
27
 
37
- def tag_names_for_selectors_for_latest_pacts
38
- selectors.select(&:latest_for_tag?).collect(&:tag)
28
+ def latest_for_tag? potential_tag = nil
29
+ selectors.latest_for_tag?(potential_tag)
39
30
  end
40
31
 
41
32
  def consumer_version_order