pact_broker 2.2.0 → 2.3.0

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 (39) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +14 -0
  3. data/db/migrations/23_create_pact_versions_table.rb +1 -5
  4. data/lib/pact_broker/api.rb +6 -0
  5. data/lib/pact_broker/api/resources/badge.rb +60 -0
  6. data/lib/pact_broker/badges/service.rb +107 -0
  7. data/lib/pact_broker/configuration.rb +3 -2
  8. data/lib/pact_broker/doc/views/publish-verification-results.markdown +4 -4
  9. data/lib/pact_broker/domain/relationship.rb +7 -1
  10. data/lib/pact_broker/domain/verification.rb +12 -0
  11. data/lib/pact_broker/locale/en.yml +2 -0
  12. data/lib/pact_broker/logging.rb +4 -2
  13. data/lib/pact_broker/pacticipants/find_potential_duplicate_pacticipant_names.rb +11 -5
  14. data/lib/pact_broker/pacts/service.rb +1 -1
  15. data/lib/pact_broker/services.rb +5 -0
  16. data/lib/pact_broker/ui/view_models/relationship.rb +12 -14
  17. data/lib/pact_broker/verifications/repository.rb +8 -4
  18. data/lib/pact_broker/verifications/service.rb +2 -2
  19. data/lib/pact_broker/verifications/verification_status.rb +47 -0
  20. data/lib/pact_broker/version.rb +1 -1
  21. data/lib/rack/pact_broker/convert_file_extension_to_accept_header.rb +1 -1
  22. data/public/images/pact-changed-orange.svg +1 -0
  23. data/public/images/pact-failed-red.svg +1 -0
  24. data/public/images/pact-unknown-lightgrey.svg +1 -0
  25. data/public/images/pact-verified-brightgreen.svg +1 -0
  26. data/public/images/pact_not_found-unknown-lightgrey.svg +1 -0
  27. data/spec/features/get_latest_pact_badge_spec.rb +53 -0
  28. data/spec/features/get_latest_tagged_pact_badge_spec.rb +38 -0
  29. data/spec/features/get_latest_untagged_pact_badge_spec.rb +38 -0
  30. data/spec/features/publish_verification_spec.rb +8 -1
  31. data/spec/lib/pact_broker/api/resources/badge_spec.rb +104 -0
  32. data/spec/lib/pact_broker/badges/service_spec.rb +244 -0
  33. data/spec/lib/pact_broker/messages_spec.rb +2 -0
  34. data/spec/lib/pact_broker/pacticipants/find_potential_duplicate_pacticipant_names_spec.rb +44 -62
  35. data/spec/lib/pact_broker/pacts/service_spec.rb +0 -3
  36. data/spec/lib/pact_broker/ui/view_models/relationship_spec.rb +5 -7
  37. data/spec/lib/pact_broker/verifications/repository_spec.rb +102 -28
  38. data/spec/lib/pact_broker/verifications/verification_status_spec.rb +48 -0
  39. metadata +22 -2
@@ -23,7 +23,7 @@ module PactBroker
23
23
  .consumer(consumer_name)
24
24
  .provider(provider_name)
25
25
  .pact_version_sha(pact_version_sha)
26
- .verification_number(verification_number).first
26
+ .verification_number(verification_number).single_record
27
27
  end
28
28
 
29
29
  def find_latest_verifications_for_consumer_version consumer_name, consumer_version_number
@@ -37,13 +37,17 @@ module PactBroker
37
37
  .all
38
38
  end
39
39
 
40
- def find_latest_verification_for consumer_name, provider_name
40
+ def find_latest_verification_for consumer_name, provider_name, tag = nil
41
41
  query = LatestVerificationsByConsumerVersion
42
42
  .join(:all_pact_publications, pact_version_id: :pact_version_id)
43
43
  .consumer(consumer_name)
44
44
  .provider(provider_name)
45
- .latest
46
- query.first
45
+ if tag == :untagged
46
+ query = query.untagged
47
+ elsif tag
48
+ query = query.tag(tag)
49
+ end
50
+ query.latest.single_record
47
51
  end
48
52
 
49
53
  def pact_version_id_for pact
@@ -38,8 +38,8 @@ module PactBroker
38
38
  verification_repository.find_latest_verifications_for_consumer_version params[:consumer_name], params[:consumer_version_number]
