pact_broker 2.12.0 → 2.13.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (100) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +42 -5
  3. data/README.md +13 -8
  4. data/bethtest.rb +21 -94
  5. data/db/migrations/20171112_add_test_results.rb +7 -0
  6. data/db/migrations/20171117_create_webhook_events.rb +14 -0
  7. data/db/migrations/20171118_create_webhook_events.rb +18 -0
  8. data/db/migrations/20180108_create_certificates_table.rb +14 -0
  9. data/db/migrations/20180109_migrate_trigger_type.rb +9 -0
  10. data/db/pact_broker_database.sqlite3 +0 -0
  11. data/db/test/backwards_compatibility/gemfiles/1.18.0.gemfile.lock +5 -5
  12. data/db/test/backwards_compatibility/gemfiles/2.0.0.gemfile.lock +5 -5
  13. data/db/test/backwards_compatibility/gemfiles/2.1.0.gemfile.lock +5 -5
  14. data/db/test/backwards_compatibility/gemfiles/2.2.0.gemfile.lock +12 -14
  15. data/db/test/backwards_compatibility/gemfiles/2.3.0.gemfile.lock +12 -14
  16. data/db/test/backwards_compatibility/gemfiles/2.4.2.gemfile.lock +12 -14
  17. data/db/test/backwards_compatibility/gemfiles/2.5.1.gemfile.lock +12 -14
  18. data/db/test/backwards_compatibility/gemfiles/2.6.0.gemfile.lock +12 -14
  19. data/db/test/backwards_compatibility/gemfiles/head.gemfile.lock +16 -15
  20. data/db/test/change_migration_strategy/before/Gemfile +1 -0
  21. data/example/README.md +65 -0
  22. data/example/config.ru +1 -0
  23. data/example/example_data.sql +17 -0
  24. data/lib/pact_broker/api.rb +1 -1
  25. data/lib/pact_broker/api/contracts/webhook_contract.rb +9 -1
  26. data/lib/pact_broker/api/decorators/verification_decorator.rb +1 -0
  27. data/lib/pact_broker/api/decorators/webhook_decorator.rb +35 -5
  28. data/lib/pact_broker/api/resources/matrix_badge.rb +21 -0
  29. data/lib/pact_broker/certificates/certificate.rb +8 -0
  30. data/lib/pact_broker/certificates/service.rb +41 -0
  31. data/lib/pact_broker/doc/controllers/app.rb +12 -2
  32. data/lib/pact_broker/doc/views/webhooks.markdown +37 -2
  33. data/lib/pact_broker/domain/verification.rb +2 -0
  34. data/lib/pact_broker/domain/webhook.rb +2 -1
  35. data/lib/pact_broker/domain/webhook_request.rb +22 -4
  36. data/lib/pact_broker/error.rb +5 -0
  37. data/lib/pact_broker/matrix/parse_query.rb +7 -10
  38. data/lib/pact_broker/matrix/repository.rb +5 -32
  39. data/lib/pact_broker/matrix/service.rb +21 -3
  40. data/lib/pact_broker/pacts/repository.rb +9 -2
  41. data/lib/pact_broker/pacts/service.rb +2 -2
  42. data/lib/pact_broker/services.rb +5 -0
  43. data/lib/pact_broker/ui/app.rb +15 -0
  44. data/lib/pact_broker/ui/controllers/matrix.rb +58 -3
  45. data/lib/pact_broker/ui/views/matrix/show.haml +65 -10
  46. data/lib/pact_broker/verifications/service.rb +6 -1
  47. data/lib/pact_broker/version.rb +1 -1
  48. data/lib/pact_broker/webhooks/job.rb +1 -1
  49. data/lib/pact_broker/webhooks/repository.rb +17 -0
  50. data/lib/pact_broker/webhooks/service.rb +8 -7
  51. data/lib/pact_broker/webhooks/triggered_webhook.rb +1 -1
  52. data/lib/pact_broker/webhooks/webhook.rb +3 -0
  53. data/lib/pact_broker/webhooks/webhook_event.rb +24 -0
  54. data/pact_broker.gemspec +2 -1
  55. data/public/javascripts/matrix.js +60 -0
  56. data/public/stylesheets/matrix.css +12 -0
  57. data/script/db-spec.sh +1 -0
  58. data/script/foo-bar-verification.json +57 -0
  59. data/script/insert-self-signed-certificate-from-url.rb +32 -0
  60. data/script/publish-verification.sh +5 -0
  61. data/script/seed-matrix.rb +6 -5
  62. data/script/seed.rb +67 -59
  63. data/spec/features/create_webhook_spec.rb +4 -1
  64. data/spec/features/get_matrix_badge_spec.rb +40 -0
  65. data/spec/features/publish_verification_spec.rb +28 -4
  66. data/spec/fixtures/certificate-invalid.pem +29 -0
  67. data/spec/fixtures/certificate.pem +53 -0
  68. data/spec/fixtures/certificates/cacert.pem +21 -0
  69. data/spec/fixtures/certificates/cert.pem +20 -0
  70. data/spec/fixtures/certificates/key.pem +27 -0
  71. data/spec/fixtures/certificates/self-signed.badssl.com.pem +21 -0
  72. data/spec/fixtures/verification.json +4 -1
  73. data/spec/fixtures/webhook_valid.json +3 -0
  74. data/spec/integration/webhooks/certificate_spec.rb +80 -0
  75. data/spec/lib/pact_broker/api/contracts/webhook_contract_spec.rb +20 -0
  76. data/spec/lib/pact_broker/api/decorators/pact_webhooks_status_decorator_spec.rb +2 -2
  77. data/spec/lib/pact_broker/api/decorators/verification_decorator_spec.rb +5 -0
  78. data/spec/lib/pact_broker/api/decorators/verification_summary_decorator_spec.rb +1 -0
  79. data/spec/lib/pact_broker/api/decorators/webhook_decorator_spec.rb +29 -19
  80. data/spec/lib/pact_broker/api/resources/badge_spec.rb +61 -0
  81. data/spec/lib/pact_broker/api/resources/matrix_badge_spec.rb +11 -0
  82. data/spec/lib/pact_broker/api/resources/pact_webhooks_spec.rb +8 -9
  83. data/spec/lib/pact_broker/certificates/service_spec.rb +60 -0
  84. data/spec/lib/pact_broker/domain/verification_spec.rb +13 -0
  85. data/spec/lib/pact_broker/domain/webhook_request_spec.rb +0 -4
  86. data/spec/lib/pact_broker/matrix/service_spec.rb +40 -8
  87. data/spec/lib/pact_broker/pacts/repository_spec.rb +18 -1
  88. data/spec/lib/pact_broker/webhooks/job_spec.rb +1 -1
  89. data/spec/lib/pact_broker/webhooks/repository_spec.rb +53 -13
  90. data/spec/lib/pact_broker/webhooks/service_spec.rb +9 -6
  91. data/spec/migrations/change_migration_strategy_spec.rb +13 -14
  92. data/spec/spec_helper.rb +4 -0
  93. data/spec/support/ssl_webhook_server.rb +37 -0
  94. data/spec/support/test_data_builder.rb +12 -4
  95. data/tasks/database.rb +9 -7
  96. data/tasks/database/table_dependency_calculator.rb +44 -0
  97. metadata +57 -6
  98. data/lib/pact_broker/doc/views/pact-webhooks.markdown +0 -50
  99. data/lib/pact_broker/doc/views/webhooks-create.markdown +0 -38
  100. data/lib/pact_broker/doc/views/webhooks-webhooks.markdown +0 -15
