pact_broker 2.75.0 → 2.78.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (193) hide show
  1. checksums.yaml +4 -4
  2. data/.codeclimate.yml +12 -0
  3. data/.github/workflows/test-ruby-3.yml +19 -0
  4. data/.github/workflows/test.yml +19 -4
  5. data/.gitignore +3 -1
  6. data/CHANGELOG.md +48 -0
  7. data/DEVELOPER_SETUP.md +62 -3
  8. data/Dockerfile +1 -0
  9. data/ISSUES.md +13 -5
  10. data/README.md +1 -1
  11. data/config.ru +1 -0
  12. data/db/ddl_statements/head_pact_tags.rb +24 -1
  13. data/db/ddl_statements/latest_tagged_pact_consumer_version_orders.rb +11 -0
  14. data/db/ddl_statements/latest_tagged_pact_publications.rb +6 -0
  15. data/db/ddl_statements/latest_verification_ids_for_consumer_version_tags.rb +13 -0
  16. data/db/migrations/20210117_add_branch_to_version.rb +9 -0
  17. data/db/migrations/20210202_add_created_at_to_head_pact_tags.rb +14 -0
  18. data/db/migrations/20210205_add_pacticipant_id_to_tag.rb +17 -0
  19. data/db/migrations/20210206_add_index_to_tags_and_versions.rb +27 -0
  20. data/db/migrations/20210207_optimise_latest_verification_ids_for_consumer_version_tags.rb +13 -0
  21. data/db/migrations/20210208_optimise_latest_tagged_pact_cv_orders.rb +13 -0
  22. data/db/migrations/20210210_create_environments_table.rb +16 -0
  23. data/docker-compose-issue-repro-with-pact-broker-docker-image.yml +44 -0
  24. data/lib/pact_broker/api.rb +7 -2
  25. data/lib/pact_broker/api/contracts/dry_validation_predicates.rb +8 -0
  26. data/lib/pact_broker/api/contracts/environment_schema.rb +49 -0
  27. data/lib/pact_broker/api/decorators/base_decorator.rb +11 -0
  28. data/lib/pact_broker/api/decorators/dashboard_decorator.rb +5 -1
  29. data/lib/pact_broker/api/decorators/environment_decorator.rb +30 -0
  30. data/lib/pact_broker/api/decorators/environments_decorator.rb +21 -0
  31. data/lib/pact_broker/api/decorators/matrix_decorator.rb +8 -2
  32. data/lib/pact_broker/api/decorators/reason_decorator.rb +2 -2
  33. data/lib/pact_broker/api/decorators/verifiable_pacts_query_decorator.rb +2 -0
  34. data/lib/pact_broker/api/decorators/version_decorator.rb +15 -2
  35. data/lib/pact_broker/api/pact_broker_urls.rb +8 -0
  36. data/lib/pact_broker/api/paths.rb +5 -0
  37. data/lib/pact_broker/api/resources/default_base_resource.rb +15 -2
  38. data/lib/pact_broker/api/resources/environment.rb +76 -0
  39. data/lib/pact_broker/api/resources/environments.rb +75 -0
  40. data/lib/pact_broker/api/resources/index.rb +20 -0
  41. data/lib/pact_broker/api/resources/latest_version.rb +27 -0
  42. data/lib/pact_broker/api/resources/provider_pacts_for_verification.rb +1 -0
  43. data/lib/pact_broker/api/resources/verifications.rb +5 -2
  44. data/lib/pact_broker/api/resources/version.rb +15 -9
  45. data/lib/pact_broker/api/resources/webhook_execution.rb +1 -1
  46. data/lib/pact_broker/app.rb +3 -0
  47. data/lib/pact_broker/certificates/certificate.rb +1 -1
  48. data/lib/pact_broker/config/setting.rb +1 -1
  49. data/lib/pact_broker/config/space_delimited_integer_list.rb +25 -0
  50. data/lib/pact_broker/configuration.rb +18 -1
  51. data/lib/pact_broker/db/data_migrations/helpers.rb +4 -0
  52. data/lib/pact_broker/db/data_migrations/set_extra_columns_for_tags.rb +29 -0
  53. data/lib/pact_broker/db/migrate_data.rb +1 -0
  54. data/lib/pact_broker/db/seed_example_data.rb +13 -13
  55. data/lib/pact_broker/deployments/environment.rb +15 -0
  56. data/lib/pact_broker/deployments/environment_service.rb +39 -0
  57. data/lib/pact_broker/doc/controllers/app.rb +1 -1
  58. data/lib/pact_broker/doc/views/index/environment.markdown +37 -0
  59. data/lib/pact_broker/doc/views/index/environments.markdown +53 -0
  60. data/lib/pact_broker/doc/views/index/latest-pact-versions.markdown +1 -1
  61. data/lib/pact_broker/doc/views/index/pacticipant-version-tag.markdown +1 -0
  62. data/lib/pact_broker/doc/views/index/pacticipant-version.markdown +13 -0
  63. data/lib/pact_broker/domain/index_item.rb +18 -4
  64. data/lib/pact_broker/domain/pacticipant.rb +9 -5
  65. data/lib/pact_broker/domain/tag.rb +131 -71
  66. data/lib/pact_broker/domain/verification.rb +3 -2
  67. data/lib/pact_broker/domain/version.rb +58 -23
  68. data/lib/pact_broker/domain/webhook.rb +12 -9
  69. data/lib/pact_broker/hash_refinements.rb +4 -0
  70. data/lib/pact_broker/index/service.rb +55 -49
  71. data/lib/pact_broker/locale/en.yml +3 -1
  72. data/lib/pact_broker/matrix/quick_row.rb +8 -0
  73. data/lib/pact_broker/metrics/service.rb +1 -1
  74. data/lib/pact_broker/pacts/eager_loaders.rb +52 -0
  75. data/lib/pact_broker/pacts/latest_pact_publication_id_for_consumer_version.rb +18 -13
  76. data/lib/pact_broker/pacts/lazy_loaders.rb +14 -0
  77. data/lib/pact_broker/pacts/pact_publication.rb +38 -84
  78. data/lib/pact_broker/pacts/pact_publication_dataset_module.rb +297 -0
  79. data/lib/pact_broker/pacts/pact_version.rb +1 -2
  80. data/lib/pact_broker/pacts/pacts_for_verification_repository.rb +286 -0
  81. data/lib/pact_broker/pacts/repository.rb +5 -231
  82. data/lib/pact_broker/pacts/selected_pact.rb +4 -0
  83. data/lib/pact_broker/pacts/selector.rb +56 -1
  84. data/lib/pact_broker/pacts/selectors.rb +16 -0
  85. data/lib/pact_broker/pacts/service.rb +6 -8
  86. data/lib/pact_broker/pacts/squash_pacts_for_verification.rb +1 -4
  87. data/lib/pact_broker/pacts/verifiable_pact.rb +45 -2
  88. data/lib/pact_broker/pacts/verifiable_pact_messages.rb +56 -16
  89. data/lib/pact_broker/repositories/helpers.rb +4 -0
  90. data/lib/pact_broker/services.rb +9 -0
  91. data/lib/pact_broker/tags/eager_loaders.rb +47 -0
  92. data/lib/pact_broker/tags/repository.rb +3 -1
  93. data/lib/pact_broker/tags/service.rb +0 -3
  94. data/lib/pact_broker/tags/tag_with_latest_flag.rb +1 -0
  95. data/lib/pact_broker/test/http_test_data_builder.rb +101 -35
  96. data/lib/pact_broker/test/test_data_builder.rb +50 -3
  97. data/lib/pact_broker/ui/app.rb +6 -0
  98. data/lib/pact_broker/ui/controllers/base_controller.rb +5 -1
  99. data/lib/pact_broker/ui/controllers/pacts.rb +18 -0
  100. data/lib/pact_broker/ui/view_models/index_item.rb +9 -0
  101. data/lib/pact_broker/ui/view_models/matrix_line.rb +36 -0
  102. data/lib/pact_broker/ui/views/index/show-with-tags.haml +8 -0
  103. data/lib/pact_broker/ui/views/matrix/show.haml +10 -0
  104. data/lib/pact_broker/verifications/latest_verification_id_for_pact_version_and_provider_version.rb +7 -5
  105. data/lib/pact_broker/verifications/service.rb +2 -1
  106. data/lib/pact_broker/version.rb +1 -1
  107. data/lib/pact_broker/versions/eager_loaders.rb +71 -0
  108. data/lib/pact_broker/versions/lazy_loaders.rb +13 -0
  109. data/lib/pact_broker/versions/repository.rb +22 -2
  110. data/lib/pact_broker/versions/service.rb +5 -1
  111. data/lib/pact_broker/webhooks/execution.rb +3 -2
  112. data/lib/pact_broker/webhooks/latest_triggered_webhook.rb +2 -0
  113. data/lib/pact_broker/webhooks/pact_and_verification_parameters.rb +10 -3
  114. data/lib/pact_broker/webhooks/service.rb +8 -7
  115. data/lib/pact_broker/webhooks/trigger_service.rb +56 -23
  116. data/lib/pact_broker/webhooks/triggered_webhook.rb +14 -5
  117. data/lib/pact_broker/webhooks/webhook.rb +1 -1
  118. data/lib/pact_broker/webhooks/webhook_event.rb +1 -1
  119. data/lib/pact_broker/webhooks/webhook_execution_result.rb +4 -1
  120. data/lib/pact_broker/webhooks/webhook_request_logger.rb +5 -1
  121. data/lib/rack/pact_broker/set_base_url.rb +22 -0
  122. data/lib/sequel/plugins/upsert.rb +18 -4
  123. data/public/stylesheets/index.css +22 -1
  124. data/public/stylesheets/matrix.css +0 -21
  125. data/regression/can_i_deploy_spec.rb +5 -4
  126. data/regression/index_spec.rb +26 -0
  127. data/regression/regression_helper.rb +29 -3
  128. data/regression/script/clear.sh +3 -0
  129. data/regression/script/run.sh +3 -0
  130. data/script/demonstrate-version-branches.rb +33 -0
  131. data/script/pry.rb +2 -2
  132. data/script/reproduce-issue-starting-up.rb +13 -23
  133. data/script/reproduce-issue.rb +18 -14
  134. data/script/trigger-release.sh +1 -1
  135. data/script/webhook-server.ru +5 -5
  136. data/spec/features/create_environment_spec.rb +47 -0
  137. data/spec/features/create_tag_spec.rb +32 -0
  138. data/spec/features/create_version_spec.rb +70 -0
  139. data/spec/features/delete_environment_spec.rb +16 -0
  140. data/spec/features/end_deployment_spec.rb +29 -0
  141. data/spec/features/get_environment_spec.rb +19 -0
  142. data/spec/features/get_environments_spec.rb +20 -0
  143. data/spec/features/record_deployment_spec.rb +28 -0
  144. data/spec/features/update_environment_spec.rb +44 -0
  145. data/spec/fixtures/approvals/modifiable_resources.approved.json +6 -0
  146. data/spec/fixtures/dashboard.json +4 -2
  147. data/spec/integration/ui/index_spec.rb +4 -4
  148. data/spec/lib/pact_broker/api/contracts/environment_schema_spec.rb +83 -0
  149. data/spec/lib/pact_broker/api/decorators/dashboard_decorator_spec.rb +4 -2
  150. data/spec/lib/pact_broker/api/decorators/matrix_decorator_spec.rb +11 -6
  151. data/spec/lib/pact_broker/api/decorators/reason_decorator_spec.rb +6 -6
  152. data/spec/lib/pact_broker/api/decorators/verifiable_pacts_query_decorator_spec.rb +6 -0
  153. data/spec/lib/pact_broker/api/decorators/version_decorator_spec.rb +18 -0
  154. data/spec/lib/pact_broker/api/resources/default_base_resource_approval_spec.rb +1 -1
  155. data/spec/lib/pact_broker/api/resources/default_base_resource_spec.rb +1 -12
  156. data/spec/lib/pact_broker/api/resources/provider_pacts_for_verification_spec.rb +4 -0
  157. data/spec/lib/pact_broker/api/resources/verifications_spec.rb +2 -5
  158. data/spec/lib/pact_broker/api/resources/webhook_execution_result_spec.rb +56 -0
  159. data/spec/lib/pact_broker/api/resources/webhook_execution_spec.rb +3 -2
  160. data/spec/lib/pact_broker/config/space_delimited_integer_list_spec.rb +47 -0
  161. data/spec/lib/pact_broker/configuration_spec.rb +12 -0
  162. data/spec/lib/pact_broker/doc/controllers/app_spec.rb +3 -5
  163. data/spec/lib/pact_broker/domain/tag_spec.rb +101 -27
  164. data/spec/lib/pact_broker/domain/version_spec.rb +103 -15
  165. data/spec/lib/pact_broker/domain/webhook_spec.rb +7 -7
  166. data/spec/lib/pact_broker/index/service_spec.rb +89 -15
  167. data/spec/lib/pact_broker/pacts/pact_publication_dataset_module_spec.rb +400 -0
  168. data/spec/lib/pact_broker/pacts/pact_publication_spec.rb +434 -14
  169. data/spec/lib/pact_broker/pacts/repository_find_for_verification_fallback_spec.rb +1 -1
  170. data/spec/lib/pact_broker/pacts/repository_find_for_verification_spec.rb +1 -1
  171. data/spec/lib/pact_broker/pacts/repository_find_wip_pact_versions_for_provider_branch_spec.rb +224 -0
  172. data/spec/lib/pact_broker/pacts/repository_find_wip_pact_versions_for_provider_spec.rb +46 -7
  173. data/spec/lib/pact_broker/pacts/selector_spec.rb +3 -2
  174. data/spec/lib/pact_broker/pacts/service_find_for_verification_spec.rb +2 -3
  175. data/spec/lib/pact_broker/pacts/service_spec.rb +9 -7
  176. data/spec/lib/pact_broker/pacts/verifiable_pact_messages_spec.rb +57 -10
  177. data/spec/lib/pact_broker/tags/repository_spec.rb +2 -0
  178. data/spec/lib/pact_broker/verifications/service_spec.rb +4 -1
  179. data/spec/lib/pact_broker/versions/repository_spec.rb +54 -0
  180. data/spec/lib/pact_broker/webhooks/render_spec.rb +6 -5
  181. data/spec/lib/pact_broker/webhooks/service_spec.rb +13 -9
  182. data/spec/lib/pact_broker/webhooks/trigger_service_spec.rb +60 -18
  183. data/spec/lib/pact_broker/webhooks/webhook_request_logger_spec.rb +8 -0
  184. data/spec/lib/sequel/plugins/upsert_spec.rb +31 -3
  185. data/spec/service_consumers/hal_relation_proxy_app.rb +3 -1
  186. data/spec/service_consumers/provider_states_for_pact_broker_client.rb +16 -0
  187. data/spec/spec_helper.rb +17 -5
  188. data/spec/support/approvals.rb +24 -0
  189. data/spec/support/shared_examples_for_responses.rb +11 -0
  190. data/tasks/db.rake +1 -0
  191. data/tasks/rspec.rake +1 -1
  192. metadata +69 -4
  193. data/docker-compose-issue-repro.yml +0 -22
