pact_broker 2.85.0 → 2.88.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (179) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/trigger_pact_docs_update.yml +22 -0
  3. data/CHANGELOG.md +67 -0
  4. data/DEVELOPER_DOCUMENTATION.md +0 -2
  5. data/db/migrations/20210914_add_labels_to_webhooks.rb +14 -0
  6. data/db/migrations/20210915_add_verified_by_to_verification.rb +6 -0
  7. data/db/migrations/20210929_increase_event_context_column_size.rb +14 -0
  8. data/docker-compose-ci-mysql.yml +1 -0
  9. data/docker-compose-test.yml +2 -0
  10. data/docs/CONFIGURATION.md +255 -66
  11. data/docs/api/WEBHOOKS.md +789 -0
  12. data/docs/configuration.yml +166 -101
  13. data/lib/db.rb +0 -1
  14. data/lib/pact/doc/interaction_view_model.rb +2 -2
  15. data/lib/pact/doc/markdown/consumer_contract_renderer.rb +1 -1
  16. data/lib/pact_broker/api/contracts/configuration.rb +33 -0
  17. data/lib/pact_broker/api/contracts/publish_contracts_schema.rb +35 -16
  18. data/lib/pact_broker/api/contracts/webhook_contract.rb +24 -2
  19. data/lib/pact_broker/api/decorators/matrix_decorator.rb +3 -1
  20. data/lib/pact_broker/api/decorators/pact_decorator.rb +12 -0
  21. data/lib/pact_broker/api/decorators/verification_decorator.rb +9 -3
  22. data/lib/pact_broker/api/decorators/webhook_decorator.rb +27 -4
  23. data/lib/pact_broker/api/pact_broker_urls.rb +30 -6
  24. data/lib/pact_broker/api/resources/all_webhooks.rb +2 -2
  25. data/lib/pact_broker/api/resources/default_base_resource.rb +5 -1
  26. data/lib/pact_broker/api/resources/environment.rb +4 -4
  27. data/lib/pact_broker/api/resources/environments.rb +1 -1
  28. data/lib/pact_broker/api/resources/index.rb +7 -1
  29. data/lib/pact_broker/api/resources/metadata_resource_methods.rb +33 -3
  30. data/lib/pact_broker/api/resources/pact_version.rb +4 -0
  31. data/lib/pact_broker/api/resources/previous_distinct_pact_version.rb +1 -1
  32. data/lib/pact_broker/api/resources/publish_contracts.rb +1 -1
  33. data/lib/pact_broker/api/resources/verification.rb +5 -2
  34. data/lib/pact_broker/api/resources/webhook_execution.rb +7 -3
  35. data/lib/pact_broker/api/resources/webhook_execution_methods.rb +23 -17
  36. data/lib/pact_broker/api.rb +6 -0
  37. data/lib/pact_broker/application_context.rb +5 -0
  38. data/lib/pact_broker/config/runtime_configuration.rb +4 -0
  39. data/lib/pact_broker/config/runtime_configuration_database_methods.rb +1 -1
  40. data/lib/pact_broker/db/clean.rb +1 -2
  41. data/lib/pact_broker/db/delete_overwritten_data.rb +41 -23
  42. data/lib/pact_broker/deployments/deployed_version.rb +1 -0
  43. data/lib/pact_broker/deployments/deployed_version_service.rb +1 -0
  44. data/lib/pact_broker/deployments/environment_service.rb +7 -2
  45. data/lib/pact_broker/deployments/released_version_service.rb +1 -0
  46. data/lib/pact_broker/doc/controllers/app.rb +1 -0
  47. data/lib/pact_broker/doc/views/can-i-deploy.markdown +2 -1
  48. data/lib/pact_broker/doc/views/index/publish-contracts.markdown +38 -9
  49. data/lib/pact_broker/doc/views/pacticipant/label.markdown +12 -0
  50. data/lib/pact_broker/doc/views/provider-pacts-for-verification.markdown +7 -7
  51. data/lib/pact_broker/doc/views/webhooks.markdown +17 -0
  52. data/lib/pact_broker/domain/index_item.rb +9 -0
  53. data/lib/pact_broker/domain/pacticipant.rb +4 -0
  54. data/lib/pact_broker/domain/verification.rb +19 -4
  55. data/lib/pact_broker/domain/webhook.rb +5 -5
  56. data/lib/pact_broker/domain/webhook_pacticipant.rb +6 -0
  57. data/lib/pact_broker/index/service.rb +4 -4
  58. data/lib/pact_broker/locale/en.yml +4 -1
  59. data/lib/pact_broker/matrix/head_row.rb +1 -1
  60. data/lib/pact_broker/matrix/parse_can_i_deploy_query.rb +5 -3
  61. data/lib/pact_broker/matrix/quick_row.rb +0 -1
  62. data/lib/pact_broker/matrix/repository.rb +0 -1
  63. data/lib/pact_broker/matrix/row.rb +2 -2
  64. data/lib/pact_broker/pacticipants/repository.rb +1 -1
  65. data/lib/pact_broker/pacts/latest_pact_publication_id_for_consumer_version.rb +0 -1
  66. data/lib/pact_broker/pacts/metadata.rb +7 -1
  67. data/lib/pact_broker/pacts/pact_publication.rb +7 -0
  68. data/lib/pact_broker/pacts/pact_publication_clean_selector_dataset_module.rb +19 -0
  69. data/lib/pact_broker/pacts/pact_publication_dataset_module.rb +30 -2
  70. data/lib/pact_broker/pacts/pact_version.rb +24 -1
  71. data/lib/pact_broker/pacts/pacts_for_verification_repository.rb +5 -4
  72. data/lib/pact_broker/pacts/repository.rb +50 -47
  73. data/lib/pact_broker/pacts/service.rb +5 -5
  74. data/lib/pact_broker/string_refinements.rb +1 -1
  75. data/lib/pact_broker/test/http_test_data_builder.rb +40 -10
  76. data/lib/pact_broker/test/test_data_builder.rb +28 -5
  77. data/lib/pact_broker/ui/helpers/url_helper.rb +12 -0
  78. data/lib/pact_broker/ui/view_models/index_item.rb +15 -1
  79. data/lib/pact_broker/ui/view_models/index_item_branch_head.rb +39 -0
  80. data/lib/pact_broker/ui/view_models/index_item_provider_branch_head.rb +39 -0
  81. data/lib/pact_broker/ui/views/dashboard/show.haml +14 -7
  82. data/lib/pact_broker/verifications/repository.rb +5 -2
  83. data/lib/pact_broker/verifications/service.rb +7 -4
  84. data/lib/pact_broker/version.rb +1 -1
  85. data/lib/pact_broker/versions/abbreviate_number.rb +8 -4
  86. data/lib/pact_broker/versions/branch_head.rb +0 -2
  87. data/lib/pact_broker/versions/branch_version.rb +1 -0
  88. data/lib/pact_broker/versions/repository.rb +0 -1
  89. data/lib/pact_broker/webhooks/event_listener.rb +4 -2
  90. data/lib/pact_broker/webhooks/pact_and_verification_parameters.rb +18 -3
  91. data/lib/pact_broker/webhooks/repository.rb +10 -4
  92. data/lib/pact_broker/webhooks/trigger_service.rb +1 -1
  93. data/lib/pact_broker/webhooks/webhook.rb +71 -8
  94. data/lib/webmachine/describe_routes.rb +62 -0
  95. data/public/stylesheets/index.css +5 -0
  96. data/script/data/auto-create-things-for-tags.rb +1 -0
  97. data/script/data/branches.rb +1 -1
  98. data/script/data/contract-published-requiring-verification.rb +0 -1
  99. data/script/data/verify-pact-for-multiple-selectors.rb +30 -0
  100. data/script/docs/generate-api-docs.rb +117 -0
  101. data/script/docs/generate-configuration-docs.rb +24 -3
  102. data/script/docs/regenerate-api-docs.sh +11 -0
  103. data/script/generate-erd +55 -0
  104. data/spec/features/create_webhook_spec.rb +55 -10
  105. data/spec/features/get_pact_spec.rb +2 -3
  106. data/spec/fixtures/approvals/docs_webhooks_executing_a_saved_webhook_options.approved.json +20 -0
  107. data/spec/fixtures/approvals/docs_webhooks_executing_a_saved_webhook_post.approved.json +43 -0
  108. data/spec/fixtures/approvals/docs_webhooks_executing_an_unsaved_webhook_options.approved.json +20 -0
  109. data/spec/fixtures/approvals/docs_webhooks_executing_an_unsaved_webhook_post.approved.json +63 -0
  110. data/spec/fixtures/approvals/docs_webhooks_logs_of_triggered_webhook_get.approved.json +20 -0
  111. data/spec/fixtures/approvals/docs_webhooks_logs_of_triggered_webhook_options.approved.json +20 -0
  112. data/spec/fixtures/approvals/docs_webhooks_pact_webhooks_get.approved.json +45 -0
  113. data/spec/fixtures/approvals/docs_webhooks_pact_webhooks_options.approved.json +20 -0
  114. data/spec/fixtures/approvals/docs_webhooks_triggered_webhooks_for_pact_publication_get.approved.json +52 -0
  115. data/spec/fixtures/approvals/docs_webhooks_triggered_webhooks_for_pact_publication_options.approved.json +20 -0
  116. data/spec/fixtures/approvals/docs_webhooks_triggered_webhooks_for_verification_publication_get.approved.json +32 -0
  117. data/spec/fixtures/approvals/docs_webhooks_triggered_webhooks_for_verification_publication_options.approved.json +20 -0
  118. data/spec/fixtures/approvals/docs_webhooks_webhook_get.approved.json +74 -0
  119. data/spec/fixtures/approvals/docs_webhooks_webhook_options.approved.json +20 -0
  120. data/spec/fixtures/approvals/docs_webhooks_webhook_put.approved.json +77 -0
  121. data/spec/fixtures/approvals/docs_webhooks_webhooks_for_a_provider_get.approved.json +41 -0
  122. data/spec/fixtures/approvals/docs_webhooks_webhooks_for_a_provider_options.approved.json +20 -0
  123. data/spec/fixtures/approvals/docs_webhooks_webhooks_for_consumer_and_provider_get.approved.json +45 -0
  124. data/spec/fixtures/approvals/docs_webhooks_webhooks_for_consumer_and_provider_options.approved.json +20 -0
  125. data/spec/fixtures/approvals/docs_webhooks_webhooks_for_consumer_get.approved.json +41 -0
  126. data/spec/fixtures/approvals/docs_webhooks_webhooks_for_consumer_options.approved.json +20 -0
  127. data/spec/fixtures/approvals/docs_webhooks_webhooks_get.approved.json +45 -0
  128. data/spec/fixtures/approvals/docs_webhooks_webhooks_options.approved.json +20 -0
  129. data/spec/fixtures/approvals/docs_webhooks_webhooks_post.approved.json +78 -0
  130. data/spec/fixtures/approvals/docs_webhooks_webhooks_status_get.approved.json +79 -0
  131. data/spec/fixtures/approvals/docs_webhooks_webhooks_status_options.approved.json +20 -0
  132. data/spec/fixtures/approvals/get_provider_pacts_for_verification.approved.json +1 -2
  133. data/spec/fixtures/approvals/publish_contract_no_branch.approved.json +1 -2
  134. data/spec/fixtures/approvals/publish_contract_nothing_exists.approved.json +1 -2
  135. data/spec/fixtures/approvals/publish_contract_nothing_exists_with_webhook.approved.json +1 -2
  136. data/spec/fixtures/approvals/publish_contract_verification_already_exists.approved.json +1 -2
  137. data/spec/fixtures/approvals/publish_contract_with_validation_error.approved.json +1 -2
  138. data/spec/fixtures/invalid-publish-contract-body.json +38 -0
  139. data/spec/fixtures/verification.json +4 -0
  140. data/spec/integration/pact_metdata_spec.rb +105 -0
  141. data/spec/integration/webhooks/contract_publication_spec.rb +68 -0
  142. data/spec/integration/webhooks/contract_requiring_verification_published_spec.rb +67 -0
  143. data/spec/integration/webhooks/pact_publication_spec.rb +51 -0
  144. data/spec/integration/webhooks_documentation_spec.rb +348 -0
  145. data/spec/lib/pact/doc/markdown/consumer_contract_renderer_spec.rb +2 -2
  146. data/spec/lib/pact_broker/api/contracts/publish_contracts_schema_spec.rb +13 -0
  147. data/spec/lib/pact_broker/api/contracts/webhook_contract_spec.rb +50 -0
  148. data/spec/lib/pact_broker/api/decorators/matrix_decorator_spec.rb +1 -1
  149. data/spec/lib/pact_broker/api/decorators/verification_decorator_spec.rb +15 -7
  150. data/spec/lib/pact_broker/api/decorators/verification_summary_decorator_spec.rb +4 -2
  151. data/spec/lib/pact_broker/api/decorators/webhook_decorator_spec.rb +4 -4
  152. data/spec/lib/pact_broker/api/pact_broker_urls_spec.rb +18 -0
  153. data/spec/lib/pact_broker/api/resources/triggered_webhook_logs_spec.rb +6 -5
  154. data/spec/lib/pact_broker/config/runtime_configuration_documentation_spec.rb +30 -0
  155. data/spec/lib/pact_broker/deployments/environment_service_spec.rb +22 -1
  156. data/spec/lib/pact_broker/domain/webhook_spec.rb +35 -0
  157. data/spec/lib/pact_broker/matrix/head_row_spec.rb +9 -5
  158. data/spec/lib/pact_broker/matrix/parse_can_i_deploy_query_spec.rb +13 -0
  159. data/spec/lib/pact_broker/pacts/{latest_tagged_pact_publications_spec.rb → pact_publication_clean_selector_dataset_module_spec.rb} +7 -9
  160. data/spec/lib/pact_broker/pacts/pact_version_spec.rb +32 -0
  161. data/spec/lib/pact_broker/pacts/repository_find_for_verification_spec.rb +4 -5
  162. data/spec/lib/pact_broker/pacts/repository_spec.rb +33 -0
  163. data/spec/lib/pact_broker/ui/view_models/index_item_spec.rb +1 -1
  164. data/spec/lib/pact_broker/verifications/service_spec.rb +22 -8
  165. data/spec/lib/pact_broker/versions/abbreviate_number_spec.rb +2 -1
  166. data/spec/lib/pact_broker/webhooks/render_spec.rb +3 -2
  167. data/spec/lib/pact_broker/webhooks/repository_spec.rb +158 -15
  168. data/spec/lib/pact_broker/webhooks/webhook_spec.rb +8 -5
  169. data/spec/support/documentation.rb +64 -0
  170. data/spec/support/rack_helpers.rb +1 -1
  171. data/tasks/db.rake +4 -1
  172. data/tasks/development.rake +14 -13
  173. metadata +89 -12
  174. data/lib/pact_broker/pacts/all_pact_publications.rb +0 -158
  175. data/lib/pact_broker/pacts/latest_pact_publications.rb +0 -48
  176. data/lib/pact_broker/pacts/latest_pact_publications_by_consumer_version.rb +0 -26
  177. data/lib/pact_broker/pacts/latest_tagged_pact_publications.rb +0 -45
  178. data/lib/pact_broker/verifications/latest_verification_for_pact_version.rb +0 -39
  179. data/spec/lib/pact_broker/verifications/latest_verification_for_pact_version_spec.rb +0 -18