@@ -12,6 +12,7 @@ module PactBroker
12
12
  provider_version_number: "4.5.6",
13
13
  provider_name: 'Provider',
14
14
  consumer_name: 'Consumer',
15
+ test_results: { 'arbitrary' => 'json' },
15
16
  build_url: 'http://build-url',
16
17
  pact_version_sha: '1234',
17
18
  latest_pact_publication: pact_publication,
@@ -39,6 +40,10 @@ module PactBroker
39
40
  expect(subject[:providerApplicationVersion]).to eq "4.5.6"
40
41
  end
41
42
 
43
+ it "includes the test results" do
44
+ expect(subject[:testResults]).to eq(arbitrary: 'json')
45
+ end
46
+
42
47
  it "includes the build URL" do
43
48
  expect(subject[:buildUrl]).to eq "http://build-url"
44
49
  end
@@ -19,6 +19,7 @@ module PactBroker
19
19
  pact_version: pact_version,
20
20
  pact_version_sha: '1234',
21
21
  latest_pact_publication: pact,
22
+ test_results: nil,
22
23
  execution_date: DateTime.now)
23
24
  end
24
25
  let(:pact_version) do
@@ -21,6 +21,7 @@ module PactBroker
21
21
 
22
22
  let(:consumer) { Domain::Pacticipant.new(name: 'Consumer') }
