pact_broker 2.27.2 → 2.27.3

Sign up to get free protection for your applications and to get access to all the features.
Files changed (61) hide show
  1. checksums.yaml +5 -5
  2. data/.travis.yml +1 -1
  3. data/CHANGELOG.md +32 -0
  4. data/DEVELOPER_SETUP.md +1 -0
  5. data/example/config.ru +1 -1
  6. data/lib/pact_broker.rb +1 -0
  7. data/lib/pact_broker/api.rb +1 -0
  8. data/lib/pact_broker/api/decorators/pact_version_decorator.rb +0 -5
  9. data/lib/pact_broker/api/decorators/tagged_pact_versions_decorator.rb +46 -0
  10. data/lib/pact_broker/api/renderers/html_pact_renderer.rb +1 -1
  11. data/lib/pact_broker/api/resources/error_handler.rb +1 -0
  12. data/lib/pact_broker/api/resources/index.rb +6 -0
  13. data/lib/pact_broker/api/resources/tagged_pact_versions.rb +38 -0
  14. data/lib/pact_broker/app.rb +12 -6
  15. data/lib/pact_broker/certificates/service.rb +1 -0
  16. data/lib/pact_broker/configuration.rb +11 -16
  17. data/lib/pact_broker/db/log_quietener.rb +38 -0
  18. data/lib/pact_broker/doc/views/index/tagged-pact-versions.markdown +7 -0
  19. data/lib/pact_broker/logging.rb +25 -20
  20. data/lib/pact_broker/logging/default_formatter.rb +16 -0
  21. data/lib/pact_broker/matrix/deployment_status_summary.rb +3 -1
  22. data/lib/pact_broker/pacticipants/service.rb +1 -1
  23. data/lib/pact_broker/pacts/all_pact_publications.rb +1 -1
  24. data/lib/pact_broker/pacts/repository.rb +18 -4
  25. data/lib/pact_broker/pacts/service.rb +4 -0
  26. data/lib/pact_broker/ui/views/index/show-with-tags.haml +34 -33
  27. data/lib/pact_broker/ui/views/index/show.haml +28 -27
  28. data/lib/pact_broker/ui/views/layouts/main.haml +2 -2
  29. data/lib/pact_broker/ui/views/matrix/show.haml +126 -127
  30. data/lib/pact_broker/verifications/service.rb +3 -1
  31. data/lib/pact_broker/version.rb +1 -1
  32. data/lib/pact_broker/versions/repository.rb +3 -1
  33. data/lib/pact_broker/webhooks/job.rb +1 -0
  34. data/pact_broker.gemspec +1 -0
  35. data/script/db-spec.sh +2 -0
  36. data/spec/features/delete_tagged_pact_versions_spec.rb +28 -0
  37. data/spec/features/get_tagged_pact_versions_spec.rb +26 -0
  38. data/spec/integration/ui/index_spec.rb +2 -2
  39. data/spec/lib/pact_broker/api/decorators/pact_version_decorator_spec.rb +0 -3
  40. data/spec/lib/pact_broker/api/decorators/tagged_pact_versions_decorator_spec.rb +79 -0
  41. data/spec/lib/pact_broker/api/renderers/html_pact_renderer_spec.rb +5 -6
  42. data/spec/lib/pact_broker/api/resources/error_handler_spec.rb +7 -1
  43. data/spec/lib/pact_broker/api/resources/tagged_pact_versions_spec.rb +88 -0
  44. data/spec/lib/pact_broker/badges/service_spec.rb +3 -2
  45. data/spec/lib/pact_broker/certificates/service_spec.rb +8 -3
  46. data/spec/lib/pact_broker/db/log_quietener_spec.rb +42 -0
  47. data/spec/lib/pact_broker/domain/webhook_request_spec.rb +17 -12
  48. data/spec/lib/pact_broker/domain/webhook_spec.rb +7 -2
  49. data/spec/lib/pact_broker/matrix/deployment_status_summary_spec.rb +8 -1
  50. data/spec/lib/pact_broker/pacticipants/service_spec.rb +5 -3
  51. data/spec/lib/pact_broker/pacts/repository_spec.rb +44 -3
  52. data/spec/lib/pact_broker/verifications/service_spec.rb +6 -2
  53. data/spec/lib/pact_broker/webhooks/job_spec.rb +2 -0
  54. data/spec/lib/pact_broker/webhooks/service_spec.rb +6 -1
  55. data/spec/spec_helper.rb +13 -13
  56. data/spec/support/database.rb +5 -0
  57. data/spec/support/fixture_pact.rb +34 -0
  58. data/spec/support/logging.rb +5 -0
  59. data/spec/support/shared_context.rb +10 -0
  60. data/tasks/development.rake +12 -3
  61. metadata +40 -3
