Skip to content

Commit 41c6d91

Browse files
committed
feat(pacts for verification): include a short description of the pact's selectors in the response
1 parent 4308117 commit 41c6d91

6 files changed

+168
-80
lines changed

lib/pact_broker/api/decorators/verifiable_pact_decorator.rb

+4-30
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,13 @@
11
require_relative 'base_decorator'
22
require 'pact_broker/api/pact_broker_urls'
3-
require 'delegate'
4-
require 'pact_broker/pacts/verifiable_pact_messages'
3+
require 'pact_broker/pacts/build_verifiable_pact_notices'
54

65
module PactBroker
76
module Api
87
module Decorators
98
class VerifiablePactDecorator < BaseDecorator
10-
def initialize(verifiable_pact)
11-
super(verifiable_pact)
12-
end
9+
10+
property :shortDescription, getter: -> (context) { PactBroker::Pacts::VerifiablePactMessages.new(context[:represented], nil).pact_version_short_description }
1311

1412
nested :verificationProperties do
1513
include PactBroker::Api::PactBrokerUrls
@@ -22,32 +20,8 @@ def initialize(verifiable_pact)
2220
property :noteToDevelopers, getter: -> (_) { "Please print out the text from the 'notices' rather than using the inclusionReason and the pendingReason fields. These will be removed when this API moves out of beta."}
2321

2422
def notices(user_options)
25-
# TODO move this out of the decorator
2623
pact_url = pact_version_url(represented, user_options[:base_url])
27-
messages = PactBroker::Pacts::VerifiablePactMessages.new(represented, pact_url)
28-
29-
the_notices = [{
30-
when: 'before_verification',
31-
text: messages.inclusion_reason
32-
}]
33-
34-
if user_options[:include_pending_status]
35-
append_notice(the_notices, 'before_verification', messages.pending_reason)
36-
append_notice(the_notices, 'after_verification:success_true_published_false', messages.verification_success_true_published_false)
37-
append_notice(the_notices, 'after_verification:success_false_published_false', messages.verification_success_false_published_false)
38-
append_notice(the_notices, 'after_verification:success_true_published_true', messages.verification_success_true_published_true)
39-
append_notice(the_notices, 'after_verification:success_false_published_true', messages.verification_success_false_published_true)
40-
end
41-
the_notices
42-
end
43-
44-
def append_notice the_notices, the_when, text
45-
if text
46-
the_notices << {
47-
when: the_when,
48-
text: text
49-
}
50-
end
24+
PactBroker::Pacts::BuildVerifiablePactNotices.call(represented, pact_url, include_pending_status: user_options[:include_pending_status])
5125
end
5226
end
5327

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
require 'pact_broker/pacts/verifiable_pact_messages'
2+
3+
module PactBroker
4+
module Pacts
5+
class BuildVerifiablePactNotices
6+
7+
def self.call(verifiable_pact, pact_url, options)
8+
messages = VerifiablePactMessages.new(verifiable_pact, pact_url)
9+
10+
notices = [{
11+
when: 'before_verification',
12+
text: messages.inclusion_reason
13+
}]
14+
15+
if options[:include_pending_status]
16+
append_notice(notices, 'before_verification', messages.pending_reason)
17+
append_notice(notices, 'after_verification:success_true_published_false', messages.verification_success_true_published_false)
18+
append_notice(notices, 'after_verification:success_false_published_false', messages.verification_success_false_published_false)
19+
append_notice(notices, 'after_verification:success_true_published_true', messages.verification_success_true_published_true)
20+
append_notice(notices, 'after_verification:success_false_published_true', messages.verification_success_false_published_true)
21+
end
22+
notices
23+
end
24+
25+
def self.append_notice notices, the_when, text
26+
if text
27+
notices << {
28+
when: the_when,
29+
text: text
30+
}
31+
end
32+
end
33+
end
34+
end
35+
end

lib/pact_broker/pacts/verifiable_pact_messages.rb

+25
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,10 @@ def verification_success_false_published_true
6464
verification_success_false_published_false
6565
end
6666

67+
def pact_version_short_description
68+
short_selector_descriptions
69+
end
70+
6771
private
6872

6973
attr_reader :verifiable_pact, :pact_version_url
@@ -141,6 +145,27 @@ def selector_description selector
141145
end
142146
end
143147