23
23
  let(:provider) { Domain::Pacticipant.new(name: 'Provider') }
24
+ let(:event) { Webhooks::WebhookEvent.new(name: 'something_happened') }
24
25
  let(:created_at) { DateTime.now }
25
26
  let(:updated_at) { created_at + 1 }
26
27
 
@@ -30,6 +31,7 @@ module PactBroker
30
31
  uuid: 'some-uuid',
31
32
  consumer: consumer,
32
33
  provider: provider,
34
+ events: [event],
33
35
  created_at: created_at,
34
36
  updated_at: updated_at
35
37
  )
@@ -44,26 +46,14 @@ module PactBroker
44
46
  expect(parsed_json[:request]).to eq request
45
47
  end
46
48
 
47
- it 'includes an embedded consumer' do
48
- expect(parsed_json[:_embedded][:consumer]).to eq ({
49
- name: 'Consumer',
50
- _links: {
51
- self: {
52
- href: 'http://example.org/pacticipants/Consumer'
53
- }
54
- }
55
- })
49
+ it 'includes a link to the consumer' do
50
+ expect(parsed_json[:_links][:'pb:consumer'][:name]).to eq 'Consumer'
51
+ expect(parsed_json[:_links][:'pb:consumer'][:href]).to eq 'http://example.org/pacticipants/Consumer'
56
52
  end
57
53
 
58
- it 'includes an embedded provider' do
59
- expect(parsed_json[:_embedded][:provider]).to eq ({
60
- name: 'Provider',
61
- _links: {
62
- self: {
63
- href: 'http://example.org/pacticipants/Provider'
64
- }
65
- }
66
- })
54
+ it 'includes a link to the provider' do
55
+ expect(parsed_json[:_links][:'pb:provider'][:name]).to eq 'Provider'
56
+ expect(parsed_json[:_links][:'pb:provider'][:href]).to eq 'http://example.org/pacticipants/Provider'
67
57
  end
68
58
 
69
59
  it 'includes a link to itself' do
@@ -83,6 +73,10 @@ module PactBroker
83
73
  expect(parsed_json[:_links][:'pb:execute'][:href]).to eq 'http://example.org/webhooks/some-uuid/execute'
84
74
  end
85
75
 
76
+ it 'includes the events' do
77
+ expect(parsed_json[:events].first).to eq name: 'something_happened'
78
+ end
79
+
86
80
  it 'includes timestamps' do
87
81
  expect(parsed_json[:createdAt]).to eq created_at.xmlschema
88
82
  expect(parsed_json[:updatedAt]).to eq updated_at.xmlschema
@@ -97,7 +91,8 @@ module PactBroker
97
91
  end
98
92
 
99
93
  describe 'from_json' do
100
- let(:hash) { { request: request } }
94
+ let(:hash) { { request: request, events: [event] } }
95
+ let(:event) { {name: 'something_happened'} }
101
96
  let(:json) { hash.to_json }
102
97
  let(:webhook) { Domain::Webhook.new }
103
98
  let(:parsed_object) { subject.from_json(json) }
@@ -117,6 +112,21 @@ module PactBroker
117
112
  it 'parses the request body' do
118
113
  expect(parsed_object.request.body).to eq 'some' => 'body'
119
114
  end
115
+
116
+ it 'parses the events' do
117
+ expect(parsed_object.events.size).to eq 1
118
+ expect(parsed_object.events.first.name).to eq 'something_happened'
119
+ end
120
+
121
+ context "when no events are specified" do
122
+ let(:hash) { { request: request } }
123
+ let(:webhook) { Domain::Webhook.new }
124
+
125
+ it "defaults to a single contract_changed event for backwards compatibility" do
126
+ expect(parsed_object.events.size).to eq 1
127
+ expect(parsed_object.events.first.name).to eq PactBroker::Webhooks::WebhookEvent::DEFAULT_EVENT_NAME
128
+ end
129
+ end
120
130
  end
121
131
  end
122
132
  end
@@ -1,5 +1,6 @@
1
1
  require 'pact_broker/api/resources/badge'
2
2
  require 'pact_broker/badges/service'
3
+ require 'pact_broker/matrix/service'
3
4
 
4
5
  module PactBroker
5
6
  module Api
@@ -118,6 +119,66 @@ module PactBroker
118
119
  subject
119
120
  end
120
121
  end
