pact_broker 2.84.0 → 2.87.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (189) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/trigger_pact_docs_update.yml +22 -0
  3. data/CHANGELOG.md +63 -0
  4. data/DEVELOPER_DOCUMENTATION.md +0 -2
  5. data/db/migrations/20210913_add_pending_to_verifications.rb +7 -0
  6. data/db/migrations/20210914_add_labels_to_webhooks.rb +14 -0
  7. data/db/migrations/20210915_add_verified_by_to_verification.rb +6 -0
  8. data/db/migrations/20210929_increase_event_context_column_size.rb +14 -0
  9. data/docker-compose-ci-mysql.yml +1 -0
  10. data/docker-compose-test.yml +2 -0
  11. data/docs/CONFIGURATION.md +255 -66
  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 +4 -4
  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/reason_decorator.rb +2 -2
  21. data/lib/pact_broker/api/decorators/verification_decorator.rb +9 -3
  22. data/lib/pact_broker/api/decorators/verification_summary_decorator.rb +1 -2
  23. data/lib/pact_broker/api/decorators/webhook_decorator.rb +27 -4
  24. data/lib/pact_broker/api/middleware/configuration.rb +33 -0
  25. data/lib/pact_broker/api/pact_broker_urls.rb +35 -7
  26. data/lib/pact_broker/api/renderers/html_pact_renderer.rb +15 -11
  27. data/lib/pact_broker/api/resources/all_webhooks.rb +2 -2
  28. data/lib/pact_broker/api/resources/default_base_resource.rb +4 -0
  29. data/lib/pact_broker/api/resources/environment.rb +1 -1
  30. data/lib/pact_broker/api/resources/environments.rb +1 -1
  31. data/lib/pact_broker/api/resources/index.rb +7 -1
  32. data/lib/pact_broker/api/resources/pact_versions_for_branch.rb +40 -0
  33. data/lib/pact_broker/api/resources/publish_contracts.rb +1 -1
  34. data/lib/pact_broker/api/resources/verification.rb +5 -2
  35. data/lib/pact_broker/api/resources/verifications.rb +5 -1
  36. data/lib/pact_broker/api/resources/webhook_execution_methods.rb +23 -17
  37. data/lib/pact_broker/api.rb +2 -0
  38. data/lib/pact_broker/app.rb +2 -0
  39. data/lib/pact_broker/application_context.rb +5 -0
  40. data/lib/pact_broker/badges/service.rb +3 -1
  41. data/lib/pact_broker/config/runtime_configuration.rb +4 -0
  42. data/lib/pact_broker/config/runtime_configuration_database_methods.rb +1 -1
  43. data/lib/pact_broker/configuration.rb +33 -29
  44. data/lib/pact_broker/db/clean.rb +1 -2
  45. data/lib/pact_broker/db/delete_overwritten_data.rb +41 -23
  46. data/lib/pact_broker/deployments/deployed_version.rb +1 -0
  47. data/lib/pact_broker/deployments/deployed_version_service.rb +1 -0
  48. data/lib/pact_broker/deployments/environment_service.rb +4 -1
  49. data/lib/pact_broker/deployments/released_version_service.rb +1 -0
  50. data/lib/pact_broker/doc/controllers/app.rb +1 -0
  51. data/lib/pact_broker/doc/views/can-i-deploy.markdown +2 -1
  52. data/lib/pact_broker/doc/views/index/publish-contracts.markdown +38 -9
  53. data/lib/pact_broker/doc/views/pacticipant/label.markdown +12 -0
  54. data/lib/pact_broker/doc/views/webhooks.markdown +17 -0
  55. data/lib/pact_broker/domain/index_item.rb +9 -0
  56. data/lib/pact_broker/domain/pacticipant.rb +4 -0
  57. data/lib/pact_broker/domain/verification.rb +28 -4
  58. data/lib/pact_broker/domain/webhook.rb +27 -15
  59. data/lib/pact_broker/domain/webhook_pacticipant.rb +6 -0
  60. data/lib/pact_broker/domain/webhook_request.rb +2 -2
  61. data/lib/pact_broker/index/service.rb +77 -26
  62. data/lib/pact_broker/locale/en.yml +6 -1
  63. data/lib/pact_broker/matrix/head_row.rb +1 -1
  64. data/lib/pact_broker/matrix/parse_can_i_deploy_query.rb +5 -3
  65. data/lib/pact_broker/matrix/quick_row.rb +0 -1
  66. data/lib/pact_broker/matrix/repository.rb +0 -1
  67. data/lib/pact_broker/matrix/row.rb +2 -2
  68. data/lib/pact_broker/pacticipants/repository.rb +1 -1
  69. data/lib/pact_broker/pacts/latest_pact_publication_id_for_consumer_version.rb +0 -1
  70. data/lib/pact_broker/pacts/metadata.rb +11 -3
  71. data/lib/pact_broker/pacts/pact_publication.rb +44 -0
  72. data/lib/pact_broker/pacts/pact_publication_clean_selector_dataset_module.rb +19 -0
  73. data/lib/pact_broker/pacts/pact_publication_dataset_module.rb +68 -1
  74. data/lib/pact_broker/pacts/pact_version.rb +24 -1
  75. data/lib/pact_broker/pacts/pacts_for_verification_repository.rb +5 -4
  76. data/lib/pact_broker/pacts/repository.rb +52 -48
  77. data/lib/pact_broker/pacts/service.rb +5 -5
  78. data/lib/pact_broker/string_refinements.rb +1 -1
  79. data/lib/pact_broker/test/http_test_data_builder.rb +40 -11
  80. data/lib/pact_broker/test/test_data_builder.rb +27 -6
  81. data/lib/pact_broker/ui/app.rb +7 -1
  82. data/lib/pact_broker/ui/controllers/dashboard.rb +80 -0
  83. data/lib/pact_broker/ui/controllers/groups.rb +23 -8
  84. data/lib/pact_broker/ui/helpers/url_helper.rb +17 -1
  85. data/lib/pact_broker/ui/view_models/index_item.rb +64 -8
  86. data/lib/pact_broker/ui/view_models/index_item_branch_head.rb +39 -0
  87. data/lib/pact_broker/ui/view_models/index_item_provider_branch_head.rb +39 -0
  88. data/lib/pact_broker/ui/view_models/matrix_branch.rb +1 -1
  89. data/lib/pact_broker/ui/view_models/matrix_tag.rb +0 -1
  90. data/lib/pact_broker/ui/views/dashboard/show.haml +202 -0
  91. data/lib/pact_broker/ui/views/groups/show.html.erb +60 -14
  92. data/lib/pact_broker/ui/views/index/_dashboard_navbar.haml +7 -0
  93. data/lib/pact_broker/ui/views/index/_navbar.haml +0 -7
  94. data/lib/pact_broker/ui/views/index/show-with-tags.haml +3 -1
  95. data/lib/pact_broker/ui/views/index/show.haml +35 -13
  96. data/lib/pact_broker/ui/views/matrix/show.haml +7 -3
  97. data/lib/pact_broker/verifications/pseudo_branch_status.rb +2 -0
  98. data/lib/pact_broker/verifications/repository.rb +5 -2
  99. data/lib/pact_broker/verifications/service.rb +8 -4
  100. data/lib/pact_broker/version.rb +1 -1
  101. data/lib/pact_broker/versions/branch_head.rb +0 -2
  102. data/lib/pact_broker/versions/branch_version.rb +1 -0
  103. data/lib/pact_broker/versions/repository.rb +0 -1
  104. data/lib/pact_broker/webhooks/event_listener.rb +7 -5
  105. data/lib/pact_broker/webhooks/execution_configuration.rb +16 -0
  106. data/lib/pact_broker/webhooks/execution_configuration_creator.rb +3 -0
  107. data/lib/pact_broker/webhooks/job.rb +1 -1
  108. data/lib/pact_broker/webhooks/pact_and_verification_parameters.rb +18 -3
  109. data/lib/pact_broker/webhooks/repository.rb +10 -4
  110. data/lib/pact_broker/webhooks/trigger_service.rb +3 -3
  111. data/lib/pact_broker/webhooks/webhook.rb +71 -8
  112. data/lib/pact_broker/webhooks/webhook_execution_result.rb +3 -7
  113. data/lib/pact_broker/webhooks/webhook_request_logger.rb +4 -12
  114. data/lib/pact_broker/webhooks/webhook_request_template.rb +6 -8
  115. data/pact_broker.gemspec +4 -0
  116. data/public/javascripts/index.js +75 -68
  117. data/public/javascripts/pact.js +14 -14
  118. data/public/stylesheets/index.css +6 -2
  119. data/public/stylesheets/pact.css +11 -0
  120. data/script/data/auto-create-things-for-tags.rb +3 -0
  121. data/script/data/branches.rb +2 -2
  122. data/script/data/contract-published-requiring-verification.rb +0 -1
  123. data/script/data/environments.rb +0 -0
  124. data/script/data/pending.rb +26 -0
  125. data/script/data/tags.rb +35 -0
  126. data/script/data/verify-pact-for-multiple-selectors.rb +30 -0
  127. data/script/data/webhook.rb +22 -0
  128. data/script/docs/generate-configuration-docs.rb +24 -3
  129. data/script/generate-erd +55 -0
  130. data/script/seed.rb +50 -89
  131. data/spec/features/create_webhook_spec.rb +55 -10
  132. data/spec/features/delete_pact_versions_for_branch_spec.rb +34 -0
  133. data/spec/features/get_pact_spec.rb +2 -3
  134. data/spec/fixtures/approvals/modifiable_resources.approved.json +4 -0
  135. data/spec/fixtures/invalid-publish-contract-body.json +38 -0
  136. data/spec/fixtures/verification.json +4 -0
  137. data/spec/integration/app_spec.rb +6 -6
  138. data/spec/integration/webhooks/contract_publication_spec.rb +68 -0
  139. data/spec/integration/webhooks/contract_requiring_verification_published_spec.rb +67 -0
  140. data/spec/integration/webhooks/pact_publication_spec.rb +51 -0
  141. data/spec/lib/pact/doc/markdown/consumer_contract_renderer_spec.rb +2 -2
  142. data/spec/lib/pact_broker/api/contracts/publish_contracts_schema_spec.rb +13 -0
  143. data/spec/lib/pact_broker/api/contracts/webhook_contract_spec.rb +50 -0
  144. data/spec/lib/pact_broker/api/decorators/matrix_decorator_spec.rb +1 -1
  145. data/spec/lib/pact_broker/api/decorators/reason_decorator_spec.rb +2 -2
  146. data/spec/lib/pact_broker/api/decorators/verification_decorator_spec.rb +15 -7
  147. data/spec/lib/pact_broker/api/decorators/verification_summary_decorator_spec.rb +6 -2
  148. data/spec/lib/pact_broker/api/decorators/webhook_decorator_spec.rb +4 -4
  149. data/spec/lib/pact_broker/api/decorators/webhook_execution_result_decorator_spec.rb +1 -1
  150. data/spec/lib/pact_broker/api/middleware/configuration_spec.rb +43 -0
  151. data/spec/lib/pact_broker/api/pact_broker_urls_spec.rb +18 -0
  152. data/spec/lib/pact_broker/api/resources/triggered_webhook_logs_spec.rb +6 -5
  153. data/spec/lib/pact_broker/api/resources/verifications_spec.rb +2 -3
  154. data/spec/lib/pact_broker/api/resources/webhook_execution_spec.rb +1 -1
  155. data/spec/lib/pact_broker/badges/service_spec.rb +22 -0
  156. data/spec/lib/pact_broker/config/runtime_configuration_documentation_spec.rb +30 -0
  157. data/spec/lib/pact_broker/deployments/environment_service_spec.rb +1 -1
  158. data/spec/lib/pact_broker/domain/webhook_request_spec.rb +2 -1
  159. data/spec/lib/pact_broker/domain/webhook_spec.rb +15 -5
  160. data/spec/lib/pact_broker/index/service_spec.rb +1 -5
  161. data/spec/lib/pact_broker/index/service_view_spec.rb +144 -0
  162. data/spec/lib/pact_broker/matrix/head_row_spec.rb +9 -5
  163. data/spec/lib/pact_broker/matrix/parse_can_i_deploy_query_spec.rb +13 -0
  164. data/spec/lib/pact_broker/pacts/metadata_spec.rb +11 -2
  165. data/spec/lib/pact_broker/pacts/{latest_tagged_pact_publications_spec.rb → pact_publication_clean_selector_dataset_module_spec.rb} +7 -9
  166. data/spec/lib/pact_broker/pacts/pact_publication_latest_verification_spec.rb +29 -0
  167. data/spec/lib/pact_broker/pacts/pact_version_spec.rb +32 -0
  168. data/spec/lib/pact_broker/pacts/repository_find_for_verification_spec.rb +4 -5
  169. data/spec/lib/pact_broker/pacts/repository_spec.rb +48 -2
  170. data/spec/lib/pact_broker/ui/view_models/index_item_spec.rb +12 -9
  171. data/spec/lib/pact_broker/verifications/pseudo_branch_status_spec.rb +9 -1
  172. data/spec/lib/pact_broker/verifications/service_spec.rb +24 -8
  173. data/spec/lib/pact_broker/webhooks/job_spec.rb +4 -4
  174. data/spec/lib/pact_broker/webhooks/render_spec.rb +3 -2
  175. data/spec/lib/pact_broker/webhooks/repository_spec.rb +158 -15
  176. data/spec/lib/pact_broker/webhooks/trigger_service_spec.rb +9 -5
  177. data/spec/lib/pact_broker/webhooks/webhook_request_logger_spec.rb +6 -12
  178. data/spec/lib/pact_broker/webhooks/webhook_request_template_spec.rb +3 -2
  179. data/spec/lib/pact_broker/webhooks/webhook_spec.rb +8 -5
  180. data/spec/support/generated_markdown.md +3 -3
  181. data/tasks/db.rake +4 -1
  182. metadata +72 -14
  183. data/lib/pact_broker/pacts/all_pact_publications.rb +0 -158
  184. data/lib/pact_broker/pacts/latest_pact_publications.rb +0 -48
  185. data/lib/pact_broker/pacts/latest_pact_publications_by_consumer_version.rb +0 -26
  186. data/lib/pact_broker/pacts/latest_tagged_pact_publications.rb +0 -45
  187. data/lib/pact_broker/verifications/latest_verification_for_pact_version.rb +0 -39
  188. data/spec/lib/pact_broker/api/resources/webhook_execution_result_spec.rb +0 -56
  189. data/spec/lib/pact_broker/verifications/latest_verification_for_pact_version_spec.rb +0 -18
