Skip to content

Commit d7011b2

Browse files
committed
feat: create endpoints for retrieving all pact versions for a provider, with and without a tag.
1 parent 278b3ea commit d7011b2

11 files changed

+326
-40
lines changed

lib/pact_broker/api.rb

+2
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,8 @@ module PactBroker
2929
# Latest pacts
3030
add ['pacts', 'provider', :provider_name, 'consumer', :consumer_name, 'latest'], Api::Resources::LatestPact, {resource_name: "latest_pact_publication"}
3131
add ['pacts', 'provider', :provider_name, 'consumer', :consumer_name, 'latest', :tag], Api::Resources::LatestPact, {resource_name: "latest_tagged_pact_publication"}
32+
add ['pacts', 'provider', :provider_name], Api::Resources::ProviderPacts, {resource_name: "provider_pact_publications"}
33+
add ['pacts', 'provider', :provider_name, 'tag', :tag], Api::Resources::ProviderPacts, {resource_name: "tagged_provider_pact_publications"}
3234
add ['pacts', 'provider', :provider_name, 'consumer', :consumer_name, 'latest-untagged'], Api::Resources::LatestPact, {resource_name: "latest_untagged_pact_publication", tag: :untagged}
3335
add ['pacts', 'provider', :provider_name, 'latest'], Api::Resources::LatestProviderPacts, {resource_name: "latest_provider_pact_publications"}
3436
add ['pacts', 'provider', :provider_name, 'latest', :tag], Api::Resources::LatestProviderPacts, {resource_name: "latest_tagged_provider_pact_publications"}

lib/pact_broker/api/decorators/provider_pacts_decorator.rb

+12-7
Original file line numberDiff line numberDiff line change
@@ -2,19 +2,15 @@
22
require_relative 'pact_version_decorator'
33

44
module PactBroker
5-
65
module Api
7-
86
module Decorators
9-
10-
117
class ProviderPactsDecorator < BaseDecorator
128

139
link :self do | context |
1410
suffix = context[:tag] ? " with tag '#{context[:tag]}'" : ""
1511
{
1612
href: context[:resource_url],
17-
title: "Latest pact versions for the provider #{context[:provider_name]}#{suffix}"
13+
title: context[:title]
1814
}
1915
end
2016

@@ -25,16 +21,25 @@ class ProviderPactsDecorator < BaseDecorator
2521
}
2622
end
2723

28-
links :'pacts' do | context |
24+
links :'pb:pacts' do | context |
2925
represented.collect do | pact |
3026
{
3127
:href => pact_url(context[:base_url], pact),
3228
:title => pact.name,
33-
:name => pact.consumer.name
29+
:name => pact.consumer_name
3430
}
3531
end
3632
end
3733

34+
links :'pacts' do | context |
35+
represented.collect do | pact |
36+
{
37+
:href => pact_url(context[:base_url], pact),
38+
:title => 'DEPRECATED - please use the pb:pacts relation',
39+
:name => pact.consumer_name
40+
}
41+
end
42+
end
3843
end
3944
end
4045
end

lib/pact_broker/api/resources/index.rb