122
+
123
+ context "when retrieving the badge for a matrix row by tag" do
124
+ before do
125
+ allow(PactBroker::Matrix::Service).to receive(:find_for_consumer_and_provider_with_tags).and_return(row)
126
+ allow(PactBroker::Verifications::Service).to receive(:find_by_id).and_return(verification)
127
+ end
128
+
129
+ let(:path) { "/matrix/provider/provider/latest/master/consumer/consumer/latest/prod/badge" }
130
+ let(:row) { { verification_id: 1 } }
131
+
132
+
133
+ it "looks up the matrix row" do
134
+ expect(PactBroker::Matrix::Service).to receive(:find_for_consumer_and_provider_with_tags).with(
135
+ hash_including(consumer_name: 'consumer',
136
+ provider_name: 'provider',
137
+ tag: 'prod',
138
+ provider_tag: 'master'
139
+ ))
140
+ subject
141
+ end
142
+
143
+ context "when a matrix row is found" do
144
+ context "when there is a verification_id" do
145
+ it "looks up the verification" do
146
+ expect(PactBroker::Verifications::Service).to receive(:find_by_id).with(1)
147
+ subject
148
+ end
149
+
150
+ it "returns the badge" do
151
+ expect(subject.body).to eq "badge"
152
+ end
153
+ end
154
+
155
+ context "when there is not a verification_id" do
156
+ let(:row) { {} }
157
+
158
+ it "does not look up the verification" do
159
+ expect(PactBroker::Verifications::Service).to_not receive(:find_by_id)
160
+ subject
161
+ end
162
+
163
+ it "returns the badge" do
164
+ expect(subject.body).to eq "badge"
165
+ end
166
+ end
167
+ end
168
+
169
+ context "when a matrix row is not found" do
170
+ let(:row) { nil }
171
+
172
+ it "does not look up the verification" do
173
+ expect(PactBroker::Verifications::Service).to_not receive(:find_by_id)
174
+ subject
175
+ end
176
+
177
+ it "returns the badge" do
178
+ expect(subject.body).to eq "badge"
179
+ end
180
+ end
181
+ end
121
182
  end
122
183
  end
123
184
  end
@@ -0,0 +1,11 @@
1
+ require 'pact_broker/api/resources/matrix_badge'
2
+
3
+ module PactBroker
4
+ module Api
5
+ module Resources
6
+ describe MatrixBadge do
7
+ # spec is in spec/lib/pact_broker/api/resources/badge_spec.rb#123 to avoid duplication
8
+ end
9
+ end
10
+ end
11
+ end
@@ -13,12 +13,14 @@ module PactBroker::Api
13
13
  let(:headers) { {'CONTENT_TYPE' => 'application/json'} }
14
14
  let(:webhook) { double('webhook')}
15
15
  let(:saved_webhook) { double('saved_webhook')}
16
- let(:provider) { instance_double(PactBroker::Domain::Pacticipant)}
17
- let(:consumer) { instance_double(PactBroker::Domain::Pacticipant)}
16
+ let(:provider) { instance_double(PactBroker::Domain::Pacticipant) }
17
+ let(:consumer) { instance_double(PactBroker::Domain::Pacticipant) }
18
+ let(:webhook_decorator) { instance_double(Decorators::WebhookDecorator, from_json: webhook) }
18
19
 
19
20
  before do
20
21
  allow(PactBroker::Pacticipants::Service).to receive(:find_pacticipant_by_name).with("Some Provider").and_return(provider)
21
22
  allow(PactBroker::Pacticipants::Service).to receive(:find_pacticipant_by_name).with("Some Consumer").and_return(consumer)
23
+ allow(Decorators::WebhookDecorator).to receive(:new).and_return(webhook_decorator)
22
24
  end
23
25
 
24
26
  describe "GET" do
@@ -83,6 +85,7 @@ module PactBroker::Api
83
85
 
84
86
  context "when the provider is not found" do
85
87
  let(:provider) { nil }
88
+
86
89
  it "returns a 404 status" do
87
90
  subject
88
91
  expect(last_response.status).to eq 404
@@ -142,10 +145,10 @@ module PactBroker::Api
142
145
  context "with valid attributes" do
143
146
 
144
147
  let(:webhook_response_json) { {some: 'webhook'}.to_json }
145
- let(:decorator) { instance_double(Decorators::WebhookDecorator) }
146
148
 
147
149
  before do