@@ -85,6 +85,31 @@ module PactBroker
85
85
  end
86
86
  end
87
87
 
88
+ context "with a consumer label" do
89
+ let(:json) do
90
+ valid_webhook_with do |hash|
91
+ hash["consumer"].delete("name")
92
+ hash["consumer"]["label"] = "my_label"
93
+ end
94
+ end
95
+
96
+ it "contains no errors" do
97
+ expect(subject.errors).to be_empty
98
+ end
99
+ end
100
+
101
+ context "with a consumer label and name provided" do
102
+ let(:json) do
103
+ valid_webhook_with do |hash|
104
+ hash["consumer"]["label"] = "my_label"
105
+ end
106
+ end
107
+
108
+ it "contains consumer.label error" do
109
+ expect(subject.errors.messages).to eq({:'consumer.label' => ["cannot be provided"]})
110
+ end
111
+ end
112
+
88
113
  context "with a nil provider name" do
89
114
  let(:json) do
90
115
  valid_webhook_with do |hash|
@@ -131,6 +156,31 @@ module PactBroker
131
156
  end
132
157
  end
133
158
 
159
+ context "with provider label" do
160
+ let(:json) do
161
+ valid_webhook_with do |hash|
162
+ hash["provider"].delete("name")
163
+ hash["provider"]["label"] = "my_label"
164
+ end
165
+ end
166
+
167
+ it "contains no errors" do
168
+ expect(subject.errors).to be_empty
169
+ end
170
+ end
171
+
172
+ context "with a provider label and name" do
173
+ let(:json) do
174
+ valid_webhook_with do |hash|
175
+ hash["provider"]["label"] = "my_label"
176
+ end
177
+ end
178
+
179
+ it "contains provider.label error" do
180
+ expect(subject.errors.messages).to eq({:'provider.label' => ["cannot be provided"]})
181
+ end
182
+ end
183
+
134
184
  context "with no request defined" do
