pact_broker 2.86.0 → 2.87.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (74) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/release_gem.yml +1 -1
  3. data/CHANGELOG.md +35 -0
  4. data/db/migrations/20210929_increase_event_context_column_size.rb +14 -0
  5. data/docker-compose-test.yml +2 -0
  6. data/lib/pact/doc/interaction_view_model.rb +2 -2
  7. data/lib/pact/doc/markdown/consumer_contract_renderer.rb +1 -1
  8. data/lib/pact_broker/api/contracts/configuration.rb +33 -0
  9. data/lib/pact_broker/api/contracts/publish_contracts_schema.rb +35 -16
  10. data/lib/pact_broker/api/decorators/matrix_decorator.rb +3 -1
  11. data/lib/pact_broker/api/decorators/verification_decorator.rb +5 -3
  12. data/lib/pact_broker/api/pact_broker_urls.rb +26 -6
  13. data/lib/pact_broker/api/resources/default_base_resource.rb +4 -0
  14. data/lib/pact_broker/api/resources/environment.rb +1 -1
  15. data/lib/pact_broker/api/resources/environments.rb +1 -1
  16. data/lib/pact_broker/api/resources/index.rb +7 -1
  17. data/lib/pact_broker/api/resources/publish_contracts.rb +1 -1
  18. data/lib/pact_broker/api/resources/verification.rb +5 -2
  19. data/lib/pact_broker/api/resources/webhook_execution_methods.rb +23 -17
  20. data/lib/pact_broker/api.rb +1 -0
  21. data/lib/pact_broker/application_context.rb +5 -0
  22. data/lib/pact_broker/db/delete_overwritten_data.rb +41 -23
  23. data/lib/pact_broker/deployments/deployed_version.rb +1 -0
  24. data/lib/pact_broker/deployments/deployed_version_service.rb +1 -0
  25. data/lib/pact_broker/deployments/environment_service.rb +4 -1
  26. data/lib/pact_broker/deployments/released_version_service.rb +1 -0
  27. data/lib/pact_broker/doc/controllers/app.rb +1 -0
  28. data/lib/pact_broker/doc/views/can-i-deploy.markdown +2 -1
  29. data/lib/pact_broker/doc/views/index/publish-contracts.markdown +38 -9
  30. data/lib/pact_broker/domain/index_item.rb +9 -0
  31. data/lib/pact_broker/domain/verification.rb +3 -0
  32. data/lib/pact_broker/index/service.rb +2 -2
  33. data/lib/pact_broker/locale/en.yml +3 -1
  34. data/lib/pact_broker/matrix/parse_can_i_deploy_query.rb +5 -3
  35. data/lib/pact_broker/pacticipants/repository.rb +1 -1
  36. data/lib/pact_broker/pacts/metadata.rb +7 -1
  37. data/lib/pact_broker/pacts/pacts_for_verification_repository.rb +3 -2
  38. data/lib/pact_broker/pacts/service.rb +5 -5
  39. data/lib/pact_broker/string_refinements.rb +1 -1
  40. data/lib/pact_broker/test/http_test_data_builder.rb +2 -0
  41. data/lib/pact_broker/ui/helpers/url_helper.rb +12 -0
  42. data/lib/pact_broker/ui/view_models/index_item.rb +15 -1
  43. data/lib/pact_broker/ui/view_models/index_item_branch_head.rb +39 -0
  44. data/lib/pact_broker/ui/view_models/index_item_provider_branch_head.rb +39 -0
  45. data/lib/pact_broker/ui/views/dashboard/show.haml +14 -7
  46. data/lib/pact_broker/verifications/service.rb +3 -3
  47. data/lib/pact_broker/version.rb +1 -1
  48. data/lib/pact_broker/versions/branch_head.rb +0 -2
  49. data/lib/pact_broker/versions/branch_version.rb +1 -0
  50. data/lib/pact_broker/versions/repository.rb +0 -1
  51. data/lib/pact_broker/webhooks/pact_and_verification_parameters.rb +17 -3
  52. data/lib/pact_broker/webhooks/trigger_service.rb +1 -1
  53. data/lib/pact_broker/webhooks/webhook.rb +5 -0
  54. data/public/stylesheets/index.css +5 -0
  55. data/script/data/auto-create-things-for-tags.rb +1 -0
  56. data/script/data/contract-published-requiring-verification.rb +0 -1
  57. data/spec/fixtures/invalid-publish-contract-body.json +38 -0
  58. data/spec/integration/webhooks/contract_publication_spec.rb +68 -0
  59. data/spec/integration/webhooks/contract_requiring_verification_published_spec.rb +67 -0
  60. data/spec/integration/webhooks/pact_publication_spec.rb +1 -1
  61. data/spec/lib/pact/doc/markdown/consumer_contract_renderer_spec.rb +2 -2
  62. data/spec/lib/pact_broker/api/contracts/publish_contracts_schema_spec.rb +13 -0
  63. data/spec/lib/pact_broker/api/decorators/matrix_decorator_spec.rb +1 -1
  64. data/spec/lib/pact_broker/api/decorators/verification_decorator_spec.rb +7 -6
  65. data/spec/lib/pact_broker/api/decorators/verification_summary_decorator_spec.rb +1 -1
  66. data/spec/lib/pact_broker/api/pact_broker_urls_spec.rb +18 -0
  67. data/spec/lib/pact_broker/api/resources/triggered_webhook_logs_spec.rb +6 -5
  68. data/spec/lib/pact_broker/matrix/parse_can_i_deploy_query_spec.rb +13 -0
  69. data/spec/lib/pact_broker/pacts/repository_find_for_verification_spec.rb +4 -5
  70. data/spec/lib/pact_broker/ui/view_models/index_item_spec.rb +1 -1
  71. data/spec/lib/pact_broker/verifications/service_spec.rb +6 -6
  72. data/spec/lib/pact_broker/webhooks/render_spec.rb +3 -2
  73. data/tasks/db.rake +4 -1
  74. metadata +13 -3