@@ -1,6 +1,7 @@
1
1
  require 'pact_broker/repositories'
2
2
  require 'pact_broker/api/decorators/verification_decorator'
3
3
  require 'pact_broker/verifications/summary_for_consumer_version'
4
+ require 'pact_broker/logging'
4
5
 
5
6
  module PactBroker
6
7
 
@@ -11,13 +12,14 @@ module PactBroker
11
12
 
12
13
  extend PactBroker::Repositories
13
14
  extend PactBroker::Services
15
+ include PactBroker::Logging
14
16
 
15
17
  def next_number
16
18
  verification_repository.next_number
17
19
  end
18
20
 
19
21
  def create next_verification_number, params, pact
20
- PactBroker.logger.info "Creating verification #{next_verification_number} for pact_id=#{pact.id} from params #{params}"
22
+ logger.info "Creating verification #{next_verification_number} for pact_id=#{pact.id} from params #{params}"
21
23
  verification = PactBroker::Domain::Verification.new
22
24
  provider_version_number = params.fetch('providerApplicationVersion')
23
25
  PactBroker::Api::Decorators::VerificationDecorator.new(verification).from_hash(params)
@@ -1,3 +1,3 @@
1
1
  module PactBroker
2
- VERSION = '2.27.2'
2
+ VERSION = '2.27.3'
3
3
  end
@@ -1,4 +1,5 @@
1
1
  require 'sequel'
2
+ require 'pact_broker/logging'
2
3
  require 'pact_broker/domain/version'
3
4
  require 'pact_broker/tags/repository'
4
5
 
@@ -6,6 +7,7 @@ module PactBroker
6
7
  module Versions
7
8
  class Repository
8
9
 
10
+ include PactBroker::Logging
9
11
  include PactBroker::Repositories::Helpers
10
12
 
11
13
  def find_by_pacticipant_id_and_number pacticipant_id, number
@@ -53,7 +55,7 @@ module PactBroker
53
55
 
54
56
  # There may be a race condition if two simultaneous requests come in to create the same version
55
57
  def create args
