Skip to content

Commit

Permalink
feat: create endpoints for retrieving all pact versions for a provide…
Browse files Browse the repository at this point in the history
…r, with and without a tag.
  • Loading branch information
bethesque committed May 1, 2018
1 parent 278b3ea commit d7011b2
Show file tree
Hide file tree
Showing 11 changed files with 326 additions and 40 deletions.
2 changes: 2 additions & 0 deletions lib/pact_broker/api.rb
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,8 @@ module PactBroker
# Latest pacts
add ['pacts', 'provider', :provider_name, 'consumer', :consumer_name, 'latest'], Api::Resources::LatestPact, {resource_name: "latest_pact_publication"}
add ['pacts', 'provider', :provider_name, 'consumer', :consumer_name, 'latest', :tag], Api::Resources::LatestPact, {resource_name: "latest_tagged_pact_publication"}
add ['pacts', 'provider', :provider_name], Api::Resources::ProviderPacts, {resource_name: "provider_pact_publications"}
add ['pacts', 'provider', :provider_name, 'tag', :tag], Api::Resources::ProviderPacts, {resource_name: "tagged_provider_pact_publications"}
add ['pacts', 'provider', :provider_name, 'consumer', :consumer_name, 'latest-untagged'], Api::Resources::LatestPact, {resource_name: "latest_untagged_pact_publication", tag: :untagged}
add ['pacts', 'provider', :provider_name, 'latest'], Api::Resources::LatestProviderPacts, {resource_name: "latest_provider_pact_publications"}
add ['pacts', 'provider', :provider_name, 'latest', :tag], Api::Resources::LatestProviderPacts, {resource_name: "latest_tagged_provider_pact_publications"}
Expand Down
19 changes: 12 additions & 7 deletions lib/pact_broker/api/decorators/provider_pacts_decorator.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2,19 +2,15 @@
require_relative 'pact_version_decorator'

module PactBroker

module Api

module Decorators


class ProviderPactsDecorator < BaseDecorator

link :self do | context |
suffix = context[:tag] ? " with tag '#{context[:tag]}'" : ""
{
href: context[:resource_url],
title: "Latest pact versions for the provider #{context[:provider_name]}#{suffix}"
title: context[:title]
}
end

Expand All @@ -25,16 +21,25 @@ class ProviderPactsDecorator < BaseDecorator
}
end

links :'pacts' do | context |
links :'pb:pacts' do | context |
represented.collect do | pact |
{
:href => pact_url(context[:base_url], pact),
:title => pact.name,
:name => pact.consumer.name
:name => pact.consumer_name
}
end
end