@@ -32,18 +32,53 @@ module PactBroker
32
32
 
33
33
  context "with a consumer and provider" do
34
34
  it { is_expected.to eq "A webhook for the pact between Consumer and Provider" }
35
+
36
+ context "when provider is specified by a label" do
37
+ let(:provider) { WebhookPacticipant.new(label: "provider-label")}
38
+
39
+ it { is_expected.to eq "A webhook for the pact between Consumer and providers labeled 'provider-label'" }
40
+ end
41
+
42
+ context "when consumer is specified by a label" do
43
+ let(:consumer) { WebhookPacticipant.new(label: "consumer-label")}
44
+
45
+ it { is_expected.to eq "A webhook for the pact between consumers labeled 'consumer-label' and Provider" }
46
+ end
47
+
48
+ context "when both are specified by labels" do
49
+ let(:consumer) { WebhookPacticipant.new(label: "consumer-label")}
50
+ let(:provider) { WebhookPacticipant.new(label: "provider-label")}
51
+
52
+ it do
53
+ is_expected.to eq(
54
+ "A webhook for the pact between consumers labeled 'consumer-label' and providers labeled 'provider-label'"
55
+ )
56
+ end
57
+ end
35
58
  end
36
59
 
37
60
  context "with a consumer only" do
38
61
  let(:provider) { nil }