135
185
  let(:json) { {}.to_json }
136
186
 
@@ -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
  }
@@ -80,13 +80,13 @@ module PactBroker
80
80
  context "when the reason is NoEnvironmentSpecified" do
81
81
  let(:reason) { PactBroker::Matrix::NoEnvironmentSpecified.new }
82
82
 
83
- its(:to_s) { is_expected.to start_with "WARN: For production use of can-i-deploy, it is recommended to specify the environment" }
83
+ its(:to_s) { is_expected.to start_with "WARN: It is recommended to specify the environment" }
84
84
  end
85
85
 
86
86
  context "when the reason is SelectorWithoutPacticipantVersionNumberSpecified" do
87
87
  let(:reason) { PactBroker::Matrix::SelectorWithoutPacticipantVersionNumberSpecified.new }
88
88
 
89
- its(:to_s) { is_expected.to start_with "WARN: For production use of can-i-deploy, it is recommended to specify the version number" }
89
+ its(:to_s) { is_expected.to start_with "WARN: It is recommended to specify the version number" }
90
90
  end
91
91
  end
92
92
  end
@@ -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,23 +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
- provider_version_tags: provider_version_tags)
23
+ provider_version_tags: provider_version_tags,
24
+ verified_by_implementation: "Ruby",
25
+ verified_by_version: "1234")
24
26
  end