39
39
  end
40
40
 
41
- def find_latest_verification_for consumer, provider
42
- verification_repository.find_latest_verification_for consumer.name, provider.name
41
+ def find_latest_verification_for consumer, provider, tag = nil
42
+ verification_repository.find_latest_verification_for consumer.name, provider.name, tag
43
43
  end
44
44
 
45
45
  def verification_summary_for_consumer_version params
@@ -0,0 +1,47 @@
1
+ module PactBroker
2
+
3
+ module Verifications
4
+
5
+ class Status
6
+
7
+ def initialize latest_pact, latest_verification
8
+ @latest_pact = latest_pact
9
+ @latest_verification = latest_verification
10
+ end
11
+
12
+ def to_s
13
+ to_sym.to_s
14
+ end
15
+
16
+ def to_sym
17
+ return :never unless latest_pact
18
+ return :never unless ever_verified?
19
+ if latest_verification_successful?
20
+ if pact_changed_since_last_verification?
21
+ :stale
22
+ else
23
+ :success
24
+ end
25
+ else
26
+ :failed
27
+ end
28
+ end
29
+
30
+ private
31
+
32
+ attr_reader :latest_pact, :latest_verification
33
+
34
+ def latest_verification_successful?
35
+ latest_verification.success
36
+ end
37
+
38
+ def pact_changed_since_last_verification?
39
+ latest_verification.pact_version_sha != latest_pact.pact_version_sha
40
+ end
41
+
42
+ def ever_verified?
43
+ !!latest_verification
44
+ end
45
+ end
46
+ end
47
+ end
@@ -1,3 +1,3 @@
1
1
  module PactBroker
2
- VERSION = '2.2.0'
2
+ VERSION = '2.3.0'
3
3
  end
@@ -7,7 +7,7 @@ module Rack
7
7
 
8
8
  class ConvertFileExtensionToAcceptHeader
9
9
 
10
- EXTENSIONS = {".csv" => "text/csv"}
10
+ EXTENSIONS = {".csv" => "text/csv", ".svg" => "image/svg+xml"}
11
11
  EXTENSION_REGEXP = /\.\w+$/
12
12
 
13
13
  def initialize app