39
62
 
40
63
  it { is_expected.to eq "A webhook for all pacts with consumer Consumer" }
64
+
65
+ context "when specified by a label" do
66
+ let(:consumer) { WebhookPacticipant.new(label: "consumer-label")}
67
+
68
+ it { is_expected.to eq "A webhook for all pacts with consumer labeled 'consumer-label'" }
69
+ end
41
70
  end
42
71
 
43
72
  context "with a provider only" do
44
73
  let(:consumer) { nil }
45
74
 
46
75
  it { is_expected.to eq "A webhook for all pacts with provider Provider" }
76
+
77
+ context "when specified by a label" do
78
+ let(:provider) { WebhookPacticipant.new(label: "provider-label")}
79
+
80
+ it { is_expected.to eq "A webhook for all pacts with provider labeled 'provider-label'" }
81
+ end
47
82
  end
48
83
 
49
84
  context "with neither a consumer nor a provider" do
@@ -13,18 +13,22 @@ module PactBroker
13
13
  .create_provider("Bar")
14
14
  .create_consumer_version
15
15
  .create_pact
16
- .create_global_webhook
17
- .create_consumer_webhook
18
- .create_provider_webhook
16
+ .create_global_webhook(description: "global")
17
+ .create_consumer_webhook(description: "consumer")
18
+ .create_provider_webhook(description: "provider")
19
19
  .create_provider("Wiffle")