25
27
 
26
- let(:pact_publication) do
27
- instance_double("PactBroker::Pacts::PactPublication",
28
+ let(:pact) do
29
+ instance_double("PactBroker::Domain::Pact",
28
30
  name: "A name",
29
31
  provider_name: "Provider",
30
32
  consumer_name: "Consumer",
31
- consumer_version_number: "1.2.3"
33
+ consumer_version_number: "1.2.3",
34
+ pact_version_sha: "1234",
32
35
  )
33
36
  end
34
37
 
35
38
  let(:provider_version_tags) { [instance_double(PactBroker::Tags::TagWithLatestFlag, name: "prod", latest?: true)] }
36
39
 
37
- let(:options) { { user_options: { base_url: "http://example.org" } } }
40
+ let(:options) { { user_options: { base_url: "http://example.org", pact: pact } } }
38
41
 
39
42
  let(:json) { VerificationDecorator.new(verification).to_json(options) }
40
43
 
@@ -61,12 +64,17 @@ module PactBroker
61
64
  end
62
65
 
63
66
  it "includes a link to its pact" do
64
- 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"
65
68
  end
66
69
 
67
70
  it "includes a link to the triggered webhooks" do
68
71
  expect(subject[:_links][:'pb:triggered-webhooks'][:href]).to eq "http://triggered-webhooks"
69
72
  end
73
+
74
+ it "includes the framework that did the verification" do
75
+ expect(subject[:verifiedBy][:implementation]).to eq "Ruby"
76
+ expect(subject[:verifiedBy][:version]).to eq "1234"
77
+ end
70
78
  end
71
79
  end
72
80
  end
@@ -21,14 +21,18 @@ module PactBroker
21
21
  latest_pact_publication: pact,
22
22
  test_results: nil,
23
23
  execution_date: DateTime.now,
24
- provider_version_tags: provider_version_tags)
24
+ provider_version_tags: provider_version_tags,
25
+ verified_by_implementation: "Ruby",
26
+ verified_by_version: "1234")
25
27
  end