@@ -23,6 +23,8 @@ module PactBroker
23
23
  it "sets the properties" do
24
24
  expect(subject.name).to eq "prod"
25
25
  expect(subject.version.id).to eq td.version.id
26
+ expect(subject.version_order).to eq td.version.order
27
+ expect(subject.pacticipant_id).to eq td.version.pacticipant_id
26
28
  end
27
29
 
28
30
  context "when the tag already exists" do
@@ -22,6 +22,8 @@ module PactBroker
22
22
  end
23
23
 
24
24
  let(:options) { { webhook_execution_configuration: webhook_execution_configuration } }
25
+ let(:event_context) { { some: "data" } }
26
+ let(:expected_event_context) { { some: "data", provider_version_tags: ["dev"] } }
25
27
  let(:webhook_execution_configuration) { instance_double(PactBroker::Webhooks::ExecutionConfiguration) }
26
28
  let(:params) { { 'success' => true, 'providerApplicationVersion' => '4.5.6', 'wip' => true, 'testResults' => { 'some' => 'results' }} }
27
29
  let(:pact) do
@@ -30,7 +32,7 @@ module PactBroker
30
32
  .create_provider_version_tag('dev')
31
33
  .and_return(:pact)
32
34
  end
33
- let(:create_verification) { subject.create 3, params, pact, options }
35
+ let(:create_verification) { subject.create 3, params, pact, event_context, options }
34
36
 