links :'pacts' do | context |
represented.collect do | pact |
{
:href => pact_url(context[:base_url], pact),
:title => 'DEPRECATED - please use the pb:pacts relation',
:name => pact.consumer_name
}
end
end
end
end
end
Expand Down
14 changes: 13 additions & 1 deletion lib/pact_broker/api/resources/index.rb
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,19 @@ def to_json
'pb:latest-provider-pacts-with-tag' =>
{
href: base_url + '/pacts/provider/{provider}/latest/{tag}',
title: 'Latest pacts by provider with the specified tag',
title: 'Latest pacts for provider with the specified tag',
templated: true
},
'pb:provider-pacts-with-tag' =>
{
href: base_url + '/pacts/provider/{provider}/tag/{tag}',
title: 'All pact versions for the provider with the specified consumer version tag',
templated: true
},
'pb:provider-pacts' =>
{
href: base_url + '/pacts/provider/{provider}',
title: 'All pact versions for the specified provider',
templated: true
},
'pb:latest-version' => {
Expand Down
26 changes: 7 additions & 19 deletions lib/pact_broker/api/resources/latest_provider_pacts.rb
Original file line number Diff line number Diff line change
@@ -1,33 +1,21 @@
require 'pact_broker/api/resources/base_resource'
require 'pact_broker/api/resources/provider_pacts'
require 'pact_broker/configuration'
require 'pact_broker/api/decorators/provider_pacts_decorator'

module PactBroker
module Api
module Resources

class LatestProviderPacts < BaseResource

def content_types_provided
[["application/hal+json", :to_json]]
end

def allowed_methods
["GET"]
end

def resource_exists?
pacticipant_service.find_pacticipant_by_name(provider_name)
end

def to_json
PactBroker::Api::Decorators::ProviderPactsDecorator.new(pacts).to_json(user_options: decorator_context(identifier_from_path))
end
class LatestProviderPacts < ProviderPacts
private

def pacts
pact_service.find_latest_pact_versions_for_provider provider_name, tag: identifier_from_path[:tag]
end

def resource_title
suffix = identifier_from_path[:tag] ? " with consumer version tag '#{identifier_from_path[:tag]}'" : ""
"Latest pact versions for the provider #{identifier_from_path[:provider_name]}#{suffix}"
end
end
end
end
Expand Down
45 changes: 45 additions & 0 deletions lib/pact_broker/api/resources/provider_pacts.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
require 'pact_broker/api/resources/base_resource'
require 'pact_broker/configuration'
require 'pact_broker/api/decorators/provider_pacts_decorator'

module PactBroker
module Api
module Resources
class ProviderPacts < BaseResource

def content_types_provided
[["application/hal+json", :to_json]]
end

def allowed_methods
["GET"]
end

def resource_exists?
pacticipant_service.find_pacticipant_by_name(provider_name)
end

def to_json
PactBroker::Api::Decorators::ProviderPactsDecorator.new(pacts).to_json(to_json_options)
end

private

def pacts
pact_service.find_pact_versions_for_provider provider_name, tag: identifier_from_path[:tag]
end

def to_json_options
{
user_options: decorator_context(identifier_from_path.merge(title: resource_title))
}
end

def resource_title
suffix = identifier_from_path[:tag] ? " with consumer version tag '#{identifier_from_path[:tag]}'" : ""
"All pact versions for the provider #{identifier_from_path[:provider_name]}#{suffix}"
end
end
end
end
end
18 changes: 18 additions & 0 deletions lib/pact_broker/pacts/repository.rb
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,24 @@ def find_latest_pact_versions_for_provider provider_name, tag = nil
end
end

def find_pact_versions_for_provider provider_name, tag = nil
if tag
LatestPactPublicationsByConsumerVersion
.join(:tags, {version_id: :consumer_version_id})
.provider(provider_name)
.order_ignore_case(:consumer_name)
.order_append(:consumer_version_order)
.where(Sequel[:tags][:name] => tag)
.collect(&:to_domain)
else
LatestPactPublicationsByConsumerVersion
.provider(provider_name)
.order_ignore_case(:consumer_name)
.order_append(:consumer_version_order)
.collect(&:to_domain)
end
end

# Returns latest pact version for the consumer_version_number
def find_by_consumer_version consumer_name, consumer_version_number
LatestPactPublicationsByConsumerVersion
Expand Down
4 changes: 4 additions & 0 deletions lib/pact_broker/pacts/service.rb
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,10 @@ def find_latest_pact_versions_for_provider provider_name, options = {}
pact_repository.find_latest_pact_versions_for_provider provider_name, options[:tag]
end

def find_pact_versions_for_provider provider_name, options = {}
pact_repository.find_pact_versions_for_provider provider_name, options[:tag]
end

def find_previous_distinct_pact_version params
pact = find_pact params
return nil if pact.nil?
Expand Down
45 changes: 33 additions & 12 deletions spec/features/get_provider_pacts_spec.rb
Original file line number Diff line number Diff line change
@@ -1,72 +1,93 @@
require 'spec/support/test_data_builder'

describe "Get provider pacts" do

let(:path) { "/pacts/provider/Provider/latest" }
let(:last_response_body) { JSON.parse(subject.body, symbolize_names: true) }

let(:pact_links) { last_response_body[:_links][:'pb:pacts'] }
subject { get path; last_response }

context "when the provider exists" do

before do
TestDataBuilder.new
.create_provider("Provider")
.create_consumer("Consumer")
.create_consumer_version("0.0.1")
.create_consumer_version_tag("prod")
.create_pact
.create_consumer_version("1.0.0")
.create_consumer_version_tag("prod")
.create_pact
.create_consumer_version("1.2.3")
.create_pact
.create_consumer("Consumer 2")
.create_consumer_version("4.5.6")
.create_consumer_version_tag("prod")
.create_pact
end

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

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

it "returns a list of links to the pacts" do
expect(last_response_body[:_links][:pacts].size).to eq 2
expect(pact_links.size).to eq 2
end
end

context "with a tag specified" do

let(:path) { "/pacts/provider/Provider/latest/prod" }

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

it "returns a list of links to the pacts" do
expect(last_response_body[:_links][:pacts].size).to eq 1
expect(pact_links.size).to eq 2
end
end

context "with a tag with no pacts" do

let(:path) { "/pacts/provider/Provider/latest/foo" }

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

it "returns a list of links to the pacts" do
expect(last_response_body[:_links][:pacts].size).to eq 0
expect(pact_links.size).to eq 0
end
end

context "with a tag for all pacts" do
let(:path) { "/pacts/provider/Provider/tag/prod" }

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

it "returns a list of links to the pacts" do
expect(pact_links.size).to eq 3
end
end

context "with no tag for all pacts" do
let(:path) { "/pacts/provider/Provider" }

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

it "returns a list of links to the pacts" do
expect(last_response_body[:_links][:'pb:pacts'].size).to eq 4
end
end
end

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

it "returns a 404 response" do
expect(subject).to be_a_404_response
end

end
end
52 changes: 52 additions & 0 deletions spec/lib/pact_broker/api/resources/latest_provider_pacts_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
require 'pact_broker/api/resources/latest_provider_pacts'

module PactBroker
module Api
module Resources
describe LatestProviderPacts do
before do
allow(PactBroker::Pacts::Service).to receive(:find_latest_pact_versions_for_provider).and_return(pacts)
allow(PactBroker::Api::Decorators::ProviderPactsDecorator).to receive(:new).and_return(decorator)
allow_any_instance_of(LatestProviderPacts).to receive(:resource_exists?).and_return(provider)
end

let(:provider) { double('provider') }
let(:pacts) { double('pacts') }
let(:path) { '/pacts/provider/Bar/latest' }
let(:decorator) { instance_double('PactBroker::Api::Decorators::ProviderPactsDecorator') }

subject { get path; last_response }

context "with no tag" do
it "finds the pacts" do
expect(PactBroker::Pacts::Service).to receive(:find_latest_pact_versions_for_provider).with("Bar", tag: nil)
subject
end

it "sets the correct resource title" do
expect(decorator).to receive(:to_json) do | options |
expect(options[:user_options][:title]).to eq "Latest pact versions for the provider Bar"
end
subject
end
end

context "with a tag" do
let(:path) { '/pacts/provider/Bar/latest/prod' }

it "finds the pacts with a tag" do
expect(PactBroker::Pacts::Service).to receive(:find_latest_pact_versions_for_provider).with("Bar", tag: "prod")
subject
end

it "sets the correct resource title" do
expect(decorator).to receive(:to_json) do | options |
expect(options[:user_options][:title]).to eq "Latest pact versions for the provider Bar with consumer version tag 'prod'"
end
subject
end
end
end
end
end
end
Loading

0 comments on commit d7011b2

Please sign in to comment.