28
+
26
29
  let(:pact_version) do
27
30
  instance_double("PactBroker::Pacts::PactVersion", name: "Name")
28
31
  end
29
32
 
30
33
  let(:provider_version_tags) { [instance_double(PactBroker::Tags::TagWithLatestFlag, name: "prod", latest?: true)] }
31
- 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
+ let(:is_pending) { true }
32
36
  let(:options) { {base_url: "http://example.org", consumer_name: "Foo", consumer_version_number: "1.2.3", resource_url: "http://self"} }
33
37
 
34
38
  subject { JSON.parse VerificationSummaryDecorator.new(summary).to_json(user_options: options), symbolize_names: true }
@@ -20,8 +20,8 @@ module PactBroker
20
20
  Webhooks::WebhookRequestTemplate.new(request)
21
21
  end
22
22
 
23
- let(:consumer) { Domain::Pacticipant.new(name: "Consumer") }
24
- let(:provider) { Domain::Pacticipant.new(name: "Provider") }
23
+ let(:consumer) { Domain::WebhookPacticipant.new(name: "Consumer") }
24
+ let(:provider) { Domain::WebhookPacticipant.new(name: "Provider") }
25
25
  let(:event) { Webhooks::WebhookEvent.new(name: "something_happened") }
26
26
  let(:created_at) { DateTime.now }
27
27
  let(:updated_at) { created_at + 1 }
@@ -193,8 +193,8 @@ module PactBroker
193
193
  context "when the decorated object has a consumer/provider but the incoming JSON does not" do
194
194
  let(:webhook) do
195
195
  Domain::Webhook.new(
196
- consumer: Domain::Pacticipant.new(name: "consumer"),
197
- provider: Domain::Pacticipant.new(name: "provider")
196
+ consumer: Domain::WebhookPacticipant.new(name: "consumer"),
197
+ provider: Domain::WebhookPacticipant.new(name: "provider")
198
198
  )
199
199
  end
200
200
 
@@ -6,7 +6,7 @@ module PactBroker
6
6
  module Decorators
7
7
  describe WebhookExecutionResultDecorator do
8
8
  describe "to_json" do
9
- let(:webhook_execution_result) { PactBroker::Webhooks::WebhookExecutionResult.new(request, response, logs, error) }
9
+ let(:webhook_execution_result) { PactBroker::Webhooks::WebhookExecutionResult.new(request, response, true, logs, error) }
10
10
  let(:logs) { "logs" }
11
11
  let(:headers) { { "Something" => ["blah", "thing"]} }
12
12
  let(:request) do
@@ -0,0 +1,43 @@
1
+ require "pact_broker/api/middleware/configuration"
2
+
3
+ module PactBroker
4
+ module Api
5
+ module Middleware
6
+ class TestApp
7
+ def call(_)
8
+ [200, {}, [PactBroker.configuration.allow_dangerous_contract_modification.to_s]]
9
+ end
10
+ end
11
+
12
+ describe Configuration do
13
+ describe "#call" do
14
+ let(:configuration) do
15
+ conf = PactBroker::Configuration.default_configuration
16
+ conf.allow_dangerous_contract_modification = false
17
+ conf
18
+ end
19
+ let(:app) { Configuration.new(TestApp.new, configuration) }
20
+ let(:rack_env) { {} }
21
+
22
+ subject { get("/", nil, rack_env) }
23
+
24
+ context "with no overrides" do
25
+ it "uses the default configuration" do
26
+ expect(subject.body).to eq "false"
27
+ end
28
+ end
29
+
30
+ context "with overrides" do
31
+ let(:rack_env) do
32
+ { "pactbroker.configuration_overrides" => { allow_dangerous_contract_modification: true }}
33
+ end
34
+
35
+ it "overrides the configuration for the duration of the request" do
36
+ expect(subject.body).to eq "true"
37
+ end
38
+ end
39
+ end
40
+ end
41
+ end
42
+ end
43
+ end
@@ -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
@@ -1,4 +1,3 @@
1
- require "spec_helper"
2
1
  require "pact_broker/api/resources/verifications"
3
2
  require "pact_broker/pacts/service"