35
37
  it "logs the creation" do
36
38
  expect(logger).to receive(:info).with(/.*verification.*3/, payload: {"providerApplicationVersion"=>"4.5.6", "success"=>true, "wip"=>true})
@@ -67,6 +69,7 @@ module PactBroker
67
69
  expect(PactBroker::Webhooks::TriggerService).to have_received(:trigger_webhooks_for_verification_results_publication).with(
68
70
  pact,
69
71
  verification,
72
+ expected_event_context,
70
73
  options
71
74
  )
72
75
  end
@@ -122,6 +122,60 @@ module PactBroker
122
122
  end
123
123
  end
124
124
  end
125
+
126
+ describe "#create_or_overwrite" do
127
+ before do
128
+ td.subtract_day
129
+ .create_consumer("Foo")
130
+ .create_consumer_version(version_number, branch: "original-branch", build_url: "original-build-url")
131
+ .create_consumer_version_tag("dev")
132
+ end
133
+
134
+ let(:pacticipant) { td.and_return(:consumer) }
135
+ let(:version_number) { "1234" }
136
+ let(:tags) { nil }
137
+ let(:open_struct_version) { OpenStruct.new(branch: "new-branch", tags: tags) }
138
+
139
+ subject { Repository.new.create_or_overwrite(pacticipant, version_number, open_struct_version) }
140
+
141
+ it "overwrites the values" do
142
+ expect(subject.branch).to eq "new-branch"
143
+ expect(subject.build_url).to eq nil
144
+ end
145
+
146
+ it "does not change the tags" do
147
+ expect { subject }.to_not change { PactBroker::Domain::Version.for("Foo", "1234").tags }
148
+ end
149
+
150
+ context "when there are tags specified" do
151
+ let(:tags) { [ OpenStruct.new(name: "main")] }
152
+
153
+ it "overwrites the tags" do
154
+ expect(subject.tags.count).to eq 1
155
+ expect(subject.tags.first.name).to eq "main"
156
+ end
157
+ end
158
+
159
+ it "does not change the created date" do
160
+ expect { subject }.to_not change { PactBroker::Domain::Version.for("Foo", "1234").created_at }
161
+ end
162
+
163
+ it "does change the updated date" do
164
+ expect { subject }.to change { PactBroker::Domain::Version.for("Foo", "1234").updated_at }
165
+ end
166
+
167
+ it "maintains the order" do
168
+ expect { subject }.to_not change { PactBroker::Domain::Version.for("Foo", "1234").order }
169
+ end
170
+
171
+ context "when the version does not already exist" do
172
+ let(:version) { OpenStruct.new(number: "555", branch: "new-branch") }
173
+
174
+ it "sets the order" do
175
+ expect(subject.order).to_not be nil
176
+ end
177
+ end
178
+ end
125
179
  end
