pact_broker 2.73.0 → 2.74.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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 1bc95def65b82d8d938fa3b245bb6f306092d8d00572778f8b3f8ae377479fd0
4
- data.tar.gz: 2790ca52a1db8ba01ca02ef24b6816482a4fdf38a925e8eb737d998ff2ff1213
3
+ metadata.gz: 4a3779dfce4701e31c25e10a37154785df8745aa022869f70bcdd3c080066169
4
+ data.tar.gz: d9c48a07a42949aea37a84ca43930a53d6403abe02a96d1c1de2d58a27d763bc
5
5
  SHA512:
6
- metadata.gz: 9d2740784d48edea10528d9b3a1db0ec6f89d5474c2b7b3c4c4077a7b1d57c714f7f902066e7e76cf921ab5b51e8cc58b6d3146a2a752c3535394c87e7457831
7
- data.tar.gz: 5fb6688a830ecd05bf7eb8985d651f0a406a5bfe348e29287b93328bb2cf9f36013fda31394e3499ee058c10e54c326366f59567dc3d5eadf02507d9512787f6
6
+ metadata.gz: 2a4a61fe0838766004ab06723b406d51149d748ec449c81139ada966a223b5491d4728fa0cdd52d6e369081af490eb03b4b7036c12c6f2a6b014bf20608c9d68
7
+ data.tar.gz: 569774601622663f53d824d40b0013afd6728f0c603fb9f2f8d66f759603daf7d361d6481003dc83a2a844415d93eae78694a076be1172eb45728d678cd672a2
@@ -1,3 +1,15 @@
1
+ <a name="v2.74.0"></a>
2
+ ### v2.74.0 (2021-01-04)
3
+
4
+ #### Features
5
+
6
+ * include the consumer version selectors in the metadata of the 'pact for verification' URL ([32bbe1c3](/../../commit/32bbe1c3))
7
+
8
+ #### Bug Fixes
9
+
10
+ * **deps**
11
+ * update nokogiri for CVE-2020-26247 ([336ec897](/../../commit/336ec897))
12
+
1
13
  <a name="v2.73.0"></a>
2
14
  ### v2.73.0 (2020-12-16)
3
15
 
@@ -1,11 +1,13 @@
1
1
  require_relative 'base_decorator'
2
2
  require 'pact_broker/api/pact_broker_urls'
3
3
  require 'pact_broker/pacts/build_verifiable_pact_notices'
4
+ require 'pact_broker/pacts/metadata'
4
5
 
5
6
  module PactBroker
6
7
  module Api
7
8
  module Decorators
8
9
  class VerifiablePactDecorator < BaseDecorator
10
+ include PactBroker::Pacts::Metadata
9
11
 
10
12
  property :shortDescription, getter: -> (context) { PactBroker::Pacts::VerifiablePactMessages.new(context[:represented], nil).pact_version_short_description }
11
13
 
@@ -27,7 +29,7 @@ module PactBroker
27
29
  end
28
30
 
29
31
  link :self do | user_options |