4
3
  require "pact_broker/verifications/service"
@@ -17,7 +16,7 @@ module PactBroker
17
16
  let(:database_connector) { double("database_connector" )}
18
17
  let(:verification) { double(PactBroker::Domain::Verification) }
19
18
  let(:errors_empty) { true }
20
- let(:parsed_metadata) { { the: "metadata", consumer_version_number: "2"} }
19
+ let(:parsed_metadata) { { the: "metadata", consumer_version_number: "2", pending: true } }
21
20
  let(:base_url) { "http://example.org" }
22
21
  let(:webhook_execution_configuration) { instance_double(PactBroker::Webhooks::ExecutionConfiguration) }
23
22
 
@@ -86,7 +85,7 @@ module PactBroker
86
85
  it "stores the verification in the database" do
87
86
  expect(PactBroker::Verifications::Service).to receive(:create).with(
88
87
  next_verification_number,
89
- hash_including("some" => "params", "wip" => false),
88
+ hash_including("some" => "params", "wip" => false, "pending" => true),
90
89
  verified_pacts,
91
90
  parsed_metadata
92
91
  )
@@ -30,7 +30,7 @@ module PactBroker
30
30
  let(:pact) { instance_double("PactBroker::Domain::Pact") }
31
31
  let(:consumer_name) { "foo" }
32
32
  let(:provider_name) { "bar" }
33
- let(:webhook_execution_configuration) { instance_double(PactBroker::Webhooks::ExecutionConfiguration, webhook_context: event_context) }
33
+ let(:webhook_execution_configuration) { instance_double(PactBroker::Webhooks::ExecutionConfiguration, retry_schedule: [], webhook_context: event_context) }
34
34
  let(:event_context) { { some: "data" } }
35
35
 
36
36
  before do
@@ -203,6 +203,18 @@ module PactBroker
203
203
  end
204
204
  end
205
205
 
206
+ context "when the pseudo_branch_verification_status is :failed_pending" do
207
+ let(:pseudo_branch_verification_status) { :failed_pending }
208
+ let(:expected_color) { "red" }
209
+ let(:expected_right_text) { "failed%20%28pending%29" }
210
+
211
+ it "create a red badge with left text 'failed'" do
212
+ subject
213
+ expect(http_request).to have_been_made
214
+ expect(pact_verification_badge_url).to eq URI(expected_url)
215
+ end
216
+ end
217
+
206
218
  context "when the pseudo_branch_verification_status is :stale" do
207
219
  let(:pseudo_branch_verification_status) { :stale }
208
220
  let(:expected_color) { "orange" }
@@ -248,6 +260,16 @@ module PactBroker
248
260
  end
249
261
  end
250
262
 
263
+ # TODO save a static image for this
264
+ context "when the pseudo_branch_verification_status is failed_pending" do
265
+ let(:pseudo_branch_verification_status) { :failed_pending }
266
+
267
+ it "returns a static failed image" do
268
+ expect(subject).to include ">pact</"
269
+ expect(subject).to include ">failed</"
270
+ end
271
+ end
272
+
251
273
  context "when the pseudo_branch_verification_status is stale" do
252
274
  let(:pseudo_branch_verification_status) { :stale }
253
275
 
@@ -0,0 +1,30 @@
1
+ require "pact_broker/config/runtime_configuration"
2
+
3
+ module PactBroker
4
+ module Config
5
+ describe RuntimeConfiguration do
6
+ ATTRIBUTES = RuntimeConfiguration.config_attributes
7
+ DOCUMENTATION = File.read("docs/configuration.yml")
8
+ DOCUMENTED_ATTRIBUTES = YAML.load(DOCUMENTATION)["groups"].flat_map{ | group | group["vars"].keys.collect(&:to_sym) }
9
+ DELIBERATELY_UNDOCUMENTED_ATTRIBUTES = [
10
+ :warning_error_class_names,
11
+ :log_configuration_on_startup,
12
+ :use_hal_browser,
13
+ :use_rack_protection,
14
+ :use_case_sensitive_resource_names,
15
+ :order_versions_by_date,
16
+ :base_equality_only_on_content_that_affects_verification_results,
17
+ :semver_formats,
18
+ :seed_example_data,
19
+ :use_first_tag_as_branch_time_limit,
20
+ :validate_database_connection_config
21
+ ]
22
+
23
+ (ATTRIBUTES - DELIBERATELY_UNDOCUMENTED_ATTRIBUTES).each do | attribute_name |
24
+ it "has documentation for #{attribute_name}" do
25
+ expect(DOCUMENTED_ATTRIBUTES & [attribute_name]).to include(attribute_name)
26
+ end
27
+ end
28
+ end
29
+ end
30
+ end
@@ -2,7 +2,7 @@ require "pact_broker/deployments/environment_service"
2
2
 
3
3
  module PactBroker
4
4
  module Deployments