56
- PactBroker.logger.info "Upserting version #{args[:number]} for pacticipant_id=#{args[:pacticipant_id]}"
58
+ logger.info "Upserting version #{args[:number]} for pacticipant_id=#{args[:pacticipant_id]}"
57
59
  version_params = {
58
60
  number: args[:number],
59
61
  pacticipant_id: args[:pacticipant_id],
@@ -8,6 +8,7 @@ module PactBroker
8
8
 
9
9
  include SuckerPunch::Job
10
10
  include PactBroker::Logging
11
+ include PactBroker::Logging
11
12
 
12
13
  def perform data
13
14
  @data = data
@@ -39,6 +39,7 @@ Gem::Specification.new do |gem|
39
39
  gem.add_runtime_dependency 'rack-protection', '~>2.0'
40
40
  gem.add_runtime_dependency 'dry-types', '~> 0.10.3' # https://travis-ci.org/pact-foundation/pact_broker/jobs/249448621
41
41
  gem.add_runtime_dependency 'table_print', '~> 1.5'
42
+ gem.add_runtime_dependency 'semantic_logger', '~> 4.3'
42
43
 
43
44
  gem.add_development_dependency 'pact', '~>1.14'
44
45
  gem.add_development_dependency 'rspec-pact-matchers', '~>0.1'
@@ -12,3 +12,5 @@ rake_exit_code=$?
12
12
  if [ $rake_exit_code -ne 0 ] && [ -n "$TRAVIS" ]; then
13
13
  cat log/pact_broker.log
14
14
  fi
15
+
16
+ exit $rake_exit_code
@@ -0,0 +1,28 @@
1
+ describe "Deleting tagged pact versions" do
2
+
3
+ let(:path) { "/pacts/provider/Bar/consumer/Foo/tag/prod" }
4
+
5
+ subject { delete(path) }
6
+
7
+ context "when the pact exists" do
8
+ before do
9
+ TestDataBuilder.new
10
+ .create_pact_with_hierarchy("Foo", "1.2.3", "Bar")
11
+ .create_consumer_version_tag("prod")
12
+ end
13
+
14
+ it "deletes the pact" do
15
+ expect{ subject }.to change{ PactBroker::Pacts::PactPublication.count }.by(-1)
16
+ end
17
+
18
+ it "returns a 204" do
19
+ expect(subject.status).to be 204
20
+ end
21
+ end
22
+
23
+ context "when the pact does not exist" do
24
+ it "returns a 404 Not Found" do
25
+ expect(subject.status).to be 404
26
+ end
27
+ end
28
+ end
@@ -0,0 +1,26 @@
1
+ describe "retrieving tagged pact versions" do
2
+
3
+ let(:path) { "/pacts/provider/Provider/consumer/Consumer/tag/prod"}
4
+
5
+ subject { get(path) }
6
+ let(:json_response_body) { JSON.parse(subject.body) }
7
+
8
+ before do
9
+ TestDataBuilder.new
10
+ .create_consumer("Consumer")
11
+ .create_provider("Provider")
12
+ .create_consumer_version("1.2.3")
13
+ .create_consumer_version_tag("prod")
14
+ .create_pact
15
+ .create_consumer_version("4.5.6")
16
+ .create_pact
17
+ end
18
+
19
+ it "returns a 200 HAL JSON response" do
20
+ expect(subject).to be_a_hal_json_success_response
21
+ end
22
+
23
+ it "returns the list of tagged pact versions" do
24
+ expect(json_response_body['_links']['pb:pact-versions']).to be_a Array
25
+ end
26
+ end
@@ -22,14 +22,14 @@ describe "UI index" do
22
22
  end
23
23
 
24
24
  it "returns a table of pacts" do
25
- expect(subject.body.scan('<tr').to_a.count).to eq 1
25
+ expect(subject.body.scan('<tr').to_a.count).to eq 2
26
26
  end
27
27
 
28
28
  context "with an array of tags" do
29
29
  let(:params) { { tags: ['prod'] } }
30
30
 
31
31
  it "returns a table of pacts with the specfied tags" do
32
- expect(subject.body.scan('<tr').to_a.count).to eq 2
32
+ expect(subject.body.scan('<tr').to_a.count).to eq 3
33
33
  end
34
34
  end
35
35
  end
@@ -2,11 +2,8 @@ require 'spec_helper'
2
2
  require 'pact_broker/api/decorators/pact_version_decorator'
3
3
 
4
4
  module PactBroker
5
-
6
5
  module Api
7
-
8
6
  module Decorators
9
-
10
7
  describe PactVersionDecorator do
11
8
 
12
9
  let(:json_content) {
@@ -0,0 +1,79 @@
1
+ require 'pact_broker/api/decorators/tagged_pact_versions_decorator'
2
+
3
+ module PactBroker
4
+ module Api
5
+ module Decorators
6
+ describe TaggedPactVersionsDecorator do
7
+ before do
8
+ allow(PactBroker::Api::Decorators::PactVersionDecorator).to receive(:new).and_return(_version_decorator)
9
+ allow_any_instance_of(TaggedPactVersionsDecorator).to receive(:pact_url).and_return('pact_url')
10
+ allow_any_instance_of(TaggedPactVersionsDecorator).to receive(:pacticipant_url).and_return('pacticipant_url')
11
+ allow_any_instance_of(TaggedPactVersionsDecorator).to receive(:pacticipant_url).and_return('pacticipant_url')
12
+ end
13
+
14
+ let(:user_options) do
15
+ register_fixture(:tagged_pact_versions_decorator_user_options) do
16
+ {
17
+ base_url: "http://example.org",
18
+ resource_url: "http://example.org/pacts/provider/Bar/consumer/Foo/tag/prod",
19
+ consumer_name: "Foo",
20
+ provider_name: "Bar",
21
+ tag: "prod"
22
+ }
23
+ end
24
+ end
25
+
26
+ let(:_version_decorator) do
27
+ instance_double(PactBroker::Api::Decorators::VersionDecorator, to_hash: { some: "pact" } )
28
+ end
29
+ let(:pact_versions) { [pact_version] }
30
+ let(:pact_version) do
31
+ instance_double("PactBroker::Domain::Pact").as_null_object
32
+ end
33
+
34
+ let(:decorator) { TaggedPactVersionsDecorator.new(pact_versions) }
35
+ let(:json) { decorator.to_json(user_options: user_options) }
36
+ subject { JSON.parse(json) }
37
+
38
+ let(:expected) do
39
+ {
40
+ "_embedded" => {
41
+ "pacts" => [
42
+ {
43
+ "some" => "pact"
44
+ }
45
+ ]
46
+ },
47
+ "_links" => {
48
+ "self" => {
49
+ "href" => "http://example.org/pacts/provider/Bar/consumer/Foo/tag/prod",
50
+ "title" => "All versions of the pact between Foo and Bar with tag prod"
51
+ },
52
+ "pb:consumer" => {
53
+ "href" => "pacticipant_url",
54
+ "title" => "Consumer",
55
+ "name" => "Foo"
56
+ },
57
+ "pb:provider" => {
58
+ "href" => "pacticipant_url",
59
+ "title" => "Provider",
60
+ "name" => "Bar"
61
+ },
62
+ "pb:pact-versions" => [
63
+ {
64
+ "href" => "pact_url",
65
+ "title" => "Pact version",
66
+ "name" => "#[InstanceDouble(PactBroker::Domain::Pact) (anonymous)]"
67
+ }
68
+ ]
69
+ }
70
+ }
71
+ end
72
+
73
+ it "matches the expected JSON" do
74
+ expect(subject).to match_pact(expected, allow_unexpected_keys: false)
75
+ end
76
+ end
77
+ end
78
+ end
79
+ end
@@ -11,6 +11,8 @@ module PactBroker
11
11
  ENV['BACKUP_TZ'] = ENV['TZ']
12
12
  ENV['TZ'] = "Australia/Melbourne"
13
13
  PactBroker.configuration.enable_public_badge_access = true
14
+ allow(PactBroker::Api::PactBrokerUrls).to receive(:pact_url).with('', pact).and_return(pact_url)
15
+ allow_any_instance_of(HtmlPactRenderer).to receive(:logger).and_return(logger)
14
16
 
15
17
  Timecop.freeze(created_at + 3)
16
18
  end
@@ -32,10 +34,7 @@ module PactBroker
32
34
  badge_url: 'http://badge'
33
35
  }
34
36
  end
35
-
36
- before do
37
- allow(PactBroker::Api::PactBrokerUrls).to receive(:pact_url).with('', pact).and_return(pact_url)
38
- end
37
+ let(:logger) { double('logger').as_null_object }
39
38
 
40
39
  subject { HtmlPactRenderer.call pact, options }
41
40
 
@@ -95,8 +94,8 @@ module PactBroker
95
94
  end
96
95
 
97
96
  it "logs a warning" do
98
- allow(PactBroker.logger).to receive(:warn).with(/Error/)
99
- expect(PactBroker.logger).to receive(:warn).with(/Could not parse/)
97
+ allow(logger).to receive(:warn).with(/Error/)
98
+ expect(logger).to receive(:warn).with(/Could not parse/)
100
99
  subject
101
100
  end
102
101
  end
@@ -5,6 +5,12 @@ module PactBroker
5
5
  module Resources
6
6
  describe ErrorHandler do
7
7
  describe "call" do
8
+
9
+ before do
10
+ allow(ErrorHandler).to receive(:logger).and_return(logger)
11
+ end
12
+
13
+ let(:logger) { double('logger').as_null_object }
8
14
  let(:error) { StandardError.new('test error') }
9
15
  let(:thing) { double('thing', call: nil, another_call: nil) }
10
16
  let(:options) { { env: env } }
@@ -91,7 +97,7 @@ module PactBroker
91
97
  end
92
98
 
93
99
  it "logs the error" do
94
- expect(PactBroker.logger).to receive(:error).at_least(1).times
100
+ expect(logger).to receive(:error).at_least(1).times
95
101
  subject
96
102
  end
97
103
 
@@ -0,0 +1,88 @@
1
+ require 'pact_broker/api/resources/tagged_pact_versions'
2
+
3
+ module PactBroker
4
+ module Api
5
+ module Resources
6
+ describe TaggedPactVersions do
7
+ include_context "stubbed services"
8
+
9
+ before do
10
+ allow(pacticipant_service).to receive(:find_pacticipant_by_name).with("Foo").and_return(consumer)
11
+ allow(pacticipant_service).to receive(:find_pacticipant_by_name).with("Bar").and_return(provider)
12
+ end
13
+
14
+ let(:path) { "/pacts/provider/Bar/consumer/Foo/tag/prod" }
15
+ let(:consumer) { double('Bar') }
16
+ let(:provider) { double('Foo') }
17
+
18
+ context "GET" do
19
+ before do
20
+ allow(PactBroker::Api::Decorators::TaggedPactVersionsDecorator).to receive(:new).and_return(decorator)
21
+ allow(pact_service).to receive(:find_all_pact_versions_between).and_return(pact_versions)
22
+ end
23
+
24
+ let(:decorator) { instance_double(PactBroker::Api::Decorators::TaggedPactVersionsDecorator, to_json: 'json') }
25
+ let(:pact_versions) { double('pacts') }
26
+
27
+ subject { get(path) }
28
+
29
+ let(:user_options) do
30
+ register_fixture(:tagged_pact_versions_decorator_user_options) do
31
+ {
32
+ base_url: "http://example.org",
33
+ resource_url: "http://example.org/pacts/provider/Bar/consumer/Foo/tag/prod",
34
+ consumer_name: "Foo",
35
+ provider_name: "Bar",
36
+ tag: "prod"
37
+ }
38
+ end
39
+ end
40
+
41
+ it "finds all the pacts with the given consumer/provider/tag" do
42
+ expect(pact_service).to receive(:find_all_pact_versions_between).with("Foo", and: "Bar", tag: "prod")
43
+ subject
44
+ end
45
+
46
+ it "returns a 200 OK hal+json response" do
47
+ expect(subject).to be_a_hal_json_success_response
48
+ end
49
+
50
+ it "creates a JSON representation of the pact versions" do
51
+ expect(PactBroker::Api::Decorators::TaggedPactVersionsDecorator).to receive(:new).with(pact_versions)
52
+ expect(decorator).to receive(:to_json).with(user_options: hash_including(user_options))
53
+ subject
54
+ end
55
+
56
+ it "returns the JSON representation of the pact versions" do
57
+ expect(subject.body).to eq 'json'
58
+ end
59
+
60
+ context "with the consumer or provider do not exist" do
61
+ let(:consumer) { nil }
62
+
63
+ it "returns a 404" do
64
+ expect(subject).to be_a_404_response
65
+ end
66
+ end
67
+ end
68
+
69
+ context "DELETE" do
70
+ before do
71
+ allow(pact_service).to receive(:delete_all_pact_versions_between)
72
+ end
73
+
74
+ subject { delete(path) }
75
+
76
+ it "deletes all the pacts with the given consumer/provider/tag" do
77
+ expect(pact_service).to receive(:delete_all_pact_versions_between).with("Foo", and: "Bar", tag: "prod")
78
+ subject
79
+ end
80
+
81
+ it "returns a 204" do
82
+ expect(subject.status).to eq 204
83
+ end
84
+ end
85
+ end
86
+ end
87
+ end
88
+ end
@@ -10,7 +10,7 @@ module PactBroker
10
10
  let(:label) { nil }
11
11
  let(:initials) { false }
12
12
  let(:verification_status) { :success }
13
-
13
+ let(:logger) { double('logger').as_null_object }
14
14
  let(:expected_url) { "https://img.shields.io/badge/#{expected_left_text}-#{expected_right_text}-#{expected_color}.svg" }
15
15
  let(:expected_color) { "brightgreen" }
16
16
  let(:expected_right_text) { "verified" }
@@ -24,6 +24,7 @@ module PactBroker
24
24
 
25
25
  before do
26
26
  Service.clear_cache
27
+ allow(Service).to receive(:logger).and_return(logger)
27
28
  end
28
29
 
29
30
  it "returns the svg file" do
@@ -224,7 +225,7 @@ module PactBroker
224
225
  end
225
226
 
226
227
  it "logs the error" do
227
- expect(PactBroker.logger).to receive(:error).with(/Error retrieving badge from.*shield.*an error/)
228
+ expect(logger).to receive(:error).with(/Error retrieving badge from.*shield.*an error/)
228
229
  subject
229
230
  end
230
231
 
@@ -4,6 +4,11 @@ module PactBroker
4
4
  module Certificates
5
5
  describe Service do
6
6
  let(:certificate_content) { File.read('spec/fixtures/certificate.pem') }
7
+ let(:logger) { double('logger').as_null_object }
8
+
9
+ before do
10
+ allow(Service).to receive(:logger).and_return(logger)
11
+ end
7
12
 
8
13
  describe "#cert_store" do
9
14
  subject { Service.cert_store }
@@ -19,7 +24,7 @@ module PactBroker
19
24
  end
20
25
 
21
26
  it "logs the error" do
22
- expect(PactBroker.logger).to receive(:error).with(/Error adding certificate/).at_least(1).times
27
+ expect(Service).to receive(:log_error).with(anything, /Error adding certificate/).at_least(1).times
23
28
  subject
24
29
  end
25
30
 
@@ -46,7 +51,7 @@ module PactBroker
46
51
  let(:certificate_content) { File.read('spec/fixtures/certificates/cacert.pem') }
47
52
 
48
53
  it "returns all the X509 Certificate objects" do
49
- expect(PactBroker.logger).to_not receive(:error).with(/Error.*1234/)
54
+ expect(logger).to_not receive(:error).with(/Error.*1234/)
50
55
  expect(subject.size).to eq 1
51
56
  end
52
57
  end
@@ -55,7 +60,7 @@ module PactBroker
55
60
  let(:certificate_content) { File.read('spec/fixtures/certificate-invalid.pem') }
56
61
 
57
62
  it "logs an error" do
58
- expect(PactBroker.logger).to receive(:error).with(/Error.*1234/)
63
+ expect(logger).to receive(:error).with(/Error.*1234/)
59
64
  subject
60
65
  end
61
66