30
- metadata = represented.wip ? { wip: true } : nil
32
+ metadata = build_metadata_for_pact_for_verification(represented)
31
33
  {
32
34
  href: pact_version_url_with_metadata(represented, metadata, user_options[:base_url]),
33
35
  name: represented.name
@@ -1,6 +1,8 @@
1
1
  require 'erb'
2
2
  require 'pact_broker/pacts/metadata'
3
3
  require 'pact_broker/logging'
4
+ require 'base64'
5
+ require 'rack'
4
6
 
5
7
  module PactBroker
6
8
  module Api
@@ -77,9 +79,7 @@ module PactBroker
77
79
  def decode_pact_metadata(metadata)
78
80
  if metadata && metadata != ''
79
81
  begin
80
- Rack::Utils.parse_nested_query(Base64.strict_decode64(metadata)).each_with_object({}) do | (k, v), new_hash |
81
- new_hash[k.to_sym] = v
82
- end
82
+ Rack::Utils.parse_nested_query(Base64.strict_decode64(metadata))
83
83
  rescue StandardError => e
84
84
  logger.warn("Exception parsing webhook metadata: #{metadata}", e)
85
85
  {}
@@ -1,4 +1,5 @@
1
1
  require 'pact_broker/hash_refinements'
2
+ require 'pact_broker/pacts/metadata'
2
3
 
3
4
  module PactBroker
4
5
  module Api
@@ -15,7 +16,7 @@ module PactBroker
15
16
  end
16
17
 
17
18
  def metadata
18
- @metadata ||= PactBrokerUrls.decode_pact_metadata(identifier_from_path[:metadata])
19
+ @metadata ||= PactBroker::Pacts::Metadata.parse_metadata(PactBrokerUrls.decode_pact_metadata(identifier_from_path[:metadata]))
19
20
  end
20
21
  end
21
22
  end
@@ -47,13 +47,20 @@ module PactBroker
47
47
  dataset_module do
48
48
  include PactBroker::Repositories::Helpers
49
49
 
50
+ def for(pacticipant_name, version_number)
51
+ where_pacticipant_name(pacticipant_name).where_number(version_number).single_record
52
+ end
53
+
50
54
  def where_pacticipant_name(pacticipant_name)
51
- join(:pacticipants) do | p |
52
- Sequel.&(
53
- { Sequel[first_source_alias][:pacticipant_id] => Sequel[p][:id] },
54
- name_like(Sequel[p][:name], pacticipant_name)
55
- )
56
- end
55
+ where(pacticipant_id: db[:pacticipants].select(:id).where(name_like(:name, pacticipant_name)))
56
+ # If we do a join, we get the extra columns from the pacticipant table that then
57
+ # make == not work
58
+ # join(:pacticipants) do | p |
59
+ # Sequel.&(
60
+ # { Sequel[first_source_alias][:pacticipant_id] => Sequel[p][:id] },
61
+ # name_like(Sequel[p][:name], pacticipant_name)
62
+ # )
63
+ # end
57
64
  end
58
65
 
59
66
  def where_tag(tag)
@@ -3,6 +3,15 @@ module PactBroker
3
3
  module Metadata
4
4
  extend self
5
5
 
6
+ MAPPINGS = [
7
+ [:consumer_version_tags, "cvt"],
8
+ [:consumer_version_number, "cvn"],
9
+ [:wip, "w"],
10
+ [:consumer_version_selectors, "s"],
11
+ [:tag, "t"],
12
+ [:latest, "l"]
13
+ ]
14
+
6
15
  # When verifying a pact at /.../latest/TAG, this stores the
7
16
  # tag and the current consumer version number in the
8
17
  # metadata parameter of the URL for publishing the verification results.
@@ -11,12 +20,12 @@ module PactBroker
11
20
  def build_metadata_for_latest_pact(pact, selection_parameters)
12
21
  if selection_parameters[:tag]
13
22
  {
14
- consumer_version_tags: [selection_parameters[:tag]],
15
- consumer_version_number: pact.consumer_version_number
23
+ "cvt" => [selection_parameters[:tag]],
24
+ "cvn" => pact.consumer_version_number
16
25
  }
17
26
  else
18
27
  {
19
- consumer_version_number: pact.consumer_version_number
28
+ "cvn" => pact.consumer_version_number
20
29
  }
21
30
  end
22
31
  end
@@ -28,12 +37,50 @@ module PactBroker
28
37
  # go back to the correct consumer version number (eg for git statuses)
29
38
  def build_metadata_for_webhook_triggered_by_pact_publication(pact)
30
39
  metadata = {
31
- consumer_version_number: pact.consumer_version_number,
32
- consumer_version_tags: pact.consumer_version_tag_names
40
+ "cvn" => pact.consumer_version_number,
41
+ "cvt" => pact.consumer_version_tag_names
33
42
  }
34
- metadata[:wip] = "true"
43
+ metadata["w"] = "true"
35
44
  metadata
36
45
  end
46
+
47
+ def build_metadata_for_pact_for_verification(verifiable_pact)
48
+ # todo put in tags
49
+ if verifiable_pact.wip
50
+ {
51
+ "w" => true
52
+ }
53
+ else
54
+ {
55
+ "s" => verifiable_pact.selectors.collect do | selector |
56
+ {
57
+ "t" => selector.tag,
58
+ "l" => selector.latest,
59
+ "cvn" => selector.consumer_version.number
60
+ }.compact
61
+ end
62
+ }
63
+ end
64
+ end
65
+
66
+ def parse_metadata(metadata)
67
+ parse_object(metadata)
68
+ end
69
+
70
+ def parse_object(object)
71
+ case object
72
+ when Hash then parse_hash(object)
73
+ when Array then object.collect{|i| parse_object(i) }
74
+ else object
75
+ end
76
+ end
77
+
78
+ def parse_hash(hash)
79
+ hash.each_with_object({}) do | (key, value), new_hash |
80
+ long_key = MAPPINGS.find{ |mapping| mapping.last == key }&.first
81
+ new_hash[long_key || key] = parse_object(value)
82
+ end
83
+ end
37
84
  end
38
85
  end
39
86
  end
@@ -168,7 +168,7 @@ module PactBroker
168
168
  .values
169
169
  .collect do | pact_publications |
170
170
  latest_pact_publication = pact_publications.sort_by{ |p| p.values.fetch(:consumer_version_order) }.last
171
- SelectedPact.new(latest_pact_publication.to_domain, Selectors.new(selector))
171
+ SelectedPact.new(latest_pact_publication.to_domain, Selectors.new(selector).resolve(latest_pact_publication.consumer_version))
172
172
  end
173
173
  end
174
174
 
@@ -428,7 +428,7 @@ module PactBroker
428
428
  .order_ignore_case(:consumer_name)
429
429
  .collect do | latest_pact_publication |
430
430
  pact_publication = PactPublication.find(id: latest_pact_publication.id)
431
- SelectedPact.new(pact_publication.to_domain, Selectors.create_for_overall_latest)
431
+ SelectedPact.new(pact_publication.to_domain, Selectors.create_for_overall_latest.resolve(pact_publication.consumer_version))
432
432
  end
433
433
  else
434
434
  selectors_for_overall_latest = consumer_version_selectors.select(&:overall_latest?)
@@ -438,7 +438,7 @@ module PactBroker
438
438
  query.collect do | latest_pact_publication |
439
439
  pact_publication = PactPublication.find(id: latest_pact_publication.id)
440
440
  resolved_selector = selector.consumer ? Selector.latest_for_consumer(selector.consumer) : Selector.overall_latest
441
- SelectedPact.new(pact_publication.to_domain, Selectors.new(resolved_selector))
441
+ SelectedPact.new(pact_publication.to_domain, Selectors.new(resolved_selector).resolve(pact_publication.consumer_version))
442
442
  end
443
443
  end
444
444
  end
@@ -453,26 +453,19 @@ module PactBroker
453
453
  query = query.consumer(selector.consumer) if selector.consumer
454
454
  query.all.collect do | latest_tagged_pact_publication |
455
455
  pact_publication = PactPublication.find(id: latest_tagged_pact_publication.id)
456
- resolved_pact = selector.consumer ? Selector.latest_for_tag_and_consumer(selector.tag, selector.consumer) : Selector.latest_for_tag(selector.tag)
456
+ resolved_selector = if selector.consumer
457
+ Selector.latest_for_tag_and_consumer(selector.tag, selector.consumer).resolve(pact_publication.consumer_version)
458
+ else
459
+ Selector.latest_for_tag(selector.tag).resolve(pact_publication.consumer_version)
460
+ end
457
461
  SelectedPact.new(
458
462
  pact_publication.to_domain,
459
- Selectors.new(resolved_pact)
463
+ Selectors.new(resolved_selector)
460
464
  )
461
465
  end
462
466
  end
463
467
  end
464
468
 
465
- def create_fallback_selected_pact(pact_publications, consumer_version_selectors)
466
- selector_tag_names = pact_publications.collect(&:tag_name)
467
- selectors = Selectors.create_for_latest_fallback_of_each_tag(selector_tag_names)
468
- last_pact_publication = pact_publications.sort_by(&:consumer_version_order).last
469
- pact_publication = unscoped(PactPublication).find(id: last_pact_publication.id)
470
- SelectedPact.new(
471
- pact_publication.to_domain,
472
- selectors
473
- )
474
- end
475
-
476
469
  def find_pacts_for_which_the_latest_version_for_the_fallback_tag_is_required(provider_name, selectors)
477
470
  selectors.collect do | selector |
478
471
  query = scope_for(LatestTaggedPactPublications).provider(provider_name).where(tag_name: selector.fallback_tag)
@@ -482,7 +475,7 @@ module PactBroker
482
475
  pact_publication = unscoped(PactPublication).find(id: latest_tagged_pact_publication.id)
483
476
  SelectedPact.new(
484
477
  pact_publication.to_domain,
485
- Selectors.new(selector)
478
+ Selectors.new(selector.resolve(pact_publication.consumer_version))
486
479
  )
487
480
  end
488
481
  end.flatten
@@ -5,6 +5,10 @@ module PactBroker
5
5
  merge!(options)
6
6
  end
7
7
 
8
+ def resolve(consumer_version)
9
+ ResolvedSelector.new(self.to_h, consumer_version)
10
+ end
11
+
8
12
  def tag= tag
9
13
  self[:tag] = tag
10
14
  end
@@ -94,6 +98,10 @@ module PactBroker
94
98
  !!(tag && !latest?)
95
99
  end
96
100
 
101
+ def == other
102
+ other.class == self.class && super
103
+ end
104
+
97
105
  def <=> other
98
106
  if overall_latest? || other.overall_latest?
99
107
  if overall_latest? == other.overall_latest?
@@ -124,5 +132,19 @@ module PactBroker
124
132
  !!self[:latest]
125
133
  end
126
134
  end
135
+
136
+ class ResolvedSelector < Selector
137
+ def initialize(options = {}, consumer_version)
138
+ super(options.merge(consumer_version: consumer_version))
139
+ end
140
+
141
+ def consumer_version
142
+ self[:consumer_version]
143
+ end
144
+
145
+ def == other
146
+ super && consumer_version == other.consumer_version
147
+ end
148
+ end
127
149
  end
128
150
  end
@@ -19,6 +19,10 @@ module PactBroker
19
19
  Selectors.new([Selector.overall_latest])
20
20
  end
21
21
 
22
+ def resolve(consumer_version)
23
+ Selectors.new(collect{ |selector| selector.resolve(consumer_version) })
24
+ end
25
+
22
26
  def + other
23
27
  Selectors.new(super)
24
28
  end
@@ -19,13 +19,13 @@ module PactBroker
19
19
  logger.filter(/(Authorization: ).*/,'\1[REMOVED]')
20
20
  end
21
21
  end
22
- # faraday.headers['Authorization'] = "Bearer #{pactflow_api_token}"
22
+ faraday.headers['Authorization'] = "Bearer #{auth[:token]}" if auth[:token]
23
23
  faraday.adapter Faraday.default_adapter
24
24
  end
25
25
  end
26
26
 
27
27
  def sleep
28
- Kernel.sleep 1
28
+ Kernel.sleep 0.5
29
29
  self
30
30
  end
31
31
 
@@ -42,7 +42,7 @@ module PactBroker
42
42
 
43
43
  def create_tag(pacticipant:, version:, tag:)
44
44
  puts "Creating tag '#{tag}' for #{pacticipant} version #{version}"
45
- client.put("/pacticipants/#{encode(pacticipant)}/versions/#{encode(version)}/tags/#{encode(tag)}", {})
45
+ client.put("/pacticipants/#{encode(pacticipant)}/versions/#{encode(version)}/tags/#{encode(tag)}", {}).tap { |response| check_for_error(response) }
46
46
  self
47
47
  end
48
48
 
@@ -53,6 +53,13 @@ module PactBroker
53
53
  self
54
54
  end
55
55
 
56
+ def create_pacticipant(name)
57
+ puts "Creating pacticipant with name #{name}"
58
+ client.post("/pacticipants", { name: name}).tap { |response| check_for_error(response) }
59
+ separate
60
+ self
61
+ end
62
+
56
63
  def publish_pact(consumer: last_consumer_name, consumer_version:, provider: last_provider_name, content_id:, tag:)
57
64
  @last_consumer_name = consumer
58
65
  @last_provider_name = provider
@@ -61,16 +68,18 @@ module PactBroker
61
68
  [*tag].each do | tag |
62
69
  create_tag(pacticipant: consumer, version: consumer_version, tag: tag)
63
70
  end
71
+ puts "" if [*tag].any?
64
72
 
65
73
  content = generate_content(consumer, provider, content_id)
66
74
  puts "Publishing pact for consumer #{consumer} version #{consumer_version} and provider #{provider}"
67
75
  pact_path = "/pacts/provider/#{encode(provider)}/consumer/#{encode(consumer)}/version/#{encode(consumer_version)}"
68
- @publish_pact_response = client.put(pact_path, content)
76
+ @publish_pact_response = client.put(pact_path, content).tap { |response| check_for_error(response) }
69
77
  separate
70
78
  self
71
79
  end
72
80
 
73
81
  def get_pacts_for_verification(provider: last_provider_name, provider_version_tag: , consumer_version_selectors:, enable_pending: false, include_wip_pacts_since: nil)
82
+ @last_provider_name = provider
74
83
  puts "Fetching pacts for verification for #{provider}"
75
84
  body = {
76
85
  providerVersionTags: [*provider_version_tag],
@@ -80,7 +89,7 @@ module PactBroker
80
89
  }.compact
81
90
  puts body.to_yaml
82
91
  puts ""
83
- @pacts_for_verification_response = client.post("/pacts/provider/#{encode(provider)}/for-verification", body)
92
+ @pacts_for_verification_response = client.post("/pacts/provider/#{encode(provider)}/for-verification", body).tap { |response| check_for_error(response) }
84
93
 
85
94
  print_pacts_for_verification
86
95
  separate
@@ -88,23 +97,32 @@ module PactBroker
88
97
  end
89
98
 
90
99
  def print_pacts_for_verification
91
- pacts = @pacts_for_verification_response.body["_embedded"]["pacts"]
92
- puts "Pacts for verification (#{pacts.count}):"
93
- pacts.each do | pact |
94
- puts({
95
- "url" => pact["_links"]["self"]["href"],
96
- "wip" => pact["verificationProperties"]["wip"],
97
- "pending" => pact["verificationProperties"]["pending"]
98
- }.to_yaml)
100
+ pacts = @pacts_for_verification_response.body&.dig("_embedded", "pacts")
101
+ if pacts
102
+ puts "Pacts for verification (#{pacts.count}):"
103
+ pacts.each do | pact |
104
+ puts({
105
+ "url" => pact["_links"]["self"]["href"],
106
+ "wip" => pact["verificationProperties"]["wip"],
107
+ "pending" => pact["verificationProperties"]["pending"]
108
+ }.to_yaml)
109
+ end
99
110
  end
100
111
  self
101
112
  end
102
113
 
103
114
  def verify_pact(index: 0, success:, provider: last_provider_name, provider_version_tag: , provider_version: )
115
+ @last_provider_name = provider
104
116
  pact_to_verify = @pacts_for_verification_response.body["_embedded"]["pacts"][index]
105
117
  raise "No pact found to verify at index #{index}" unless pact_to_verify
106
118
  url_of_pact_to_verify = pact_to_verify["_links"]["self"]["href"]
107
- pact_response = client.get(url_of_pact_to_verify)
119
+
120
+ [*provider_version_tag].each do | tag |
121
+ create_tag(pacticipant: provider, version: provider_version, tag: tag)
122
+ end
123
+ puts "" if [*provider_version_tag].any?
124
+
125
+ pact_response = client.get(url_of_pact_to_verify).tap { |response| check_for_error(response) }
108
126
  verification_results_url = pact_response.body["_links"]["pb:publish-verification-results"]["href"]
109
127
 
110
128
  results = {
@@ -112,8 +130,9 @@ module PactBroker
112
130
  testResults: [],
113
131
  providerApplicationVersion: provider_version
114
132
  }
115
- puts "\nPublishing verification"
116
- response = client.post(verification_results_url, results.to_json)
133
+ puts "Publishing verification"
134
+ puts results.to_yaml
135
+ response = client.post(verification_results_url, results.to_json).tap { |response| check_for_error(response) }
117
136
  separate
118
137
  self
119
138
  end
@@ -124,7 +143,7 @@ module PactBroker
124
143
  end
125
144
 
126
145
  def can_i_deploy(pacticipant:, version:, to:)
127
- can_i_deploy_response = client.get("/can-i-deploy", { pacticipant: pacticipant, version: version, to: to} )
146
+ can_i_deploy_response = client.get("/can-i-deploy", { pacticipant: pacticipant, version: version, to: to} ).tap { |response| check_for_error(response) }
128
147
  can = !!(can_i_deploy_response.body['summary'] || {})['deployable']
129
148
  puts "can-i-deploy #{pacticipant} version #{version} to #{to}: #{can ? 'yes' : 'no'}"
130
149
  puts (can_i_deploy_response.body['summary'] || can_i_deploy_response.body).to_yaml
@@ -133,7 +152,8 @@ module PactBroker
133
152
  end
134
153
 
135
154
  def delete_integration(consumer:, provider:)
136
- client.delete("/integrations/provider/#{encode(provider)}/consumer/#{encode(consumer)}")
155
+ puts "Deleting all data for the integration between #{consumer} and #{provider}"
156
+ client.delete("/integrations/provider/#{encode(provider)}/consumer/#{encode(consumer)}").tap { |response| check_for_error(response) }
137
157
  separate
138
158
  self
139
159
  end
@@ -163,6 +183,13 @@ module PactBroker
163
183
  def encode string
164
184
  ERB::Util.url_encode(string)
165
185
  end
186
+
187
+ def check_for_error(response)
188
+ if ! response.success?
189
+ puts response.status
190
+ puts response.body
191
+ end
192
+ end
166
193
  end
167
194
  end
168
195
  end
@@ -1,3 +1,3 @@
1
1
  module PactBroker
2
- VERSION = '2.73.0'
2
+ VERSION = '2.74.0'
3
3
  end
@@ -64,4 +64,5 @@ Gem::Specification.new do |gem|
64
64
  gem.add_runtime_dependency 'table_print', '~> 1.5'
65
65
  gem.add_runtime_dependency 'semantic_logger', '~> 4.3'
66
66
  gem.add_runtime_dependency 'sanitize', '>= 5.2.1', '~> 5.2'
67
+ gem.add_runtime_dependency 'nokogiri', '< 2.0', '>= 1.11.0.rc4' # For CVE-2020-26247 Remove when 1.11 is released properly
67
68
  end
@@ -9,10 +9,15 @@ begin
9
9
 
10
10
  td = PactBroker::Test::HttpTestDataBuilder.new(base_url, { })
11
11
  td.delete_integration(consumer: "MyConsumer", provider: "MyProvider")
12
+ .create_pacticipant("MyConsumer")
13
+ .create_pacticipant("MyProvider")
12
14
  .publish_pact(consumer: "MyConsumer", consumer_version: "1", provider: "MyProvider", content_id: "111", tag: "main")
15
+ .publish_pact(consumer: "MyConsumer", consumer_version: "2", provider: "MyProvider", content_id: "222", tag: "main")
16
+ .publish_pact(consumer: "MyConsumer", consumer_version: "3", provider: "MyProvider", content_id: "111", tag: "feat/a")
13
17
  .get_pacts_for_verification(
14
18
  provider_version_tag: "main",
15
- consumer_version_selectors: [{ tag: "main", latest: true }])
19
+ consumer_version_selectors: [{ tag: "main" }, { tag: "feat/a", latest: true }])
20
+ .verify_pact(success: true, provider_version_tag: "main", provider_version: "2" )
16
21
 