@@ -7,6 +7,7 @@ module PactBroker
7
7
  PROVIDER_VERSION_NUMBER = "pactbroker.providerVersionNumber"
8
8
  PROVIDER_VERSION_TAGS = "pactbroker.providerVersionTags"
9
9
  PROVIDER_VERSION_BRANCH = "pactbroker.providerVersionBranch"
10
+ PROVIDER_VERSION_DESCRIPTIONS = "pactbroker.providerVersionDescriptions"
10
11
  CONSUMER_VERSION_TAGS = "pactbroker.consumerVersionTags"
11
12
  CONSUMER_VERSION_BRANCH = "pactbroker.consumerVersionBranch"
12
13
  CONSUMER_NAME = "pactbroker.consumerName"
@@ -17,6 +18,7 @@ module PactBroker
17
18
  GITLAB_VERIFICATION_STATUS = "pactbroker.gitlabVerificationStatus"
18
19
  CONSUMER_LABELS = "pactbroker.consumerLabels"
19
20
  PROVIDER_LABELS = "pactbroker.providerLabels"
21
+ BUILD_URL = "pactbroker.buildUrl"
20
22
  EVENT_NAME = "pactbroker.eventName"
21
23
  CURRENTLY_DEPLOYED_PROVIDER_VERSION_NUMBER = "pactbroker.currentlyDeployedProviderVersionNumber"
22
24
 
@@ -26,6 +28,7 @@ module PactBroker
26
28
  CONSUMER_VERSION_NUMBER,
27
29
  PROVIDER_VERSION_NUMBER,
28
30
  PROVIDER_VERSION_TAGS,
31
+ PROVIDER_VERSION_DESCRIPTIONS,
29
32
  PROVIDER_VERSION_BRANCH,
30
33
  CONSUMER_VERSION_TAGS,
31
34
  CONSUMER_VERSION_BRANCH,
@@ -38,6 +41,7 @@ module PactBroker
38
41
  CONSUMER_LABELS,
39
42
  PROVIDER_LABELS,
40
43
  EVENT_NAME,
44
+ BUILD_URL,
41
45
  CURRENTLY_DEPLOYED_PROVIDER_VERSION_NUMBER
42
46
  ]
43
47
 
@@ -57,6 +61,7 @@ module PactBroker
57
61
  PROVIDER_VERSION_NUMBER => provider_version_number,
58
62
  PROVIDER_VERSION_TAGS => provider_version_tags,
59
63
  PROVIDER_VERSION_BRANCH => provider_version_branch,
64
+ PROVIDER_VERSION_DESCRIPTIONS => provider_version_descriptions,
60
65
  CONSUMER_VERSION_TAGS => consumer_version_tags,
61
66
  CONSUMER_VERSION_BRANCH => consumer_version_branch,
62
67
  CONSUMER_NAME => pact ? pact.consumer_name : "",