20
- .create_provider_webhook
20
+ .create_provider_webhook(description: "wiffle")
21
21
  end
22
22
 
23
23
  let(:row) { HeadRow.where(consumer_name: "Foo", provider_name: "Bar").single_record }
24
24
 
25
25
  it "returns all the webhooks" do
26
26
  rows = HeadRow.eager(:webhooks).all
27
- expect(rows.first.webhooks.count).to eq 3
27
+ expect(rows.first.webhooks).to contain_exactly(
28
+ have_attributes(description: "global"),
29
+ have_attributes(description: "provider"),
30
+ have_attributes(description: "consumer")
31
+ )
28
32
  end
29
33
  end
30
34
 
@@ -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
  {
@@ -1,9 +1,7 @@
1
- require "pact_broker/pacts/latest_tagged_pact_publications"
2
-
3
1
  module PactBroker
4
2
  module Pacts
5
- describe LatestTaggedPactPublications do
6
- subject { LatestTaggedPactPublications.for_selector(selector).order(:consumer_name, :consumer_version_order) }
3
+ describe PactPublicationCleanSelectorDatasetModule do
4
+ subject { PactPublication.latest_by_consumer_tag_for_clean_selector(selector).all.sort_by{ | pp | [pp.consumer_name, pp.consumer_version_number]} }
7
5
 
8
6
  context "for latest for a specified tag" do
9
7
  before do
@@ -15,7 +13,7 @@ module PactBroker
15
13
  .create_consumer_version_tag("prod")
16
14
  end
17
15
 
18
- let(:selector) { PactBroker::Matrix::UnresolvedSelector.new(tag: "dev", latest: true) }
16
+ let(:selector) { PactBroker::DB::Clean::Selector.new(tag: "dev", latest: true) }
19
17
 
20
18
  it "returns matching rows" do
21
19
  expect(subject.count).to eq 1
@@ -33,7 +31,7 @@ module PactBroker
33
31
  .create_consumer_version_tag("dev")
34
32
  end
35
33
 
36
- let(:selector) { PactBroker::Matrix::UnresolvedSelector.new(tag: "dev", latest: true, pacticipant_name: "Foo") }
34
+ let(:selector) { PactBroker::DB::Clean::Selector.new(tag: "dev", latest: true, pacticipant_name: "Foo") }
37
35
 
38
36
  it "returns matching rows" do
39
37
  expect(subject.count).to eq 1
@@ -51,7 +49,7 @@ module PactBroker
51
49
  .create_consumer_version_tag("prod")
52
50
  end
53
51
 
54
- let(:selector) { PactBroker::Matrix::UnresolvedSelector.new(tag: "dev") }
52
+ let(:selector) { PactBroker::DB::Clean::Selector.new(tag: "dev") }
55
53
 
56
54
  it "returns matching rows (which are only the latest)" do
57
55
  expect(subject.count).to eq 1
@@ -69,7 +67,7 @@ module PactBroker
69
67
  .create_consumer_version_tag("prod")
70
68
  end
71
69
 
72
- let(:selector) { PactBroker::Matrix::UnresolvedSelector.new(tag: true, latest: true) }
70
+ let(:selector) { PactBroker::DB::Clean::Selector.new(tag: true, latest: true) }
73
71
 
74
72
  it "returns matching rows" do
75
73
  expect(subject.count).to eq 2
@@ -87,7 +85,7 @@ module PactBroker
87
85
  .create_consumer_version_tag("dev")
88
86
  end
89
87
 
90
- let(:selector) { PactBroker::Matrix::UnresolvedSelector.new(tag: true, latest: true, max_age: 5) }
88
+ let(:selector) { PactBroker::DB::Clean::Selector.new(tag: true, latest: true, max_age: 5) }
91
89
 
92
90
  it "returns matching rows" do
93
91
  expect(subject.count).to eq 1
@@ -65,6 +65,38 @@ module PactBroker
65
65
  end
66
66
  end
67
67
 
68
+ describe "#latest_main_branch_verification" do
69
+ before do
70
+ td.create_pact_with_verification("Foo", "1", "Bar", "2")
71
+ .create_verification(provider_version: "3", number: 2, branch: "main")
72
+ .create_verification(provider_version: "3", number: 3)
73
+ .create_verification(provider_version: "3", number: 4)
74
+ .create_pact_with_verification("NotFoo", "1", "Bar", "4")
75
+ .create_verification(provider_version: "5", number: 5)
76
+ .create_pact_with_verification("NotFoo2", "1", "NotBar", "4")
77
+ .create_verification(provider_version: "6", number: 6)
78
+ .create_pact_with_verification("NotFoo3", "2", "NotBar", "5")
79
+ .create_verification(provider_version: "7", number: 7)
80
+ end
81
+
82
+ context "lazy loading" do
83
+ it "lazy loads" do
84
+ expect(PactPublication.order(:id).all.first.pact_version.latest_main_branch_verification).to have_attributes(provider_version_number: "3", number: 4)
85
+ expect(PactPublication.order(:id).all.last.pact_version.latest_main_branch_verification).to be_nil
86
+ end
87
+ end
88
+
89
+ context "eager loading" do
90
+ let(:pact_version_1) { PactVersion.eager(:latest_main_branch_verification).order(:id).all.first }
91
+ let(:pact_version_2) { PactVersion.eager(:latest_main_branch_verification).order(:id).all.last }
92
+
93
+ it "eager loads" do
94
+ expect(PactPublication.order(:id).all.first.pact_version.latest_main_branch_verification).to have_attributes(provider_version_number: "3", number: 4)
95
+ expect(pact_version_2.associations[:latest_main_branch_verification]).to be_nil
96
+ end
97
+ end
98
+ end
99
+
68
100
  describe "latest_consumer_version" do
69
101
  before do
70
102
  td.create_consumer("consumer")
@@ -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
@@ -967,6 +967,9 @@ module PactBroker
967
967
  before do
968
968
  td.create_consumer("Consumer")
969
969
  .create_provider("Provider")
970
+ .create_consumer_version("0")
971
+ .create_consumer_version_tag("main")
972
+ .create_pact
970
973
  .create_consumer_version("1")
971
974
  .create_pact
972
975
  .create_provider("Another Provider")
@@ -997,6 +1000,36 @@ module PactBroker
997
1000
  expect(pact.consumer_version.number).to eq("2")
998
1001
  end
999
1002
  end
1003
+
1004
+ context "with a tag" do
1005
+ let(:pact) { Repository.new.search_for_latest_pact("Consumer", "Provider", "main") }
1006
+
1007
+ it "returns the latest" do
1008
+ expect(pact.consumer_version.number).to eq("0")
1009
+ end
1010
+ end
1011
+
1012
+ context "untagged" do
1013
+ before do
1014
+ td.create_consumer("Foo")
1015
+ .create_provider("Bar")
1016
+ .create_consumer_version("0")
1017
+ .create_consumer_version_tag("main")
1018
+ .create_pact
1019
+ .create_consumer_version("1")
1020
+ .create_pact
1021
+ .create_consumer_version("2")
1022
+ .create_consumer_version_tag("main")
1023
+ .create_pact
1024
+
1025
+ end
1026
+
1027
+ let(:pact) { Repository.new.search_for_latest_pact("Foo", "Bar", :untagged) }
1028
+
1029
+ it "returns the latest" do
1030
+ expect(pact.consumer_version.number).to eq("1")
1031
+ end
1032
+ end
1000
1033
  end
1001
1034
  end
1002
1035
 
@@ -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
 
@@ -21,7 +21,19 @@ module PactBroker
21
21
 
22
22
  let(:event_context) { { some: "data", consumer_version_selectors: [{ foo: "bar" }] } }
23
23
  let(:expected_event_context) { { some: "data", provider_version_tags: ["dev"] } }
24
- let(:params) { { "success" => success, "providerApplicationVersion" => "4.5.6", "wip" => true, "pending" => is_pending, "testResults" => { "some" => "results" }} }
24
+ let(:params) do
25
+ {
26
+ "success" => success,
27
+ "providerApplicationVersion" => "4.5.6",
28
+ "wip" => true,
29
+ "pending" => is_pending,
30
+ "testResults" => { "some" => "results" },
31
+ "verifiedBy" => {
32
+ "implementation" => "Ruby",
33
+ "version" => "1234"
34
+ }
35
+ }
36
+ end
25
37
  let(:is_pending) { true }
26
38
  let(:success) { true }
27
39
  let(:pact) do
@@ -34,7 +46,7 @@ module PactBroker
34
46
  let(:create_verification) { subject.create 3, params, selected_pacts, event_context }
35
47
 
36
48
  it "logs the creation" do
37
- expect(logger).to receive(:info).with(/.*verification.*3/, payload: {"providerApplicationVersion"=>"4.5.6", "success"=>true, "wip"=>true, "pending" => is_pending})
49
+ expect(logger).to receive(:info).with(/.*verification.*3/, payload: hash_including("providerApplicationVersion"=>"4.5.6", "success"=>true, "wip"=>true, "pending" => is_pending))
38
50
  create_verification
39
51
  end
40
52
 
@@ -47,6 +59,8 @@ module PactBroker
47
59
  expect(verification.test_results).to eq "some" => "results"
48
60
  expect(verification.consumer_version_selector_hashes).to eq [{ foo: "bar" }]
49
61
  expect(verification.tag_names).to eq ["dev"]
62
+ expect(verification.verified_by_implementation).to eq "Ruby"
63
+ expect(verification.verified_by_version).to eq "1234"
50
64
  end
51
65
 
52
66
  it "sets the pact content for the verification" do
@@ -101,7 +115,7 @@ module PactBroker
101
115
  expect(subject).to eq [
102
116
  RequiredVerification.new(
103
117
  provider_version: td.find_version("Bar", "1"),
104
- provider_version_descriptions: ["latest version from main branch"]
118
+ provider_version_descriptions: ["latest from main branch"]
105
119
  )
106
120
  ]
107
121
  end
@@ -139,7 +153,7 @@ module PactBroker
139
153
  expect(subject).to eq [
140
154
  RequiredVerification.new(
141
155
  provider_version: td.find_version("Bar", "1"),
142
- provider_version_descriptions: ["currently deployed version (test)"]
156
+ provider_version_descriptions: ["deployed in test"]
143
157
  )
144
158
  ]
145
159
  end
@@ -179,7 +193,7 @@ module PactBroker
179
193
  expect(subject).to eq [
180
194
  RequiredVerification.new(
181
195
  provider_version: td.find_version("Bar", "1"),
182
- provider_version_descriptions: ["currently released version (test)"]
196
+ provider_version_descriptions: ["released in test"]
183
197
  )
184
198
  ]
185
199
  end
@@ -221,9 +235,9 @@ module PactBroker
221
235
  RequiredVerification.new(
222
236
  provider_version: td.find_version("Bar", "1"),
223
237
  provider_version_descriptions: [
224
- "latest version from main branch",
225
- "currently deployed version (test)",
226
- "currently released version (test)"
238
+ "latest from main branch",
239
+ "deployed in test",
240
+ "released in test"
227
241
  ])
228
242
  ]