17
22
 
18
23
  rescue StandardError => e
@@ -8,6 +8,7 @@ module PactBroker
8
8
  allow_any_instance_of(PactBroker::Api::PactBrokerUrls).to receive(:pact_version_url_with_metadata).and_return('http://pact')
9
9
  allow(PactBroker::Pacts::BuildVerifiablePactNotices).to receive(:call).and_return(notices)
10
10
  allow_any_instance_of(PactBroker::Pacts::VerifiablePactMessages).to receive(:pact_version_short_description).and_return('short desc')
11
+ allow_any_instance_of(VerifiablePactDecorator).to receive(:build_metadata_for_pact_for_verification).and_return(metadata)
11
12
  end
12
13
 
13
14
  let(:pending_reason) { "the pending reason" }
@@ -45,13 +46,15 @@ module PactBroker
45
46
  name: "name",
46
47
  provider_name: "Bar",
47
48
  pending_provider_tags: pending_provider_tags,
48
- consumer_tags: consumer_tags)
49
+ consumer_tags: consumer_tags,
50
+ selectors: PactBroker::Pacts::Selectors.new([PactBroker::Pacts::ResolvedSelector.new({ latest: true }, double('version', number: "2", id: 1))]))
49
51
  end
50
52
  let(:pending_provider_tags) { %w[dev] }
