pact_broker 2.4.2 → 2.5.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (156) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +3 -0
  3. data/.travis.yml +4 -2
  4. data/CHANGELOG.md +54 -0
  5. data/DEVELOPER_DOCUMENTATION.md +11 -7
  6. data/README.md +5 -1
  7. data/UPGRADING.md +18 -0
  8. data/db/migrations/19_make_pact_version_content_sha_not_nullable.rb +9 -1
  9. data/db/migrations/25_make_pv_pacticipants_mandatory.rb +8 -0
  10. data/db/migrations/38_create_triggered_webhooks_table.rb +19 -0
  11. data/db/migrations/39_add_triggered_webhooks_fk_to_execution.rb +24 -0
  12. data/db/migrations/40_create_latest_triggered_webhooks_view.rb +24 -0
  13. data/db/migrations/41_migrate_execution_data.rb +47 -0
  14. data/db/test/backwards_compatibility/.rspec +3 -0
  15. data/db/test/backwards_compatibility/Appraisals +49 -0
  16. data/db/test/backwards_compatibility/Gemfile +11 -0
  17. data/db/test/backwards_compatibility/Rakefile +55 -0
  18. data/db/test/backwards_compatibility/config.ru +18 -0
  19. data/db/test/backwards_compatibility/gemfiles/1.18.0.gemfile +14 -0
  20. data/db/test/backwards_compatibility/gemfiles/1.18.0.gemfile.lock +210 -0
  21. data/db/test/backwards_compatibility/gemfiles/2.0.0.gemfile +14 -0
  22. data/db/test/backwards_compatibility/gemfiles/2.0.0.gemfile.lock +208 -0
  23. data/db/test/backwards_compatibility/gemfiles/2.1.0.gemfile +14 -0
  24. data/db/test/backwards_compatibility/gemfiles/2.1.0.gemfile.lock +209 -0
  25. data/db/test/backwards_compatibility/gemfiles/2.2.0.gemfile +14 -0
  26. data/db/test/backwards_compatibility/gemfiles/2.2.0.gemfile.lock +197 -0
  27. data/db/test/backwards_compatibility/gemfiles/2.3.0.gemfile +13 -0
  28. data/db/test/backwards_compatibility/gemfiles/2.3.0.gemfile.lock +196 -0
  29. data/db/test/backwards_compatibility/gemfiles/2.4.2.gemfile +13 -0
  30. data/db/test/backwards_compatibility/gemfiles/2.4.2.gemfile.lock +196 -0
  31. data/db/test/backwards_compatibility/gemfiles/head.gemfile +13 -0
  32. data/db/test/backwards_compatibility/gemfiles/head.gemfile.lock +200 -0
  33. data/db/test/backwards_compatibility/spec/fixtures/foo-bar.json +22 -0
  34. data/db/test/backwards_compatibility/spec/publish_pact_spec.rb +72 -0
  35. data/db/test/backwards_compatibility/spec/spec_helper.rb +20 -0
  36. data/db/test/backwards_compatibility/spec/support/fixture_helpers.rb +12 -0
  37. data/db/test/backwards_compatibility/spec/support/request_helpers.rb +20 -0
  38. data/example/Gemfile +2 -2
  39. data/example/pact_broker_database.sqlite3 +0 -0
  40. data/lib/pact_broker/api/decorators/pact_collection_decorator.rb +1 -2
  41. data/lib/pact_broker/api/decorators/pact_decorator.rb +12 -10
  42. data/lib/pact_broker/api/decorators/pact_versions_decorator.rb +1 -2
  43. data/lib/pact_broker/api/decorators/pact_webhooks_status_decorator.rb +123 -0
  44. data/lib/pact_broker/api/decorators/versions_decorator.rb +17 -6
  45. data/lib/pact_broker/api/decorators/webhook_decorator.rb +8 -10
  46. data/lib/pact_broker/api/decorators/webhooks_decorator.rb +0 -1
  47. data/lib/pact_broker/api/pact_broker_urls.rb +13 -1
  48. data/lib/pact_broker/api/renderers/html_pact_renderer.rb +47 -3
  49. data/lib/pact_broker/api/resources/badge.rb +3 -3
  50. data/lib/pact_broker/api/resources/base_resource.rb +1 -1
  51. data/lib/pact_broker/api/resources/latest_pact.rb +5 -1
  52. data/lib/pact_broker/api/resources/pact.rb +5 -1
  53. data/lib/pact_broker/api/resources/pact_webhooks_status.rb +61 -0
  54. data/lib/pact_broker/api/resources/triggered_webhook_logs.rb +36 -0
  55. data/lib/pact_broker/api/resources/webhook.rb +31 -3
  56. data/lib/pact_broker/api/resources/webhook_execution.rb +12 -2
  57. data/lib/pact_broker/api.rb +3 -0
  58. data/lib/pact_broker/app.rb +11 -3
  59. data/lib/pact_broker/badges/service.rb +26 -5
  60. data/lib/pact_broker/configuration.rb +12 -5
  61. data/lib/pact_broker/constants.rb +1 -1
  62. data/lib/pact_broker/diagnostic/resources/heartbeat.rb +1 -2
  63. data/lib/pact_broker/doc/views/pact-webhooks.markdown +1 -1
  64. data/lib/pact_broker/doc/views/webhooks-webhooks.markdown +1 -1
  65. data/lib/pact_broker/doc/views/webhooks.markdown +1 -1
  66. data/lib/pact_broker/domain/relationship.rb +13 -4
  67. data/lib/pact_broker/domain/verification.rb +0 -4
  68. data/lib/pact_broker/domain/webhook.rb +2 -6
  69. data/lib/pact_broker/domain/webhook_execution_result.rb +1 -2
  70. data/lib/pact_broker/domain/webhook_request.rb +59 -40
  71. data/lib/pact_broker/pacticipants/service.rb +4 -3
  72. data/lib/pact_broker/pacts/repository.rb +8 -0
  73. data/lib/pact_broker/pacts/service.rb +2 -0
  74. data/lib/pact_broker/services.rb +1 -1
  75. data/lib/pact_broker/ui/view_models/relationship.rb +29 -2
  76. data/lib/pact_broker/ui/views/relationships/show.haml +7 -10
  77. data/lib/pact_broker/verifications/repository.rb +8 -1
  78. data/lib/pact_broker/version.rb +1 -1
  79. data/lib/pact_broker/webhooks/execution.rb +25 -4
  80. data/lib/pact_broker/webhooks/job.rb +55 -13
  81. data/lib/pact_broker/webhooks/latest_triggered_webhook.rb +9 -0
  82. data/lib/pact_broker/webhooks/redact_logs.rb +10 -0
  83. data/lib/pact_broker/webhooks/repository.rb +76 -8
  84. data/lib/pact_broker/webhooks/service.rb +48 -8
  85. data/lib/pact_broker/webhooks/status.rb +29 -0
  86. data/lib/pact_broker/webhooks/triggered_webhook.rb +96 -0
  87. data/lib/pact_broker/webhooks/webhook.rb +19 -8
  88. data/lib/rack/pact_broker/database_transaction.rb +9 -3
  89. data/pact_broker.gemspec +3 -3
  90. data/public/javascripts/pact.js +5 -0
  91. data/public/stylesheets/pact.css +14 -1
  92. data/public/stylesheets/relationships.css +0 -1
  93. data/script/db-spec.sh +7 -0
  94. data/script/seed.rb +13 -8
  95. data/spec/features/create_webhook_spec.rb +1 -1
  96. data/spec/features/delete_pact_spec.rb +5 -1
  97. data/spec/features/delete_webhook_spec.rb +2 -1
  98. data/spec/features/edit_webhook_spec.rb +61 -0
  99. data/spec/features/execute_webhook_spec.rb +73 -0
  100. data/spec/features/get_latest_pact_badge_spec.rb +1 -1
  101. data/spec/features/get_latest_tagged_pact_badge_spec.rb +1 -1
  102. data/spec/features/get_latest_untagged_pact_badge_spec.rb +1 -1
  103. data/spec/features/get_pact_spec.rb +1 -1
  104. data/spec/features/merge_pact_spec.rb +1 -1
  105. data/spec/features/publish_pact_spec.rb +1 -1
  106. data/spec/integration/app_spec.rb +1 -1
  107. data/spec/integration/endpoints/group.rb +1 -1
  108. data/spec/lib/pact_broker/api/decorators/latest_pact_decorator_spec.rb +2 -1
  109. data/spec/lib/pact_broker/api/decorators/pact_decorator_spec.rb +8 -6
  110. data/spec/lib/pact_broker/api/decorators/pact_webhooks_status_decorator_spec.rb +134 -0
  111. data/spec/lib/pact_broker/api/decorators/relationships_csv_decorator_spec.rb +1 -1
  112. data/spec/lib/pact_broker/api/decorators/representable_pact_spec.rb +1 -1
  113. data/spec/lib/pact_broker/api/renderers/html_pact_renderer_spec.rb +27 -1
  114. data/spec/lib/pact_broker/api/resources/badge_spec.rb +32 -15
  115. data/spec/lib/pact_broker/api/resources/base_resource_spec.rb +17 -0
  116. data/spec/lib/pact_broker/api/resources/latest_pact_spec.rb +5 -3
  117. data/spec/lib/pact_broker/api/resources/pact_spec.rb +9 -2
  118. data/spec/lib/pact_broker/api/resources/triggered_webhook_logs_spec.rb +28 -0
  119. data/spec/lib/pact_broker/api/resources/webhook_execution_spec.rb +15 -5
  120. data/spec/lib/pact_broker/api/resources/webhook_spec.rb +43 -31
  121. data/spec/lib/pact_broker/app_spec.rb +12 -8
  122. data/spec/lib/pact_broker/badges/service_spec.rb +15 -1
  123. data/spec/lib/pact_broker/configuration_spec.rb +3 -2
  124. data/spec/lib/pact_broker/domain/relationship_spec.rb +24 -0
  125. data/spec/lib/pact_broker/domain/webhook_request_spec.rb +47 -31
  126. data/spec/lib/pact_broker/domain/webhook_spec.rb +4 -6
  127. data/spec/lib/pact_broker/pacticipants/service_spec.rb +16 -1
  128. data/spec/lib/pact_broker/pacts/repository_spec.rb +22 -1
  129. data/spec/lib/pact_broker/pacts/service_spec.rb +32 -1
  130. data/spec/lib/pact_broker/ui/view_models/relationship_spec.rb +44 -0
  131. data/spec/lib/pact_broker/verifications/repository_spec.rb +19 -0
  132. data/spec/lib/pact_broker/verifications/service_spec.rb +1 -1
  133. data/spec/lib/pact_broker/webhooks/job_spec.rb +80 -19
  134. data/spec/lib/pact_broker/webhooks/redact_logs_spec.rb +49 -0
  135. data/spec/lib/pact_broker/webhooks/repository_spec.rb +271 -21
  136. data/spec/lib/pact_broker/webhooks/service_spec.rb +70 -3
  137. data/spec/lib/pact_broker/webhooks/status_spec.rb +48 -0
  138. data/spec/lib/pact_broker/webhooks/triggered_webhook_spec.rb +40 -0
  139. data/spec/lib/rack/pact_broker/database_transaction_spec.rb +14 -4
  140. data/spec/migrations/23_pact_versions_spec.rb +8 -30
  141. data/spec/migrations/24_populate_pact_contents_spec.rb +3 -21
  142. data/spec/migrations/34_latest_tagged_pacts_spec.rb +1 -17
  143. data/spec/migrations/34_pact_revisions_spec.rb +7 -23
  144. data/spec/migrations/41_migrate_execution_data_spec.rb +109 -0
  145. data/spec/service_consumers/pact_helper.rb +5 -1
  146. data/spec/spec_helper.rb +15 -7
  147. data/spec/support/database_cleaner.rb +15 -2
  148. data/spec/support/migration_helpers.rb +16 -0
  149. data/spec/support/test_data_builder.rb +41 -9
  150. data/tasks/database.rb +7 -2
  151. data/tasks/db.rake +10 -0
  152. data/tasks/rspec.rake +1 -1
  153. data/vendor/hal-browser/browser.html +3 -2
  154. data/vendor/hal-browser/js/hal/resource.js +16 -2
  155. metadata +72 -13
  156. data/script/record_verification.sh +0 -4