229
243
  end
@@ -8,7 +8,8 @@ module PactBroker
8
8
  ["202326572516dea6998a7f311fcaa161c0768fc2", "2023265"],
9
9
  ["1.2.3+areallyreallyreallylongexplanation", "1.2.3+areallyreallyreallylongexplanation"],
10
10
  ["2516dea6998a7f", "2516dea6998a7f"],
11
- ["1.2.3+202326572516dea6998a7f311fcaa161c0768fc2", "1.2.3+2023265"]
11
+ ["1.2.3+202326572516dea6998a7f311fcaa161c0768fc2", "1.2.3+2023265"],
12
+ ["this-is-very-long-text-this-is-very-long-text-this-is-very-long-text-this-is-very-long-text", "this-is-very-long-text-this-is-very-lon…-long-text"]
12
13
  ]
13
14
 
14
15
  TEST_CASES.each do |(input, output)|
@@ -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) |
@@ -23,6 +23,8 @@ module PactBroker
23
23
  let(:webhook) { Domain::Webhook.new(request: request, events: events) }
24
24
  let(:consumer) { td.create_pacticipant("Consumer").and_return(:pacticipant) }
25
25
  let(:provider) { td.create_pacticipant("Provider").and_return(:pacticipant) }
26
+ let(:webhook_consumer) { Domain::WebhookPacticipant.new(name: consumer.name) }
27
+ let(:webhook_provider) { Domain::WebhookPacticipant.new(name: provider.name) }
26
28
  let(:uuid) { "the-uuid" }