@@ -0,0 +1 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="94" height="20"><linearGradient id="b" x2="0" y2="100%"><stop offset="0" stop-color="#bbb" stop-opacity=".1"/><stop offset="1" stop-opacity=".1"/></linearGradient><clipPath id="a"><rect width="94" height="20" rx="3" fill="#fff"/></clipPath><g clip-path="url(#a)"><path fill="#555" d="M0 0h33v20H0z"/><path fill="#fe7d37" d="M33 0h61v20H33z"/><path fill="url(#b)" d="M0 0h94v20H0z"/></g><g fill="#fff" text-anchor="middle" font-family="DejaVu Sans,Verdana,Geneva,sans-serif" font-size="11"><text x="16.5" y="15" fill="#010101" fill-opacity=".3">pact</text><text x="16.5" y="14">pact</text><text x="62.5" y="15" fill="#010101" fill-opacity=".3">changed</text><text x="62.5" y="14">changed</text></g></svg>
@@ -0,0 +1 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="72" height="20"><linearGradient id="b" x2="0" y2="100%"><stop offset="0" stop-color="#bbb" stop-opacity=".1"/><stop offset="1" stop-opacity=".1"/></linearGradient><clipPath id="a"><rect width="72" height="20" rx="3" fill="#fff"/></clipPath><g clip-path="url(#a)"><path fill="#555" d="M0 0h33v20H0z"/><path fill="#e05d44" d="M33 0h39v20H33z"/><path fill="url(#b)" d="M0 0h72v20H0z"/></g><g fill="#fff" text-anchor="middle" font-family="DejaVu Sans,Verdana,Geneva,sans-serif" font-size="11"><text x="16.5" y="15" fill="#010101" fill-opacity=".3">pact</text><text x="16.5" y="14">pact</text><text x="51.5" y="15" fill="#010101" fill-opacity=".3">failed</text><text x="51.5" y="14">failed</text></g></svg>
@@ -0,0 +1 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="94" height="20"><linearGradient id="b" x2="0" y2="100%"><stop offset="0" stop-color="#bbb" stop-opacity=".1"/><stop offset="1" stop-opacity=".1"/></linearGradient><clipPath id="a"><rect width="94" height="20" rx="3" fill="#fff"/></clipPath><g clip-path="url(#a)"><path fill="#555" d="M0 0h33v20H0z"/><path fill="#9f9f9f" d="M33 0h61v20H33z"/><path fill="url(#b)" d="M0 0h94v20H0z"/></g><g fill="#fff" text-anchor="middle" font-family="DejaVu Sans,Verdana,Geneva,sans-serif" font-size="11"><text x="16.5" y="15" fill="#010101" fill-opacity=".3">pact</text><text x="16.5" y="14">pact</text><text x="62.5" y="15" fill="#010101" fill-opacity=".3">unknown</text><text x="62.5" y="14">unknown</text></g></svg>
@@ -0,0 +1 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="84" height="20"><linearGradient id="b" x2="0" y2="100%"><stop offset="0" stop-color="#bbb" stop-opacity=".1"/><stop offset="1" stop-opacity=".1"/></linearGradient><clipPath id="a"><rect width="84" height="20" rx="3" fill="#fff"/></clipPath><g clip-path="url(#a)"><path fill="#555" d="M0 0h33v20H0z"/><path fill="#4c1" d="M33 0h51v20H33z"/><path fill="url(#b)" d="M0 0h84v20H0z"/></g><g fill="#fff" text-anchor="middle" font-family="DejaVu Sans,Verdana,Geneva,sans-serif" font-size="11"><text x="16.5" y="15" fill="#010101" fill-opacity=".3">pact</text><text x="16.5" y="14">pact</text><text x="57.5" y="15" fill="#010101" fill-opacity=".3">verified</text><text x="57.5" y="14">verified</text></g></svg>
@@ -0,0 +1 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="152" height="20"><linearGradient id="b" x2="0" y2="100%"><stop offset="0" stop-color="#bbb" stop-opacity=".1"/><stop offset="1" stop-opacity=".1"/></linearGradient><clipPath id="a"><rect width="152" height="20" rx="3" fill="#fff"/></clipPath><g clip-path="url(#a)"><path fill="#555" d="M0 0h91v20H0z"/><path fill="#9f9f9f" d="M91 0h61v20H91z"/><path fill="url(#b)" d="M0 0h152v20H0z"/></g><g fill="#fff" text-anchor="middle" font-family="DejaVu Sans,Verdana,Geneva,sans-serif" font-size="11"><text x="45.5" y="15" fill="#010101" fill-opacity=".3">pact not found</text><text x="45.5" y="14">pact not found</text><text x="120.5" y="15" fill="#010101" fill-opacity=".3">unknown</text><text x="120.5" y="14">unknown</text></g></svg>
@@ -0,0 +1,53 @@
1
+ require 'webmock/rspec'
2
+
3
+ describe "get latest pact badge" do
4
+
5
+ before do
6
+ PactBroker.configuration.enable_badge_resources = true
7
+ TestDataBuilder.new
8
+ .create_consumer('consumer')
9
+ .create_provider('provider')
10
+ .create_consumer_version('1.2.3')
11
+ .create_pact
12
+ .create_verification
13
+ end
14
+
15
+ let!(:http_request) do
16
+ stub_request(:get, /http/).to_return(:status => 200, :body => "<svg/>")
17
+ end
18
+
19
+ let(:path) { "/pacts/provider/provider/consumer/consumer/latest/badge" }
20
+
21
+ # In the full app, the .svg extension is turned into an Accept header
22
+ # by ConvertFileExtensionToAcceptHeader
23
+
24
+ subject { get path, nil, {'HTTP_ACCEPT' => "image/svg+xml"}; last_response }
25
+
26
+ it "returns a 200 status" do
27
+ expect(subject.status).to eq 200
28
+ end
29
+
30
+ it "returns an svg/xml response" do
31
+ expect(subject.headers['Content-Type']).to include("image/svg+xml")
32
+ end
33
+
34
+ it "returns an svg body" do
35
+ expect(subject.body).to include "<svg/>"
36
+ end
37
+
38
+ context "when the pact doesn't exist" do
39
+ let(:path) { "/pacts/provider/foo/consumer/bar/latest/badge" }
40
+
41
+ it "returns a 200 status" do
42
+ expect(subject.status).to eq 200
43
+ end
44
+
45
+ it "returns an svg/xml response" do
46
+ expect(subject.headers['Content-Type']).to include("image/svg+xml")
47
+ end
48
+
49
+ it "returns a static svg image" do
50
+ expect(subject.body).to include ">unknown<"
51
+ end
52
+ end
53
+ end
@@ -0,0 +1,38 @@
1
+ require 'webmock/rspec'
2
+
3
+ describe "get latest tagged pact badge" do
4
+
5
+ before do
6
+ PactBroker.configuration.enable_badge_resources = true
7
+ PactBroker.configuration.shields_io_base_url = nil
8
+ TestDataBuilder.new
9
+ .create_consumer('consumer')
10
+ .create_provider('provider')
11
+ .create_consumer_version('1.0.0')
12
+ .create_consumer_version_tag('prod')
13
+ .create_pact
14
+ .create_verification(success: true)
15
+ .create_consumer_version('1.2.3')
16
+ .create_pact
17
+ .create_verification(success: false)
18
+ end
19
+
20
+ let(:path) { "/pacts/provider/provider/consumer/consumer/latest/prod/badge" }
21
+
22
+ # In the full app, the .svg extension is turned into an Accept header
23
+ # by ConvertFileExtensionToAcceptHeader
24
+
25
+ subject { get path, nil, {'HTTP_ACCEPT' => "image/svg+xml"}; last_response }
26
+
27
+ it "returns a 200 status" do
28
+ expect(subject.status).to eq 200
29
+ end
30
+
31
+ it "returns an svg/xml response" do
32
+ expect(subject.headers['Content-Type']).to include("image/svg+xml")
33
+ end
34
+
35
+ it "returns an svg body" do
36
+ expect(subject.body).to include ">verified<"
37
+ end
38
+ end
@@ -0,0 +1,38 @@
1
+ require 'webmock/rspec'
2
+
3
+ describe "get latest untagged pact badge" do
4
+
5
+ before do
6
+ PactBroker.configuration.enable_badge_resources = true
7
+ PactBroker.configuration.shields_io_base_url = nil
8
+ TestDataBuilder.new
9
+ .create_consumer('consumer')
10
+ .create_provider('provider')
11
+ .create_consumer_version('1.0.0')
12
+ .create_pact
13
+ .create_verification(success: true)
14
+ .create_consumer_version('1.2.3')
15
+ .create_consumer_version_tag('prod')
16
+ .create_pact
17
+ .create_verification(success: false)
18
+ end
19
+
20
+ let(:path) { "/pacts/provider/provider/consumer/consumer/latest-untagged/badge" }
21
+
22
+ # In the full app, the .svg extension is turned into an Accept header
23
+ # by ConvertFileExtensionToAcceptHeader
24
+
25
+ subject { get path, nil, {'HTTP_ACCEPT' => "image/svg+xml"}; last_response }
26
+
27
+ it "returns a 200 status" do
28
+ expect(subject.status).to eq 200
29
+ end
30
+
31
+ it "returns an svg/xml response" do
32
+ expect(subject.headers['Content-Type']).to include("image/svg+xml")
33
+ end
34
+
35
+ it "returns an svg body" do
36
+ expect(subject.body).to include ">verified<"
37
+ end
38
+ end
@@ -12,6 +12,8 @@ describe "Recording a pact verification" do
12
12
  TestDataBuilder.new