@@ -68,6 +73,7 @@ module PactBroker
68
73
  CONSUMER_LABELS => pacticipant_labels(pact && pact.consumer),
69
74
  PROVIDER_LABELS => pacticipant_labels(pact && pact.provider),
70
75
  EVENT_NAME => event_name,
76
+ BUILD_URL => build_url,
71
77
  CURRENTLY_DEPLOYED_PROVIDER_VERSION_NUMBER => currently_deployed_provider_version_number
72
78
  }
73
79
  end
@@ -137,10 +143,10 @@ module PactBroker
137
143
  end
138
144
 
139
145
  def consumer_version_branch
140
- if webhook_context[:consumer_version_branch]
141
- webhook_context[:consumer_version_branch]
146
+ if webhook_context.key?(:consumer_version_branch)
147
+ webhook_context[:consumer_version_branch] || ""
142
148
  else
143
- pact&.consumer_version&.branch || ""
149
+ pact&.consumer_version&.branch_names&.last || ""
144
150
  end
145
151
  end
146
152
 
@@ -172,6 +178,10 @@ module PactBroker
172
178
  end
173
179
  end
174
180
 
181
+ def provider_version_descriptions
182
+ webhook_context[:provider_version_descriptions]&.join(", ") || ""
183
+ end
184
+
175
185
  def pacticipant_labels pacticipant
176
186
  pacticipant && pacticipant.labels ? pacticipant.labels.collect(&:name).join(", ") : ""
177
187
  end
@@ -180,6 +190,10 @@ module PactBroker
180
190
  webhook_context.fetch(:event_name)
181
191
  end
182
192
 
193
+ def build_url
194
+ webhook_context[:build_url] || ""
195
+ end
196
+
183
197
  def currently_deployed_provider_version_number
184
198
  webhook_context[:currently_deployed_provider_version_number] || ""
185
199
  end
@@ -135,7 +135,7 @@ module PactBroker
135
135
  required_verifications = verification_service.calculate_required_verifications_for_pact(pact)
136
136
  event_contexts.flat_map do | event_context |
137
137
  required_verifications.collect do | required_verification |
138
- event_context.merge(provider_version_number: required_verification.provider_version.number, provider_version_descriptions: required_verification.provider_version_descriptions)
138
+ event_context.merge(provider_version_number: required_verification.provider_version.number, provider_version_descriptions: required_verification.provider_version_descriptions.uniq)
139
139
  end
140
140
  end
141
141
  else
@@ -204,9 +204,14 @@ end
204
204
  # enabled | boolean | DEFAULT true
205
205
  # description | text |
206
206
  # headers | text |
207
+ # consumer_label | text |
208
+ # provider_label | text |
207
209
  # Indexes:
208
210
  # webhooks_pkey | PRIMARY KEY btree (id)
209
211
  # uq_webhook_uuid | UNIQUE btree (uuid)
212
+ # Check constraints:
213
+ # consumer_label_exclusion | (consumer_id IS NULL OR consumer_id IS NOT NULL AND consumer_label IS NULL)
214
+ # provider_label_exclusion | (provider_id IS NULL OR provider_id IS NOT NULL AND provider_label IS NULL)
210
215
  # Foreign key constraints:
211
216
  # fk_webhooks_consumer | (consumer_id) REFERENCES pacticipants(id)
212
217
  # fk_webhooks_provider | (provider_id) REFERENCES pacticipants(id)