51
53
  let(:consumer_tags) { %w[dev] }
52
54
  let(:options) { { user_options: { base_url: 'http://example.org', include_pending_status: include_pending_status } } }
53
55
  let(:include_pending_status) { true }
54
56
  let(:wip){ false }
57
+ let(:metadata) { double('metadata') }
55
58
  let(:json) { decorator.to_json(options) }
56
59
 
57
60
  subject { JSON.parse(json) }
@@ -61,7 +64,7 @@ module PactBroker
61
64
  end
62
65
 
63
66
  it "creates the pact version url" do
64
- expect(decorator).to receive(:pact_version_url_with_metadata).with(pact, nil, 'http://example.org')
67
+ expect(decorator).to receive(:pact_version_url_with_metadata).with(pact, metadata, 'http://example.org')
65
68
  subject
66
69
  end
67
70
 
@@ -84,11 +87,6 @@ module PactBroker
84
87
  it "includes the wip flag" do
85
88
  expect(subject['verificationProperties']['wip']).to be true
86
89
  end
87
-
88
- it "includes it in the metadata" do
89
- expect(decorator).to receive(:pact_version_url_with_metadata).with(pact, { wip: true }, 'http://example.org')
90
- subject
91
- end
92
90
  end
93
91
  end
94
92
  end