5
- module EnvironmentService
5
+ describe EnvironmentService do
6
6
  describe ".create" do
7
7
  let(:environment) do
8
8
  Environment.new(
@@ -19,7 +19,8 @@ module PactBroker
19
19
  headers: headers,
20
20
  username: username,
21
21
  password: password,
22
- body: body)
22
+ body: body,
23
+ user_agent: "Pact Broker")
23
24
  end
24
25
 
25
26
  let(:execute) { subject.execute }
@@ -11,10 +11,11 @@ module PactBroker
11
11
  let(:webhook_template_parameters) { instance_double(PactBroker::Webhooks::PactAndVerificationParameters, to_hash: webhook_template_parameters_hash) }
12
12
  let(:webhook_template_parameters_hash) { { "foo" => "bar" } }
13
13
  let(:http_request) { double("http request") }
14
- let(:http_response) { double("http response", code: "200") }
14
+ let(:http_response) { double("http response", code: response_code) }
15
+ let(:response_code) { "200" }
15
16
  let(:event_context) { { some: "things" } }
16
17
  let(:logging_options) { { other: "options" } }
17
- let(:options) { { logging_options: logging_options } }
18
+ let(:options) { { logging_options: logging_options, http_success_codes: [200], user_agent: "user agent" } }
18
19
  let(:pact) { double("pact") }
19
20
  let(:verification) { double("verification") }
20
21
  let(:logger) { double("logger").as_null_object }
@@ -71,7 +72,7 @@ module PactBroker
71
72
  end
72
73
 
73
74
  it "builds the request" do
74
- expect(request_template).to receive(:build).with(webhook_template_parameters_hash)
75
+ expect(request_template).to receive(:build).with(webhook_template_parameters_hash, "user agent")
75
76
  execute
76
77
  end
77
78
 
@@ -81,7 +82,7 @@ module PactBroker
81
82
  end
82
83
 
83
84
  it "generates the execution logs" do
84
- expect(webhook_request_logger).to receive(:log).with(uuid, webhook_request, http_response, nil, event_context)
85
+ expect(webhook_request_logger).to receive(:log).with(uuid, webhook_request, http_response, true, nil, event_context)
85
86
  execute
86
87
  end
87
88
 
@@ -90,6 +91,7 @@ module PactBroker
90
91
  expect(execute.response).to_not be nil
91
92
  expect(execute.logs).to eq "logs"
92
93
  expect(execute.error).to be nil
94
+ expect(execute.success?).to be true
93
95
  end
94
96
 
95
97
  it "logs before and after" do
@@ -98,6 +100,14 @@ module PactBroker
98
100
  execute
99
101
  end
100
102
 
103
+ context "when a response status is returned that is not in the http_success_codes" do
104
+ let(:response_code) { "301" }
105
+
106
+ it "returns a result with success? false" do
107
+ expect(execute.success?).to be false
108
+ end
109
+ end
110
+
101
111
  context "when an error is thrown" do
102
112
  let(:error_class) { Class.new(StandardError) }
103
113
 
@@ -106,7 +116,7 @@ module PactBroker
106
116
  end
107
117
 
108
118
  it "generates the execution logs" do
109
- expect(webhook_request_logger).to receive(:log).with(uuid, webhook_request, nil, instance_of(error_class), event_context)
119
+ expect(webhook_request_logger).to receive(:log).with(uuid, webhook_request, nil, false, instance_of(error_class), event_context)
110
120
  execute
111
121
  end
112
122
 
@@ -1,12 +1,8 @@
1
- require "spec_helper"
2
1
  require "pact_broker/index/service"
3
- require "pact_broker/domain/tag"
4
- require "pact_broker/domain/pact"
5
2
 
6
3
  module PactBroker
7
4
  module Index
8
5
  describe Service do
9
- let(:td) { TestDataBuilder.new }
10
6
  let(:tags) { ["prod", "production"] }
11
7
  let(:options) { { tags: tags, page_size: page_size, page_number: page_number } }
12
8
  let(:page_number) { nil }
@@ -19,7 +15,7 @@ module PactBroker
19
15
 
20
16
  subject { Service }
21
17
 
22
- describe "find_relationships integration test" do
18
+ describe "find_index_items integration test" do
23
19
  context "when a prod pact exists and is not the latest version" do
24
20
  before do
25
21
  td.create_pact_with_hierarchy("Foo", "1.2.3", "Bar")
