Skip to content

Commit 50c003b

Browse files
committed
feat: add resource for "work in progress" pacts for a provider
1 parent ccdd46f commit 50c003b

10 files changed

+199
-3
lines changed

lib/pact_broker/api.rb

+1
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ module PactBroker
3838
add ['pacts', 'provider', :provider_name, 'consumer', :consumer_name, 'latest-untagged'], Api::Resources::LatestPact, {resource_name: "latest_untagged_pact_publication", tag: :untagged}
3939
add ['pacts', 'provider', :provider_name, 'latest'], Api::Resources::LatestProviderPacts, {resource_name: "latest_provider_pact_publications"}
4040
add ['pacts', 'provider', :provider_name, 'latest', :tag], Api::Resources::LatestProviderPacts, {resource_name: "latest_tagged_provider_pact_publications"}
41+
add ['pacts', 'provider', :provider_name, 'wip'], Api::Resources::WipProviderPacts, {resource_name: "wip_provider_pact_publications"}
4142
add ['pacts', 'latest'], Api::Resources::LatestPacts, {resource_name: "latest_pacts"}
4243

4344
# Deprecated pact

lib/pact_broker/api/resources/index.rb

+6
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,12 @@ def to_json
6565
title: 'All pact versions for the specified provider',
6666
templated: true
6767
},
68+
'pb:wip-provider-pacts' =>
69+
{
70+
href: base_url + '/pacts/provider/{provider}/wip',
71+
title: 'WIP pact versions for the specified provider',
72+
templated: true
73+
},
6874
'pb:latest-version' => {
6975
href: base_url + '/pacticipants/{pacticipant}/latest-version',
7076
title: 'Latest pacticipant version',
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
require 'pact_broker/api/resources/provider_pacts'
2+
require 'pact_broker/configuration'
3+
require 'pact_broker/api/decorators/provider_pacts_decorator'
4+
5+
module PactBroker
6+
module Api
7+
module Resources
8+
class WipProviderPacts < ProviderPacts
9+
private
10+
11+
def pacts
12+
pact_service.find_wip_pact_versions_for_provider provider_name
13+
end
14+
15+
def resource_title
16+
"WIP pact versions for the provider #{provider_name}"
17+
end
18+
end
19+
end
20+
end
21+
end

lib/pact_broker/pacts/pact_publication.rb

+6-2
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
require 'pact_broker/domain/pact'
22
require 'pact_broker/pacts/pact_version'
3+
require 'pact_broker/repositories/helpers'
34

45
module PactBroker
56
module Pacts
6-
77
class PactPublication < Sequel::Model(:pact_publications)
88

99
extend Forwardable
@@ -15,7 +15,9 @@ class PactPublication < Sequel::Model(:pact_publications)
1515
associate(:many_to_one, :consumer_version, :class => "PactBroker::Domain::Version", :key => :consumer_version_id, :primary_key => :id)
1616
associate(:many_to_one, :pact_version, class: "PactBroker::Pacts::PactVersion", :key => :pact_version_id, :primary_key => :id)
1717

18-
PactPublication.plugin :timestamps, :update_on_create=>true
18+
dataset_module do
19+
include PactBroker::Repositories::Helpers
20+
end
1921

2022
def before_create
2123
super
@@ -55,5 +57,7 @@ def cached_domain_for_delegation
5557
@domain_object ||= to_domain
5658
end
5759
end
60+
61+
PactPublication.plugin :timestamps, update_on_create: true
5862
end
5963
end

lib/pact_broker/pacts/repository.rb

+7
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ module Pacts
1616
class Repository
1717

1818
include PactBroker::Logging
19+
include PactBroker::Repositories
1920

2021
def create params
2122
PactPublication.new(
@@ -71,6 +72,12 @@ def find_latest_pact_versions_for_provider provider_name, tag = nil
7172
end
7273
end
7374

75+
def find_wip_pact_versions_for_provider provider_name
76+
provider_id = pacticipant_repository.find_by_name(provider_name).id
77+
pact_publication_ids = PactBroker::Matrix::HeadRow.where(provider_id: provider_id).exclude(success: true).select_for_subquery(:pact_publication_id)
78+
AllPactPublications.where(id: pact_publication_ids).order_ignore_case(:consumer_name).order_append(:consumer_version_order).collect(&:to_domain)
79+
end
80+
7481
def find_pact_versions_for_provider provider_name, tag = nil
7582
if tag
7683
LatestPactPublicationsByConsumerVersion

lib/pact_broker/pacts/service.rb

+4
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,10 @@ def find_latest_pact_versions_for_provider provider_name, options = {}
7272
pact_repository.find_latest_pact_versions_for_provider provider_name, options[:tag]
7373
end
7474

75+
def find_wip_pact_versions_for_provider provider_name
76+
pact_repository.find_wip_pact_versions_for_provider provider_name
77+
end
78+
7579
def find_pact_versions_for_provider provider_name, options = {}
7680
pact_repository.find_pact_versions_for_provider provider_name, options[:tag]
7781
end
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
describe "Get WIP provider pacts" do
2+
subject { get path; last_response }
3+
4+
let(:last_response_body) { JSON.parse(subject.body, symbolize_names: true) }
5+
let(:pact_links) { last_response_body[:_links][:'pb:pacts'] }
6+
7+
context "when the provider exists" do
8+
before do
9+
TestDataBuilder.new
10+
.create_provider("Provider")
11+
.create_consumer("Consumer")
12+
.create_consumer_version("0.0.1")
13+
.create_pact
14+
end
15+
16+
let(:path) { "/pacts/provider/Provider/wip" }
17+
18+
it "returns a 200 HAL JSON response" do
19+
expect(subject).to be_a_hal_json_success_response
20+
end
21+
22+
it "returns a list of links to the pacts" do
23+
expect(pact_links.size).to eq 1
24+
end
25+
end
26+
end
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
require 'pact_broker/api/resources/latest_provider_pacts'
2+
3+
module PactBroker
4+
module Api
5+
module Resources
6+
describe WipProviderPacts do
7+
before do
8+
allow(PactBroker::Pacts::Service).to receive(:find_wip_pact_versions_for_provider).and_return(pacts)
9+
allow(PactBroker::Api::Decorators::ProviderPactsDecorator).to receive(:new).and_return(decorator)
10+
allow_any_instance_of(WipProviderPacts).to receive(:resource_exists?).and_return(provider)
11+
end
12+
13+
let(:provider) { double('provider') }
14+
let(:pacts) { double('pacts') }
15+
let(:path) { '/pacts/provider/Bar/wip' }
16+
let(:decorator) { instance_double('PactBroker::Api::Decorators::ProviderPactsDecorator') }
17+
18+
subject { get path; last_response }
19+
20+
it "finds the wip pacts for the provider" do
21+
expect(PactBroker::Pacts::Service).to receive(:find_wip_pact_versions_for_provider).with("Bar")
22+
subject
23+
end
24+
25+
it "sets the correct resource title" do
26+
expect(decorator).to receive(:to_json) do | options |
27+
expect(options[:user_options][:title]).to eq "WIP pact versions for the provider Bar"
28+
end
29+
subject
30+
end
31+
end
32+
end
33+
end
34+
end
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,94 @@
1+
require 'pact_broker/pacts/repository'
2+
3+
module PactBroker
4+
module Pacts
5+
describe Repository do
6+
let(:td) { TestDataBuilder.new }
7+
8+
describe "find_wip_pact_versions_for_provider" do
9+
subject { Repository.new.find_wip_pact_versions_for_provider("bar") }
10+
11+
context "when the latest pact for a tag has been successfully verified" do
12+
before do
13+
td.create_pact_with_hierarchy("foo", "1", "bar")
14+
.comment("above not included because it's not the latest prod")
15+
.create_consumer_version("2")
16+
.create_consumer_version_tag("prod")
17+
.create_pact
18+
.create_verification(provider_version: "3", comment: "not included because already verified")
19+
end
20+
21+
it "is not included" do
22+
expect(subject.size).to be 0
23+
end
24+
end
25+
26+
context "when the latest pact without a tag has failed verification" do
27+
before do
28+
td.create_pact_with_hierarchy("foo", "1", "bar")
29+
.create_verification(provider_version: "3", success: false)
30+
end
31+
32+
it "is included" do
33+
expect(subject.size).to be 1
34+
end
35+
end
36+
37+
context "when the latest pact without a tag has not been verified" do
38+
before do
39+
td.create_pact_with_hierarchy("foo", "1", "bar")
40+
.create_consumer_version("2")
41+
.create_pact
42+
end
43+
44+
it "is included" do
45+
expect(subject.first.consumer_version_number).to eq "2"
46+
expect(subject.size).to be 1
47+
end
48+
end
49+
50+
context "when the latest pact for a tag has failed verification" do
51+
before do
52+
td.create_pact_with_hierarchy("foo", "1", "bar")
53+
.create_consumer_version_tag("prod")
54+
.create_verification(provider_version: "3", success: true)
55+
.create_consumer_version("2", tag_names: ["prod"])
56+
.create_pact
57+
.create_verification(provider_version: "5", success: false)
58+
end
59+
60+
it "is included" do
61+
expect(subject.first.consumer_version_number).to eq "2"
62+
expect(subject.size).to be 1
63+
end
64+
end
65+
66+
context "when the latest pact for a tag has not been verified" do
67+
before do
68+
td.create_pact_with_hierarchy("foo", "1", "bar")
69+
.create_consumer_version_tag("prod")
70+
.create_verification(provider_version: "5")
71+
.create_consumer_version("2", tag_names: ["prod"])
72+
.create_pact
73+
end
74+
75+
it "is included" do
76+
expect(subject.first.consumer_version_number).to eq "2"
77+
expect(subject.size).to be 1
78+
end
79+
end
80+
81+
context "when the provider name does not match the given provider name" do
82+
before do
83+
td.create_pact_with_hierarchy("foo", "1", "baz")
84+
.create_provider("bar")
85+
end
86+
87+
it "is not included" do
88+
expect(subject.size).to be 0
89+
end
90+
end
91+
end
92+
end
93+
end
94+
end

spec/lib/pact_broker/pacts/repository_spec.rb

-1
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
# Yes, I know this file is too bug, but cmd+shift+t is too useful!
22

33
require 'pact_broker/pacts/repository'
4-
require 'spec/support/test_data_builder'
54
require 'pact_broker/pacts/pact_params'
65
require 'pact_broker/versions/repository'
76
require 'pact_broker/pacticipants/repository'

0 commit comments

Comments
 (0)