13
13
  .create_provider("Provider")
14
14
  .create_consumer("Consumer")
15
+ .create_consumer_version("1.0.0")
16
+ .create_pact
15
17
  .create_consumer_version("1.2.3")
16
18
  .create_pact
17
19
  .revise_pact
@@ -22,10 +24,15 @@ describe "Recording a pact verification" do
22
24
  expect(subject.status).to be 201
23
25
  end
24
26
 
25
- it "saves a verification against the pact" do
27
+ it "saves new verification" do
26
28
  expect { subject }.to change { PactBroker::Domain::Verification.count }.by(1)
27
29
  end
28
30
 
31
+ it "saves the verification against the correct pact" do
32
+ subject
33
+ expect(PactBroker::Domain::Verification.order(:id).last.pact_version_sha).to eq pact.pact_version_sha
34
+ end
35
+
29
36
  it "returns a link to itself that can be followed" do
30
37
  get_verification_link = parsed_response_body['_links']['self']['href']
31
38
  get get_verification_link
@@ -0,0 +1,104 @@
1
+ require 'pact_broker/api/resources/badge'
2
+ require 'pact_broker/badges/service'
3
+
4
+ module PactBroker
5
+ module Api
6
+ module Resources
7
+ describe Badge do
8
+ let(:path) { "/pacts/provider/provider/consumer/consumer/latest/badge" }
9
+ let(:params) { {} }
10
+
11
+ subject { get path, params, {'HTTP_ACCEPT' => 'image/svg+xml'}; last_response }
12
+
13
+ context "when enable_badge_resources is false" do
14
+ before do
15
+ PactBroker.configuration.enable_badge_resources = false
16
+ end
17
+
18
+ it "returns a 404" do
19
+ expect(subject.status).to eq 404
20
+ end
21
+ end
22
+
23
+ context "when enable_badge_resources is true" do
24
+ before do
25
+ PactBroker.configuration.enable_badge_resources = true
26
+ allow(PactBroker::Pacts::Service).to receive(:find_latest_pact).and_return(pact)
27
+ allow(PactBroker::Verifications::Service).to receive(:find_latest_verification_for).and_return(verification)
28
+ allow(PactBroker::Badges::Service).to receive(:pact_verification_badge).and_return("badge")
29
+ allow(PactBroker::Verifications::Status).to receive(:new).and_return(verification_status)
30
+ end
31
+
32
+ let(:pact) { instance_double("PactBroker::Domain::Pact", consumer: consumer, provider: provider) }
33
+ let(:consumer) { double('consumer') }
34
+ let(:provider) { double('provider') }
35
+ let(:verification) { double("verification") }
36
+ let(:verification_status) { instance_double("PactBroker::Verifications::Status", to_sym: :verified) }
37
+
38
+ it "retrieves the latest pact" do
39
+ expect(PactBroker::Pacts::Service).to receive(:find_latest_pact)
40
+ subject
41
+ end
42
+
43
+ it "retrieves the latest verification for the pact's consumer and provider" do
44
+ expect(PactBroker::Verifications::Service).to receive(:find_latest_verification_for).with(consumer, provider, nil)
45
+ subject
46
+ end
47
+
48
+ it "determines the pact's verification status based on the latest pact and latest verification" do
49
+ expect(PactBroker::Verifications::Status).to receive(:new).with(pact, verification)
50
+ subject
51
+ end
52
+
53
+ it "creates a badge" do
54
+ expect(PactBroker::Badges::Service).to receive(:pact_verification_badge).with(pact, nil, false, :verified)
55
+ subject
56
+ end
57
+
58
+ it "returns a 200 status" do
59
+ expect(subject.status).to eq 200
60
+ end
61
+
62
+ it "returns the badge" do
63
+ expect(subject.body).to eq "badge"
64
+ end
65
+
66
+ context "when the label param is specified" do
67
+ let(:params) { {label: 'consumer'} }
68
+
69
+ it "creates a badge with the specified label" do
70
+ expect(PactBroker::Badges::Service).to receive(:pact_verification_badge).with(anything, 'consumer', anything, anything)
71
+ subject
72
+ end
73
+ end
74
+
75
+ context "when the initials param is true" do
76
+ let(:params) { {initials: 'true'} }
77
+
78
+ it "creates a badge with initials" do
79
+ expect(PactBroker::Badges::Service).to receive(:pact_verification_badge).with(anything, anything, true, anything)
80
+ subject
81
+ end
82
+ end
83
+
84
+ context "when the pact is not found" do
85
+ let(:pact) { nil }
86
+
87
+ it "returns a 200 status" do
88
+ expect(subject.status).to eq 200
89
+ end
90
+ end
91
+
92
+ context "when retrieving the badge for the latest pact with a tag" do
93
+ let(:path) { "/pacts/provider/provider/consumer/consumer/latest/prod/badge" }
94
+
95
+ it "retrieves the latest verification for the pact's consumer and provider and specified tag" do
96
+ expect(PactBroker::Verifications::Service).to receive(:find_latest_verification_for).with(anything, anything, 'prod')
97
+ subject
98
+ end
99
+ end
100
+ end
101
+ end
102
+ end
103
+ end
104
+ end
@@ -0,0 +1,244 @@
1
+ require 'pact_broker/badges/service'
2
+ require 'webmock/rspec'
3
+
4
+ module PactBroker
5
+ module Badges
6
+ module Service
7
+ describe "#pact_verification_badge" do
8
+ let(:pacticipant_name) { "Foo-Bar_Thing Service" }
9
+ let(:pact) { double("pact", consumer_name: "Foo-Bar", provider_name: "Thing_Blah") }
10
+ let(:label) { nil }
11
+ let(:initials) { false }
12
+ let(:verification_status) { :success }
13
+
14
+ let(:expected_url) { "https://img.shields.io/badge/#{expected_left_text}-#{expected_right_text}-#{expected_color}.svg" }
15
+ let(:expected_color) { "brightgreen" }
16
+ let(:expected_right_text) { "verified" }
17
+ let(:expected_left_text) { "foo--bar%2Fthing__blah%20pact" }
18
+ let(:response_status) { 200 }
19
+ let!(:http_request) do
20
+ stub_request(:get, expected_url).to_return(:status => response_status, :body => "svg")
21
+ end
22
+
23
+ let(:subject) { PactBroker::Badges::Service.pact_verification_badge pact, label, initials, verification_status }
24
+
25
+ it "returns the svg file" do
26
+ expect(subject).to eq "svg"
27
+ end
28
+
29
+ context "when the label is not specified" do
30
+ it "creates a badge with the consumer and provider names" do
31
+ subject
32
+ expect(http_request).to have_been_made
33
+ end
34
+
35
+ context "when initials is true" do
36
+ let(:expected_left_text) { "fb%2Ftb%20pact" }
37
+ let(:initials) { true }
38
+
39
+ it "creates a badge with the consumer and provider initials" do
40
+ subject
41
+ expect(http_request).to have_been_made
42
+ end
43
+ end
44
+
45
+ context "when initials is true but the consumer and provider names only contain one word" do
46
+ let(:expected_left_text) { "foo%2Fbar%20pact" }
47
+ let(:initials) { true }
48
+ let(:pact) { double("pact", consumer_name: "Foo", provider_name: "Bar") }
49
+
50
+ it "creates a badge with the consumer and provider names, not initials" do
51
+ subject
52
+ expect(http_request).to have_been_made
53
+ end
54
+ end
55
+
56
+ context "when initials is true but the consumer and provider names are one camel cased word" do
57
+ let(:expected_left_text) { "fa%2Fbp%20pact" }
58
+ let(:initials) { true }
59
+ let(:pact) { double("pact", consumer_name: "FooApp", provider_name: "barProvider") }
60
+
61
+ it "creates a badge with the consumer and provider names, not initials" do
62
+ subject
63
+ expect(http_request).to have_been_made
64
+ end
65
+ end
66
+
67
+ context "when initials is true but the consumer and provider names are one camel cased word" do
68
+ let(:expected_left_text) { "fa%2Fdat%20pact" }
69
+ let(:initials) { true }
70
+ let(:pact) { double("pact", consumer_name: "FooApp", provider_name: "doAThing") }
71
+
72
+ it "creates a badge with the consumer and provider names, not initials", pending: "Need to make regexp smarter" do
73
+ subject
74
+ expect(http_request).to have_been_made
75
+ end
76
+ end
77
+ end
78
+
79
+ context "when label is consumer" do
80
+ let(:expected_left_text) { "foo--bar%20pact" }
81
+ let(:label) { 'consumer' }
82
+
83
+ it "creates a badge with only the consumer name" do
84
+ subject
85
+ expect(http_request).to have_been_made
86
+ end
87
+
88
+ context "when initials is true" do
89
+ let(:expected_left_text) { "fb%20pact" }
90
+ let(:initials) { true }
91
+
92
+ it "creates a badge with only the consumer initials" do
93
+ subject
94
+ expect(http_request).to have_been_made
95
+ end
96
+ end
97
+ end
98
+
99
+ context "when label is provider" do
100
+ let(:expected_left_text) { "thing__blah%20pact" }
101
+ let(:label) { 'provider' }
102
+
103
+ it "creates a badge with only the provider name" do
104
+ subject
105
+ expect(http_request).to have_been_made
106
+ end
107
+
108
+ context "when initials is true" do
109
+ let(:expected_left_text) { "tb%20pact" }
110
+ let(:initials) { true }
111
+
112
+ it "creates a badge with only the provider initials" do
113
+ subject
114
+ expect(http_request).to have_been_made
115
+ end
116
+ end
117
+ end
118
+
119
+ context "when the verification_status is :success" do
120
+ it "create a green badge with left text 'verified'" do
121
+ subject
122
+ expect(http_request).to have_been_made
123
+ end
124
+ end
125
+
126
+ context "when the verification_status is :never" do
127
+ let(:verification_status) { :never }
128
+ let(:expected_color) { "lightgrey" }
129
+ let(:expected_right_text) { "unknown" }
130
+
131
+ it "create a lightgrey badge with left text 'unknown'" do
132
+ subject
133
+ expect(http_request).to have_been_made
134
+ end
135
+ end
136
+
137
+ context "when the verification_status is :failed" do
138
+ let(:verification_status) { :failed }
139
+ let(:expected_color) { "red" }
140
+ let(:expected_right_text) { "failed" }
141
+
142
+ it "create a red badge with left text 'failed'" do
143
+ subject
144
+ expect(http_request).to have_been_made
145
+ end
146
+ end
147
+
148
+ context "when the verification_status is :stale" do
149
+ let(:verification_status) { :stale }
150
+ let(:expected_color) { "orange" }
151
+ let(:expected_right_text) { "changed" }
152
+
153
+ it "create a orange badge with left text 'changed'" do
154
+ subject
155
+ expect(http_request).to have_been_made
156
+ end
157
+ end
158
+
159
+ context "when the pact is nil" do
160
+ let(:pact) { nil }
161
+ it "does not make a dynamic badge" do
162
+ subject
163
+ expect(http_request).to_not have_been_made
164
+ end
165
+
166
+ it "returns a static image" do
167
+ expect(subject).to include ">pact not found</"
168
+ expect(subject).to include ">unknown</"
169
+ end
170
+ end
171
+
172
+ context "when a non-200 response is returned" do
173
+ let(:expected_url) { /http/ }
174
+ let(:response_status) { 404 }
175
+
176
+ context "when the verification_status is success" do
177
+ it "returns a static success image" do
178
+ expect(subject).to include ">pact</"
179
+ expect(subject).to include ">verified</"
180
+ end
181
+ end
182
+
183
+ context "when the verification_status is failed" do
184
+ let(:verification_status) { :failed }
185
+
186
+ it "returns a static failed image" do
187
+ expect(subject).to include ">pact</"
188
+ expect(subject).to include ">failed</"
189
+ end
190
+ end
191
+
192
+ context "when the verification_status is stale" do
193
+ let(:verification_status) { :stale }
194
+
195
+ it "returns a static stale image" do
196
+ expect(subject).to include ">pact</"
197
+ expect(subject).to include ">changed</"
198
+ end
199
+ end
200
+
201
+ context "when the verification_status is never" do
202
+ let(:verification_status) { :never }
203
+
204
+ it "returns a static stale image" do
205
+ expect(subject).to include ">pact</"
206
+ expect(subject).to include ">unknown</"
207
+ end
208
+ end
209
+ end
210
+
211
+ context "when an exception is raised connecting to the shields.io server" do
212
+ before do
213
+ allow(Net::HTTP).to receive(:start).and_raise("an error")
214
+ end
215
+
216
+ it "logs the error" do
217
+ expect(PactBroker.logger).to receive(:error).with(/Error retrieving badge from.*shield.*an error/)
218
+ subject
219
+ end
220
+
221
+ it "returns a static image" do
222
+ expect(subject).to include ">pact</"
223
+ end
224
+ end
225
+
226
+ context "when the shields_io_base_url is not configured" do
227
+ before do
228
+ PactBroker.configuration.shields_io_base_url = nil
229
+ end
230
+
231
+ it "does not make an http request" do
232
+ subject
233
+ expect(http_request).to_not have_been_made
234
+ end
235
+
236
+ it "returns a static image" do
237
+ expect(subject).to include ">pact</"
238
+ expect(subject).to include ">verified</"
239
+ end
240
+ end
241
+ end
242
+ end
243
+ end
244
+ end