@@ -0,0 +1,48 @@
1
+ require 'pact_broker/webhooks/status'
2
+
3
+ module PactBroker
4
+ module Webhooks
5
+ describe Status do
6
+ let(:webhooks) { [double('webhook')]}
7
+ let(:latest_triggered_webhooks) { [ triggered_webhook_1, triggered_webhook_2] }
8
+ let(:pact) { double('pact') }
9
+ let(:triggered_webhook_1) { double('triggered_webhook', status: status_1) }
10
+ let(:triggered_webhook_2) { double('triggered_webhook', status: status_2) }
11
+ let(:status_1) { TriggeredWebhook::STATUS_SUCCESS }
12
+ let(:status_2) { TriggeredWebhook::STATUS_SUCCESS }
13
+
14
+ subject { Status.new(pact, webhooks, latest_triggered_webhooks) }
15
+
16
+ context "when there are no webhooks configured" do
17
+ let(:webhooks) { [] }
18
+ its(:to_sym) { is_expected.to eq :none }
19
+ end
20
+
21
+ context "when there are webhooks, but no triggered webhooks" do
22
+ let(:latest_triggered_webhooks) { [] }
23
+ its(:to_sym) { is_expected.to eq :not_run }
24
+ end
25
+
26
+ context "when the most recent triggered webhooks are successful" do
27
+ its(:to_sym) { is_expected.to eq :success }
28
+ end
29
+
30
+ context "when one of the most recent executions is a failure" do
31
+ let(:status_1) { TriggeredWebhook::STATUS_FAILURE }
32
+ its(:to_sym) { is_expected.to eq :failure }
33
+ end
34
+
35
+ context "when one of the most recent executions is a failure and one is retrying" do
36
+ let(:status_1) { TriggeredWebhook::STATUS_FAILURE }
37
+ let(:status_2) { TriggeredWebhook::STATUS_RETRYING }
38
+ its(:to_sym) { is_expected.to eq :retrying }
39
+ end
40
+
41
+ context "when the most recent executions are failures" do
42
+ let(:status_1) { TriggeredWebhook::STATUS_FAILURE }
43
+ let(:status_2) { TriggeredWebhook::STATUS_FAILURE }
44
+ its(:to_sym) { is_expected.to eq :failure }
45
+ end
46
+ end
47
+ end
48
+ end
@@ -0,0 +1,40 @@
1
+ require 'pact_broker/webhooks/triggered_webhook'
2
+
3
+ module PactBroker
4
+ module Webhooks
5
+ describe TriggeredWebhook do
6
+ let(:status) { TriggeredWebhook::STATUS_SUCCESS }
7
+
8
+ subject { TriggeredWebhook.new(status: status) }
9
+
10
+ describe "remaining_attempts" do
11
+ before do
12
+ PactBroker.configuration.webhook_retry_schedule = [1, 1, 1]
13
+ allow(subject).to receive(:webhook_executions).and_return([double('execution')])
14
+ end
15
+
16
+ its(:number_of_attempts_made) { is_expected.to eq 1 }
17
+
18
+ context "when its status is retrying" do
19
+ let(:status) { TriggeredWebhook::STATUS_RETRYING }
20
+ its(:number_of_attempts_remaining) { is_expected.to eq 3 }
21
+ end
22
+
23
+ context "when its status is not_run" do
24
+ let(:status) { TriggeredWebhook::STATUS_NOT_RUN }
25
+ its(:number_of_attempts_remaining) { is_expected.to eq 3 }
26
+ end
27
+
28
+ context "when its status is success" do
29
+ let(:status) { TriggeredWebhook::STATUS_SUCCESS }
30
+ its(:number_of_attempts_remaining) { is_expected.to eq 0}
31
+ end
32
+
33
+ context "when its status is failure" do
34
+ let(:status) { TriggeredWebhook::STATUS_FAILURE }
35
+ its(:number_of_attempts_remaining) { is_expected.to eq 0}
36
+ end
37
+ end
38
+ end
39
+ end
40
+ end
@@ -13,20 +13,21 @@ module Rack
13
13
  ::PactBroker::Database.truncate
