pact_broker 2.0.2 → 2.0.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (59) hide show
  1. checksums.yaml +4 -4
  2. data/.travis.yml +15 -2
  3. data/CHANGELOG.md +9 -0
  4. data/CONTRIBUTING.md +15 -0
  5. data/config/database.travis.yml +13 -0
  6. data/config/database.yml +25 -13
  7. data/db/migrations/32_create_latest_verifications.rb +6 -5
  8. data/db/migrations/33_create_config_table.rb +1 -1
  9. data/db/migrations/34_create_index_on_consumer_version_order.rb +10 -0
  10. data/db/migrations/35_create_index_on_names.rb +11 -0
  11. data/db/migrations/36_create_webhook_execution.rb +16 -0
  12. data/example/pact_broker_database.sqlite3 +0 -0
  13. data/lib/db.rb +6 -1
  14. data/lib/pact_broker/api/contracts/put_pact_params_contract.rb +1 -0
  15. data/lib/pact_broker/app.rb +1 -0
  16. data/lib/pact_broker/domain/order_versions.rb +37 -15
  17. data/lib/pact_broker/domain/relationship.rb +11 -5
  18. data/lib/pact_broker/domain/tag.rb +4 -0
  19. data/lib/pact_broker/domain/version.rb +6 -1
  20. data/lib/pact_broker/domain/webhook_execution_result.rb +7 -2
  21. data/lib/pact_broker/domain/webhook_request.rb +24 -2
  22. data/lib/pact_broker/pacticipants/service.rb +4 -2
  23. data/lib/pact_broker/pacts/all_pact_publications.rb +1 -1
  24. data/lib/pact_broker/pacts/repository.rb +3 -3
  25. data/lib/pact_broker/repositories/helpers.rb +16 -0
  26. data/lib/pact_broker/ui/view_models/relationship.rb +9 -0
  27. data/lib/pact_broker/ui/views/relationships/show.haml +9 -0
  28. data/lib/pact_broker/version.rb +1 -1
  29. data/lib/pact_broker/webhooks/execution.rb +17 -0
  30. data/lib/pact_broker/webhooks/repository.rb +20 -2
  31. data/lib/pact_broker/webhooks/service.rb +4 -1
  32. data/public/stylesheets/relationships.css +1 -0
  33. data/script/publish-2.sh +1 -0
  34. data/script/publish-new.sh +1 -0
  35. data/script/publish-not-a-pact.sh +1 -0
  36. data/script/publish.sh +1 -0
  37. data/script/record_verification.sh +1 -0
  38. data/script/recreate-pg-db.sh +2 -0
  39. data/spec/lib/pact_broker/api/contracts/put_pact_params_contract_spec.rb +20 -0
  40. data/spec/lib/pact_broker/api/decorators/webhook_execution_result_decorator_spec.rb +2 -1
  41. data/spec/lib/pact_broker/domain/order_versions_spec.rb +37 -15
  42. data/spec/lib/pact_broker/domain/version_spec.rb +14 -0
  43. data/spec/lib/pact_broker/domain/webhook_request_spec.rb +49 -6
  44. data/spec/lib/pact_broker/domain/webhook_spec.rb +1 -0
  45. data/spec/lib/pact_broker/pacticipants/service_spec.rb +28 -4
  46. data/spec/lib/pact_broker/pacts/pact_version_spec.rb +1 -1
  47. data/spec/lib/pact_broker/pacts/repository_spec.rb +10 -10
  48. data/spec/lib/pact_broker/tags/repository_spec.rb +2 -2
  49. data/spec/lib/pact_broker/ui/controllers/relationships_spec.rb +7 -7
  50. data/spec/lib/pact_broker/webhooks/repository_spec.rb +52 -4
  51. data/spec/lib/pact_broker/webhooks/service_spec.rb +6 -1
  52. data/spec/migrations/23_pact_versions_spec.rb +1 -1
  53. data/spec/support/database_cleaner.rb +5 -1
  54. data/spec/support/provider_state_builder.rb +8 -0
  55. data/spec/support/rspec_matchers.rb +9 -0
  56. data/tasks/database.rb +3 -2
  57. data/tasks/db.rake +41 -3
  58. metadata +10 -3
  59. data/lib/pact_broker/api/contracts/consumer_version_number_validation.rb +0 -27