@@ -241,3 +241,8 @@ span.copy-success-icon {
241
241
  div.top-of-group {
242
242
  margin-top: 20px;
243
243
  }
244
+
245
+
246
+ div[data-toggle="tooltip"] {
247
+ cursor: pointer;
248
+ }
@@ -13,6 +13,7 @@ begin
13
13
  .deploy_to_prod(pacticipant: "AutoDetectTestProvider", version: "1")
14
14
  .publish_pact(consumer: "AutoDetectTestConsumer", provider: "AutoDetectTestProvider", consumer_version: "1", tag: "feat/x", content_id: "2111")
15
15
  .publish_pact(consumer: "AutoDetectTestConsumer", provider: "AutoDetectTestProvider", consumer_version: "2", tag: "feat/y", content_id: "21asdfd")
16
+ .deploy_to_prod(pacticipant: "AutoDetectTestConsumer", version: "1")
16
17
 
17
18
  rescue StandardError => e
18
19
  puts "#{e.class} #{e.message}"
@@ -14,7 +14,6 @@ begin
14
14
  .create_pacticipant("NewWebhookTestConsumer")
15
15
  .create_pacticipant("NewWebhookTestProvider")
16
16
  .create_tagged_pacticipant_version(pacticipant: "NewWebhookTestProvider", version: "1", tag: "main")
17
- .deploy_to_prod(pacticipant: "NewWebhookTestProvider", version: "1")
18
17
  .record_deployment(pacticipant: "NewWebhookTestProvider", version: "1", environment_name: "test")
19
18
  .record_deployment(pacticipant: "NewWebhookTestProvider", version: "1", environment_name: "prod")
20
19
  .create_version(pacticipant: "NewWebhookTestProvider", version: "2", branch: "main")
@@ -0,0 +1,38 @@
1
+ {
2
+ "contracts":
3
+ [
4
+ {
5
+ "consumer":
6
+ {
7
+ "name": "foo"
8
+ },
9
+ "interactions":
10
+ [
11
+ {
12
+ "description": "a request",
13
+ "providerState": "some state",
14
+ "request":
15
+ {
16
+ "method": "post",
17
+ "path": "/path"
18
+ },
19
+ "response":
20
+ {
21
+ "status": 200
22
+ }
23
+ }
24
+ ],
25
+ "metadata":
26
+ {
27
+ "pactSpecification":
28
+ {
29
+ "version": "2.0.0"
30
+ }
31
+ },
32
+ "provider":
33
+ {
34
+ "name": "provider"
35
+ }
36
+ }
37
+ ]
38
+ }
@@ -0,0 +1,68 @@
1
+ RSpec.describe "triggering a webhook for a contract publication" do
2
+ before do
3
+ td.create_global_webhook(event_names: ["contract_published"], body: webhook_body_template)
4
+ end
5
+
6
+ let(:webhook_body_template) do
7
+ {
8
+ "consumer_version_number" => "${pactbroker.consumerVersionNumber}",
9
+ "consumer_version_branch" => "${pactbroker.consumerVersionBranch}",
10
+ "build_url" => "${pactbroker.buildUrl}",
11
+ "consumer_version_tags" => "${pactbroker.consumerVersionTags}",
12
+ }
13
+ end
14
+
15
+ let(:expected_webhook_body) do
16
+ {
17
+ consumer_version_number: "1",
18
+ consumer_version_branch: "main",
19
+ consumer_version_tags: "a, b",
20
+ build_url: "http://ci/builds/1234"
21
+ }
22
+ end
23
+
24
+ let(:request_body_hash) do
25
+ {
26
+ :pacticipantName => "Foo",
27
+ :pacticipantVersionNumber => "1",
28
+ :branch => "main",
29
+ :tags => ["a", "b"],
30
+ :buildUrl => "http://ci/builds/1234",
31
+ :contracts => [
32
+ {
33
+ :consumerName => "Foo",
34
+ :providerName => "Bar",
35
+ :specification => "pact",
36
+ :contentType => "application/json",
37
+ :content => encoded_contract
38
+ }
39
+ ]
40
+ }
41
+ end
42
+
43
+ let(:rack_headers) do
44
+ {
45
+ "CONTENT_TYPE" => "application/json",
46
+ "HTTP_ACCEPT" => "application/hal+json",
47
+ "pactbroker.database_connector" => database_connector}
48
+ end
49
+
50
+ let(:contract) { { consumer: { name: "Foo" }, provider: { name: "Bar" }, interactions: [] }.to_json }
51
+ let(:encoded_contract) { Base64.strict_encode64(contract) }
52
+ let(:path) { "/contracts/publish" }
53
+
54
+ let!(:request) do
55
+ stub_request(:post, /http/).to_return(:status => 200)
56
+ end
57
+
58
+ subject { post(path, request_body_hash.to_json, rack_headers) }
59
+
60
+ let(:database_connector) { ->(&block) { block.call } }
61
+
62
+ it { is_expected.to be_a_hal_json_success_response }
63
+
64
+ it "passes through the correct parameters to the webhook" do
65
+ subject
66
+ expect(a_request(:post, /http/).with(body: expected_webhook_body)).to have_been_made
67
+ end
68
+ end
@@ -0,0 +1,67 @@
1
+ RSpec.describe "triggering a contract_requiring_verification_published webhook for a contract publication" do
2
+ before do
3
+ td.create_global_webhook(event_names: ["contract_requiring_verification_published"], body: webhook_body_template)
4
+ .create_environment("test")
5
+ .create_provider("Bar", main_branch: "main")
6
+ .create_provider_version("1", branch: "main")
7
+ end
8
+
9
+ let(:webhook_body_template) do
10
+ {
11
+ "provider_version_number" => "${pactbroker.providerVersionNumber}",
12
+ "provider_version_descriptions" => "${pactbroker.providerVersionDescriptions}"
13
+ }
14
+ end
15
+
16
+ let(:expected_webhook_body) do
17
+ {
18
+ provider_version_number: "1",
19
+ provider_version_descriptions: a_kind_of(String)
20
+ }
21
+ end
22
+
23
+ let(:request_body_hash) do
24
+ {
25
+ :pacticipantName => "Foo",
26
+ :pacticipantVersionNumber => "1",
27
+ :branch => "main",
28
+ :tags => ["a", "b"],
29
+ :buildUrl => "http://ci/builds/1234",
30
+ :contracts => [
31
+ {
32
+ :consumerName => "Foo",
33
+ :providerName => "Bar",
34
+ :specification => "pact",
35
+ :contentType => "application/json",
36
+ :content => encoded_contract
37
+ }
38
+ ]
39
+ }
40
+ end
41
+
42
+ let(:rack_headers) do
43
+ {
44
+ "CONTENT_TYPE" => "application/json",
45
+ "HTTP_ACCEPT" => "application/hal+json",
46
+ "pactbroker.database_connector" => database_connector}
47
+ end
48
+
49
+ let(:contract) { { consumer: { name: "Foo" }, provider: { name: "Bar" }, interactions: [] }.to_json }
50
+ let(:encoded_contract) { Base64.strict_encode64(contract) }
51
+ let(:path) { "/contracts/publish" }
52
+
53
+ let!(:request) do
54
+ stub_request(:post, /http/).to_return(:status => 200)
55
+ end
56
+
57
+ subject { post(path, request_body_hash.to_json, rack_headers) }
58
+
59
+ let(:database_connector) { ->(&block) { block.call } }
60
+
61
+ it { is_expected.to be_a_hal_json_success_response }
62
+
63
+ it "passes through the correct parameters to the webhook" do
64
+ subject
65
+ expect(a_request(:post, /http/).with(body: expected_webhook_body)).to have_been_made
66
+ end
67
+ end
@@ -11,7 +11,7 @@ RSpec.describe "triggering a webhook for a pact publication" do
11
11
 
12
12
  let(:database_connector) { ->(&block) { block.call } }
13
13
 
14
- subject { put("/pacts/provider/Bar/consumer/Foo/version/2", pact_content, { "CONTENT_TYPE" => "application/json", "pactbroker.database_connector" => database_connector}) }
14
+ subject { put("/pacts/provider/Bar/consumer/Foo/version/2", pact_content, { "CONTENT_TYPE" => "application/json", "pactbroker.database_connector" => database_connector }) }
15
15
 
16
16
  context "when there is a verification from the main branch of the provider" do
17
17
  before do
@@ -27,8 +27,8 @@ module Pact
27
27
  let(:consumer_contract) { Pact::ConsumerContract.from_uri "./spec/support/markdown_pact_with_markdown_chars_in_names.json" }
28
28
 
29
29
  it "escapes the markdown characters" do
30
- expect(subject.call).to include '# A pact between Some\*Consumer\*App and Some\_Provider\_App'
31
- expect(subject.call).to include '### Requests from Some\*Consumer\*App to Some\_Provider\_App'
30
+ expect(subject.call).to include "# A pact between Some\\*Consumer\\*App and Some\\_Provider\\_App"
31
+ expect(subject.call).to include "### Requests from Some\\*Consumer\\*App to Some\\_Provider\\_App"
32
32
  end
33
33
  end
34
34
 
@@ -108,6 +108,19 @@ module PactBroker
108
108
 
109
109
  its([:contracts, 0]) { is_expected.to include "provider name in contract content ('WRONG') must match providerName ('Bar') in contracts at index 0" }
110
110
  end
111
+
112
+ context "when the consumer name is missing and there is a validation error with the content" do
113
+ let(:params) do
114
+ JSON.parse(File.read("spec/fixtures/invalid-publish-contract-body.json"), symbolize_names: true)
115
+ end
116
+
117
+ it "handles multiple errors" do
118
+ expect(subject[:contracts]).to include "consumerName is missing at index 0"
119
+ expect(subject[:contracts]).to include "providerName is missing at index 0"
120
+ expect(subject[:contracts]).to include "contentType is missing at index 0"
121
+ expect(subject[:contracts]).to include "specification is missing at index 0"
122
+ end
123
+ end
111
124
  end
112
125
  end
113
126
  end
@@ -129,7 +129,7 @@ module PactBroker
129
129
  verifiedAt: "2017-12-31T00:00:00+00:00",
130
130
  _links: {
131
131
  self: {
132
- href: "http://example.org/pacts/provider/Provider/consumer/Consumer/pact-version/1234/verification-results/1"
132
+ href: "http://example.org/pacts/provider/Provider/consumer/Consumer/pact-version/1234/metadata/Y3ZuPTEuMC4w/verification-results/1"
133
133
  }
134
134
  }
135
135
  }