14
14
  end
15
15
 
16
+ let(:headers) { {} }
17
+
16
18
  let(:api) do
17
- ->(env) { ::PactBroker::Domain::Pacticipant.create(name: 'Foo'); [500, {}, []] }
19
+ ->(env) { ::PactBroker::Domain::Pacticipant.create(name: 'Foo'); [500, headers, []] }
18
20
  end
19
21
 
20
- let(:api_with_transaction) do
22
+ let(:app) do
21
23
  ::Rack::PactBroker::DatabaseTransaction.new(api, ::PactBroker::DB.connection)
22
24
  end
23
25
 
24
26
  subject { self.send(http_method, "/") }
25
27
 
26
28
  context "for get requests" do
27
- let(:app) { api_with_transaction }
28
-
29
29
  let(:http_method) { :get }
30
+
30
31
  it "does not use a transaction" do
31
32
  expect { subject }.to change { ::PactBroker::Domain::Pacticipant.count }.by(1)
32
33
  end
@@ -40,6 +41,15 @@ module Rack
40
41
  end
41
42
  end
42
43
  end
44
+
45
+ context "when there is an error but the resource sets the no rollback header" do
46
+ let(:headers) { {::PactBroker::DO_NOT_ROLLBACK => 'true'} }
47
+ let(:http_method) { :post }
48
+
49
+ it "does not roll back" do
50
+ expect { subject }.to change { ::PactBroker::Domain::Pacticipant.count }.by(1)
51
+ end
52
+ end
43
53
  end
