pact_broker 2.12.0 → 2.13.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (100) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +42 -5
  3. data/README.md +13 -8
  4. data/bethtest.rb +21 -94
  5. data/db/migrations/20171112_add_test_results.rb +7 -0
  6. data/db/migrations/20171117_create_webhook_events.rb +14 -0
  7. data/db/migrations/20171118_create_webhook_events.rb +18 -0
  8. data/db/migrations/20180108_create_certificates_table.rb +14 -0
  9. data/db/migrations/20180109_migrate_trigger_type.rb +9 -0
  10. data/db/pact_broker_database.sqlite3 +0 -0
  11. data/db/test/backwards_compatibility/gemfiles/1.18.0.gemfile.lock +5 -5
  12. data/db/test/backwards_compatibility/gemfiles/2.0.0.gemfile.lock +5 -5
  13. data/db/test/backwards_compatibility/gemfiles/2.1.0.gemfile.lock +5 -5
  14. data/db/test/backwards_compatibility/gemfiles/2.2.0.gemfile.lock +12 -14
  15. data/db/test/backwards_compatibility/gemfiles/2.3.0.gemfile.lock +12 -14
  16. data/db/test/backwards_compatibility/gemfiles/2.4.2.gemfile.lock +12 -14
  17. data/db/test/backwards_compatibility/gemfiles/2.5.1.gemfile.lock +12 -14
  18. data/db/test/backwards_compatibility/gemfiles/2.6.0.gemfile.lock +12 -14
  19. data/db/test/backwards_compatibility/gemfiles/head.gemfile.lock +16 -15
  20. data/db/test/change_migration_strategy/before/Gemfile +1 -0
  21. data/example/README.md +65 -0
  22. data/example/config.ru +1 -0
  23. data/example/example_data.sql +17 -0
  24. data/lib/pact_broker/api.rb +1 -1
  25. data/lib/pact_broker/api/contracts/webhook_contract.rb +9 -1
  26. data/lib/pact_broker/api/decorators/verification_decorator.rb +1 -0
  27. data/lib/pact_broker/api/decorators/webhook_decorator.rb +35 -5
  28. data/lib/pact_broker/api/resources/matrix_badge.rb +21 -0
  29. data/lib/pact_broker/certificates/certificate.rb +8 -0
  30. data/lib/pact_broker/certificates/service.rb +41 -0
  31. data/lib/pact_broker/doc/controllers/app.rb +12 -2
  32. data/lib/pact_broker/doc/views/webhooks.markdown +37 -2
  33. data/lib/pact_broker/domain/verification.rb +2 -0
  34. data/lib/pact_broker/domain/webhook.rb +2 -1
  35. data/lib/pact_broker/domain/webhook_request.rb +22 -4
  36. data/lib/pact_broker/error.rb +5 -0
  37. data/lib/pact_broker/matrix/parse_query.rb +7 -10
  38. data/lib/pact_broker/matrix/repository.rb +5 -32
  39. data/lib/pact_broker/matrix/service.rb +21 -3
  40. data/lib/pact_broker/pacts/repository.rb +9 -2
  41. data/lib/pact_broker/pacts/service.rb +2 -2
  42. data/lib/pact_broker/services.rb +5 -0
  43. data/lib/pact_broker/ui/app.rb +15 -0
  44. data/lib/pact_broker/ui/controllers/matrix.rb +58 -3
  45. data/lib/pact_broker/ui/views/matrix/show.haml +65 -10
  46. data/lib/pact_broker/verifications/service.rb +6 -1
  47. data/lib/pact_broker/version.rb +1 -1
  48. data/lib/pact_broker/webhooks/job.rb +1 -1
  49. data/lib/pact_broker/webhooks/repository.rb +17 -0
  50. data/lib/pact_broker/webhooks/service.rb +8 -7
  51. data/lib/pact_broker/webhooks/triggered_webhook.rb +1 -1
  52. data/lib/pact_broker/webhooks/webhook.rb +3 -0
  53. data/lib/pact_broker/webhooks/webhook_event.rb +24 -0
  54. data/pact_broker.gemspec +2 -1
  55. data/public/javascripts/matrix.js +60 -0
  56. data/public/stylesheets/matrix.css +12 -0
  57. data/script/db-spec.sh +1 -0
  58. data/script/foo-bar-verification.json +57 -0
  59. data/script/insert-self-signed-certificate-from-url.rb +32 -0
  60. data/script/publish-verification.sh +5 -0
  61. data/script/seed-matrix.rb +6 -5
  62. data/script/seed.rb +67 -59
  63. data/spec/features/create_webhook_spec.rb +4 -1
  64. data/spec/features/get_matrix_badge_spec.rb +40 -0
  65. data/spec/features/publish_verification_spec.rb +28 -4
  66. data/spec/fixtures/certificate-invalid.pem +29 -0
  67. data/spec/fixtures/certificate.pem +53 -0
  68. data/spec/fixtures/certificates/cacert.pem +21 -0
  69. data/spec/fixtures/certificates/cert.pem +20 -0
  70. data/spec/fixtures/certificates/key.pem +27 -0
  71. data/spec/fixtures/certificates/self-signed.badssl.com.pem +21 -0
  72. data/spec/fixtures/verification.json +4 -1
  73. data/spec/fixtures/webhook_valid.json +3 -0
  74. data/spec/integration/webhooks/certificate_spec.rb +80 -0
  75. data/spec/lib/pact_broker/api/contracts/webhook_contract_spec.rb +20 -0
  76. data/spec/lib/pact_broker/api/decorators/pact_webhooks_status_decorator_spec.rb +2 -2
  77. data/spec/lib/pact_broker/api/decorators/verification_decorator_spec.rb +5 -0
  78. data/spec/lib/pact_broker/api/decorators/verification_summary_decorator_spec.rb +1 -0
  79. data/spec/lib/pact_broker/api/decorators/webhook_decorator_spec.rb +29 -19
  80. data/spec/lib/pact_broker/api/resources/badge_spec.rb +61 -0
  81. data/spec/lib/pact_broker/api/resources/matrix_badge_spec.rb +11 -0
  82. data/spec/lib/pact_broker/api/resources/pact_webhooks_spec.rb +8 -9
  83. data/spec/lib/pact_broker/certificates/service_spec.rb +60 -0
  84. data/spec/lib/pact_broker/domain/verification_spec.rb +13 -0
  85. data/spec/lib/pact_broker/domain/webhook_request_spec.rb +0 -4
  86. data/spec/lib/pact_broker/matrix/service_spec.rb +40 -8
  87. data/spec/lib/pact_broker/pacts/repository_spec.rb +18 -1
  88. data/spec/lib/pact_broker/webhooks/job_spec.rb +1 -1
  89. data/spec/lib/pact_broker/webhooks/repository_spec.rb +53 -13
  90. data/spec/lib/pact_broker/webhooks/service_spec.rb +9 -6
  91. data/spec/migrations/change_migration_strategy_spec.rb +13 -14
  92. data/spec/spec_helper.rb +4 -0
  93. data/spec/support/ssl_webhook_server.rb +37 -0
  94. data/spec/support/test_data_builder.rb +12 -4
  95. data/tasks/database.rb +9 -7
  96. data/tasks/database/table_dependency_calculator.rb +44 -0
  97. metadata +57 -6
  98. data/lib/pact_broker/doc/views/pact-webhooks.markdown +0 -50
  99. data/lib/pact_broker/doc/views/webhooks-create.markdown +0 -38
  100. data/lib/pact_broker/doc/views/webhooks-webhooks.markdown +0 -15