@@ -26,6 +26,7 @@ module PactBroker
26
26
  end
27
27
 
28
28
  it "logs before and after" do
29
+ allow(PactBroker.logger).to receive(:info)
29
30
  expect(PactBroker.logger).to receive(:info).with(/Executing/)
30
31
  subject.execute
31
32
  end
@@ -103,14 +103,26 @@ module PactBroker
103
103
  let(:pact) { instance_double("PactBroker::Domain::Pact", consumer: consumer, provider: provider)}
104
104
  let(:verification) { instance_double("PactBroker::Domain::Verification")}
105
105
  let(:pacts) { [pact]}
106
+ let(:webhooks) { [instance_double("PactBroker::Domain::Webhook")]}
106
107
 
107
108
  before do
108
109
  allow_any_instance_of(PactBroker::Pacts::Repository).to receive(:find_latest_pacts).and_return(pacts)
109
110
  allow(PactBroker::Verifications::Service).to receive(:find_latest_verification_for).and_return(verification)
111
+ allow(PactBroker::Webhooks::Service).to receive(:find_by_consumer_and_provider).and_return(webhooks)
112
+ end
113
+
114
+ it "retrieves the webhooks for the pact" do
115
+ expect(PactBroker::Webhooks::Service).to receive(:find_by_consumer_and_provider).with(consumer, provider)
116
+ subject.find_relationships
117
+ end
118
+
119
+ it "retrieves the latest verification for the pact" do
120
+ expect(PactBroker::Verifications::Service).to receive(:find_latest_verification_for).with(consumer, provider)
121
+ subject.find_relationships
110
122
  end
111
123
 
112
124
  it "returns a list of relationships" do
113
- expect(subject.find_relationships).to eq([PactBroker::Domain::Relationship.create(consumer, provider, pact, verification)])
125
+ expect(subject.find_relationships).to eq([PactBroker::Domain::Relationship.create(consumer, provider, pact, verification, webhooks)])
114
126
  end
115
127
 
116
128
  end
@@ -127,6 +139,7 @@ module PactBroker
127
139
  .create_consumer_version_tag("prod")
128
140
  .create_pact
129
141
  .create_webhook
142
+ .create_webhook_execution
130
143
  .create_verification
131
144
  end
132
145
 
@@ -158,6 +171,12 @@ module PactBroker
158
171
  }.by(-1)
159
172
  end
160
173
 
174
+ it "deletes the webhook executions" do
175
+ expect{ delete_consumer }.to change{
176
+ PactBroker::Webhooks::Execution.count
177
+ }.by(-1)
178
+ end
179
+
161
180
  it "deletes the child pacts" do
162
181
  expect{ delete_consumer }.to change{
163
182
  PactBroker::Pacts::PactPublication.count
@@ -196,6 +215,12 @@ module PactBroker
196
215
  }.by(-1)
197
216
  end
198
217
 
218
+ it "deletes the webhook executions" do
219
+ expect{ delete_provider }.to change{
220
+ PactBroker::Webhooks::Execution.count
221
+ }.by(-1)
222
+ end
223
+
199
224
  it "deletes the child pacts" do
200
225
  expect{ delete_provider }.to change{
201
226
  PactBroker::Pacts::PactPublication.count
@@ -207,10 +232,9 @@ module PactBroker
207
232
  PactBroker::Domain::Verification.count
208
233
  }.by(-1)
209
234
  end
210
- end
211
235
 
236
+ end
212
237
  end
213
-
214
238
  end
215
239
  end
216
- end
240
+ end
@@ -48,7 +48,7 @@ module PactBroker
48
48
  describe "#latest_consumer_version_number" do