44
54
  end
45
55
  end
@@ -1,20 +1,5 @@
1
- require 'tasks/database'
2
-
3
- describe 'migrate to pact versions (migrate 22-31)', no_db_clean: :true do
4
-
5
- def create table_name, params, id_column_name = :id
6
- database[table_name].insert(params);
7
- database[table_name].order(id_column_name).last
8
- end
9
-
10
- def clean table_name
11
- database[table_name].delete rescue puts "Error cleaning #{table_name} #{$!}"
12
- end
13
-
14
- let(:database) { DB.connection_for_env 'test' }
15
-
1
+ describe 'migrate to pact versions (migrate 22-31)', migration: true do
16
2
  before do
17
- PactBroker::Database.drop_objects
18
3
  PactBroker::Database.migrate(22)
19
4
  end
20
5
 
@@ -29,22 +14,20 @@ describe 'migrate to pact versions (migrate 22-31)', no_db_clean: :true do
29
14
  let!(:pact_2) { create(:pacts, {version_id: consumer_version_2[:id], provider_id: provider[:id], pact_version_content_sha: '1234', created_at: now, updated_at: pact_updated_at}) }
30
15
 
31
16
 
32
- let(:do_migration) do
33
- PactBroker::Database.migrate(34)
34
- end
17
+ subject { PactBroker::Database.migrate(34) }
35
18
 
36
19
  it "keeps the same number of pacts" do
37
- do_migration
20
+ subject
38
21
  expect(database[:latest_pact_publications_by_consumer_versions].count).to eq 2
39
22
  end
40
23
 
41
24
  it "uses the old updated date for the new creation date" do
42
- do_migration
25
+ subject
43
26
  expect(database[:latest_pact_publications_by_consumer_versions].order(:id).first[:created_at].to_datetime).to eq pact_updated_at
44
27
  end
45
28
 
46
29
  it "sets each revision number to 1" do
47
- do_migration
30
+ subject
48
31
  expect(database[:latest_pact_publications_by_consumer_versions].order(:id).first[:revision_number]).to eq 1
49
32
  expect(database[:latest_pact_publications_by_consumer_versions].order(:id).last[:revision_number]).to eq 1
50
33
  end
@@ -56,7 +39,7 @@ describe 'migrate to pact versions (migrate 22-31)', no_db_clean: :true do
56
39
  old_all_pact.delete(:created_at)
57
40
  old_all_pact.delete(:created_at)
58
41
  old_all_pact[:pact_version_sha] = old_all_pact.delete(:pact_version_content_sha)
59
- do_migration
42
+ subject
60
43
  database[:latest_pact_publications_by_consumer_versions]
61
44
  new_all_pact = database[:latest_pact_publications_by_consumer_versions].order(:id).first
62
45
  new_all_pact.delete(:created_at)
@@ -70,7 +53,7 @@ describe 'migrate to pact versions (migrate 22-31)', no_db_clean: :true do
70
53
  old_all_pact.delete(:updated_at)
71
54
  old_all_pact.delete(:created_at)
72
55
  old_all_pact[:pact_version_sha] = old_all_pact.delete(:pact_version_content_sha)
73
- do_migration
56
+ subject
74
57
  new_all_pact = database[:latest_pact_publications_by_consumer_versions].order(:id).last
75
58
  new_all_pact.delete(:created_at)
76
59
  new_all_pact.delete(:revision_number)
@@ -79,15 +62,10 @@ describe 'migrate to pact versions (migrate 22-31)', no_db_clean: :true do
79
62
  end
80
63
 
81
64
  it "allows a new pact to be inserted with no duplicate ID error" do
82
- do_migration
65
+ subject
83
66
 
84
67
  PactBroker::Pacts::Service.create_or_update_pact(
85
68
  consumer_id: consumer[:id], provider_id: provider[:id], consumer_version_number: '1.2.3', json_content: load_fixture('a_consumer-a_provider.json')
86
69
  )