148
150
  allow_any_instance_of(Decorators::WebhookDecorator).to receive(:to_json).and_return(webhook_response_json)
151
+ allow(webhook_decorator).to receive(:to_json).and_return(webhook_response_json)
149
152
  end
150
153
 
151
154
  it "saves the webhook" do
@@ -169,9 +172,8 @@ module PactBroker::Api
169
172
  end
170
173
 
171
174
  it "generates the JSON response body" do
172
- allow(Decorators::WebhookDecorator).to receive(:new).and_call_original #Deserialise
173
- expect(Decorators::WebhookDecorator).to receive(:new).with(saved_webhook).and_return(decorator) #Serialize
174
- expect(decorator).to receive(:to_json).with(user_options: { base_url: 'http://example.org' })
175
+ expect(Decorators::WebhookDecorator).to receive(:new).with(saved_webhook).and_return(webhook_decorator)
176
+ expect(webhook_decorator).to receive(:to_json).with(user_options: { base_url: 'http://example.org' })
175
177
  subject
176
178
  end
177
179
 
@@ -180,10 +182,7 @@ module PactBroker::Api
180
182
  expect(last_response.body).to eq webhook_response_json
181
183
  end
182
184
  end
183
-
184
185
  end
185
-
186
186
  end
187
187
  end
188
-
189
188
  end
@@ -0,0 +1,60 @@
1
+ require 'pact_broker/certificates/service'
2
+
3
+ module PactBroker
4
+ module Certificates
5
+ describe Service do
6
+ let(:certificate_content) { File.read('spec/fixtures/certificate.pem') }
7
+
8
+ describe "#cert_store" do
9
+ subject { Service.cert_store }
10
+
11
+ it "returns an OpenSSL::X509::Store" do
12
+ expect(subject).to be_instance_of(OpenSSL::X509::Store)
13
+ end
14
+
15
+ context "when there is a duplicate certificate" do
16
+ before do
17
+ Certificate.create(uuid: '1234', content: certificate_content)
18
+ Certificate.create(uuid: '5678', content: certificate_content)
19
+ end
20
+
21
+ it "logs the error" do
22
+ expect(PactBroker.logger).to receive(:error).with(/Error adding certificate/).at_least(1).times
23
+ subject
24
+ end
25
+
26
+ it "returns an OpenSSL::X509::Store" do
27
+ expect(subject).to be_instance_of(OpenSSL::X509::Store)
28
+ end
29
+ end
30
+ end
31
+
32
+ describe "#find_all_certificates" do
33
+ let!(:certificate) do
34
+ Certificate.create(uuid: '1234', content: certificate_content)
35
+ end
36
+
37
+ subject { Service.find_all_certificates }
38
+
39
+ context "with a valid certificate file" do
40
+ it "returns all the X509 Certificate objects" do
41
+ expect(subject.size).to eq 2
42
+ end
43
+ end
44
+
45
+ context "with an invalid certificate file" do
46
+ let(:certificate_content) { File.read('spec/fixtures/certificate-invalid.pem') }
47
+
48
+ it "logs an error" do
49
+ expect(PactBroker.logger).to receive(:error).with(/Error.*1234/)
50
+ subject
51
+ end
52
+
53
+ it "returns all the valid X509 Certificate objects" do
54
+ expect(subject.size).to eq 1
55
+ end
56
+ end
57
+ end
58
+ end
59
+ end
60
+ end
@@ -5,6 +5,19 @@ module PactBroker
5
5
  module Domain
6
6
  describe Verification do
7
7
 
8
+ describe "#save" do
9
+ let!(:verification) do
10
+ TestDataBuilder.new
11
+ .create_pact_with_hierarchy("A", "1", "B")
12
+ .create_verification(test_results: {'some' => 'thing'})
13
+ .and_return(:verification)
14
+ end
15
+
16
+ it "saves and loads the test_results" do
17
+ expect(Verification.find(id: verification.id).test_results).to eq({ 'some' => 'thing' })
18
+ end
19
+ end
20
+
8
21
  describe "#consumer" do
9
22
  let!(:consumer) do
10
23
  TestDataBuilder.new
@@ -3,9 +3,7 @@ require 'pact_broker/domain/webhook_request'
3
3
  require 'webmock/rspec'
4
4
 
5
5
  module PactBroker
6
-
7
6
  module Domain
8
-
9
7
  describe WebhookRequest do
10
8
  before do
11
9
  allow(PactBroker::Api::PactBrokerUrls).to receive(:pact_url).and_return('http://example.org/pact-url')