27
29
  let(:created_webhook_record) { ::DB::PACT_BROKER_DB[:webhooks].order(:id).last }
28
30
  let(:created_events) { ::DB::PACT_BROKER_DB[:webhook_events].where(webhook_id: created_webhook_record[:id]).order(:name).all }
@@ -57,13 +59,13 @@ module PactBroker
57
59
  end
58
60
 
59
61
  context "when consumer and provider domain objects are set on the object rather than passed in" do
60
- let(:webhook) { Domain::Webhook.new(request: request, events: events, consumer: consumer, provider: provider) }
62
+ let(:webhook) { Domain::Webhook.new(request: request, events: events, consumer: webhook_consumer, provider: webhook_provider) }
61
63
 
62
64
  subject { Repository.new.create(uuid, webhook, nil, nil) }
63
65
 
64
66
  it "sets the consumer and provider relationships" do
65
- expect(subject.consumer.id).to eq consumer.id
66
- expect(subject.provider.id).to eq provider.id
67
+ expect(subject.consumer.name).to eq consumer.name
68
+ expect(subject.provider.name).to eq provider.name
67
69
  end
68
70
  end
69
71
  end
@@ -185,12 +187,10 @@ module PactBroker
185
187
  end
186
188
 
187
189
  it "returns a webhook with the consumer set" do