@@ -3,7 +3,7 @@ require 'support/test_data_builder'
3
3
  describe "Creating a webhook" do
4
4
 
5
5
  before do
6
- TestDataBuilder.new.create_pact_with_hierarchy("Some Consumer", "1", "Some Provider").and_return(:pact)
6
+ TestDataBuilder.new.create_pact_with_hierarchy("Some Consumer", "1", "Some Provider")
7
7
  end
8
8
 
9
9
  let(:path) { "/webhooks/provider/Some%20Provider/consumer/Some%20Consumer" }
@@ -38,6 +38,9 @@ describe "Creating a webhook" do
38
38
 
39
39
  let(:webhook_hash) do
40
40
  {
41
+ events: [{
42
+ name: 'something_happened'
43
+ }],
41
44
  request: {
42
45
  method: 'POST',
43
46
  url: 'http://example.org',
@@ -0,0 +1,40 @@
1
+ require 'webmock/rspec'
2
+
3
+ describe "get latest matrix badge with tags" do
4
+
5
+ before do
6
+ PactBroker.configuration.enable_public_badge_access = true
7
+ TestDataBuilder.new
8
+ .create_consumer('consumer')
9
+ .create_provider('provider')
10
+ .create_consumer_version('1')
11
+ .create_consumer_version_tag('prod')
12
+ .create_pact
13
+ .create_verification(provider_version: '4')
14
+ .use_provider_version('4')
15
+ .create_provider_version_tag('master')
16
+ end
17
+
18
+ let!(:http_request) do
19
+ stub_request(:get, /http/).to_return(:status => 200, :body => "<svg/>")
20
+ end
21
+
22
+ let(:path) { "/matrix/provider/provider/latest/master/consumer/consumer/latest/prod/badge" }
23
+
24
+ # In the full app, the .svg extension is turned into an Accept header
25
+ # by ConvertFileExtensionToAcceptHeader
26
+
27
+ subject { get path, nil, {'HTTP_ACCEPT' => "image/svg+xml"}; last_response }
28
+
29
+ it "returns a 200 status" do
30
+ expect(subject.status).to eq 200
31
+ end
32
+
33
+ it "returns an svg/xml response" do
34
+ expect(subject.headers['Content-Type']).to include("image/svg+xml")
35
+ end
36
+
37
+ it "returns an svg body" do
38
+ expect(subject.body).to include "<svg/>"
39
+ end
40
+ end
@@ -2,22 +2,23 @@ require 'pact_broker/domain/verification'
2
2
 
3
3
  describe "Recording a pact verification" do
4
4
 
5
+ let(:td) { TestDataBuilder.new }
5
6
  let(:path) { "/pacts/provider/Provider/consumer/Consumer/pact-version/#{pact.pact_version_sha}/verification-results" }
6
7
  let(:verification_content) { load_fixture('verification.json') }
7
8
  let(:parsed_response_body) { JSON.parse(subject.body) }
9
+ let(:pact) { td.pact }
8
10
 
9
11
  subject { post path, verification_content, {'CONTENT_TYPE' => 'application/json' }; last_response }
10
12
 
11
- let(:pact) do
12
- TestDataBuilder.new
13
- .create_provider("Provider")
13
+
14
+ before do
15
+ td.create_provider("Provider")
14
16
  .create_consumer("Consumer")
15
17
  .create_consumer_version("1.0.0")
16
18
  .create_pact
17
19
  .create_consumer_version("1.2.3")
18
20
  .create_pact
19
21
  .revise_pact
20
- .and_return(:pact)
21
22
  end
22
23
 
23
24
  it "Responds with a 201 Created" do
@@ -33,10 +34,33 @@ describe "Recording a pact verification" do
33
34
  expect(PactBroker::Domain::Verification.order(:id).last.pact_version_sha).to eq pact.pact_version_sha
34
35
  end
35
36
 
37
+ it "saves the test results" do
38
+ subject
39
+ expect(PactBroker::Domain::Verification.order(:id).last.test_results).to eq('some' => 'results')
40
+ end
41
+
36
42
  it "returns a link to itself that can be followed" do
37
43
  get_verification_link = parsed_response_body['_links']['self']['href']
38
44
  get get_verification_link
39
45
  expect(last_response.status).to be 200
40
46
  expect(JSON.parse(subject.body)).to include JSON.parse(verification_content)
41
47
  end
48
+
49
+ context "with a webhook configured" do
50
+ before do
51
+ td.create_webhook(
52
+ method: 'POST',
53
+ url: 'http://example.org',
54
+ events: [{ name: PactBroker::Webhooks::WebhookEvent::VERIFICATION_PUBLISHED }]
55
+ )
56
+ end
57
+ let!(:request) do
58
+ stub_request(:post, 'http://example.org').to_return(:status => 200)
59
+ end
60
+
61
+ it "executes the webhook" do
62
+ subject
63
+ expect(request).to have_been_made
64
+ end
65
+ end
42
66
  end
@@ -0,0 +1,29 @@
1
+ -----BEGIN CERTIFICATE-----
2
+ foo
3
+ -----END CERTIFICATE-----
4
+ -----BEGIN CERTIFICATE-----
5
+ MIIEXDCCA0SgAwIBAgIEOGO5ZjANBgkqhkiG9w0BAQUFADCBtDEUMBIGA1UEChML
6
+ RW50cnVzdC5uZXQxQDA+BgNVBAsUN3d3dy5lbnRydXN0Lm5ldC9DUFNfMjA0OCBp
7
+ bmNvcnAuIGJ5IHJlZi4gKGxpbWl0cyBsaWFiLikxJTAjBgNVBAsTHChjKSAxOTk5
8
+ IEVudHJ1c3QubmV0IExpbWl0ZWQxMzAxBgNVBAMTKkVudHJ1c3QubmV0IENlcnRp
9
+ ZmljYXRpb24gQXV0aG9yaXR5ICgyMDQ4KTAeFw05OTEyMjQxNzUwNTFaFw0xOTEy
10
+ MjQxODIwNTFaMIG0MRQwEgYDVQQKEwtFbnRydXN0Lm5ldDFAMD4GA1UECxQ3d3d3
11
+ LmVudHJ1c3QubmV0L0NQU18yMDQ4IGluY29ycC4gYnkgcmVmLiAobGltaXRzIGxp
12
+ YWIuKTElMCMGA1UECxMcKGMpIDE5OTkgRW50cnVzdC5uZXQgTGltaXRlZDEzMDEG
13
+ A1UEAxMqRW50cnVzdC5uZXQgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkgKDIwNDgp
14
+ MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEArU1LqRKGsuqjIAcVFmQq
15
+ K0vRvwtKTY7tgHalZ7d4QMBzQshowNtTK91euHaYNZOLGp18EzoOH1u3Hs/lJBQe
16
+ sYGpjX24zGtLA/ECDNyrpUAkAH90lKGdCCmziAv1h3edVc3kw37XamSrhRSGlVuX
17
+ MlBvPci6Zgzj/L24ScF2iUkZ/cCovYmjZy/Gn7xxGWC4LeksyZB2ZnuU4q941mVT
18
+ XTzWnLLPKQP5L6RQstRIzgUyVYr9smRMDuSYB3Xbf9+5CFVghTAp+XtIpGmG4zU/
19
+ HoZdenoVve8AjhUiVBcAkCaTvA5JaJG/+EfTnZVCwQ5N328mz8MYIWJmQ3DW1cAH
20
+ 4QIDAQABo3QwcjARBglghkgBhvhCAQEEBAMCAAcwHwYDVR0jBBgwFoAUVeSB0RGA
21
+ vtiJuQijMfmhJAkWuXAwHQYDVR0OBBYEFFXkgdERgL7YibkIozH5oSQJFrlwMB0G
22
+ CSqGSIb2fQdBAAQQMA4bCFY1LjA6NC4wAwIEkDANBgkqhkiG9w0BAQUFAAOCAQEA
23
+ WUesIYSKF8mciVMeuoCFGsY8Tj6xnLZ8xpJdGGQC49MGCBFhfGPjK50xA3B20qMo
24
+ oPS7mmNz7W3lKtvtFKkrxjYR0CvrB4ul2p5cGZ1WEvVUKcgF7bISKo30Axv/55IQ
25
+ h7A6tcOdBTcSo8f0FbnVpDkWm1M6I5HxqIKiaohowXkCIryqptau37AUX7iH0N18
26
+ f3v/rxzP5tsHrV7bhZ3QKw0z2wTR5klAEyt2+z7pnIkPFc4YsIV4IU9rTw76NmfN
27
+ B/L/CNDi3tm/Kq+4h4YhPATKt5Rof8886ZjXOP/swNlQ8C5LWK5Gb9Auw2DaclVy
28
+ vUxFnmG6v4SBkgPR0ml8xQ==
29
+ -----END CERTIFICATE-----
@@ -0,0 +1,53 @@
1
+ -----BEGIN CERTIFICATE-----
2
+ MIIEhjCCA26gAwIBAgIJAOoR4cViLrYBMA0GCSqGSIb3DQEBBQUAMIGIMQswCQYD
3
+ VQQGEwJBVTERMA8GA1UECBMIVmljdG9yaWExEjAQBgNVBAcTCU1lbGJvdXJuZTEY
4
+ MBYGA1UEChMPUGFjdCBGb3VuZGF0aW9uMRUwEwYDVQQDEwxCZXRoIFNrdXJyaWUx
5
+ ITAfBgkqhkiG9w0BCQEWEmJldGhAYmV0aGVzcXVlLmNvbTAeFw0xNzEyMDcwMDI1
6
+ MjZaFw00NTA0MjQwMDI1MjZaMIGIMQswCQYDVQQGEwJBVTERMA8GA1UECBMIVmlj
7
+ dG9yaWExEjAQBgNVBAcTCU1lbGJvdXJuZTEYMBYGA1UEChMPUGFjdCBGb3VuZGF0
8
+ aW9uMRUwEwYDVQQDEwxCZXRoIFNrdXJyaWUxITAfBgkqhkiG9w0BCQEWEmJldGhA
9
+ YmV0aGVzcXVlLmNvbTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAKli
10
+ EwzIbbZdoDbuJPkMsdGihSYK6KQrLCsvFmNLEgDBKds387E5mQoOjDvlDHLkY+uq
11
+ Lm10bI2MSnQAj9B+jqf48FNaoHq2A30iohmK2hPKsrIMi3eaWrXYm9+ZxnNUO/j6
12
+ /WKCsX/InUsZDd0J6F6HO9RZ+/AmfBC6fTuxKFgGENwsZSPIpi2JwBeEV+YCthPf
13
+ yOBzgNyljd+BqvZCJK3+r074131TC4AEzWZsV33ipOTpcY3y8XAOa79npWUfnTOX
14
+ E3NW1Jqrd9Ozky9+HldGGr0VhRkAUneyhhT0HZsSoYcI6QRaYbA1+GkHNIWtPhhk
15
+ coSjhKBXJ2RduJi7eisCAwEAAaOB8DCB7TAdBgNVHQ4EFgQUb7yD7klC/K/sJCoK
16
+ SJjhWRvygsYwgb0GA1UdIwSBtTCBsoAUb7yD7klC/K/sJCoKSJjhWRvygsahgY6k
17
+ gYswgYgxCzAJBgNVBAYTAkFVMREwDwYDVQQIEwhWaWN0b3JpYTESMBAGA1UEBxMJ
18
+ TWVsYm91cm5lMRgwFgYDVQQKEw9QYWN0IEZvdW5kYXRpb24xFTATBgNVBAMTDEJl
19
+ dGggU2t1cnJpZTEhMB8GCSqGSIb3DQEJARYSYmV0aEBiZXRoZXNxdWUuY29tggkA
20
+ 6hHhxWIutgEwDAYDVR0TBAUwAwEB/zANBgkqhkiG9w0BAQUFAAOCAQEARThJZnP0
21
+ 21PjLxb0/RZ/W/Rl7qqp5jh6sxPTfdztDpfJHcQztmmXQhZaKmcPtqSp7zFKZKIC
22
+ D5b0n1lSKqf1bwxwcGQfBu1EAZMYBSNNRJsdMqqnaj76RFysOye4KXXMrCNJ0Md6
23
+ MEObX87XBWiKmy5ZbtfoqiWcHrsw9Bnl+9ZPwIaxndtlaaJbnAyKTP28Z8rltiva
24
+ kUxcmh37DpAjEBPMWgiD+pfVWhz54rNN7IqndIJhAE8Zphvq2RguMo6CgMbmwlcv
25
+ gf9w/hcz5FES3GA01bDmp9CVdGxWN+njcstuOOrVuFgdFR8z3WokPI4YsACXxIZc
26
+ 5R2NaXTfO9Mw2w==
27
+ -----END CERTIFICATE-----
28
+ -----BEGIN CERTIFICATE-----
29
+ MIIEXDCCA0SgAwIBAgIEOGO5ZjANBgkqhkiG9w0BAQUFADCBtDEUMBIGA1UEChML
30
+ RW50cnVzdC5uZXQxQDA+BgNVBAsUN3d3dy5lbnRydXN0Lm5ldC9DUFNfMjA0OCBp
31
+ bmNvcnAuIGJ5IHJlZi4gKGxpbWl0cyBsaWFiLikxJTAjBgNVBAsTHChjKSAxOTk5
32
+ IEVudHJ1c3QubmV0IExpbWl0ZWQxMzAxBgNVBAMTKkVudHJ1c3QubmV0IENlcnRp
33
+ ZmljYXRpb24gQXV0aG9yaXR5ICgyMDQ4KTAeFw05OTEyMjQxNzUwNTFaFw0xOTEy
34
+ MjQxODIwNTFaMIG0MRQwEgYDVQQKEwtFbnRydXN0Lm5ldDFAMD4GA1UECxQ3d3d3
35
+ LmVudHJ1c3QubmV0L0NQU18yMDQ4IGluY29ycC4gYnkgcmVmLiAobGltaXRzIGxp
36
+ YWIuKTElMCMGA1UECxMcKGMpIDE5OTkgRW50cnVzdC5uZXQgTGltaXRlZDEzMDEG
37
+ A1UEAxMqRW50cnVzdC5uZXQgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkgKDIwNDgp
38
+ MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEArU1LqRKGsuqjIAcVFmQq
39
+ K0vRvwtKTY7tgHalZ7d4QMBzQshowNtTK91euHaYNZOLGp18EzoOH1u3Hs/lJBQe
40
+ sYGpjX24zGtLA/ECDNyrpUAkAH90lKGdCCmziAv1h3edVc3kw37XamSrhRSGlVuX
41
+ MlBvPci6Zgzj/L24ScF2iUkZ/cCovYmjZy/Gn7xxGWC4LeksyZB2ZnuU4q941mVT
42
+ XTzWnLLPKQP5L6RQstRIzgUyVYr9smRMDuSYB3Xbf9+5CFVghTAp+XtIpGmG4zU/
43
+ HoZdenoVve8AjhUiVBcAkCaTvA5JaJG/+EfTnZVCwQ5N328mz8MYIWJmQ3DW1cAH
44
+ 4QIDAQABo3QwcjARBglghkgBhvhCAQEEBAMCAAcwHwYDVR0jBBgwFoAUVeSB0RGA
45
+ vtiJuQijMfmhJAkWuXAwHQYDVR0OBBYEFFXkgdERgL7YibkIozH5oSQJFrlwMB0G
46
+ CSqGSIb2fQdBAAQQMA4bCFY1LjA6NC4wAwIEkDANBgkqhkiG9w0BAQUFAAOCAQEA
47
+ WUesIYSKF8mciVMeuoCFGsY8Tj6xnLZ8xpJdGGQC49MGCBFhfGPjK50xA3B20qMo
48
+ oPS7mmNz7W3lKtvtFKkrxjYR0CvrB4ul2p5cGZ1WEvVUKcgF7bISKo30Axv/55IQ
49
+ h7A6tcOdBTcSo8f0FbnVpDkWm1M6I5HxqIKiaohowXkCIryqptau37AUX7iH0N18
50
+ f3v/rxzP5tsHrV7bhZ3QKw0z2wTR5klAEyt2+z7pnIkPFc4YsIV4IU9rTw76NmfN
51
+ B/L/CNDi3tm/Kq+4h4YhPATKt5Rof8886ZjXOP/swNlQ8C5LWK5Gb9Auw2DaclVy
52
+ vUxFnmG6v4SBkgPR0ml8xQ==
53
+ -----END CERTIFICATE-----
@@ -0,0 +1,21 @@
1
+ -----BEGIN CERTIFICATE-----
2
+ MIIDZDCCAkygAwIBAgIBATANBgkqhkiG9w0BAQsFADBCMRMwEQYKCZImiZPyLGQB
3
+ GRYDb3JnMRkwFwYKCZImiZPyLGQBGRYJcnVieS1sYW5nMRAwDgYDVQQDDAdSdWJ5
4
+ IENBMCAXDTE4MDEwODAwNTkyMloYDzIxMTcxMjE1MDA1OTIyWjBCMRMwEQYKCZIm
5
+ iZPyLGQBGRYDb3JnMRkwFwYKCZImiZPyLGQBGRYJcnVieS1sYW5nMRAwDgYDVQQD
6
+ DAdSdWJ5IENBMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAv5dZFUaE
7
+ +bvxnOGSNEg0DmAMnEFBK5xNV4dDQwe3qNBzvZZxcZ+Y/AefR6mPKx7MMbXFjS4j
8
+ BBGgs3fatBqGAbPlBnqUJqe+Oa/HRcrnM2SW6ipisX0PG1TjvJ1fTUXv8MAfBI5t
9
+ bnKyErs0Mbe+HugZAiTJSdWfbyKbxca1hBltoRYZP/NrYyMWM5n8qhzGu7K6bTGI
10
+ qtlnLJ5RD/BC7ze9SkWsPkWPP1WVGsuCqHkUfCBZkY+6qbWQHLBrFmIZYo6Ixk2y
11
+ Pk5Py4wRUNGkRTXDRLRyQMTX6TUKNod7J2/tXkAMLxPVbd52C0XHfnzw1DZIkE7k
12
+ DR7KxnL0tyBhkQIDAQABo2MwYTAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQE
13
+ AwIBBjAdBgNVHQ4EFgQUMrYg0IBY8mSqxL8TIjQM9Eiuox0wHwYDVR0jBBgwFoAU
14
+ MrYg0IBY8mSqxL8TIjQM9Eiuox0wDQYJKoZIhvcNAQELBQADggEBAHQIZ/nWUrf4
15
+ p34ZbWs3H7THSF4m3RlYcl+vf9ngP3peDw/SCTpuR2xlextUhJnpJFBIOoZHA+14
16
+ mxoPgufFhgdXdhsUvivoB7d6jlFz+mDZPVRrYEYfPGi+JeMukbfqIXC5rake4QCI
17
+ ENoo7MPVS4RWibqeN2x5sFXARKepi/GFm8jg5IqRH6Ctu4BJ/NB7wXPZn/wtNISR
18
+ 7m+hgN1u0+Wk4zLuUSsbHWkZeZKrvQuU8ZSInIiLFXnN4BgJ5QGnStTFdypxDtw7
19
+ Kb97JG0MWy6BGrLKaqkNtsX4xezSg4NlPZNJ4mNYZMQs3fHI2RKIwM3+klMtm8GF
20
+ qygx7MqK9bI=
21
+ -----END CERTIFICATE-----
@@ -0,0 +1,20 @@
1
+ -----BEGIN CERTIFICATE-----
2
+ MIIDMjCCAhqgAwIBAgIBAjANBgkqhkiG9w0BAQsFADBCMRMwEQYKCZImiZPyLGQB
3
+ GRYDb3JnMRkwFwYKCZImiZPyLGQBGRYJcnVieS1sYW5nMRAwDgYDVQQDDAdSdWJ5
4
+ IENBMB4XDTE4MDEwODAwNTkyM1oXDTE5MDEwODAwNTkyM1owRDETMBEGCgmSJomT
5
+ 8ixkARkWA29yZzEZMBcGCgmSJomT8ixkARkWCXJ1YnktbGFuZzESMBAGA1UEAwwJ
6
+ bG9jYWxob3N0MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAtjNCx+If
7
+ GDeaI1rxw6X09IxsaGg6TenO8FXo808yC+38VMePSHzrNlfGBh4GLRX9TV4dd9k2
8
+ hAWf/UpdvcucYjlKBdTGisY4ADbqlXcwJRbOk/Ag0W3al4u7WJ4EMRVZDGgif59y
9
+ Pz0b1jTcJFWmD98rZoRHzStDK+Ok+Ru1Rh7IIYSVsuhH+JivZxTrJDKZoAqMPgiO
10
+ txnzJX2LsZiT0cdH9zsefmYttkmMHUydCdhiGuFSNDzGXQeUlncZYAcxp6FIIZVg
11
+ Xs1ZY8Xwn3RsiNpkqAQrhXLX/NX+b5LnMerul9t2OE1thTyW6iz5X7P2RmtaGN5X
12
+ Ej65mg73lhc4VwIDAQABozEwLzAOBgNVHQ8BAf8EBAMCB4AwHQYDVR0OBBYEFIsz
13
+ dweRZTX0WpGJkWo5dG5GjUi5MA0GCSqGSIb3DQEBCwUAA4IBAQAt0WA5eWgCxRNs
14
+ yk5m1lJEEvcxb1LRBXRIZQQooAel2cq546NfVwE7XCvQBmM5eXcY4pEUFOdpcJWA
15
+ Wr2US7hiWDrN4XpZUtXAK5hBJXXzHaOmiAARZvfXMi0AwJqgtc7V/o+6j1VBMhMM
16
+ r3YXmn84FeSnbT5umjjuZ6qbZnSRxXU+g2Db4LqInEfdg8BOKvyPz5oyiEKIeRsK
17
+ FkdWx3f2Xn4As4DAR7sszdU0r0QiaAFpFoVbqV8glCqygcqv0UAmM1N2qUrf1u6x
18
+ SPI3WTZiiwH4Bb6N28gC0v80PEQEQXfb/0kJqrapKJU1hCb/PkrrQOIq7QAVb+lK
19
+ 6cnn0hrz
20
+ -----END CERTIFICATE-----
@@ -0,0 +1,27 @@
1
+ -----BEGIN RSA PRIVATE KEY-----
2
+ MIIEpAIBAAKCAQEAtjNCx+IfGDeaI1rxw6X09IxsaGg6TenO8FXo808yC+38VMeP
3
+ SHzrNlfGBh4GLRX9TV4dd9k2hAWf/UpdvcucYjlKBdTGisY4ADbqlXcwJRbOk/Ag
4
+ 0W3al4u7WJ4EMRVZDGgif59yPz0b1jTcJFWmD98rZoRHzStDK+Ok+Ru1Rh7IIYSV
5
+ suhH+JivZxTrJDKZoAqMPgiOtxnzJX2LsZiT0cdH9zsefmYttkmMHUydCdhiGuFS
6
+ NDzGXQeUlncZYAcxp6FIIZVgXs1ZY8Xwn3RsiNpkqAQrhXLX/NX+b5LnMerul9t2
7
+ OE1thTyW6iz5X7P2RmtaGN5XEj65mg73lhc4VwIDAQABAoIBAEOdeF33U3TIRaJz
8
+ QJ9LukD6z8xbSa/aYdqc9ys8K6Vztx27RTgwa5WqMynYAJDAxVTt5V+xs2KBN+Nm
9
+ sq0Zn7pv6kGJufiMIQIrXxkCt1I8SYNrLLKr4uA0kd0MHyAb/QT2rD7SbDJ9uhPf
10
+ YAb35f2j41ZTJtZEBNSH0ZRErRwM9bpOgkAReDoNlxkZpNz9KK988vTT5i/njtiQ
11
+ 9lSxbRgVFc/00LnFwd5IEAjX6uqIXqnsYCd5h8+B6YSFLCb5DVeHDP/Bb1/UFS6V
12
+ cttKpt06Q4BrG0d+SQ6AqgA3HhIUyet7fMsPAd70HSNft5O+h2S5m+6m3DazTCqd
13
+ g9eAf2kCgYEA5d8+SwWAL/1/HjRXVvYXB8z/cSMwYziDMiAl9g85zpJlSNuOWmdB
14
+ T4RgxDZOC/kMe29BNRLMykRKeD+JpIgFfydDAx1ykdyUcOWhAUmaS5cSeHH25Sng
15
+ ACYVINxTCIL/v9j/YjB54eXs3rdpsslnq+xISIoSerO7wTe2EPeoVKUCgYEAyujg
16
+ Mf+l9jKi6EWFfJ3URU4QL2lhKgMs80/uOLRyGSeSRPJoI/xMRSXxLVy/eh/+K6zN
17
+ zksXeDeqq0l6jzBDlgMl8Kc63hLdOkWXtFneGxfk0bBzcTZ5dZ0TET9+aWF4gMq9
18
+ NqT62Yu7wZe/6HBRy0U7iMrRLYSRXEv4+/Rk/EsCgYEAnLSMnc4ZLh4M+4VJCTJo
19
+ TtwUQ4dupCVRYumBl3WXvdgVDg8Gw2BiqJeg9AHlQMo+FSOp+0lerIDTl5gQ+EX2
20
+ IVGdoFEB2qfZ1gDkuqD3e5J4d/2RB3Z9ivxrKOSqAkJzoNCIgOJ1JGd/C/FTMBuW
21
+ /h/swu7FXDqMw1J8XqLGcTUCgYEAuXjuXaWCDS4x7MCHiOY3vvXhI4VetGlcsDdS
22
+ 2HBQjx+1uuIdQS+AhABvmPhbagVObpuxL61CEbhIf/NVXQdP8BKGnpgt3go+P+KX
23
+ DdrLg9ZuaSGyFD0n/tMKN8zi/u6CmK85D3b0eOAaSpYsbAonKffpuFszozi3Kjej
24
+ qqK1oEsCgYANLkfN2vldeLbu8JnY1moGFnss4hqE+0FV4VUFPob+4CgSNhnk1taS
25
+ Zgw0E8d54s/tiPLEb0PCWbc9gzgyhgh57V2FnPzeXz/X0swjQvkab1T/YO1DVWJ+
26
+ cYQZZ1ZngyQ6sZB7FIZO4CcurwpDk+czagofD7bt6B6UlOcN9J4cZA==
27
+ -----END RSA PRIVATE KEY-----
@@ -0,0 +1,21 @@
1
+ -----BEGIN CERTIFICATE-----
2
+ MIIDeTCCAmGgAwIBAgIJAIb7Tcjl3Q8YMA0GCSqGSIb3DQEBCwUAMGIxCzAJBgNV
3
+ BAYTAlVTMRMwEQYDVQQIDApDYWxpZm9ybmlhMRYwFAYDVQQHDA1TYW4gRnJhbmNp
4
+ c2NvMQ8wDQYDVQQKDAZCYWRTU0wxFTATBgNVBAMMDCouYmFkc3NsLmNvbTAeFw0x
5
+ NjA4MDgyMTE3MDVaFw0xODA4MDgyMTE3MDVaMGIxCzAJBgNVBAYTAlVTMRMwEQYD
6
+ VQQIDApDYWxpZm9ybmlhMRYwFAYDVQQHDA1TYW4gRnJhbmNpc2NvMQ8wDQYDVQQK
7
+ DAZCYWRTU0wxFTATBgNVBAMMDCouYmFkc3NsLmNvbTCCASIwDQYJKoZIhvcNAQEB
8
+ BQADggEPADCCAQoCggEBAMIE7PiM7gTCs9hQ1XBYzJMY61yoaEmwIrX5lZ6xKyx2
9
+ PmzAS2BMTOqytMAPgLaw+XLJhgL5XEFdEyt/ccRLvOmULlA3pmccYYz2QULFRtMW
10
+ hyefdOsKnRFSJiFzbIRMeVXk0WvoBj1IFVKtsyjbqv9u/2CVSndrOfEk0TG23U3A
11
+ xPxTuW1CrbV8/q71FdIzSOciccfCFHpsKOo3St/qbLVytH5aohbcabFXRNsKEqve
12
+ ww9HdFxBIuGa+RuT5q0iBikusbpJHAwnnqP7i/dAcgCskgjZjFeEU4EFy+b+a1SY
13
+ QCeFxxC7c3DvaRhBB0VVfPlkPz0sw6l865MaTIbRyoUCAwEAAaMyMDAwCQYDVR0T
14
+ BAIwADAjBgNVHREEHDAaggwqLmJhZHNzbC5jb22CCmJhZHNzbC5jb20wDQYJKoZI
15
+ hvcNAQELBQADggEBALW4pad52T7VNw2nFMjPH98ZJNAQQgWyr3H2KlZN6IFGsonO
16
+ nCC/Do8BPx6BnP3PFwovWMat1VvnRRoC8lw/30eEazWqBRGZWPz6LHTE3DNBJdc8
17
+ xz6mh8q9RJX/PAj+YYGNElTu6qj49YT0BEhMF4U+dTQ0G8y3x4WNfiu9pGqyrp8d
18
+ AzeidMfQ/pU01PpoPTDLvRDNkmMsABNE1fXBfJxDDGwfq1xY1j23Fm6BolwZC2y7
19
+ n19h+vMYVWbGoovrf2/ibTvtcTyfDop7gl5Yy3OncZxokFj21rUZpLgx9ea4a9z3
20
+ FzEz5ufynq03RhHTE1eu+gDzMEF0GNhGGsKqeA4=
21
+ -----END CERTIFICATE-----
@@ -1,4 +1,7 @@
1
1
  {
2
2
  "success": true,
3
- "providerApplicationVersion": "4.5.6"
3
+ "providerApplicationVersion": "4.5.6",
4
+ "testResults": {
5
+ "some": "results"
6
+ }
4
7
  }
@@ -1,4 +1,7 @@
1
1
  {
2
+ "events": [{
3
+ "name": "something_happened"
4
+ }],
2
5
  "request": {
3
6
  "method": "POST",
4
7
  "url": "http://some.url",
@@ -0,0 +1,80 @@
1
+ require 'pact_broker/domain/webhook_request'
2
+
3
+ describe "executing a webhook to a server with a self signed certificate" do
4
+ let(:td) { TestDataBuilder.new }
5
+ before(:all) do
6
+ @pipe = IO.popen("bundle exec ruby spec/support/ssl_webhook_server.rb")
7
+ sleep 2
8
+ end
9
+
10
+ let(:webhook_request) do
11
+ PactBroker::Domain::WebhookRequest.new(
12
+ method: 'get',
13
+ url: 'https://localhost:4444')
14
+ end
15
+
16
+ let(:pact) { td.create_pact_with_hierarchy.and_return(:pact) }
17
+
18
+ subject { webhook_request.execute(pact) }
19
+
20
+ context "without the correct cacert" do
21
+ it "fails" do
22
+ expect(subject.success?).to be false
23
+ end
24
+ end
25
+
26
+ context "with the correct cacert" do
27
+ let!(:certificate) do
28
+ td.create_certificate(path: 'spec/fixtures/certificates/cacert.pem')
29
+ end
30
+
31
+ it "succeeds" do
32
+ puts subject.error unless subject.success?
33
+ expect(subject.success?).to be true
34
+ end
35
+ end
36
+
37
+ after(:all) do
38
+ Process.kill 'KILL', @pipe.pid
39
+ end
40
+ end
41
+
42
+ # Code to generate certificates
43
+ # root_key = OpenSSL::PKey::RSA.new 2048 # the CA's public/private key
44
+ # root_ca = OpenSSL::X509::Certificate.new
45
+ # root_ca.version = 2 # cf. RFC 5280 - to make it a "v3" certificate
46
+ # root_ca.serial = 1
47
+ # root_ca.subject = OpenSSL::X509::Name.parse "/DC=org/DC=ruby-lang/CN=Ruby CA"
48
+ # root_ca.issuer = root_ca.subject # root CA's are "self-signed"
49
+ # root_ca.public_key = root_key.public_key
50
+ # root_ca.not_before = Time.now
51
+ # root_ca.not_after = root_ca.not_before + 100 * 365 * 24 * 60 * 60 # 100 years validity
52
+ # ef = OpenSSL::X509::ExtensionFactory.new
53
+ # ef.subject_certificate = root_ca
54
+ # ef.issuer_certificate = root_ca
55
+ # root_ca.add_extension(ef.create_extension("basicConstraints","CA:TRUE",true))
56
+ # root_ca.add_extension(ef.create_extension("keyUsage","keyCertSign, cRLSign", true))
57
+ # root_ca.add_extension(ef.create_extension("subjectKeyIdentifier","hash",false))
58
+ # root_ca.add_extension(ef.create_extension("authorityKeyIdentifier","keyid:always",false))
59
+ # root_ca.sign(root_key, OpenSSL::Digest::SHA256.new)
60
+ # puts root_ca.to_pem
61
+ # File.open("spec/fixtures/certificates/cacert.pem", "w") { |file| file << root_ca.to_pem }
62
+
63
+ # key = OpenSSL::PKey::RSA.new 2048
64
+ # cert = OpenSSL::X509::Certificate.new
65
+ # cert.version = 2
66
+ # cert.serial = 2
67
+ # cert.subject = OpenSSL::X509::Name.parse "/DC=org/DC=ruby-lang/CN=Ruby certificate"
68
+ # cert.issuer = root_ca.subject # root CA is the issuer
69
+ # cert.public_key = key.public_key
70
+ # cert.not_before = Time.now
71
+ # cert.not_after = cert.not_before + 1 * 365 * 24 * 60 * 60 # 1 years validity
72
+ # ef = OpenSSL::X509::ExtensionFactory.new
73
+ # ef.subject_certificate = cert
74
+ # ef.issuer_certificate = root_ca
75
+ # cert.add_extension(ef.create_extension("keyUsage","digitalSignature", true))
76
+ # cert.add_extension(ef.create_extension("subjectKeyIdentifier","hash",false))
77
+ # cert.sign(root_key, OpenSSL::Digest::SHA256.new)
78
+ # puts cert.to_pem
79
+ # File.open("spec/fixtures/certificates/cert.pem", "w") { |file| file << cert.to_pem }
80
+ # File.open("spec/fixtures/certificates/key.pem", "w") { |file| file << key.to_pem }
@@ -37,6 +37,26 @@ module PactBroker
37
37
  end
38
38
  end
39
39
 
40
+ context "with no events defined" do
41
+ let(:json) { {}.to_json }
42
+
43
+ it "does not contain an error for missing event, as it will be defaulted" do
44
+ expect(subject.errors.messages[:events]).to be nil
45
+ end
46
+ end
47
+
48
+ context "with empty events" do
49
+ let(:json) do
50
+ valid_webhook_with do |hash|
51
+ hash['events'] = []
52
+ end
53
+ end
54
+
55
+ it "contains an error for missing request" do
56
+ expect(subject.errors[:events]).to eq ["size cannot be less than 1"]
57
+ end
58
+ end
59
+
40
60
  context "with no method" do
41
61
  let(:json) do
42
62
  valid_webhook_with do |hash|
@@ -11,7 +11,7 @@ module PactBroker
11
11
 
12
12
  let(:triggered_webhook) do
13
13
  double('PactBroker::Webhooks::TriggeredWebhook',
14
- trigger_type: PactBroker::Webhooks::TriggeredWebhook::TRIGGER_TYPE_PUBLICATION,
14
+ trigger_type: PactBroker::Webhooks::TriggeredWebhook::TRIGGER_TYPE_RESOURCE_CREATION,
15
15
  status: status,
16
16
  failure?: failure,
17
17
  retrying?: retrying,
@@ -61,7 +61,7 @@ module PactBroker
61
61
  it "includes the triggered webhooks properties" do
62
62
  expect(subject[:_embedded][:triggeredWebhooks].first).to include(
63
63
  status: 'success',
64
- triggerType: 'pact_publication',
64
+ triggerType: 'resource_creation',
65
65
  attemptsMade: 1,
66
66
  attemptsRemaining: 2
67
67
  )