87
70
  end
88
-
89
- after do
90
- PactBroker::Database.migrate
91
- PactBroker::Database.truncate
92
- end
93
71
  end
@@ -1,16 +1,5 @@
1
- require 'tasks/database'
2
-
3
- describe 'migrate to pact versions (migrate 22-24)', no_db_clean: :true do
4
-
5
- def create table_name, params, id_column_name = :id
6
- database[table_name].insert(params);
7
- database[table_name].order(id_column_name).last
8
- end
9
-
10
- let(:database) { DB.connection_for_env 'test' }
11
-
1
+ describe 'migrate to pact versions (migrate 22-24)', migration: true do
12
2
  before do
13
- PactBroker::Database.drop_objects
14
3
  PactBroker::Database.migrate(22)
15
4
  end
16
5
 
@@ -24,17 +13,10 @@ describe 'migrate to pact versions (migrate 22-24)', no_db_clean: :true do
24
13
 
25
14
  let!(:pact_version_content_orphan) { create(:pact_version_contents, {content: {some: 'json'}.to_json, sha: '4567', created_at: now, updated_at: now}, :sha) }
26
15
 
27
- let(:do_migration) do
28
- PactBroker::Database.migrate(34)
29
- end
16
+ subject { PactBroker::Database.migrate(34) }
30
17
 
31
18
  it "deletes orphan pact_versions" do
32
- do_migration
19
+ subject
33
20
  expect(database[:pact_versions].count).to eq 1
34
21
  end
35
-
36
- after do
37
- PactBroker::Database.migrate
38
- PactBroker::Database.truncate
39
- end
40
22
  end
@@ -1,16 +1,5 @@
1
- require 'tasks/database'
2
-
3
- describe 'using pact publications (migrate 31-32)', no_db_clean: :true do
4
-
5
- def create table_name, params, id_column_name = :id
6
- database[table_name].insert(params);
7
- database[table_name].order(id_column_name).last
8
- end
9
-
10
- let(:database) { DB.connection_for_env 'test' }
11
-
1
+ describe 'using pact publications (migrate 31-32)', migration: true do
12
2
  before do
13
- PactBroker::Database.drop_objects
14
3
  PactBroker::Database.migrate(34)
15
4
  end
16
5
 
@@ -92,9 +81,4 @@ describe 'using pact publications (migrate 31-32)', no_db_clean: :true do
92
81
  expect(database[:latest_tagged_pact_publications].order(:id).first).to_not have_key(:updated_at)
93
82
  end
94
83
  end
95
-
96
- after do
97
- PactBroker::Database.migrate
98
- PactBroker::Database.truncate
99
- end
100
84
  end
@@ -1,16 +1,5 @@
1
- require 'tasks/database'
2
-
3
- describe 'using pact publications (migrate 31-32)', no_db_clean: :true do
4
-
5
- def create table_name, params, id_column_name = :id
6
- database[table_name].insert(params);
7
- database[table_name].order(id_column_name).last
8
- end
9
-
10
- let(:database) { DB.connection_for_env 'test' }
11
-
1
+ describe 'using pact publications (migrate 31-32)', migration: true do
12
2
  before do
13
- PactBroker::Database.drop_objects
14
3
  PactBroker::Database.migrate(33)
15
4
  end
16
5
 
@@ -30,28 +19,28 @@ describe 'using pact publications (migrate 31-32)', no_db_clean: :true do
30
19
  let!(:pact_version_content_2) { create(:pact_versions, {content: {some: 'json'}.to_json, sha: '4567', consumer_id: consumer_2[:id], provider_id: provider_2[:id], created_at: now}) }
31
20
  let!(:pact_version_3_revision_1) { create(:pact_publications, {consumer_version_id: consumer_version_3[:id], provider_id: provider_2[:id], pact_version_id: pact_version_content_2[:id], created_at: now, revision_number: 1}) }
32
21
 
33
- let(:do_migration) do
22
+ subject do
34
23
  PactBroker::Database.migrate(34)
35
24
  database.schema(:latest_pact_publication_revision_numbers, reload: true)
36
25
  end
37
26
 
38
27
  describe "all_pact_publications" do
39
28
  it "has a row for every revision" do
40
- do_migration
29
+ subject
41
30
  expect(database[:all_pact_publications].count).to eq 4
42
31
  end
43
32
  end
44
33
 
45
34
  describe "latest_pact_publications_by_consumer_versions" do
46
35
  it "has a row for every pact" do
47
- do_migration
36
+ subject
48
37
  expect(database[:latest_pact_publications_by_consumer_versions].count).to eq 3
49
38
  end
50
39
  end
51
40
 
52
41
  describe "latest_pact_publication_revision_numbers" do
53
42
  it "contains the latest revision number for each consumer version" do