188
- expect(subject.consumer.id).to eq consumer.id
189
190
  expect(subject.consumer.name).to eq consumer.name
190
191
  end
191
192
 
192
193
  it "returns a webhook with the provider set" do
193
- expect(subject.provider.id).to eq provider.id
194
194
  expect(subject.provider.name).to eq provider.name
195
195
  end
196
196
 
@@ -286,7 +286,7 @@ module PactBroker
286
286
  let(:new_event) do
287
287
  PactBroker::Webhooks::WebhookEvent.new(name: "something_else")
288
288
  end
289
- let(:new_consumer) { PactBroker::Domain::Pacticipant.new(name: "Foo2") }
289
+ let(:new_consumer) { Domain::WebhookPacticipant.new(name: "Foo2") }
290
290
  let(:new_webhook) do
291
291
  PactBroker::Domain::Webhook.new(
292
292
  consumer: new_consumer,
@@ -423,11 +423,13 @@ module PactBroker
423
423
  subject { Repository.new.find_webhooks_to_trigger(consumer: td.consumer, provider: td.provider, event_name: "contract_published") }
424
424
 
425
425
  it "does not use a policy" do
426
- td.create_webhook(event_names: ["contract_published"], enabled: enabled)
426
+ td.create_webhook(event_names: ["contract_published"], enabled: enabled, description: "Enabled webhook")
427
427
  .create_consumer("Foo")
428
428
  .create_provider("Bar")
429
429
  expect(PactBroker).to_not receive(:policy_scope!)
430
- expect(subject.size).to eq 1
430
+ is_expected.to contain_exactly(
431
+ have_attributes(description: "Enabled webhook")
432
+ )
431
433
  end
432
434
 
433
435
  context "when the webhook is disabled" do
@@ -437,21 +439,25 @@ module PactBroker
437
439
  .create_provider("Bar")
438
440
  end
439
441
  let(:enabled) { false }
440
- its(:size) { is_expected.to eq 0 }
442
+
443
+ it "finds no webhooks to trigger" do
444
+ is_expected.to be_empty
445
+ end
441
446
  end
442
447
 
443
448
  context "when the webhook is specified for a consumer and all providers" do
444
449
  before do
445
450
  td.create_consumer("Foo1")
446
451
  .create_provider("Bar1")
447
- .create_webhook(provider: nil, event_names: ["contract_published"])
452
+ .create_webhook(provider: nil, event_names: ["contract_published"], description: "Right webhook")
448
453
  end
449
454
 
450
- its(:size) { is_expected.to eq 1 }
455
+ let(:webhook_consumer) { Domain::WebhookPacticipant.new(name: td.consumer.name) }
451
456
 
452
- it "returns the right webhook" do
453
- expect(subject.first.consumer).to eq td.consumer
454
- expect(subject.first.provider).to be nil
457
+ it "finds one webhook to trigger" do
458
+ is_expected.to contain_exactly(
459
+ have_attributes(description: "Right webhook")
460
+ )
455
461
  end
456
462
  end
457
463
 
@@ -463,7 +469,144 @@ module PactBroker
463
469
  .create_provider("Bar3")
464
470
  end
465
471
 
466
- its(:size) { is_expected.to eq 0 }
472
+ it "finds no webhooks to trigger" do
473
+ is_expected.to be_empty
474
+ end
475
+ end
476
+
477
+ context "when the webhook is specified for matching consumer label" do
478
+ before do
479
+ td.create_webhook(
480
+ event_names: ["contract_published"],
481
+ consumer_label: "my_label",
482
+ description: "Labeled webhook"
483
+ )
484
+ .create_consumer("Consumer")
485
+ .create_label("my_label")
486
+ .create_provider("Provider")
487
+ end
488
+
489
+ it "finds one webhook to trigger" do
490
+ is_expected.to contain_exactly(
491
+ have_attributes(description: "Labeled webhook")
492
+ )
493
+ end
494
+ end
495
+
496
+ context "when the webhook is specified for matching consumer label and specific provider" do
497
+ before do
498
+ td.create_provider("Provider")
499
+ .create_webhook(
500
+ event_names: ["contract_published"],
501
+ consumer_label: "my_label",
502
+ description: "Labeled webhook"
503
+ )
504
+ .create_consumer("Consumer")
505
+ .create_label("my_label")
506
+ end
507
+
508
+ it "finds one webhook to trigger" do
509
+ is_expected.to contain_exactly(
510
+ have_attributes(description: "Labeled webhook")
511
+ )
512
+ end
513
+ end
514
+
515
+ context "when the webhook is specified for consumer label that does not match" do
516
+ before do
517
+ td.create_webhook(event_names: ["contract_published"], consumer_label: "my_label")
518
+ .create_consumer("Consumer")
519
+ .create_label("other_label")
520
+ .create_provider("Provider")
521
+ end
522
+
523
+ it "finds no webhooks to trigger" do
524
+ is_expected.to be_empty
525
+ end
526
+ end
527
+
528
+ context "when the webhook is specified for matching provider label" do
529
+ before do
530
+ td.create_webhook(
531
+ event_names: ["contract_published"],
532
+ provider_label: "my_label",
533
+ description: "Labeled webhook"
534
+ )
535
+ .create_consumer("Consumer")
536
+ .create_provider("Provider")
537
+ .create_label("my_label")
538
+ end
539
+
540
+ it "finds one webhook to trigger" do
541
+ is_expected.to contain_exactly(
542
+ have_attributes(description: "Labeled webhook")
543
+ )
544
+ end
545
+ end
546
+
547
+ context "when the webhook is specified for matching provider label and specific consumer" do
548
+ before do
549
+ td.create_consumer("Consumer")
550
+ .create_webhook(
551
+ event_names: ["contract_published"],
552
+ provider_label: "my_label",
553
+ description: "Labeled webhook"
554
+ )
555
+ .create_provider("Provider")
556
+ .create_label("my_label")
557
+ end
558
+
559
+ it "finds one webhook to trigger" do
560
+ is_expected.to contain_exactly(
561
+ have_attributes(description: "Labeled webhook")
562
+ )
563
+ end
564
+ end
565
+
566
+ context "when the webhook is specified for provider label that does not match" do
567
+ before do
568
+ td.create_webhook(event_names: ["contract_published"], provider_label: "my_label")
569
+ .create_consumer("Consumer")
570
+ .create_provider("Provider")
571
+ .create_label("other_label")
572
+ end
573
+
574
+ it "find no webhooks to trigger" do
575
+ is_expected.to be_empty
576
+ end
577
+ end
578
+
579
+ context "when the webhook is specified for consumer and provider label" do
580
+ before do
581
+ td.create_webhook(
582
+ event_names: ["contract_published"],
583
+ consumer_label: "clabel",
584
+ provider_label: "plabel",
585
+ description: "Labeled webhook"
586
+ )
587
+ .create_webhook(
588
+ event_names: ["contract_published"],
589
+ consumer_label: "clabel",
590
+ provider_label: "plabel2",
591
+ description: "Labeled consumer webhook"
592
+ )
593
+ .create_webhook(
594
+ event_names: ["contract_published"],
595
+ consumer_label: "clabel2",
596
+ provider_label: "plabel",
597
+ description: "Labeled provider webhook"
598
+ )
599
+ .create_consumer("Consumer")
600
+ .create_label("clabel")
601
+ .create_provider("Provider")
602
+ .create_label("plabel")
603
+ end
604
+
605
+ it "finds one webhook to trigger" do
606
+ is_expected.to contain_exactly(
607
+ have_attributes(description: "Labeled webhook")
608
+ )
609
+ end
467
610
  end
468
611
  end
469
612