49
49
  before do
50
50
  builder = ProviderStateBuilder.new
51
- builder
51
+ builder
52
52
  .create_consumer
53
53
  .create_provider
54
54
  .create_consumer_version("1.0.1")
@@ -35,7 +35,7 @@ module PactBroker
35
35
  expect(subject.consumer_version_number).to eq '1.2.3'
36
36
  expect(subject.consumer_version.number).to eq '1.2.3'
37
37
  expect(subject.json_content).to eq json_content
38
- expect(subject.created_at).to be_instance_of(DateTime)
38
+ expect(subject.created_at).to be_datey
39
39
  end
40
40
 
41
41
  context "when a pact already exists with the same content" do
@@ -158,7 +158,7 @@ module PactBroker
158
158
  end
159
159
 
160
160
  it "does not update the created_at timestamp" do
161
- expect(subject.created_at).to eq created_at
161
+ expect(subject.created_at.to_datetime).to eq created_at
162
162
  end
163
163
  end
164
164
  end
@@ -237,8 +237,8 @@ module PactBroker
237
237
  expect(subject.first.consumer.name).to eq consumer_name
238
238
  expect(subject.first.provider.name).to eq provider_name
239
239
  expect(subject.first.consumer_version.number).to eq "2.3.4"
240
- expect(subject.first.consumer_version.tags.first.name).to eq "prod"
241
- expect(subject.first.consumer_version.tags.last.name).to eq "branch"
240
+ expect(subject.first.consumer_version.tags.first.name).to eq "branch"
241
+ expect(subject.first.consumer_version.tags.last.name).to eq "prod"
242
242
  end
243
243
 
244
244
  end
@@ -254,7 +254,7 @@ module PactBroker
254
254
  .create_pact
255
255
  .create_consumer_version("1.2.3")
256
256
  .create_pact
257
- .create_consumer("another consumer")
257
+ .create_consumer("wiffle consumer")
258
258
  .create_consumer_version("4.0.0")
259
259
  .create_pact
260
260
  .create_consumer_version("4.5.6")
@@ -271,7 +271,7 @@ module PactBroker
271
271
  expect(subject.first.provider.name).to eq provider_name
272
272
  expect(subject.first.consumer_version.number).to eq "1.2.3"
273
273
  expect(subject.first.json_content).to be nil
274
- expect(subject.last.consumer.name).to eq "another consumer"
274
+ expect(subject.last.consumer.name).to eq "wiffle consumer"
275
275
  end
276
276
  end
277
277
 
@@ -285,7 +285,7 @@ module PactBroker
285
285
  .create_pact
286
286
  .create_consumer_version("2.0.0")
287
287
  .create_pact
288
- .create_consumer("another consumer")
288
+ .create_consumer("wiffle consumer")
289
289
  .create_consumer_version("4.5.6")
290
290
  .create_pact
291
291
  .create_consumer_version("5.0.0")
@@ -304,7 +304,7 @@ module PactBroker
304
304
  expect(subject.first.consumer.name).to eq consumer_name
305
305
  expect(subject.first.consumer_version.number).to eq "1.2.3"
306
306
  expect(subject.first.json_content).to be nil
307
- expect(subject.last.consumer.name).to eq "another consumer"
307
+ expect(subject.last.consumer.name).to eq "wiffle consumer"
308
308
  expect(subject.last.consumer_version.number).to eq "5.0.0"
309
309
  end
310
310
  end
@@ -498,7 +498,7 @@ module PactBroker
498
498
  end
499
499
 
500
500
  it "has timestamps" do
501
- expect(latest_prod_pact.created_at).to be_instance_of(DateTime)
501
+ expect(latest_prod_pact.created_at).to be_datey
502
502
  end
503
503
  end
504
504
 
@@ -543,7 +543,7 @@ module PactBroker
543
543
  it "includes the timestamps - need to update view" do
544
544
  pacts = Repository.new.find_latest_pacts
545
545
 