54
- do_migration
43
+ subject
55
44
  expect(database[:latest_pact_publication_revision_numbers].where(
56
45
  provider_id: provider_1[:id], consumer_id: consumer_1[:id],
57
46
  consumer_version_order: 1, latest_revision_number: 1
@@ -72,7 +61,7 @@ describe 'using pact publications (migrate 31-32)', no_db_clean: :true do
72
61
 
73
62
  describe "latest_pact_consumer_version_orders" do
74
63
  it "contains the latest consumer version for each consumer/provider pair" do
75
- do_migration
64
+ subject
76
65
  expect(database[:latest_pact_consumer_version_orders].count).to eq 2
77
66
  expect(database[:latest_pact_consumer_version_orders].where(
78
67
  provider_id: provider_1[:id], consumer_id: consumer_1[:id],
@@ -85,14 +74,9 @@ describe 'using pact publications (migrate 31-32)', no_db_clean: :true do
85
74
 
86
75
  describe "latest_pact_publications" do
87
76
  it "only contains the latest revision of the pact for the latest consumer version" do
88
- do_migration
77
+ subject
89
78
  expect(database[:latest_pact_publications].count).to eq 2
90
79
  expect(database[:latest_pact_publications].where(provider_id: provider_1[:id], consumer_id: consumer_1[:id]).count).to eq 1
91
80
  end
92
81
  end
93
-
94
- after do
95
- PactBroker::Database.migrate
96
- PactBroker::Database.truncate
97
- end
98
82
  end
@@ -0,0 +1,109 @@
1
+ describe 'creating triggered webhooks from webhook executions (migrate 36-41)', migration: true do
2
+ before do
3
+ PactBroker::Database.migrate(36)
4
+ end
5
+
6
+ let(:before_now) { DateTime.new(2016, 1, 1) }
7
+ let(:now) { DateTime.new(2018, 2, 2) }
8
+ let(:consumer) { create(:pacticipants, {name: 'Consumer', created_at: now, updated_at: now}) }
9
+ let(:provider) { create(:pacticipants, {name: 'Provider', created_at: now, updated_at: now}) }
10
+ let(:consumer_version) { create(:versions, {number: '1.2.3', order: 1, pacticipant_id: consumer[:id], created_at: now, updated_at: now}) }
11
+ let(:pact_version) { create(:pact_versions, {content: {some: 'json'}.to_json, sha: '1234', consumer_id: consumer[:id], provider_id: provider[:id], created_at: now}) }
12
+ let(:pact_publication) do
13
+ create(:pact_publications, {
14
+ consumer_version_id: consumer_version[:id],
15
+ provider_id: provider[:id],
16
+ revision_number: 1,
17
+ pact_version_id: pact_version[:id],
18
+ created_at: (now - 1)
19
+ })
20
+ end
21
+
22
+ let(:pact_publication_2) do
23
+ create(:pact_publications, {
24
+ consumer_version_id: consumer_version[:id],
25
+ provider_id: provider[:id],
26
+ revision_number: 2,
27
+ pact_version_id: pact_version[:id],
28
+ created_at: now
29
+ })
30
+ end
31
+ let(:pact_publication_3) do
32
+ create(:pact_publications, {
33
+ consumer_version_id: consumer_version[:id],
34
+ provider_id: provider[:id],
35
+ revision_number: 3,
36
+ pact_version_id: pact_version[:id],
37
+ created_at: (now + 1)
38
+ })
39
+ end
40
+ let(:webhook) do
41
+ create(:webhooks, {
42
+ uuid: '1234',
43
+ method: 'GET',
44
+ url: 'http://www.example.org',
45
+ consumer_id: consumer[:id],
46
+ provider_id: provider[:id],
47
+ is_json_request_body: false,
48
+ created_at: now
49
+ })
50
+ end
51
+ let(:webhook_execution) do
52
+ create(:webhook_executions, {
53
+ webhook_id: webhook[:id],
54
+ pact_publication_id: pact_publication[:id],
55
+ consumer_id: consumer[:id],
56
+ provider_id: provider[:id],
57
+ success: true,
58
+ logs: 'logs',
59
+ created_at: now
60
+ })
61
+ end
62
+
63
+ subject { PactBroker::Database.migrate(41) }
64
+
65
+ context "when a pact_publication can be found" do
66
+ before do
67
+ pact_publication
68
+ pact_publication_2
69
+ pact_publication_3
70
+ webhook_execution
71
+ end
72
+
73
+ it "creates a triggered webhook for each webhook execution" do
74
+ subject
75
+ expect(database[:triggered_webhooks].count).to eq 1
76
+ expect(database[:triggered_webhooks].first[:webhook_id]).to eq webhook[:id]
77
+ expect(database[:triggered_webhooks].first[:webhook_uuid]).to eq '1234'
78
+ expect(database[:triggered_webhooks].first[:consumer_id]).to eq consumer[:id]
79
+ expect(database[:triggered_webhooks].first[:provider_id]).to eq provider[:id]
80
+ expect(database[:triggered_webhooks].first[:pact_publication_id]).to eq pact_publication_2[:id]
81
+ expect(database[:triggered_webhooks].first[:status]).to eq 'success'
82
+ expect(database[:triggered_webhooks].first[:created_at]).to eq webhook[:created_at]
83
+ expect(database[:triggered_webhooks].first[:updated_at]).to eq webhook[:created_at]
84
+ end
85
+
86
+ it "nils out the unused foreign_keys on the webhook_execution" do
87
+ subject
88
+ expect(database[:webhook_executions].first[:webhook_id]).to be_nil
89
+ expect(database[:webhook_executions].first[:consumer_id]).to be_nil
90
+ expect(database[:webhook_executions].first[:provider_id]).to be_nil
91
+ expect(database[:webhook_executions].first[:pact_publication_id]).to be_nil
92
+ end
93
+
94
+ context "migrating backwards" do
95
+ it "deletes the triggered_webhooks again" do
96
+ subject
97
+ PactBroker::Database.migrate(40)
98
+ expect(database[:triggered_webhooks].count).to eq 0
99
+ end
100
+ end
101
+ end
102
+
103
+ context "when a pact_publication cannot be found" do
104
+ it "does not insert a triggered webhook" do
105
+ subject
106
+ expect(database[:triggered_webhooks].count).to eq 0
107
+ end
108
+ end
109
+ end
@@ -1,6 +1,10 @@
1
1
  $: << File.expand_path("../../../", __FILE__)
2
2
  require 'pact/provider/rspec'
3
3
  require 'db'
4
+ require 'tasks/database'
5
+ require 'pact_broker/db'
6
+ PactBroker::DB.connection = PactBroker::Database.database = DB::PACT_BROKER_DB
7
+
4
8
  require 'spec/support/database_cleaner'
5
9
  require 'pact_broker/api'
6
10
 
@@ -9,7 +13,7 @@ require_relative 'provider_states_for_pact_broker_client'
9
13
  Pact.service_provider "Pact Broker" do
10
14
 
11
15
  honours_pact_with "Pact Broker Client" do
12
- pact_uri "https://raw.githubusercontent.com/bethesque/pact_broker-client/master/spec/pacts/pact_broker_client-pact_broker.json"
16
+ pact_uri "https://raw.githubusercontent.com/pact-foundation/pact_broker-client/master/spec/pacts/pact_broker_client-pact_broker.json"
13
17
  end
14
18
 
15
19
  end
data/spec/spec_helper.rb CHANGED
@@ -5,10 +5,15 @@ ENV['RACK_ENV'] = 'test'
5
5
  RACK_ENV = 'test'
6
6
 
7
7
  $: << File.expand_path("../../", __FILE__)
8
- require 'rack/test'
8
+
9
9
  require 'db'
10
- require 'pact_broker/api'
11
10
  require 'tasks/database'
11
+ require 'pact_broker/db'
12
+ raise "Wrong environment!!! Don't run this script!! ENV['RACK_ENV'] is #{ENV['RACK_ENV']} and RACK_ENV is #{RACK_ENV}" if ENV['RACK_ENV'] != 'test' || RACK_ENV != 'test'
13
+ PactBroker::DB.connection = PactBroker::Database.database = DB::PACT_BROKER_DB
14
+
15
+ require 'rack/test'
16
+ require 'pact_broker/api'
12
17
  require 'rspec/its'
13
18
 
14
19
  Dir.glob("./spec/support/**/*.rb") { |file| require file }
@@ -16,21 +21,24 @@ Dir.glob("./spec/support/**/*.rb") { |file| require file }
16
21
  I18n.config.enforce_available_locales = false
17
22
 
18
23
  RSpec.configure do | config |
19
- config.before :suite do
20
- raise "Wrong environment!!! Don't run this script!! ENV['RACK_ENV'] is #{ENV['RACK_ENV']} and RACK_ENV is #{RACK_ENV}" if ENV['RACK_ENV'] != 'test' || RACK_ENV != 'test'
21
- PactBroker::DB.connection = PactBroker::Database.database = DB::PACT_BROKER_DB
22
- end
23
-
24
24
  config.before :each do
25
25
  PactBroker.reset_configuration
26
+ require 'pact_broker/badges/service'
27
+ PactBroker::Badges::Service.clear_cache
26
28
  end
27
29
 
28
30
  config.include Rack::Test::Methods
31
+
29
32
  config.mock_with :rspec do |mocks|
30
33
  mocks.verify_partial_doubles = true
31
34
  end
32
35
 
36
+ config.define_derived_metadata do |meta|
37
+ meta[:aggregate_failures] = true unless meta.key?(:aggregate_failures)
38
+ end
39
+
33
40
  config.include FixtureHelpers
41
+ config.example_status_persistence_file_path = "./spec/examples.txt"
34
42
 
35
43
  def app
36
44
  PactBroker::API
@@ -1,6 +1,10 @@
1
1
  require 'database_cleaner'
2
+ require 'support/migration_helpers'
2
3
 
3
4
  RSpec.configure do |config|
5
+
6
+ config.include MigrationHelpers, migration: true
7
+
4
8
  config.before(:suite) do
5
9
  if defined?(::DB)
6
10
  DatabaseCleaner.strategy = :transaction
@@ -12,14 +16,23 @@ RSpec.configure do |config|
12
16
  end
13
17
  end
14
18
 
19
+ config.before :each, migration: true do
20
+ PactBroker::Database.drop_objects
21
+ end
22
+
23
+ config.after :each, migration: true do
24
+ PactBroker::Database.migrate
25
+ PactBroker::Database.truncate
26
+ end
27
+
15
28
  config.before(:each) do | example |
16
- unless example.metadata[:no_db_clean]
29
+ unless example.metadata[:no_db_clean] || example.metadata[:migration]
17
30
  DatabaseCleaner.start if defined?(::DB)
18
31
  end
19
32
  end
20
33
 
21
34
  config.after(:each) do | example |
22
- unless example.metadata[:no_db_clean]
35
+ unless example.metadata[:no_db_clean] || example.metadata[:migration]
23
36
  DatabaseCleaner.clean if defined?(::DB)
24
37
  end
25
38
  end
@@ -0,0 +1,16 @@
1
+ require 'tasks/database'
2
+
3
+ module MigrationHelpers
4
+ def create table_name, params, id_column_name = :id
5
+ database[table_name].insert(params);
6
+ database[table_name].order(id_column_name).last
7
+ end
8
+
9
+ def clean table_name
10
+ database[table_name].delete rescue puts "Error cleaning #{table_name} #{$!}"
11
+ end
12
+
13
+ def database
14
+ @database ||= DB.connection_for_env 'test'
15
+ end
16
+ end
@@ -1,4 +1,5 @@
1
1
  require 'pact_broker/repositories'
2
+ require 'pact_broker/services'
2
3
  require 'pact_broker/webhooks/repository'
3
4
  require 'pact_broker/webhooks/service'
4
5
  require 'pact_broker/domain/webhook_execution_result'
@@ -25,11 +26,16 @@ require 'ostruct'
25
26
  class TestDataBuilder
26
27
 
27
28
  include PactBroker::Repositories
29
+ include PactBroker::Services
28
30
 
29
31
  attr_reader :pacticipant
30
32
  attr_reader :consumer
31
33
  attr_reader :provider
34
+ attr_reader :consumer_version
35
+ attr_reader :pact
32
36
  attr_reader :webhook
37
+ attr_reader :webhook_execution
38
+ attr_reader :triggered_webhook
33
39
 
34
40
  def create_pricing_service
35
41
  @pricing_service_id = pacticipant_repository.create(:name => 'Pricing Service', :repository_url => 'git@git.realestate.com.au:business-systems/pricing-service').save(raise_on_save_failure: true).id
@@ -82,10 +88,11 @@ class TestDataBuilder
82
88
  end
83
89
 
84
90
  def create_pact_with_hierarchy consumer_name = "Consumer", consumer_version = "1.2.3", provider_name = "Provider", json_content = default_json_content
85
- provider = PactBroker::Domain::Pacticipant.create(:name => provider_name)
86
- consumer = PactBroker::Domain::Pacticipant.create(:name => consumer_name)
87
- version = PactBroker::Domain::Version.create(:number => consumer_version, :pacticipant => consumer)
88
- PactBroker::Pacts::Repository.new.create(version_id: version.id, consumer_id: consumer.id, provider_id: provider.id, json_content: json_content)
91
+ create_consumer consumer_name
92
+ create_provider provider_name
93
+ create_consumer_version consumer_version
94
+ create_pact json_content: json_content
95
+ self
89
96
  end
90
97
 
91
98
  def create_version_with_hierarchy pacticipant_name, pacticipant_version
@@ -156,15 +163,40 @@ class TestDataBuilder
156
163
  end
157
164
 
158
165
  def create_webhook params = {}
166
+ uuid = params[:uuid] || PactBroker::Webhooks::Service.next_uuid
159
167
  default_params = {method: 'POST', url: 'http://example.org', headers: {'Content-Type' => 'application/json'}}
160
168
  request = PactBroker::Domain::WebhookRequest.new(default_params.merge(params))
161
- @webhook = PactBroker::Webhooks::Repository.new.create PactBroker::Webhooks::Service.next_uuid, PactBroker::Domain::Webhook.new(request: request), @consumer, @provider
169
+ @webhook = PactBroker::Webhooks::Repository.new.create uuid, PactBroker::Domain::Webhook.new(request: request), @consumer, @provider
170
+ self
171
+ end
172
+
173
+ def create_triggered_webhook params = {}
174
+ trigger_uuid = params[:trigger_uuid] || webhook_service.next_uuid
175
+ @triggered_webhook = webhook_repository.create_triggered_webhook trigger_uuid, @webhook, @pact, PactBroker::Webhooks::Service::PUBLICATION
176
+ @triggered_webhook.update(status: params[:status]) if params[:status]
177
+ set_created_at_if_set params[:created_at], :triggered_webhooks, {id: @triggered_webhook.id}
178
+ self
179
+ end
180
+
181
+ def create_webhook_execution params = {}
182
+ logs = params[:logs] || "logs"
183
+ webhook_execution_result = PactBroker::Domain::WebhookExecutionResult.new(OpenStruct.new(code: "200"), logs, nil)
184
+ @webhook_execution = PactBroker::Webhooks::Repository.new.create_execution @triggered_webhook, webhook_execution_result
185
+ created_at = params[:created_at] || @pact.created_at + Rational(1, 86400)
186
+ set_created_at_if_set created_at, :webhook_executions, {id: @webhook_execution.id}
187
+ @webhook_execution = PactBroker::Webhooks::Execution.find(id: @webhook_execution.id)
162
188
  self
163
189
  end
164
190
 
165
- def create_webhook_execution
166
- webhook_execution_result = PactBroker::Domain::WebhookExecutionResult.new(OpenStruct.new(code: "200"), "logs", nil)
167
- @webhook_execution = PactBroker::Webhooks::Repository.new.create_execution @webhook, webhook_execution_result
191
+ def create_deprecated_webhook_execution params = {}
192
+ create_webhook_execution params
193
+ Sequel::Model.db[:webhook_executions].where(id: webhook_execution.id).update(
194
+ triggered_webhook_id: nil,
195
+ consumer_id: consumer.id,
196
+ provider_id: provider.id,
197
+ webhook_id: PactBroker::Webhooks::Webhook.find(uuid: webhook.uuid).id,
198
+ pact_publication_id: pact.id
199
+ )
168
200
  self
169
201
  end
170
202
 
@@ -189,7 +221,7 @@ class TestDataBuilder
189
221
 
190
222
  def set_created_at_if_set created_at, table_name, selector
191
223
  if created_at
192
- Sequel::Model.db[table_name].where(selector.keys.first => selector.values.first).update(created_at: created_at.xmlschema)
224
+ Sequel::Model.db[table_name].where(selector.keys.first => selector.values.first).update(created_at: created_at)
193
225
  end
194
226
  end
195
227