@@ -6,6 +6,7 @@ module PactBroker
6
6
  describe VerificationDecorator do
7
7
  before do
8
8
  allow_any_instance_of(VerificationDecorator).to receive(:verification_triggered_webhooks_url).and_return("http://triggered-webhooks")
9
+ allow_any_instance_of(VerificationDecorator).to receive(:pact_version_with_consumer_version_metadata_url).and_return("http://pact")
9
10
  end
10
11
 
11
12
  let(:verification) do
@@ -18,25 +19,25 @@ module PactBroker
18
19
  test_results: { "arbitrary" => "json" },
19
20
  build_url: "http://build-url",
20
21
  pact_version_sha: "1234",
21
- latest_pact_publication: pact_publication,
22
22
  execution_date: DateTime.now,
23
23
  provider_version_tags: provider_version_tags,
24
24
  verified_by_implementation: "Ruby",
25
25
  verified_by_version: "1234")
26
26
  end
27
27
 
28
- let(:pact_publication) do
29
- instance_double("PactBroker::Pacts::PactPublication",
28
+ let(:pact) do
29
+ instance_double("PactBroker::Domain::Pact",
30
30
  name: "A name",
31
31
  provider_name: "Provider",
32
32
  consumer_name: "Consumer",
33
- consumer_version_number: "1.2.3"
33
+ consumer_version_number: "1.2.3",
34
+ pact_version_sha: "1234",
34
35
  )
35
36
  end
36
37
 
37
38
  let(:provider_version_tags) { [instance_double(PactBroker::Tags::TagWithLatestFlag, name: "prod", latest?: true)] }
38
39
 
39
- let(:options) { { user_options: { base_url: "http://example.org" } } }
40
+ let(:options) { { user_options: { base_url: "http://example.org", pact: pact } } }
40
41
 
41
42
  let(:json) { VerificationDecorator.new(verification).to_json(options) }
42
43
 
@@ -63,7 +64,7 @@ module PactBroker
63
64
  end
64
65
 
65
66
  it "includes a link to its pact" do
66
- expect(subject[:_links][:'pb:pact-version'][:href]).to match %r{http://example.org/pacts/}
67
+ expect(subject[:_links][:'pb:pact-version'][:href]).to eq "http://pact"
67
68
  end
68
69
 
69
70
  it "includes a link to the triggered webhooks" do
@@ -31,7 +31,7 @@ module PactBroker
31
31
  end
32
32
 
33
33
  let(:provider_version_tags) { [instance_double(PactBroker::Tags::TagWithLatestFlag, name: "prod", latest?: true)] }
34
- let(:pact) { instance_double("PactBroker::Domain::Pact", name: "Some pact", consumer_name: "Foo", provider_name: "Bar", consumer_version_number: "1.2.3") }
34
+ let(:pact) { instance_double("PactBroker::Domain::Pact", name: "Some pact", consumer_name: "Foo", provider_name: "Bar", consumer_version_number: "1.2.3", pact_version_sha: "1234") }
35
35
  let(:is_pending) { true }
36
36
  let(:options) { {base_url: "http://example.org", consumer_name: "Foo", consumer_version_number: "1.2.3", resource_url: "http://self"} }
37
37
 
@@ -100,6 +100,24 @@ module PactBroker
100
100
  end
101
101
  end
102
102
 
103
+ describe "verification_url_from_params" do
104
+ context "with consumer_version_number" do
105
+ let(:params) do
106
+ {
107
+ consumer_name: consumer_name,
108
+ provider_name: provider_name,
109
+ pact_version_sha: "1234",
110
+ consumer_version_number: "2",
111
+ verification_number: "1"
112
+ }
113
+ end
114
+
115
+ subject { PactBrokerUrls.verification_url_from_params(params, base_url)}
116
+
117
+ it { is_expected.to eq "http://example.org/pacts/provider/Bar%2FBar/consumer/Foo%2FFoo/pact-version/1234/metadata/Y3ZuPTI/verification-results/1" }
118
+ end
119
+ end
120
+
103
121
  describe "templated_diff_url" do
104
122
  subject { PactBrokerUrls.templated_diff_url(pact, base_url) }
105
123
 
@@ -15,15 +15,16 @@ module PactBroker
15
15
  .create_webhook_execution(logs: "waffle")
16
16
  end
17
17
 
18
- let(:path) { "/webhooks/5432/trigger/1234/logs" }
19
-
20
18
  subject { get(path) }
21
19
 
22
20
  let(:triggered_webhook_uuid) { PactBroker::Webhooks::TriggeredWebhook.first.uuid }
23
- let(:path) { "/triggered-webhooks/#{triggered_webhook_uuid}/logs" }
24
21
 
25
- it "returns the concatenated webhook execution logs" do
26
- expect(subject.body).to eq "foo\nbar"
22
+ describe "by triggered webhook uuid" do
23
+ let(:path) { "/triggered-webhooks/1234/logs" }
24
+
25
+ it "returns the concatenated webhook execution logs" do
26
+ expect(subject.body).to eq "foo\nbar"
27
+ end
27
28
  end
28
29
  end
29
30
  end
@@ -38,6 +38,19 @@ module PactBroker
38
38
  end
39
39
  end
40
40
 
41
+ context "with pacticipant selectors to ignore" do
42
+ before do
43
+ params[:ignore] = [{ pacticipant: "foo" }, { pacticipant: "bar", version: "2" }]
44
+ end
45
+
46
+ its([:ignore_selectors]) do
47
+ is_expected.to eq [
48
+ PactBroker::Matrix::UnresolvedSelector.new(pacticipant_name: "foo"),
49
+ PactBroker::Matrix::UnresolvedSelector.new(pacticipant_name: "bar", pacticipant_version_number: "2")
50
+ ]
51
+ end
52
+ end
53
+
41
54
  context "with a tag" do
42
55
  let(:params) do
43
56
  {
@@ -15,14 +15,13 @@ module PactBroker
15
15
  subject { Repository.new.find_for_verification("Bar", consumer_version_selectors) }
16
16
 
17
17
  context "when there are no selectors" do
18
-
19
18
  let(:foo_main_branch) { nil }
20
19
 
21
20
  let(:consumer_version_selectors) { Selectors.new }
22
21
 
23
22
  context "when there is no main branch version" do
24
23
  before do
25
- td.create_consumer("Foo")
24
+ td.create_consumer("Foo", main_branch: "main")
26
25
  .create_pact_with_hierarchy("Foo", "foo-latest-prod-version", "Bar")
27
26
  .create_consumer_version_tag("prod")
28
27
  .create_consumer_version("not-latest-dev-version", tag_names: ["dev"])
@@ -31,14 +30,14 @@ module PactBroker
31
30
  .create_consumer_version("foo-latest-dev-version", tag_names: ["dev"])
32
31
  .create_pact
33
32
  .create_consumer("Baz")
34
- .create_consumer_version("baz-latest-dev-version", tag_names: ["dev"])
33
+ .create_consumer_version("baz-latest-dev-version", tag_names: ["dev", "main"])
35
34
  .create_pact
36
35
  end
37
36
 
38
37
  it "returns the latest pact for each consumer" do
39
38
  expect(subject.size).to eq 2
40
- expect(find_by_consumer_name_and_consumer_version_number("Foo", "foo-latest-dev-version")).to_not be nil
41
- expect(find_by_consumer_name_and_consumer_version_number("Baz", "baz-latest-dev-version")).to_not be nil
39
+ expect(subject).to include(have_attributes(consumer_name: "Foo", consumer_version_number: "foo-latest-dev-version"))
40
+ expect(subject).to include(have_attributes(consumer_name: "Baz", consumer_version_number: "baz-latest-dev-version"))
42
41
  expect(subject.all?(&:overall_latest?)).to be true
43
42
  end
44
43
  end
@@ -26,7 +26,7 @@ module PactBroker
26
26
  its(:provider_name) { should eq "Provider Name"}
27
27
  its(:latest_pact_url) { should eq "/pacts/provider/Provider%20Name/consumer/Consumer%20Name/latest" }
28
28
  its(:pact_url) { should eq "/pacts/provider/Provider%20Name/consumer/Consumer%20Name/version/1.2.3" }
29
- its(:pact_matrix_url) { should eq "/matrix/provider/Provider%20Name/consumer/Consumer%20Name" }
29
+ its(:pact_matrix_url) { should eq "/matrix?q[][pacticipant]=Consumer+Name&q[][version]=1.2.3&q[][pacticipant]=Provider+Name&latestby=cvpv" }
30
30
  its(:consumer_group_url) { should eq "/pacticipants/Consumer%20Name" }
31
31
  its(:provider_group_url) { should eq "/pacticipants/Provider%20Name" }
32
32
 
@@ -115,7 +115,7 @@ module PactBroker
115
115
  expect(subject).to eq [
116
116
  RequiredVerification.new(
117
117
  provider_version: td.find_version("Bar", "1"),
118
- provider_version_descriptions: ["latest version from main branch"]
118
+ provider_version_descriptions: ["latest from main branch"]
119
119
  )
120
120
  ]
121
121
  end
@@ -153,7 +153,7 @@ module PactBroker
153
153
  expect(subject).to eq [
154
154
  RequiredVerification.new(
155
155
  provider_version: td.find_version("Bar", "1"),
156
- provider_version_descriptions: ["currently deployed version (test)"]
156
+ provider_version_descriptions: ["deployed in test"]
157
157
  )
158
158
  ]
159
159
  end
@@ -193,7 +193,7 @@ module PactBroker
193
193
  expect(subject).to eq [
194
194
  RequiredVerification.new(
195
195
  provider_version: td.find_version("Bar", "1"),
196
- provider_version_descriptions: ["currently released version (test)"]
196
+ provider_version_descriptions: ["released in test"]
197
197
  )
198
198
  ]
199
199
  end
@@ -235,9 +235,9 @@ module PactBroker
235
235
  RequiredVerification.new(
236
236
  provider_version: td.find_version("Bar", "1"),
237
237
  provider_version_descriptions: [
238
- "latest version from main branch",
239
- "currently deployed version (test)",
240
- "currently released version (test)"
238
+ "latest from main branch",
239
+ "deployed in test",
240
+ "released in test"
241
241
  ])
242
242
  ]
243
243
  end
@@ -75,7 +75,7 @@ module PactBroker
75
75
  end
76
76
 
77
77
  let(:consumer_version) do
78
- double("version", tags: consumer_tags, branch: "consumer-branch")
78
+ double("version", tags: consumer_tags, branch_names: ["foo-branch","consumer-branch"])
79
79
  end
80
80
 
81
81
  let(:provider_tags) do
@@ -94,7 +94,7 @@ module PactBroker
94
94
  [ double("label", name: "foo"), double("label", name: "bar") ]
95
95
  end
96
96
 
97
- let(:webhook_context) { { base_url: base_url, event_name: "something" } }
97
+ let(:webhook_context) { { base_url: base_url, event_name: "something", build_url: "http://build"} }
98
98
 
99
99
  let(:nil_pact) { nil }
100
100
  let(:nil_verification) { nil }
@@ -140,6 +140,7 @@ module PactBroker
140
140
  ["${pactbroker.consumerVersionBranch}", "consumer-branch", :pact_with_successful_verification, :verification],
141
141
  ["${pactbroker.consumerLabels}", "foo, bar", :pact_with_successful_verification, :verification],
142
142
  ["${pactbroker.providerLabels}", "finance, IT", :pact, :nil_verification],
143
+ ["${pactbroker.buildUrl}", "http://build", :nil_pact, :nil_verification]
143
144
  ]
144
145
 
145
146
  TEST_CASES.each do | (template, expected_output, pact_var_name, verification_var_name) |
data/tasks/db.rake CHANGED
@@ -95,7 +95,10 @@ namespace :db do
95
95
  PactBroker::Database.ensure_database_dir_exists
96
96
  end
97
97
 
98
- desc "Annotate the Sequel domain classes with schema information - start the postgres db with script/docker/db-start.sh first"
98
+ desc "Annotate the Sequel domain classes with schema information.
99
+ Start the postgres db with script/docker/db-start.sh first and run
100
+ INSTALL_PG=true bundle exec rake db:annotate
101
+ "
99
102
  task :annotate do
100
103
  begin
101
104
  raise "Need to set INSTALL_PG=true" unless ENV["INSTALL_PG"] == "true"