126
180
  end
127
181
  end
@@ -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 } }
97
+ let(:webhook_context) { { base_url: base_url, event_name: "something" } }
98
98
 
99
99
  let(:nil_pact) { nil }
100
100
  let(:nil_verification) { nil }
@@ -158,7 +158,8 @@ module PactBroker
158
158
  {
159
159
  consumer_version_number: "webhook-version-number",
160
160
  consumer_version_tags: %w[webhook tags],
161
- base_url: base_url
161
+ base_url: base_url,
162
+ event_name: "something"
162
163
 
163
164
  }
164
165
  end
@@ -186,16 +187,16 @@ module PactBroker
186
187
  let(:base_url) { "http://broker" }
187
188
 
188
189
  let(:template_parameters) do
189
- PactAndVerificationParameters.new(placeholder_pact, nil, { base_url: base_url }).to_hash
190
+ PactAndVerificationParameters.new(placeholder_pact, nil, { base_url: base_url, event_name: "something" }).to_hash
190
191
  end
191
192
 
192
193
  it "does not blow up with a placeholder pact" do
193
- template_parameters = PactAndVerificationParameters.new(placeholder_pact, nil, { base_url: base_url }).to_hash
194
+ template_parameters = PactAndVerificationParameters.new(placeholder_pact, nil, { base_url: base_url, event_name: "something" }).to_hash
194
195
  Render.call("", template_parameters)