546
- expect(pacts[0].created_at).to be_instance_of DateTime
546
+ expect(pacts[0].created_at).to be_datey
547
547
  end
548
548
  end
549
549
  end
@@ -37,8 +37,8 @@ module PactBroker
37
37
  expect(find_tag.name).to eq tag_name
38
38
  expect(find_tag.version.number).to eq version_number
39
39
  expect(find_tag.version.pacticipant.name).to eq pacticipant_name
40
- expect(find_tag.created_at).to be_instance_of(DateTime)
41
- expect(find_tag.updated_at).to be_instance_of(DateTime)
40
+ expect(find_tag.created_at).to be_datey
41
+ expect(find_tag.updated_at).to be_datey
42
42
  end
43
43
 
44
44
  context "when case sensitivity is turned off and a name with different case is used" do
@@ -15,14 +15,14 @@ module PactBroker
15
15
  describe "/" do
16
16
  describe "GET" do
17
17
 
18
- let(:consumer) { instance_double("PactBroker::Domain::Pacticipant", name: 'consumer_name')}
19
- let(:provider) { instance_double("PactBroker::Domain::Pacticipant", name: 'provider_name')}
20
- let(:pact) { instance_double("PactBroker::Domain::Pact", created_at: Date.new(2017))}
21
- let(:relationship) { PactBroker::Domain::Relationship.new(consumer, provider, pact)}
22
- let(:relationships) { [relationship] }
23
-
24
18
  before do
25
- allow(PactBroker::Pacticipants::Service).to receive(:find_relationships).and_return(relationships)
19
+ ProviderStateBuilder.new
20
+ .create_consumer
21
+ .create_provider
22
+ .create_consumer_version
23
+ .create_pact
24
+ .create_webhook
25
+ .create_verification
26
26
  end
27
27
 
28
28
  it "does something" do
@@ -38,7 +38,6 @@ module PactBroker
38
38
 
39
39
  subject { Repository.new.create uuid, webhook, consumer, provider }
40
40
 
41
-
42
41
  it "saves webhook" do
43
42
  subject
44
43
  expect(created_webhook_record).to include expected_webhook_record
@@ -154,11 +153,11 @@ module PactBroker
154
153
  end
155
154
 
156
155
  it "returns a webhook with a created_at date" do
157
- expect(subject.created_at).to be_instance_of(DateTime)
156
+ expect(subject.created_at).to be_datey
158
157
  end
159
158
 
160
159
  it "returns a webhook with a updated_at date" do
161
- expect(subject.updated_at).to be_instance_of(DateTime)
160
+ expect(subject.updated_at).to be_datey
162
161
  end
163
162
 
164
163
  context "when the body is a XML string" do
@@ -241,6 +240,55 @@ module PactBroker
241
240
  end
242
241
  end
243
242
 
243
+ describe "create_execution" do
244
+ let(:webhook_domain) { Repository.new.create uuid, webhook, consumer, provider }
245
+ let(:webhook_execution_result) { instance_double("PactBroker::Domain::WebhookExecutionResult", success?: true, logs: "logs") }
246
+
247
+ subject { Repository.new.create_execution webhook_domain, webhook_execution_result }
248
+
249
+ it "saves a new webhook execution " do
250
+ expect { subject }.to change { Execution.count }.by(1)
251
+ end
252
+
253
+ it "sets the webhook" do
254
+ expect(subject.webhook.uuid).to eq webhook_domain.uuid
255
+ end
256
+
257
+ it "sets the success" do
258
+ expect(subject.success).to be true
259
+ end
260
+
261
+ it "sets the logs" do
262
+ expect(subject.logs).to eq "logs"
263
+ end
264
+
265
+ it "sets the consumer" do
266
+ expect(subject.consumer).to eq consumer
267
+ end
268
+
269
+ it "sets the provider" do
270
+ expect(subject.provider).to eq provider
271
+ end
272
+
273
+ it "sets the PactPublication" do
274
+ expect(subject.pact_publication)
275
+ end
276
+ end
277
+
278
+ describe "unlink_executions_by_webhook_uuid" do
279
+ let!(:webhook_domain) { Repository.new.create uuid, webhook, consumer, provider }
280
+ let!(:webhook_execution_result) { instance_double("PactBroker::Domain::WebhookExecutionResult", success?: true, logs: "logs") }
281
+ let!(:webhook_execution) { Repository.new.create_execution webhook_domain, webhook_execution_result }
282
+
283
+ subject { Repository.new.unlink_executions_by_webhook_uuid uuid }
284
+
285
+ it "sets the webhook id to nil" do
286
+ webhook_id = Webhook.find(uuid: uuid).id
287
+ expect { subject }.to change {
288
+ Execution.find(id: webhook_execution.id).webhook_id
289
+ }.from(webhook_id).to(nil)
290
+ end
291
+ end
244
292
  end