@@ -0,0 +1,144 @@
1
+ require "pact_broker/index/service"
2
+
3
+ module PactBroker
4
+ module Index
5
+ describe Service do
6
+ let(:tags) { ["prod", "production"] }
7
+ let(:options) do
8
+ {
9
+ page_size: page_size,
10
+ page_number: page_number,
11
+ view: view,
12
+ consumer_name: consumer_name,
13
+ provider_name: provider_name
14
+ }
15
+ end
16
+ let(:page_number) { nil }
17
+ let(:page_size) { nil }
18
+ let(:consumer_name) { "Foo"}
19
+ let(:provider_name) { "Bar"}
20
+
21
+ subject { Service.find_index_items(options) }
22
+
23
+ describe "find_index_items" do
24
+ context "when view == branch" do
25
+ before do
26
+ td.create_consumer("Foo")
27
+ .create_provider("Bar")
28
+ .create_consumer_version("1", branch: "main", tag_names: ["dev"])
29
+ .create_pact
30
+ .create_consumer_version("2", tag_names: ["dev"])
31
+ .create_pact
32
+ .create_consumer_version("3", branch: "feat/x", tag_names: ["dev-1"])
33
+ .create_pact
34
+ .create_consumer_version("4", branch: "main", tag_names: ["dev-2"])
35
+ .create_pact
36
+ .create_consumer_version("4", branch: "feat/y")
37
+ .create_consumer("NotFoo")
38
+ .create_consumer_version("10", branch: "main")
39
+ .create_pact
40
+ end
41
+
42
+ let(:view) { "branch" }
43
+
44
+ let(:consumer_version_numbers) { subject.collect(&:consumer_version_number) }
45
+
46
+ it "returns the latest pacts for each branch" do
47
+ expect(consumer_version_numbers).to eq ["4", "3"]
48
+ end
49
+ end
50
+
51
+ context "when view == tag" do
52
+ before do
53
+ td.create_consumer("Foo")
54
+ .create_provider("Bar")
55
+ .create_consumer_version("1", branch: "main", tag_names: ["dev"])
56
+ .create_pact
57
+ .create_consumer_version("2", tag_names: ["dev"])
58
+ .create_pact
59
+ .create_consumer_version("3", branch: "feat/x", tag_names: ["dev-2"])
60
+ .create_pact
61
+ .create_consumer_version("4", branch: "main", tag_names: ["dev-3"])
62
+ .create_pact
63
+ .create_consumer_version("4", branch: "feat/y")
64
+ .create_consumer("NotFoo")
65
+ .create_consumer_version("10", branch: "main")
66
+ .create_pact
67
+ end
68
+
69
+ let(:view) { "tag" }
70
+
71
+ let(:consumer_version_numbers) { subject.collect(&:consumer_version_number) }
72
+
73
+ it "returns the latest pacts for each tag" do
74
+ expect(consumer_version_numbers).to eq ["4", "3", "2"]
75
+ end
76
+ end
77
+
78
+ context "when view == environment" do
79
+ before do
80
+ td.create_environment("test")
81
+ .create_consumer("Foo")
82
+ .create_provider("Bar")
83
+ .create_consumer_version("1")
84
+ .create_pact
85
+ .create_deployed_version_for_consumer_version(currently_deployed: false)
86
+ .create_consumer_version("2")
87
+ .create_pact
88
+ .create_deployed_version_for_consumer_version
89
+ .create_consumer_version("3")
90
+ .create_pact
91
+ .create_released_version_for_consumer_version(currently_supported: false)
92
+ .create_consumer_version("4")
93
+ .create_pact
94
+ .create_released_version_for_consumer_version
95
+ .create_consumer_version("5")
96
+ .create_pact
97
+ end
98
+
99
+ let(:view) { "environment" }
100
+
101
+ let(:consumer_version_numbers) { subject.collect(&:consumer_version_number) }
102
+
103
+ it "returns the currently deployed and released+supported pacts" do
104
+ expect(consumer_version_numbers).to eq ["4", "2"]
105
+ end
106
+ end
107
+
108
+ context "when view == all" do
109
+ before do
110
+ td.create_environment("test")
111
+ .create_consumer("Foo")
112
+ .create_provider("Bar")
113
+ .create_consumer_version("1")
114
+ .create_pact
115
+ .create_deployed_version_for_consumer_version
116
+ .create_consumer_version("2")
117
+ .create_pact
118
+ .create_released_version_for_consumer_version
119
+ .create_consumer_version("3", branch: "main")
120
+ .create_pact
121
+ .create_consumer_version("4", branch: "main")
122
+ .create_pact
123
+ .create_consumer_version("5", tag_names: "dev")
124
+ .create_pact
125
+ .create_consumer_version("6", tag_names: "dev")
126
+ .create_pact
127
+ .create_consumer_version("7")
128
+ .create_pact
129
+ .create_consumer_version("8")
130
+ .create_pact
131
+ end
132
+
133
+ let(:view) { "all" }
134
+
135
+ let(:consumer_version_numbers) { subject.collect(&:consumer_version_number) }
136
+
137
+ it "returns the latest for each branch, tag, deployed, released + overall latest" do
138
+ expect(consumer_version_numbers).to eq ["8", "6", "4", "2", "1"]
139
+ end
140
+ end
141
+ end
142
+ end
143
+ end
144
+ end