+13-1
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,19 @@ def to_json
5050
'pb:latest-provider-pacts-with-tag' =>
5151
{
5252
href: base_url + '/pacts/provider/{provider}/latest/{tag}',
53-
title: 'Latest pacts by provider with the specified tag',
53+
title: 'Latest pacts for provider with the specified tag',
54+
templated: true
55+
},
56+
'pb:provider-pacts-with-tag' =>
57+
{
58+
href: base_url + '/pacts/provider/{provider}/tag/{tag}',
59+
title: 'All pact versions for the provider with the specified consumer version tag',
60+
templated: true
61+
},
62+
'pb:provider-pacts' =>
63+
{
64+
href: base_url + '/pacts/provider/{provider}',
65+
title: 'All pact versions for the specified provider',
5466
templated: true
5567
},
5668
'pb:latest-version' => {

lib/pact_broker/api/resources/latest_provider_pacts.rb

+7-19
Original file line numberDiff line numberDiff line change
@@ -1,33 +1,21 @@
1-
require 'pact_broker/api/resources/base_resource'
1+
require 'pact_broker/api/resources/provider_pacts'
22
require 'pact_broker/configuration'
33
require 'pact_broker/api/decorators/provider_pacts_decorator'
44

55
module PactBroker
66
module Api
77
module Resources
8-
9-
class LatestProviderPacts < BaseResource
10-
11-
def content_types_provided
12-
[["application/hal+json", :to_json]]
13-
end
14-
15-
def allowed_methods
16-
["GET"]
17-
end
18-
19-
def resource_exists?
20-
pacticipant_service.find_pacticipant_by_name(provider_name)
21-
end
22-
23-
def to_json
24-
PactBroker::Api::Decorators::ProviderPactsDecorator.new(pacts).to_json(user_options: decorator_context(identifier_from_path))
25-
end
8+
class LatestProviderPacts < ProviderPacts
9+
private
2610

2711
def pacts
2812
pact_service.find_latest_pact_versions_for_provider provider_name, tag: identifier_from_path[:tag]
2913
end
3014

15+
def resource_title
16+
suffix = identifier_from_path[:tag] ? " with consumer version tag '#{identifier_from_path[:tag]}'" : ""
17+
"Latest pact versions for the provider #{identifier_from_path[:provider_name]}#{suffix}"
18+
end
3119
end
3220
end
3321
end
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
require 'pact_broker/api/resources/base_resource'
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 ProviderPacts < BaseResource
9+
10+
def content_types_provided
11+
[["application/hal+json", :to_json]]
12+
end
13+
14+
def allowed_methods
15+
["GET"]
16+
end
17+
18+
def resource_exists?
19+
pacticipant_service.find_pacticipant_by_name(provider_name)
20+
end
21+
22+
def to_json
23+
PactBroker::Api::Decorators::ProviderPactsDecorator.new(pacts).to_json(to_json_options)
24+
end
25+
26+
private
27+
28+
def pacts
29+
pact_service.find_pact_versions_for_provider provider_name, tag: identifier_from_path[:tag]
30+
end
31+
32+
def to_json_options
33+
{
34+
user_options: decorator_context(identifier_from_path.merge(title: resource_title))
35+
}
36+
end
37+
38+
def resource_title
39+
suffix = identifier_from_path[:tag] ? " with consumer version tag '#{identifier_from_path[:tag]}'" : ""
40+
"All pact versions for the provider #{identifier_from_path[:provider_name]}#{suffix}"
41+
end
42+
end
43+
end
44+
end
45+
end

lib/pact_broker/pacts/repository.rb

+18
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,24 @@ def find_latest_pact_versions_for_provider provider_name, tag = nil
7070
end
7171
end
7272

73+
def find_pact_versions_for_provider provider_name, tag = nil
74+
if tag
75+
LatestPactPublicationsByConsumerVersion
76+
.join(:tags, {version_id: :consumer_version_id})
77+
.provider(provider_name)
78+
.order_ignore_case(:consumer_name)
79+
.order_append(:consumer_version_order)
80+
.where(Sequel[:tags][:name] => tag)
81+
.collect(&:to_domain)
82+
else
83+
LatestPactPublicationsByConsumerVersion
84+
.provider(provider_name)
85+
.order_ignore_case(:consumer_name)
86+
.order_append(:consumer_version_order)
87+
.collect(&:to_domain)
88+
end
89+
end
90+
7391
# Returns latest pact version for the consumer_version_number
7492
def find_by_consumer_version consumer_name, consumer_version_number
7593
LatestPactPublicationsByConsumerVersion

lib/pact_broker/pacts/service.rb

+4
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,10 @@ def find_latest_pact_versions_for_provider provider_name, options = {}
6868
pact_repository.find_latest_pact_versions_for_provider provider_name, options[:tag]
6969
end
7070

71+
def find_pact_versions_for_provider provider_name, options = {}
72+
pact_repository.find_pact_versions_for_provider provider_name, options[:tag]
73+
end
74+
7175
def find_previous_distinct_pact_version params
7276
pact = find_pact params
7377
return nil if pact.nil?
+33-12
Original file line numberDiff line numberDiff line change
@@ -1,72 +1,93 @@
1-
require 'spec/support/test_data_builder'
2-
31
describe "Get provider pacts" do
4-
5-
let(:path) { "/pacts/provider/Provider/latest" }
62
let(:last_response_body) { JSON.parse(subject.body, symbolize_names: true) }
7-
3+
let(:pact_links) { last_response_body[:_links][:'pb:pacts'] }
84
subject { get path; last_response }
95

106
context "when the provider exists" do
11-
127
before do
138
TestDataBuilder.new
149
.create_provider("Provider")
1510
.create_consumer("Consumer")
11+
.create_consumer_version("0.0.1")
12+
.create_consumer_version_tag("prod")
13+
.create_pact
1614
.create_consumer_version("1.0.0")
1715
.create_consumer_version_tag("prod")
1816
.create_pact
1917
.create_consumer_version("1.2.3")
2018
.create_pact
2119
.create_consumer("Consumer 2")
2220
.create_consumer_version("4.5.6")
21+
.create_consumer_version_tag("prod")
2322
.create_pact
2423
end
2524

2625
context "with no tag specified" do
26+
let(:path) { "/pacts/provider/Provider/latest" }
2727

2828
it "returns a 200 HAL JSON response" do
2929
expect(subject).to be_a_hal_json_success_response
3030
end
3131

3232
it "returns a list of links to the pacts" do
33-
expect(last_response_body[:_links][:pacts].size).to eq 2
33+
expect(pact_links.size).to eq 2
3434
end
3535
end
3636

3737
context "with a tag specified" do
38-
3938
let(:path) { "/pacts/provider/Provider/latest/prod" }
4039

4140
it "returns a 200 HAL JSON response" do
4241
expect(subject).to be_a_hal_json_success_response
4342
end
4443

4544
it "returns a list of links to the pacts" do
46-
expect(last_response_body[:_links][:pacts].size).to eq 1
45+
expect(pact_links.size).to eq 2
4746
end
4847
end
4948

5049
context "with a tag with no pacts" do
51-
5250
let(:path) { "/pacts/provider/Provider/latest/foo" }
5351

5452
it "returns a 200 HAL JSON response" do
5553
expect(subject).to be_a_hal_json_success_response
5654
end
5755

5856
it "returns a list of links to the pacts" do
59-
expect(last_response_body[:_links][:pacts].size).to eq 0
57+
expect(pact_links.size).to eq 0
6058
end
6159
end
6260

61+
context "with a tag for all pacts" do
62+
let(:path) { "/pacts/provider/Provider/tag/prod" }
63+
64+
it "returns a 200 HAL JSON response" do
65+
expect(subject).to be_a_hal_json_success_response
66+
end
67+
68+
it "returns a list of links to the pacts" do
69+
expect(pact_links.size).to eq 3
70+
end
71+
end
72+
73+
context "with no tag for all pacts" do
74+
let(:path) { "/pacts/provider/Provider" }
75+
76+
it "returns a 200 HAL JSON response" do
77+
expect(subject).to be_a_hal_json_success_response
78+
end
79+
80+
it "returns a list of links to the pacts" do
81+
expect(last_response_body[:_links][:'pb:pacts'].size).to eq 4
82+
end
83+
end
6384
end
6485

6586
context "when the provider does not exist" do
87+
let(:path) { "/pacts/provider/Provider" }
6688

6789
it "returns a 404 response" do
6890
expect(subject).to be_a_404_response
6991
end
70-
7192
end
7293
end
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
require 'pact_broker/api/resources/latest_provider_pacts'
2+
3+
module PactBroker
4+
module Api
5+
module Resources
6+
describe LatestProviderPacts do
7+
before do
8+
allow(PactBroker::Pacts::Service).to receive(:find_latest_pact_versions_for_provider).and_return(pacts)
9+
allow(PactBroker::Api::Decorators::ProviderPactsDecorator).to receive(:new).and_return(decorator)
10+
allow_any_instance_of(LatestProviderPacts).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/latest' }
16+
let(:decorator) { instance_double('PactBroker::Api::Decorators::ProviderPactsDecorator') }
17+
18+
subject { get path; last_response }
19+
20+
context "with no tag" do
21+
it "finds the pacts" do
22+
expect(PactBroker::Pacts::Service).to receive(:find_latest_pact_versions_for_provider).with("Bar", tag: nil)
23+
subject
24+
end
25+
26+
it "sets the correct resource title" do
27+
expect(decorator).to receive(:to_json) do | options |
28+
expect(options[:user_options][:title]).to eq "Latest pact versions for the provider Bar"
29+
end
30+
subject
31+
end
32+
end
33+
34+
context "with a tag" do
35+
let(:path) { '/pacts/provider/Bar/latest/prod' }
36+
37+
it "finds the pacts with a tag" do
38+
expect(PactBroker::Pacts::Service).to receive(:find_latest_pact_versions_for_provider).with("Bar", tag: "prod")
39+
subject
40+
end
41+
42+
it "sets the correct resource title" do
43+
expect(decorator).to receive(:to_json) do | options |
44+
expect(options[:user_options][:title]).to eq "Latest pact versions for the provider Bar with consumer version tag 'prod'"
45+
end
46+
subject
47+
end
48+
end
49+
end
50+
end
51+
end
52+
end

0 commit comments

Comments
 (0)