245
293
  end
246
- end
294
+ end
@@ -77,11 +77,16 @@ module PactBroker
77
77
  .and_return(:pact)
78
78
  end
79
79
 
80
+ subject { PactBroker::Webhooks::Service.execute_webhooks pact }
80
81
 
81
82
  it "executes the HTTP request of the webhook" do
82
- PactBroker::Webhooks::Service.execute_webhooks pact
83
+ subject
83
84
  expect(http_request).to have_been_made
84
85
  end
86
+
87
+ it "saves the execution" do
88
+ expect { subject }.to change { PactBroker::Webhooks::Execution.count }.by(1)
89
+ end
85
90
  end
86
91
  end
87
92
  end
@@ -40,7 +40,7 @@ describe 'migrate to pact versions (migrate 22-31)', no_db_clean: :true do
40
40
 
41
41
  it "uses the old updated date for the new creation date" do
42
42
  do_migration
43
- expect(database[:latest_pact_publications_by_consumer_versions].order(:id).first[:created_at]).to eq pact_updated_at
43
+ expect(database[:latest_pact_publications_by_consumer_versions].order(:id).first[:created_at].to_datetime).to eq pact_updated_at
44
44
  end
45
45
 
46
46
  it "sets each revision number to 1" do
@@ -4,7 +4,11 @@ RSpec.configure do |config|
4
4
  config.before(:suite) do
5
5
  if defined?(::DB)
6
6
  DatabaseCleaner.strategy = :transaction
7
- DatabaseCleaner.clean_with :truncation
7
+ if DB.mysql?
8
+ DatabaseCleaner.clean_with :deletion
9
+ else
10
+ DatabaseCleaner.clean_with :truncation
11
+ end
8
12
  end
9
13
  end
10
14
 
@@ -1,6 +1,7 @@
1
1
  require 'pact_broker/repositories'
2
2
  require 'pact_broker/webhooks/repository'
3
3
  require 'pact_broker/webhooks/service'
4
+ require 'pact_broker/domain/webhook_execution_result'
4
5
  require 'pact_broker/pacts/repository'
5
6
  require 'pact_broker/pacts/service'
6
7
  require 'pact_broker/pacticipants/repository'
@@ -18,6 +19,7 @@ require 'pact_broker/verifications/repository'
18
19
  require 'pact_broker/verifications/service'
19
20
  require 'pact_broker/tags/repository'
20
21
  require 'pact_broker/webhooks/repository'
22
+ require 'ostruct'
21
23
 
22
24
  class ProviderStateBuilder
23
25
 
@@ -154,6 +156,12 @@ class ProviderStateBuilder
154
156
  self
155
157
  end
156
158
 
159
+ def create_webhook_execution
160
+ webhook_execution_result = PactBroker::Domain::WebhookExecutionResult.new(OpenStruct.new(code: "200"), "logs", nil)
161
+ @webhook_execution = PactBroker::Webhooks::Repository.new.create_execution @webhook, webhook_execution_result
162
+ self
163
+ end
164
+
157
165
  def create_verification parameters = {}
158
166
  default_parameters = {success: true, provider_version: '4.5.6', number: 1}