148+
def short_selector_descriptions
149+
selectors.collect{ | selector | short_selector_description(selector) }.join(", ")
150+
end
151+
152+
# this is used by Pact Go to create the test method name, so needs to be concise
153+
def short_selector_description selector
154+
if selector.overall_latest?
155+
"latest"
156+
elsif selector.latest_for_tag?
157+
if selector.fallback_tag?
158+
"latest #{selector.fallback_tag}"
159+
else
160+
"latest #{selector.tag}"
161+
end
162+
elsif selector.tag
163+
"one of #{selector.tag}"
164+
else
165+
selector.to_json
166+
end
167+
end
168+
144169
def selectors
145170
verifiable_pact.selectors
146171
end

spec/lib/pact_broker/api/decorators/verifiable_pact_decorator_spec.rb

+18-40
Original file line numberDiff line numberDiff line change
@@ -5,53 +5,41 @@ module Api
55
module Decorators
66
describe VerifiablePactDecorator do
77
before do
8-
allow_any_instance_of(PactBroker::Api::PactBrokerUrls).to receive(:pact_version_url).and_return('/pact-version-url')
9-
allow_any_instance_of(PactBroker::Pacts::VerifiablePactMessages).to receive(:inclusion_reason).and_return("the inclusion reason")
10-
allow_any_instance_of(PactBroker::Pacts::VerifiablePactMessages).to receive(:pending_reason).and_return(pending_reason)
11-
allow_any_instance_of(PactBroker::Pacts::VerifiablePactMessages).to receive(:verification_success_true_published_false).and_return('verification_success_true_published_false')
12-
allow_any_instance_of(PactBroker::Pacts::VerifiablePactMessages).to receive(:verification_success_false_published_false).and_return('verification_success_false_published_false')
13-
allow_any_instance_of(PactBroker::Pacts::VerifiablePactMessages).to receive(:verification_success_true_published_true).and_return('verification_success_true_published_true')
14-
allow_any_instance_of(PactBroker::Pacts::VerifiablePactMessages).to receive(:verification_success_false_published_true).and_return('verification_success_false_published_true')
8+
allow_any_instance_of(PactBroker::Api::PactBrokerUrls).to receive(:pact_version_url).and_return('http://pact')
9+
allow(PactBroker::Pacts::BuildVerifiablePactNotices).to receive(:call).and_return(notices)
10+
allow_any_instance_of(PactBroker::Pacts::VerifiablePactMessages).to receive(:pact_version_short_description).and_return('short desc')
1511
end
12+
1613
let(:pending_reason) { "the pending reason" }
14+
let(:notices) do
15+
[
16+
{
17+
some: "notice"
18+
}
19+
]
20+
end
1721
let(:expected_hash) do
1822
{
23+
"shortDescription" => "short desc",
1924
"verificationProperties" => {
2025
"pending" => true,
2126
"notices" => [
2227
{
23-
"when" => "before_verification",
24-
"text" => "the inclusion reason"
25-
},{
26-
"when" => "before_verification",
27-
"text" => pending_reason
28-
},{
29-
"when" => "after_verification:success_true_published_false",
30-
"text" => "verification_success_true_published_false"
31-
},{
32-
"when" => "after_verification:success_false_published_false",
33-
"text" => "verification_success_false_published_false"
34-
},{
35-
"when" => "after_verification:success_true_published_true",
36-
"text" => "verification_success_true_published_true"
37-
},{
38-
"when" => "after_verification:success_false_published_true",
39-
"text" => "verification_success_false_published_true"
28+
"some" => "notice"
4029
}
4130
]
4231
},
4332
"_links" => {
4433
"self" => {
45-
"href" => "/pact-version-url",
34+
"href" => "http://pact",
4635
"name" => "name"
4736
}
4837
}
4938
}
5039
end
51-
5240
let(:decorator) { VerifiablePactDecorator.new(pact) }
5341
let(:pact) do
54-
double('pact',
42+
double('PactBroker::Pacts::VerifiablePact',
5543
pending: true,
5644
wip: wip,
5745
name: "name",
@@ -61,10 +49,10 @@ module Decorators
6149
end
6250
let(:pending_provider_tags) { %w[dev] }
6351
let(:consumer_tags) { %w[dev] }
64-
let(:json) { decorator.to_json(options) }
6552
let(:options) { { user_options: { base_url: 'http://example.org', include_pending_status: include_pending_status } } }
6653
let(:include_pending_status) { true }
6754
let(:wip){ false }
55+
let(:json) { decorator.to_json(options) }
6856

6957
subject { JSON.parse(json) }
7058

@@ -77,27 +65,17 @@ module Decorators
7765
subject
7866
end
7967

80-
it "creates the inclusion message" do
81-
expect(PactBroker::Pacts::VerifiablePactMessages).to receive(:new).with(pact, '/pact-version-url').and_call_original
68+
it "creates the notices" do
69+
allow(PactBroker::Pacts::BuildVerifiablePactNotices).to receive(:call).with(pact, 'http://pact', include_pending_status: include_pending_status)
8270
subject
8371
end
8472

8573
context "when include_pending_status is false" do
8674
let(:include_pending_status) { false }
87-
let(:notices) { subject['verificationProperties']['notices'].collect{ | notice | notice['text'] } }
8875

8976
it "does not include the pending flag" do
9077
expect(subject['verificationProperties']).to_not have_key('pending')
9178
end
92-
93-
it "does not include the pending reason" do
94-
expect(subject['verificationProperties']).to_not have_key('pendingReason')
95-
expect(notices).to_not include(pending_reason)
96-
end
97-
98-
it "does not include the pending notices" do
99-
expect(subject['verificationProperties']['notices'].size).to eq 1
100-
end
10179
end
10280

10381
context "when wip is true" do
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
require 'pact_broker/pacts/build_verifiable_pact_notices'
2+
3+
module PactBroker
4+
module Pacts
5+
describe BuildVerifiablePactNotices do
6+
before do
7+
allow(VerifiablePactMessages).to receive(:new).and_return(verifiable_pact_messages)
8+
end
9+
10+
let(:verifiable_pact_messages) do
11+
instance_double(VerifiablePactMessages,
12+
inclusion_reason: 'the inclusion reason',
13+
pending_reason: 'pending reason',
14+
verification_success_true_published_false: 'verification_success_true_published_false',
15+
verification_success_false_published_false: 'verification_success_false_published_false',
16+
verification_success_true_published_true: 'verification_success_true_published_true',
17+
verification_success_false_published_true: 'verification_success_false_published_true'
18+
)
19+
end
20+
21+
let(:options) { {} }
22+
let(:pact_url) { 'http://pact' }
23+
let(:verifiable_pact) { instance_double('PactBroker::Pacts::VerifiablePact') }
24+
25+
subject { BuildVerifiablePactNotices.call(verifiable_pact, pact_url, options) }
26+
27+
28+
context "when include_pending_status is true" do
29+
let(:expected_notices) do
30+
[
31+
{
32+
:when => "before_verification",
33+
:text => "the inclusion reason"
34+
},{
35+
:when => "before_verification",
36+
:text => 'pending reason'
37+
},{
38+
:when => "after_verification:success_true_published_false",
39+
:text => "verification_success_true_published_false"
40+
},{
41+
:when => "after_verification:success_false_published_false",
42+
:text => "verification_success_false_published_false"
43+
},{
44+
:when => "after_verification:success_true_published_true",
45+
:text => "verification_success_true_published_true"
46+
},{
47+
:when => "after_verification:success_false_published_true",
48+
:text => "verification_success_false_published_true"
49+
}
50+
]
51+
end
52+
53+
let(:options) { { include_pending_status: true } }
54+
55+
it "it returns a list of notices with information about the pending status" do
56+
expect(subject).to eq expected_notices
57+
end
58+
end
59+
60+
context "when include_pending_status is not true" do
61+
let(:expected_notices) do
62+
[
63+
{
64+
:when => "before_verification",
65+
:text => "the inclusion reason"
66+
}
67+
]
68+
end
69+
70+
it "it returns a list of notices without information about the pending status" do
71+
expect(subject).to eq expected_notices
72+
end
73+
end
74+
end
75+
end
76+
end

spec/lib/pact_broker/pacts/verifiable_pact_messages_spec.rb

+10-10
Original file line numberDiff line numberDiff line change
@@ -9,20 +9,20 @@ module Pacts
99
let(:non_pending_provider_tags) { [] }
1010
let(:pending) { false }
1111
let(:wip) { false }
12+
let(:selectors) { Selectors.new }
13+
let(:pact_version_url) { "http://pact" }
1214
let(:verifiable_pact) do
1315
double(VerifiablePact,
14-
consumer_name: "Foo",
15-
consumer_version_number: "123",
16-
provider_name: "Bar",
17-
pending_provider_tags: pending_provider_tags,
18-
non_pending_provider_tags: non_pending_provider_tags,
19-
pending?: pending,
20-
wip?: wip,
21-
selectors: selectors
16+
consumer_name: "Foo",
17+
consumer_version_number: "123",
18+
provider_name: "Bar",
19+
pending_provider_tags: pending_provider_tags,
20+
non_pending_provider_tags: non_pending_provider_tags,
21+
pending?: pending,
22+
wip?: wip,
23+
selectors: selectors
2224
)
2325
end
24-
let(:selectors) { [] }
25-
let(:pact_version_url) { "http://pact" }
2626

2727
subject { VerifiablePactMessages.new(verifiable_pact, pact_version_url) }
2828

0 commit comments

Comments
 (0)