@@ -33,7 +31,6 @@ module PactBroker
33
31
 
34
32
  let(:logs) { subject.execute(pact, options).logs }
35
33
 
36
-
37
34
  describe "description" do
38
35
  it "returns a brief description of the HTTP request" do
39
36
  expect(subject.description).to eq 'POST example.org'
@@ -55,7 +52,6 @@ module PactBroker
55
52
  end
56
53
 
57
54
  describe "execute" do
58
-
59
55
  let!(:http_request) do
60
56
  stub_request(:post, "http://example.org/hook").
61
57
  with(:headers => {'Content-Type'=>'text/plain'}, :body => 'body').
@@ -63,14 +63,6 @@ module PactBroker
63
63
  end
64
64
  end
65
65
 
66
- context "when the pacticipant name and version are not specified" do
67
- let(:selectors) { [{ pacticipant_name: nil, pacticipant_version_number: nil }] }
68
-
69
- it "returns error messages" do
70
- expect(subject.first).to eq "Please specify the pacticipant name and version"
71
- end
72
- end
73
-
74
66
  context "when the latest_tag is used instead of a version" do
75
67
  before do
76
68
  td.create_pacticipant("Foo")
@@ -130,6 +122,46 @@ module PactBroker
130
122
  end
131
123
  end
132
124
  end
125
+
126
+ describe "find_for_consumer_and_provider_with_tags integration test" do
127
+
128
+ let(:params) do
129
+ {
130
+ consumer_name: 'consumer',
131
+ provider_name: 'provider',
132
+ tag: 'prod',
133
+ provider_tag: 'master'
134
+ }
135
+ end
136
+
137
+ subject { Service.find_for_consumer_and_provider_with_tags(params) }
138
+
139
+ context "when the specified row exists" do
140
+ before do
141
+ td.create_pact_with_hierarchy('consumer', '1', 'provider')
142
+ .create_consumer_version_tag('prod')
143
+ .create_verification(provider_version: '2')
144
+ .use_provider_version('2')
145
+ .create_provider_version_tag('master')
146
+ .create_verification(provider_version: '3', number: 2)
147
+ .create_consumer_version('2')
148
+ .create_pact
149
+ end
150
+
151
+ it "returns the row" do
152
+ expect(subject[:consumer_name]).to eq 'consumer'
153
+ expect(subject[:provider_name]).to eq 'provider'
154
+ expect(subject[:consumer_version_number]).to eq '1'
155
+ expect(subject[:provider_version_number]).to eq '2'
156
+ end
157
+ end
158
+
159
+ context "when the specified row does not exist" do
160
+ it "returns nil" do
161
+ expect(subject).to be nil
162
+ end
163
+ end
164
+ end
133
165
  end
134
166
  end
135
167
  end
@@ -347,7 +347,7 @@ module PactBroker
347
347
  context "with a pact_version_sha" do
348
348
  subject { Repository.new.find_pact "Consumer", nil, "Provider", pact.pact_version_sha }
349
349
 
350
- it "finds the pact with the given version and revision" do
350
+ it "finds the pact with the given pact_version_sha" do
351
351
  expect(subject.pact_version_sha).to eq pact.pact_version_sha
352
352
  expect(subject.consumer.name).to eq "Consumer"
353
353
  expect(subject.provider.name).to eq "Provider"
@@ -355,7 +355,24 @@ module PactBroker
355
355
  expect(subject.revision_number).to eq 2
356
356
 
357
357
  end
358
+ context "when there are multiple pact publications for the pact version" do
359
+ before do
360
+ # Double check the data is set up correctly...
361
+ expect(pact_1.pact_version_sha).to eq(pact_2.pact_version_sha)
362
+ end
363
+
364
+ let(:td) { TestDataBuilder.new }
365
+ let!(:pact_1) { td.create_pact_with_hierarchy("Foo", "1", "Bar").and_return(:pact) }
366
+ let!(:pact_2) { td.create_consumer_version("2").create_pact(json_content: pact_1.json_content).and_return(:pact) }
367
+
368
+ subject { Repository.new.find_pact "Foo", nil, "Bar", pact_1.pact_version_sha }
369
+
370
+ it "returns the latest pact, ordered by consumer version order" do
371
+ expect(subject.consumer_version_number).to eq "2"
372
+ end
373
+ end
358
374
  end
375
+
359
376
  end
360
377
 
361
378
  describe "find_all_revisions" do