159
167
  verification = PactBroker::Domain::Verification.new(default_parameters.merge(parameters))
@@ -0,0 +1,9 @@
1
+ RSpec::Matchers.define :be_datey do |expected|
2
+ match do |actual|
3
+ actual.instance_of?(DateTime) || actual.instance_of?(Time)
4
+ end
5
+
6
+ failure_message do |actual|
7
+ "expected #{actual} to be an instance of DateTime or Time"
8
+ end
9
+ end
data/tasks/database.rb CHANGED
@@ -8,7 +8,7 @@ Sequel.extension :migration
8
8
  module PactBroker
9
9
  module Database
10
10
 
11
- TABLES = [:config, :pacts, :pact_version_contents, :tags, :verifications, :pact_publications, :pact_versions, :webhook_headers, :webhooks, :versions, :pacticipants].freeze
11
+ TABLES = [:webhook_executions, :config, :pacts, :pact_version_contents, :tags, :verifications, :pact_publications, :pact_versions, :webhook_headers, :webhooks, :versions, :pacticipants].freeze
12
12
 
13
13
  extend self
14
14
 
@@ -123,7 +123,8 @@ module PactBroker
123
123
  def configuration_for_env env
124
124
  database_yml = PactBroker.project_root.join('config','database.yml')
125
125
  config = YAML.load(ERB.new(File.read(database_yml)).result)
126
- config.fetch(env)
126
+ adapter = ENV.fetch('DATABASE_ADAPTER','default')
127
+ config.fetch(env)[adapter]
127
128
  end
128
129
 
129
130
  def env
data/tasks/db.rake CHANGED
@@ -20,6 +20,44 @@ namespace :db do
20
20
  require File.dirname(__FILE__) + '/database.rb'
21
21
  end
22
22
 
23
+ task :create do
24
+ Rake::Task["db:create:#{ENV.fetch('DATABASE_ADAPTER', 'default')}"].invoke
25
+ end
26
+
27
+ namespace :create do
28
+ task :default do
29
+ end
30
+
31
+ task :postgres do
32
+ puts `psql postgres -c "CREATE DATABASE pact_broker;"`
33
+ puts `psql postgres -c "GRANT ALL PRIVILEGES ON DATABASE pact_broker TO pact_broker;"`
34
+ end
35
+
36
+ task :mysql do
37
+ puts `mysql -h localhost -u root -e "CREATE DATABASE IF NOT EXISTS pact_broker"`
38
+ puts `mysql -h localhost -u root -e "GRANT ALL PRIVILEGES ON pact_broker.* TO 'pact_broker'@'localhost' identified by 'pact_broker';"`
39
+ end
40
+ end
41
+
42
+ task :drop do
43
+ Rake::Task["db:drop:#{ENV.fetch('DATABASE_ADAPTER', 'default')}"].invoke
44
+ end
45
+
46
+ namespace :drop do
47
+ desc 'Delete the dev/test database - uses RACK_ENV, defaulting to "development"'
48
+ task :default => 'db:env' do
49
+ PactBroker::Database.delete_database_file
50
+ end
51
+
52
+ task :postgres do
53
+ puts `psql postgres -c "drop DATABASE pact_broker;"`
54
+ end
55
+
56
+ task :mysql do
57
+ puts `mysql -h localhost -u root -e "DROP DATABASE IF EXISTS pact_broker"`
58
+ end
59
+ end
60
+
23
61
  desc 'Print current schema version'
24
62
  task :version => 'db:env' do
25
63
  puts "Schema Version: #{PactBroker::Database.version}"
@@ -53,9 +91,9 @@ namespace :db do
53
91
  PactBroker::Database.ensure_database_dir_exists
54
92
  end
55
93
 
56
- task :create => 'db:env' do
57
- PactBroker::Database.create
58
- end
94
+ # task :create => 'db:env' do
95
+ # PactBroker::Database.create
96
+ # end
59
97
 
60
98
  # Private
61
99
  task :set_test_env do