@@ -107,13 +107,9 @@ module PactBroker
107
107
  end
108
108
 
109
109
  describe "webhook metadata" do
110
- let(:expected_metadata) do
111
- { consumer_version_number: "123/456", consumer_version_tags: %w[dev], wip: "true" }
112
- end
113
-
114
110
  it "builds the webhook metadata" do
115
- encoded_metadata = PactBrokerUrls.encode_metadata(PactBrokerUrls.build_metadata_for_webhook_triggered_by_pact_publication(pact))
116
- expect(PactBrokerUrls.decode_pact_metadata(encoded_metadata)).to eq (expected_metadata)
111
+ encoded_metadata = PactBrokerUrls.encode_metadata("some" => "metadata")
112
+ expect(PactBrokerUrls.decode_pact_metadata(encoded_metadata)).to eq "some" => "metadata"
117
113
  end
118
114
  end
119
115
 
@@ -0,0 +1,73 @@
1
+ require 'pact_broker/pacts/metadata'
2
+
3
+ module PactBroker
4
+ module Pacts
5
+ module Metadata
6
+ describe "#build_metadata_for_pact_for_verification" do
7
+ let(:selectors) do
8
+ Selectors.new([ResolvedSelector.new({ latest: true, consumer: "consumer", tag: "tag" }, consumer_version)])
9
+ end
10
+ let(:consumer_version) { double('version', number: "2") }
11
+ let(:verifiable_pact) { double('PactBroker::Pacts::VerifiablePact', wip: wip, selectors: selectors) }
12
+ let(:wip) { false }
13
+
14
+ subject { Metadata.build_metadata_for_pact_for_verification(verifiable_pact) }
15
+
16
+ it "builds the metadata with the resolved selectors" do
17
+ expect(subject).to eq({
18
+ "s" => [
19
+ {
20
+ "l" => true,
21
+ "t" => "tag",
22
+ "cvn" => "2"
23
+ }
24
+ ]
25
+ })
26
+ end
27
+
28
+ context "when wip is true" do
29
+ let(:wip) { true }
30
+
31
+ it { is_expected.to eq "w" => true }
32
+
33
+ end
34
+ end
35
+
36
+ describe "parse_metadata" do
37
+ let(:incoming_metadata) do
38
+ {
39
+ "cvn" => "2",
40
+ "cvt" => ["tag"],
41
+ "w" => true,
42
+ "s" => [
43
+ {
44
+ "l" => true,
45
+ "t" => "tag",
46
+ "cvn" => "2"
47
+ }
48
+ ]
49
+ }
50
+ end
51
+
52
+ let(:parsed_metadata) do
53
+ {
54
+ :consumer_version_number => "2",
55
+ :consumer_version_tags => ["tag"],
56
+ :wip => true,
57
+ :consumer_version_selectors => [
58
+ {
59
+ :latest => true,
60
+ :tag => "tag",
61
+ :consumer_version_number => "2"
62
+ }
63
+ ]
64
+ }
65
+ end
66
+
67
+ it "expands the key names" do
68
+ expect(Metadata.parse_metadata(incoming_metadata)).to eq parsed_metadata
69
+ end
70
+ end
71
+ end
72
+ end
73
+ end
@@ -30,7 +30,7 @@ module PactBroker
30
30
  context "when a pact exists for the main tag" do