195
196
  end
196
197
 
197
198
  it "does not blow up with a placeholder verification" do
198
- template_parameters = PactAndVerificationParameters.new(placeholder_pact, placeholder_verification, { base_url: base_url }).to_hash
199
+ template_parameters = PactAndVerificationParameters.new(placeholder_pact, placeholder_verification, { base_url: base_url, event_name: "something" }).to_hash
199
200
  Render.call("", template_parameters)
200
201
  end
201
202
  end
@@ -181,7 +181,9 @@ module PactBroker
181
181
  let(:webhooks) { [instance_double(PactBroker::Domain::Webhook, description: 'description', uuid: '1244')]}
182
182
  let(:triggered_webhook) { instance_double(PactBroker::Webhooks::TriggeredWebhook) }
183
183
  let(:webhook_execution_configuration) { double('webhook_execution_configuration', webhook_context: webhook_context) }
184
- let(:webhook_context) { double('webhook_context') }
184
+ let(:webhook_context) { { base_url: "http://example.org" } }
185
+ let(:event_context) { { some: "data" } }
186
+ let(:expected_event_context) { { some: "data", event_name: PactBroker::Webhooks::WebhookEvent::CONTRACT_CONTENT_CHANGED, base_url: "http://example.org" } }
185
187
  let(:options) do