31
31
  it "returns the pact with the main tag" do
32
32
  expect(find_by_consumer_version_number("2")).to_not be nil
33
- expect(find_by_consumer_version_number("2").selectors.first).to eq Selector.latest_for_tag(tag)
33
+ expect(find_by_consumer_version_number("2").selectors.first).to eq Selector.latest_for_tag(tag).resolve(PactBroker::Domain::Version.for("Foo", "2"))
34
34
  end
35
35
 
36
36
  it "does not set the fallback_tag on the selector" do
@@ -67,7 +67,7 @@ module PactBroker
67
67
  it "only returns the pacts for the consumer" do
68
68
  expect(subject.size).to eq 1
69
69
  expect(subject.first.consumer.name).to eq "Foo"
70
- expect(subject.first.selectors.first).to eq selector
70
+ expect(subject.first.selectors.first).to eq selector.resolve(PactBroker::Domain::Version.for("Foo", "1"))
71
71
  end
72
72
  end
73
73
  end
@@ -3,8 +3,6 @@ require 'pact_broker/pacts/repository'
3
3
  module PactBroker
4
4
  module Pacts
5
5
  describe Repository do
6
- let(:td) { TestDataBuilder.new }
7
-
8
6
  describe "#find_for_verification" do
9
7
  def find_by_consumer_version_number(consumer_version_number)
10
8
  subject.find{ |pact| pact.consumer_version_number == consumer_version_number }
@@ -55,8 +53,8 @@ module PactBroker
55
53
 
56
54
  it "returns the latest pact for each consumer" do
57
55
  expect(subject.size).to eq 2
58
- expect(find_by_consumer_name_and_consumer_version_number("Foo1", "2").selectors).to eq [Selector.overall_latest]
59
- expect(find_by_consumer_name_and_consumer_version_number("Foo2", "3").selectors).to eq [Selector.overall_latest]
56
+ expect(find_by_consumer_name_and_consumer_version_number("Foo1", "2").selectors).to eq [Selector.overall_latest.resolve(PactBroker::Domain::Version.find(number: "2"))]
57
+ expect(find_by_consumer_name_and_consumer_version_number("Foo2", "3").selectors).to eq [Selector.overall_latest.resolve(PactBroker::Domain::Version.find(number: "3"))]
60
58
  end
61
59
  end
62
60
 
@@ -76,7 +74,7 @@ module PactBroker
76
74
 
77
75
  it "returns the latest pact for each consumer" do
78
76
  expect(subject.size).to eq 1
79
- expect(find_by_consumer_name_and_consumer_version_number("Foo1", "2").selectors).to eq [pact_selector_1]
77
+ expect(find_by_consumer_name_and_consumer_version_number("Foo1", "2").selectors).to eq [pact_selector_1.resolve(PactBroker::Domain::Version.find(number: "2"))]
80
78
  end
81
79
  end
82
80
 
@@ -98,7 +96,8 @@ module PactBroker
98
96
 
99
97
  it "returns the latest pact for each consumer" do
100
98
  expect(subject.size).to eq 1
101
- expect(find_by_consumer_name_and_consumer_version_number("Foo1", "1").selectors).to eq [pact_selector_1]
99
+ expected_consumer_version = PactBroker::Domain::Version.where_pacticipant_name("Foo1").where(number: "1").single_record
100
+ expect(find_by_consumer_name_and_consumer_version_number("Foo1", "1").selectors).to eq [pact_selector_1.resolve(expected_consumer_version)]
102
101
  end
103
102
  end
104
103
 
@@ -122,11 +121,17 @@ module PactBroker
122
121
  let(:consumer_version_selectors) do
123
122
  Selectors.new(pact_selector_1, pact_selector_2)
124
123
  end
124
+ let(:expected_sorted_selectors) do
125
+ [
126
+ ResolvedSelector.new({ tag: 'dev', latest: true }, PactBroker::Domain::Version.for("Baz", "baz-latest-dev-version")),
127
+ ResolvedSelector.new({ tag: 'prod', latest: true }, PactBroker::Domain::Version.for("Baz", "baz-latest-dev-version"))
128
+ ]
129
+ end
125
130
 
126
131
  it "returns the latest pact with the specified tags for each consumer" do
127
- expect(find_by_consumer_version_number("foo-latest-prod-version").selectors).to eq [Selector.latest_for_tag('prod')]
128
- expect(find_by_consumer_version_number("foo-latest-dev-version").selectors).to eq [Selector.latest_for_tag('dev')]
129
- expect(find_by_consumer_version_number("baz-latest-dev-version").selectors.sort_by{ |s| s[:tag] }).to eq [{ tag: 'dev', latest: true }, { tag: 'prod', latest: true }]
132
+ expect(find_by_consumer_version_number("foo-latest-prod-version").selectors).to eq [Selector.latest_for_tag('prod').resolve(PactBroker::Domain::Version.for("Foo", "foo-latest-prod-version"))]
133
+ expect(find_by_consumer_version_number("foo-latest-dev-version").selectors).to eq [Selector.latest_for_tag('dev').resolve(PactBroker::Domain::Version.for("Foo", "foo-latest-dev-version"))]
134
+ expect(find_by_consumer_version_number("baz-latest-dev-version").selectors.sort_by{ |s| s[:tag] }).to eq expected_sorted_selectors
130
135
  expect(subject.size).to eq 3
131
136
  end
132
137
 
@@ -134,14 +139,29 @@ module PactBroker
134
139
  expect(find_by_consumer_version_number("foo-latest-prod-version").selectors.collect(&:tag)).to eq ['prod']
135
140
  end
136
141
 