186
188
  { database_connector: double('database_connector'),
187
189
  webhook_execution_configuration: webhook_execution_configuration,
@@ -196,7 +198,7 @@ module PactBroker
196
198
  allow(Job).to receive(:perform_in)
197
199
  end
198
200
 
199
- subject { Service.trigger_webhooks pact, verification, PactBroker::Webhooks::WebhookEvent::CONTRACT_CONTENT_CHANGED, options }
201
+ subject { Service.trigger_webhooks(pact, verification, PactBroker::Webhooks::WebhookEvent::CONTRACT_CONTENT_CHANGED, event_context, options) }
200
202
 
201
203
  it "finds the webhooks" do
202
204
  expect_any_instance_of(PactBroker::Webhooks::Repository).to receive(:find_by_consumer_and_or_provider_and_event_name).with(consumer, provider, PactBroker::Webhooks::WebhookEvent::DEFAULT_EVENT_NAME)
@@ -205,7 +207,7 @@ module PactBroker
205
207
 
206
208
  context "when webhooks are found" do
207
209
  it "executes the webhook" do
208
- expect(Service).to receive(:run_later).with(webhooks, pact, verification, PactBroker::Webhooks::WebhookEvent::CONTRACT_CONTENT_CHANGED, options)
210
+ expect(Service).to receive(:run_later).with(webhooks, pact, verification, PactBroker::Webhooks::WebhookEvent::CONTRACT_CONTENT_CHANGED, expected_event_context, options)
209
211
  subject
210
212
  end
211
213
 
@@ -258,6 +260,7 @@ module PactBroker
258
260
  instance_double(PactBroker::Webhooks::ExecutionConfiguration, to_hash: execution_configuration_hash)
259
261
  end
260
262
  let(:execution_configuration_hash) { { the: 'options' } }
263
+ let(:event_context) { { some: "data" } }
261
264
 
262
265
  before do
263
266
  allow(PactBroker::Pacts::Service).to receive(:search_for_latest_pact).and_return(pact)
@@ -266,7 +269,7 @@ module PactBroker
266
269
  allow(execution_configuration).to receive(:with_failure_log_message).and_return(execution_configuration)
267
270
  end
268
271
 
269
- subject { Service.test_execution(webhook, execution_configuration) }
272
+ subject { Service.test_execution(webhook, event_context, execution_configuration) }
270
273
 
271
274
  it "searches for the latest matching pact" do
272
275
  expect(PactBroker::Pacts::Service).to receive(:search_for_latest_pact).with(consumer_name: 'consumer', provider_name: 'provider')
@@ -279,7 +282,7 @@ module PactBroker
279
282
 
280
283
  context "when the trigger is not for a verification" do
281
284
  it "executes the webhook with the pact" do
282
- expect(webhook).to receive(:execute).with(pact, nil, execution_configuration_hash)
285
+ expect(webhook).to receive(:execute).with(pact, nil, event_context.merge(event_name: "test"), execution_configuration_hash)
283
286
  subject
284
287
  end
285
288
  end
@@ -288,7 +291,7 @@ module PactBroker
288
291
  let(:pact) { nil }
289
292
 
290
293
  it "executes the webhook with a placeholder pact" do
291
- expect(webhook).to receive(:execute).with(an_instance_of(PactBroker::Pacts::PlaceholderPact), anything, anything)
294
+ expect(webhook).to receive(:execute).with(an_instance_of(PactBroker::Pacts::PlaceholderPact), anything, anything, anything)
292
295
  subject
293
296
  end
294
297
  end
@@ -302,7 +305,7 @@ module PactBroker
302
305
  end
303
306
 
304
307
  it "executes the webhook with the pact and the verification" do
305
- expect(webhook).to receive(:execute).with(pact, verification, execution_configuration_hash)
308
+ expect(webhook).to receive(:execute).with(pact, verification, event_context.merge(event_name: "test"), execution_configuration_hash)
306
309
  subject
307
310
  end
308
311
 
@@ -310,7 +313,7 @@ module PactBroker
310
313
  let(:verification) { nil }
311
314
 
312
315
  it "executes the webhook with a placeholder verification" do
313
- expect(webhook).to receive(:execute).with(anything, an_instance_of(PactBroker::Verifications::PlaceholderVerification), anything)
316
+ expect(webhook).to receive(:execute).with(anything, an_instance_of(PactBroker::Verifications::PlaceholderVerification), anything, anything)
314
317
  subject
315
318
  end
316
319
  end
@@ -329,6 +332,7 @@ module PactBroker
329
332
  .with_webhook_context(base_url: 'http://example.org')
330
333
  .with_show_response(true)
331
334
  end
335
+ let(:event_context) { { some: "data", base_url: "http://example.org" }}
332
336
  let(:options) do
333
337
  {
334
338
  database_connector: database_connector,
@@ -347,7 +351,7 @@ module PactBroker
347
351
  .and_return(:pact)
348
352
  end
349
353
 
350
- subject { PactBroker::Webhooks::Service.trigger_webhooks pact, td.verification, PactBroker::Webhooks::WebhookEvent::CONTRACT_CONTENT_CHANGED, options }
354
+ subject { PactBroker::Webhooks::Service.trigger_webhooks(pact, td.verification, PactBroker::Webhooks::WebhookEvent::CONTRACT_CONTENT_CHANGED, event_context, options) }
351
355
 
352
356
  it "executes the HTTP request of the webhook" do
353
357
  subject
@@ -11,6 +11,7 @@ module PactBroker
11
11
  let(:previous_pact_version_sha) { "111" }
12
12
  let(:previous_pacts) { { untagged: previous_pact } }
13
13
  let(:logger) { double('logger').as_null_object }
14
+ let(:event_context) { { some: "data" } }
14
15
  let(:webhook_options) { { the: 'options'} }
15
16
 
16
17
  before do
@@ -21,27 +22,27 @@ module PactBroker
21
22
 
22
23
  shared_examples_for "triggering a contract_published event" do
23
24
  it "triggers a contract_published webhook" do
24
- expect(webhook_service).to receive(:trigger_webhooks).with(pact, nil, PactBroker::Webhooks::WebhookEvent::CONTRACT_PUBLISHED, webhook_options)
25
+ expect(webhook_service).to receive(:trigger_webhooks).with(pact, nil, PactBroker::Webhooks::WebhookEvent::CONTRACT_PUBLISHED, event_context, webhook_options)
25
26
  subject
26
27
  end
27
28
  end
28
29
 
29
30
  shared_examples_for "triggering a contract_content_changed event" do
30
31
  it "triggers a contract_content_changed webhook" do
31
- expect(webhook_service).to receive(:trigger_webhooks).with(pact, nil, PactBroker::Webhooks::WebhookEvent::CONTRACT_CONTENT_CHANGED, webhook_options)
32
+ expect(webhook_service).to receive(:trigger_webhooks).with(pact, nil, PactBroker::Webhooks::WebhookEvent::CONTRACT_CONTENT_CHANGED, event_context, webhook_options)
32
33
  subject
33
34
  end
34
35
  end
35
36
 
36
37
  shared_examples_for "not triggering a contract_content_changed event" do
37
38
  it "does not trigger a contract_content_changed webhook" do
38
- expect(webhook_service).to_not receive(:trigger_webhooks).with(anything, anything, PactBroker::Webhooks::WebhookEvent::CONTRACT_CONTENT_CHANGED, anything)
39
+ expect(webhook_service).to_not receive(:trigger_webhooks).with(anything, anything, PactBroker::Webhooks::WebhookEvent::CONTRACT_CONTENT_CHANGED, event_context, anything)
39
40
  subject
40
41
  end
41
42
  end
42
43
 
43
44
  describe "#trigger_webhooks_for_new_pact" do
44
- subject { TriggerService.trigger_webhooks_for_new_pact(pact, webhook_options) }
45
+ subject { TriggerService.trigger_webhooks_for_new_pact(pact, event_context, webhook_options) }
45
46
 
46
47
  context "when no previous untagged pact exists" do
47
48
  let(:previous_pact) { nil }
@@ -117,7 +118,7 @@ module PactBroker
117
118
  end
118
119
  let(:existing_pact_version_sha) { pact_version_sha }
119
120
 
120
- subject { TriggerService.trigger_webhooks_for_updated_pact(existing_pact, pact, webhook_options) }
121
+ subject { TriggerService.trigger_webhooks_for_updated_pact(existing_pact, pact, event_context, webhook_options) }
121
122
 
122
123
  context "when the pact version sha of the previous revision is different" do
123
124
  let(:existing_pact_version_sha) { "456" }
@@ -140,32 +141,73 @@ module PactBroker
140
141
  describe "#trigger_webhooks_for_verification_results_publication" do
141
142
  let(:verification) { double("verification", success: success) }
142
143
  let(:success) { true }
144
+ # See lib/pact_broker/pacts/metadata.rb build_metadata_for_pact_for_verification
145
+ let(:selector_1) { { latest: true, consumer_version_number: "1", tag: "prod" } }
146
+ let(:selector_2) { { latest: true, consumer_version_number: "1", tag: "main" } }
147
+ let(:selector_3) { { latest: true, consumer_version_number: "2", tag: "feat/2" } }
148
+ let(:event_context) do
149
+ {
150
+ consumer_version_selectors: [selector_1, selector_2, selector_3],
151
+ other: "foo"
152
+ }
153
+ end
154
+ let(:expected_event_context_1) { { consumer_version_number: "1", consumer_version_tags: ["prod", "main"], other: "foo" } }
155
+ let(:expected_event_context_2) { { consumer_version_number: "2", consumer_version_tags: ["feat/2"], other: "foo" } }
143
156
 
144
- subject { TriggerService.trigger_webhooks_for_verification_results_publication(pact, verification, webhook_options) }
157
+ subject { TriggerService.trigger_webhooks_for_verification_results_publication(pact, verification, event_context, webhook_options) }
145
158
 
146
159
  context "when the verification is successful" do
147
- it "triggers a provider_verification_succeeded webhook" do
148
- expect(webhook_service).to receive(:trigger_webhooks).with(pact, verification, PactBroker::Webhooks::WebhookEvent::VERIFICATION_SUCCEEDED, webhook_options)
149
- subject
160
+
161
+ context "when there are consumer_version_selectors in the event_context" do
162
+ it "triggers a provider_verification_succeeded webhook for each consumer version (ie. commit)" do
163
+ expect(webhook_service).to receive(:trigger_webhooks).with(pact, verification, PactBroker::Webhooks::WebhookEvent::VERIFICATION_SUCCEEDED, expected_event_context_1, webhook_options)
164
+ expect(webhook_service).to receive(:trigger_webhooks).with(pact, verification, PactBroker::Webhooks::WebhookEvent::VERIFICATION_SUCCEEDED, expected_event_context_2, webhook_options)
165
+ subject
166
+ end
167
+
168
+ it "triggers a provider_verification_published webhook for each consumer version (ie. commit)" do
169
+ expect(webhook_service).to receive(:trigger_webhooks).with(pact, verification, PactBroker::Webhooks::WebhookEvent::VERIFICATION_PUBLISHED, expected_event_context_1, webhook_options)
170
+ expect(webhook_service).to receive(:trigger_webhooks).with(pact, verification, PactBroker::Webhooks::WebhookEvent::VERIFICATION_PUBLISHED, expected_event_context_2, webhook_options)
171
+ subject
172
+ end
150
173
  end
151
174
 
152
- it "triggers a provider_verification_published webhook" do
153
- expect(webhook_service).to receive(:trigger_webhooks).with(pact, verification, PactBroker::Webhooks::WebhookEvent::VERIFICATION_PUBLISHED, webhook_options)
154
- subject
175
+ context "when there are no consumer_version_selectors" do
176
+ let(:event_context) { { some: "data" } }
177
+
178
+ it "passes through the event context" do
179
+ expect(webhook_service).to receive(:trigger_webhooks).with(pact, verification, PactBroker::Webhooks::WebhookEvent::VERIFICATION_SUCCEEDED, event_context, webhook_options)
180
+ expect(webhook_service).to receive(:trigger_webhooks).with(pact, verification, PactBroker::Webhooks::WebhookEvent::VERIFICATION_PUBLISHED, event_context, webhook_options)
181
+ subject
182
+ end
155
183
  end
156
184
  end
157
185
 
158
186
  context "when the verification is not successful" do
159
187
  let(:success) { false }
160
188
 
161
- it "triggers a provider_verification_failed webhook" do
162
- expect(webhook_service).to receive(:trigger_webhooks).with(pact, verification, PactBroker::Webhooks::WebhookEvent::VERIFICATION_FAILED, webhook_options)
163
- subject
189
+ context "when there are consumer_version_selectors in the event_context" do
190
+ it "triggers a provider_verification_failed webhook for each consumer version (ie. commit)" do
191
+ expect(webhook_service).to receive(:trigger_webhooks).with(pact, verification, PactBroker::Webhooks::WebhookEvent::VERIFICATION_FAILED, expected_event_context_1, webhook_options)
192
+ expect(webhook_service).to receive(:trigger_webhooks).with(pact, verification, PactBroker::Webhooks::WebhookEvent::VERIFICATION_FAILED, expected_event_context_2, webhook_options)
193
+ subject
194
+ end
195
+
196
+ it "triggeres a provider_verification_published webhook for each consumer version (ie. commit)" do
197
+ expect(webhook_service).to receive(:trigger_webhooks).with(pact, verification, PactBroker::Webhooks::WebhookEvent::VERIFICATION_PUBLISHED, expected_event_context_1, webhook_options)
198
+ expect(webhook_service).to receive(:trigger_webhooks).with(pact, verification, PactBroker::Webhooks::WebhookEvent::VERIFICATION_PUBLISHED, expected_event_context_2, webhook_options)
199
+ subject
200
+ end
164
201
  end
165
202
 
166
- it "triggeres a provider_verification_published webhook" do
167
- expect(webhook_service).to receive(:trigger_webhooks).with(pact, verification, PactBroker::Webhooks::WebhookEvent::VERIFICATION_PUBLISHED, webhook_options)
168
- subject
203
+ context "when there are no consumer_version_selectors" do
204
+ let(:event_context) { { some: "data" } }
205
+
206
+ it "passes through the event context" do
207
+ expect(webhook_service).to receive(:trigger_webhooks).with(pact, verification, PactBroker::Webhooks::WebhookEvent::VERIFICATION_FAILED, event_context, webhook_options)
208
+ expect(webhook_service).to receive(:trigger_webhooks).with(pact, verification, PactBroker::Webhooks::WebhookEvent::VERIFICATION_PUBLISHED, event_context, webhook_options)
209
+ subject
210
+ end
169
211
  end
170
212
  end
171
213
  end
@@ -129,6 +129,14 @@ module PactBroker
129
129
  end
130
130
  end
131
131
 
132
+ context "when the response code '100' is not in 'webhook_http_code_success'" do
133
+ let(:status) { 100 }
134
+
135
+ it "not successful, code '100' not in 'webhook_http_code_success'" do
136
+ expect(logs).to include "oops"
137
+ end
138
+ end
139
+
132
140
  context "when the response code is not successful" do
133
141
  let(:status) { 400 }
134
142
 
@@ -24,6 +24,12 @@ module Sequel
24
24
  plugin :upsert, identifying_columns: [:provider_id, :consumer_version_id]
25
25
  end
26
26
 
27
+ describe PacticipantNoUpsert do
28
+ it "has an _insert_dataset method" do
29
+ expect(PacticipantNoUpsert.private_instance_methods).to include (:_insert_dataset)
30
+ end
31
+ end
32
+
27
33
  describe "LatestPactPublicationIdForConsumerVersion" do
28
34
  before do
29
35
  td.create_pact_with_hierarchy("Foo", "1", "Bar")
@@ -102,10 +108,20 @@ module Sequel
102
108
 
103
109
  context "when a duplicate Version is inserted with upsert" do
104
110
  let!(:pacticipant) { Pacticipant.new(name: "Foo").save }
105
- let!(:original_version) { Version.new(number: "1", pacticipant_id: pacticipant.id).upsert }
111
+ let!(:original_version) do
112
+ version = Version.new(
113
+ number: "1",
114
+ pacticipant_id: pacticipant.id,
115
+ branch: "original-branch",
116
+ build_url: "original-url"
117
+ ).upsert
118
+ Version.where(id: version.id).update(created_at: yesterday, updated_at: yesterday)
119
+ version
120
+ end
121
+ let(:yesterday) { DateTime.now - 2 }
106
122
 
107
123
  subject do
108
- Version.new(number: "1", pacticipant_id: pacticipant.id).upsert
124
+ Version.new(number: "1", pacticipant_id: pacticipant.id, branch: "new-branch").upsert
109
125
  end
110
126
 
111
127
  it "does not raise an error" do
@@ -113,12 +129,24 @@ module Sequel
113
129
  end
114
130
 
115
131
  it "sets the values on the object" do
116
- expect(subject.id).to eq original_version.id
132
+ expect(subject.branch).to eq "new-branch"
133
+ end
134
+
135
+ it "nils out values that weren't set on the second model" do
136
+ expect(subject.build_url).to eq nil
117
137
  end
118
138
 
119
139
  it "does not insert another row" do
120
140
  expect { subject }.to_not change { Version.count }
121
141
  end
142
+
143
+ it "does not change the created_at" do
144
+ expect { subject }.to_not change { Version.where(number: "1").first.created_at }
145
+ end
146
+
147
+ it "does change the updated_at" do
148
+ expect { subject }.to change { Version.where(number: "1").first.updated_at }
149
+ end
122
150
  end
123
151
  end
124
152
  end
@@ -9,7 +9,9 @@ class HalRelationProxyApp
9
9
  '/HAL-REL-PLACEHOLDER-INDEX-PB-LATEST-VERSION-Condor' =>
10
10
  '/pacticipants/Condor/latest-version',
11
11
  '/HAL-REL-PLACEHOLDER-PB-WEBHOOKS' =>
12
- '/webhooks'
12
+ '/webhooks',
13
+ '/HAL-REL-PLACEHOLDER-INDEX-PB-PACTICIPANT-VERSION-Foo-26f353580936ad3b9baddb17b00e84f33c69e7cb' =>
14
+ '/pacticipants/Foo/versions/26f353580936ad3b9baddb17b00e84f33c69e7cb'
13
15
  }
14
16
 
15
17
  RESPONSE_BODY_REPLACEMENTS = {