137
- context "when a consumer name is specified", pending: "not yet implemented, but will do" do
142
+ context "when a consumer name is specified" do
143
+ before do
144
+ td.create_pact_with_hierarchy("Foo", "2", "Bar")
145
+ .create_consumer_version_tag("prod")
146
+ .create_pact_with_hierarchy("Foo", "3", "Bar")
147
+ .create_consumer_version_tag("prod")
148
+ .create_consumer_version("4")
149
+ .create_consumer_version_tag("prod")
150
+ .republish_same_pact
151
+ end
152
+
138
153
  let(:consumer_version_selectors) do
139
154
  Selectors.new(Selector.all_for_tag_and_consumer('prod', 'Foo'))
140
155
  end
141
156
 
142
- it "only returns the pacts for that consumer" do
157
+ it "returns all the pacts with that tag for that consumer" do
143
158
  expect(subject.size).to eq 3
144
- expect(find_by_consumer_version_number("foo-latest-prod-version").selectors).to eq [Selector.all_for_tag_and_consumer('prod', 'Foo')]
159
+ expect(find_by_consumer_version_number("foo-latest-prod-version").selectors).to eq [Selector.all_for_tag_and_consumer('prod', 'Foo').resolve(PactBroker::Domain::Version.for("Foo", "foo-latest-prod-version"))]
160
+ end
161
+
162
+ it "uses the latest consumer verison number as the resolved version when the same pact content is selected multiple times" do
163
+ expect(find_by_consumer_version_number("3")).to be nil
164
+ expect(find_by_consumer_version_number("4").selectors).to eq [Selector.all_for_tag_and_consumer('prod', 'Foo').resolve(PactBroker::Domain::Version.for("Foo", "4"))]
145
165
  end
146
166
  end
147
167
  end
@@ -246,7 +266,7 @@ module PactBroker
246
266
  end
247
267
 
248
268
  it "does not set the tag name" do
249
- expect(find_by_consumer_version_number("foo-latest-dev-version").selectors).to eq [{ latest: true }]
269
+ expect(find_by_consumer_version_number("foo-latest-dev-version").selectors).to eq [ResolvedSelector.new({ latest: true }, PactBroker::Domain::Version.find(number: "foo-latest-dev-version"))]
250
270
  expect(find_by_consumer_version_number("foo-latest-dev-version").overall_latest?).to be true
251
271
  end
252
272
  end
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.73.0
4
+ version: 2.74.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-12-16 00:00:00.000000000 Z
13
+ date: 2021-01-04 00:00:00.000000000 Z
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
16
  name: httparty
@@ -354,6 +354,26 @@ dependencies:
354
354
  - - "~>"
355
355
  - !ruby/object:Gem::Version
356
356
  version: '5.2'
357
+ - !ruby/object:Gem::Dependency
358
+ name: nokogiri
359
+ requirement: !ruby/object:Gem::Requirement
360
+ requirements:
361
+ - - "<"
362
+ - !ruby/object:Gem::Version
363
+ version: '2.0'
364
+ - - ">="
365
+ - !ruby/object:Gem::Version
366
+ version: 1.11.0.rc4
367
+ type: :runtime
368
+ prerelease: false
369
+ version_requirements: !ruby/object:Gem::Requirement
370
+ requirements:
371
+ - - "<"
372
+ - !ruby/object:Gem::Version
373
+ version: '2.0'
374
+ - - ">="
375
+ - !ruby/object:Gem::Version
376
+ version: 1.11.0.rc4
357
377
  description: A server that stores and returns pact files generated by the pact gem.
358
378
  It enables head/prod cross testing of the consumer and provider projects.
359
379
  email:
@@ -1294,6 +1314,7 @@ files:
1294
1314
  - spec/lib/pact_broker/pacts/generate_sha_spec.rb
1295
1315
  - spec/lib/pact_broker/pacts/latest_tagged_pact_publications_spec.rb
1296
1316
  - spec/lib/pact_broker/pacts/merger_spec.rb
1317
+ - spec/lib/pact_broker/pacts/metadata_spec.rb
1297
1318
  - spec/lib/pact_broker/pacts/pact_params_spec.rb
1298
1319
  - spec/lib/pact_broker/pacts/pact_publication_spec.rb
1299
1320
  - spec/lib/pact_broker/pacts/pact_version_spec.rb
@@ -1463,7 +1484,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
1463
1484
  - !ruby/object:Gem::Version
1464
1485
  version: '0'
1465
1486
  requirements: []
1466
- rubygems_version: 3.2.1
1487
+ rubygems_version: 3.2.4
1467
1488
  signing_key:
1468
1489
  specification_version: 4
1469
1490
  summary: See description
@@ -1693,6 +1714,7 @@ test_files:
1693
1714
  - spec/lib/pact_broker/pacts/generate_sha_spec.rb
1694
1715
  - spec/lib/pact_broker/pacts/latest_tagged_pact_publications_spec.rb
1695
1716
  - spec/lib/pact_broker/pacts/merger_spec.rb
1717
+ - spec/lib/pact_broker/pacts/metadata_spec.rb
1696
1718
  - spec/lib/pact_broker/pacts/pact_params_spec.rb
1697
1719
  - spec/lib/pact_broker/pacts/pact_publication_spec.rb
1698
1720
  - spec/lib/pact_broker/pacts/pact_version_spec.rb