diff --git a/lib/pact_broker/api.rb b/lib/pact_broker/api.rb
index b37345ca0..4b9813a13 100644
--- a/lib/pact_broker/api.rb
+++ b/lib/pact_broker/api.rb
@@ -61,6 +61,7 @@ module PactBroker
# matrix
add ['matrix', 'provider', :provider_name, 'consumer', :consumer_name], Api::Resources::MatrixForConsumerAndProvider, {resource_name: "matrix_consumer_provider"}
+ add ['matrix', 'provider', :provider_name, 'latest', :provider_tag, 'consumer', :consumer_name, 'latest', :tag, 'badge'], Api::Resources::MatrixBadge, {resource_name: "matrix_tag_badge"}
add ['matrix'], Api::Resources::Matrix, {resource_name: "matrix"}
add [], Api::Resources::Index, {resource_name: "index"}
@@ -73,5 +74,4 @@ module PactBroker
pact_api.adapter
end
-
end
diff --git a/lib/pact_broker/api/resources/matrix_badge.rb b/lib/pact_broker/api/resources/matrix_badge.rb
new file mode 100644
index 000000000..f8995f24f
--- /dev/null
+++ b/lib/pact_broker/api/resources/matrix_badge.rb
@@ -0,0 +1,21 @@
+require 'pact_broker/api/resources/badge'
+
+module PactBroker
+ module Api
+ module Resources
+ class MatrixBadge < Badge
+
+ private
+
+ def latest_verification
+ @latest_verification ||= begin
+ matrix_row = matrix_service.find_for_consumer_and_provider_with_tags(identifier_from_path)
+ if matrix_row && matrix_row[:verification_id]
+ verification_service.find_by_id(matrix_row[:verification_id])
+ end
+ end
+ end
+ end
+ end
+ end
+end
diff --git a/lib/pact_broker/matrix/service.rb b/lib/pact_broker/matrix/service.rb
index 440b7e184..97aa3fd86 100644
--- a/lib/pact_broker/matrix/service.rb
+++ b/lib/pact_broker/matrix/service.rb
@@ -16,6 +16,26 @@ def find_for_consumer_and_provider params
matrix_repository.find_for_consumer_and_provider params[:consumer_name], params[:provider_name]
end
+ def find_for_consumer_and_provider_with_tags params
+ consumer_criteria = {
+ pacticipant_name: params[:consumer_name],
+ tag: params[:tag],
+ latest: true
+ }
+ provider_criteria = {
+ pacticipant_name: params[:provider_name],
+ tag: params[:provider_tag],
+ latest: true
+ }
+ selectors = [consumer_criteria, provider_criteria]
+ options = { latestby: 'cvpv' }
+ if validate_selectors(selectors).empty?
+ matrix_repository.find(selectors, options).first
+ else
+ nil
+ end
+ end
+
def find_compatible_pacticipant_versions criteria
matrix_repository.find_compatible_pacticipant_versions criteria
end
diff --git a/lib/pact_broker/verifications/service.rb b/lib/pact_broker/verifications/service.rb
index c7d7de161..21be27c90 100644
--- a/lib/pact_broker/verifications/service.rb
+++ b/lib/pact_broker/verifications/service.rb
@@ -35,6 +35,10 @@ def find params
verification_repository.find(params.fetch(:consumer_name), params.fetch(:provider_name), params.fetch(:pact_version_sha), params.fetch(:verification_number))
end
+ def find_by_id id
+ PactBroker::Domain::Verification.find(id: id)
+ end
+
def find_latest_verifications_for_consumer_version params
verification_repository.find_latest_verifications_for_consumer_version params[:consumer_name], params[:consumer_version_number]
end
diff --git a/spec/features/get_matrix_badge_spec.rb b/spec/features/get_matrix_badge_spec.rb
new file mode 100644
index 000000000..7b39cd5b6
--- /dev/null
+++ b/spec/features/get_matrix_badge_spec.rb
@@ -0,0 +1,40 @@
+require 'webmock/rspec'
+
+describe "get latest matrix badge with tags" do
+
+ before do
+ PactBroker.configuration.enable_public_badge_access = true
+ TestDataBuilder.new
+ .create_consumer('consumer')
+ .create_provider('provider')
+ .create_consumer_version('1')
+ .create_consumer_version_tag('prod')
+ .create_pact
+ .create_verification(provider_version: '4')
+ .use_provider_version('4')
+ .create_provider_version_tag('master')
+ end
+
+ let!(:http_request) do
+ stub_request(:get, /http/).to_return(:status => 200, :body => "")
+ end
+
+ let(:path) { "/matrix/provider/provider/latest/master/consumer/consumer/latest/prod/badge" }
+
+ # In the full app, the .svg extension is turned into an Accept header
+ # by ConvertFileExtensionToAcceptHeader
+
+ subject { get path, nil, {'HTTP_ACCEPT' => "image/svg+xml"}; last_response }
+
+ it "returns a 200 status" do
+ expect(subject.status).to eq 200
+ end
+
+ it "returns an svg/xml response" do
+ expect(subject.headers['Content-Type']).to include("image/svg+xml")
+ end
+
+ it "returns an svg body" do
+ expect(subject.body).to include ""
+ end
+end
diff --git a/spec/lib/pact_broker/api/resources/badge_spec.rb b/spec/lib/pact_broker/api/resources/badge_spec.rb
index 92468777e..ba6658d7f 100644
--- a/spec/lib/pact_broker/api/resources/badge_spec.rb
+++ b/spec/lib/pact_broker/api/resources/badge_spec.rb
@@ -1,5 +1,6 @@
require 'pact_broker/api/resources/badge'
require 'pact_broker/badges/service'
+require 'pact_broker/matrix/service'
module PactBroker
module Api
@@ -118,6 +119,66 @@ module Resources
subject
end
end
+
+ context "when retrieving the badge for a matrix row by tag" do
+ before do
+ allow(PactBroker::Matrix::Service).to receive(:find_for_consumer_and_provider_with_tags).and_return(row)
+ allow(PactBroker::Verifications::Service).to receive(:find_by_id).and_return(verification)
+ end
+
+ let(:path) { "/matrix/provider/provider/latest/master/consumer/consumer/latest/prod/badge" }
+ let(:row) { { verification_id: 1 } }
+
+
+ it "looks up the matrix row" do
+ expect(PactBroker::Matrix::Service).to receive(:find_for_consumer_and_provider_with_tags).with(
+ hash_including(consumer_name: 'consumer',
+ provider_name: 'provider',
+ tag: 'prod',
+ provider_tag: 'master'
+ ))
+ subject
+ end
+
+ context "when a matrix row is found" do
+ context "when there is a verification_id" do
+ it "looks up the verification" do
+ expect(PactBroker::Verifications::Service).to receive(:find_by_id).with(1)
+ subject
+ end
+
+ it "returns the badge" do
+ expect(subject.body).to eq "badge"
+ end
+ end
+
+ context "when there is not a verification_id" do
+ let(:row) { {} }
+
+ it "does not look up the verification" do
+ expect(PactBroker::Verifications::Service).to_not receive(:find_by_id)
+ subject
+ end
+
+ it "returns the badge" do
+ expect(subject.body).to eq "badge"
+ end
+ end
+ end
+
+ context "when a matrix row is not found" do
+ let(:row) { nil }
+
+ it "does not look up the verification" do
+ expect(PactBroker::Verifications::Service).to_not receive(:find_by_id)
+ subject
+ end
+
+ it "returns the badge" do
+ expect(subject.body).to eq "badge"
+ end
+ end
+ end
end
end
end
diff --git a/spec/lib/pact_broker/api/resources/matrix_badge_spec.rb b/spec/lib/pact_broker/api/resources/matrix_badge_spec.rb
new file mode 100644
index 000000000..732955aa1
--- /dev/null
+++ b/spec/lib/pact_broker/api/resources/matrix_badge_spec.rb
@@ -0,0 +1,11 @@
+require 'pact_broker/api/resources/matrix_badge'
+
+module PactBroker
+ module Api
+ module Resources
+ describe MatrixBadge do
+ # spec is in spec/lib/pact_broker/api/resources/badge_spec.rb#123 to avoid duplication
+ end
+ end
+ end
+end
diff --git a/spec/lib/pact_broker/matrix/service_spec.rb b/spec/lib/pact_broker/matrix/service_spec.rb
index faadd9010..7fc98d8a2 100644
--- a/spec/lib/pact_broker/matrix/service_spec.rb
+++ b/spec/lib/pact_broker/matrix/service_spec.rb
@@ -122,6 +122,46 @@ module Matrix
end
end
end
+
+ describe "find_for_consumer_and_provider_with_tags integration test" do
+
+ let(:params) do
+ {
+ consumer_name: 'consumer',
+ provider_name: 'provider',
+ tag: 'prod',
+ provider_tag: 'master'
+ }
+ end
+
+ subject { Service.find_for_consumer_and_provider_with_tags(params) }
+
+ context "when the specified row exists" do
+ before do
+ td.create_pact_with_hierarchy('consumer', '1', 'provider')
+ .create_consumer_version_tag('prod')
+ .create_verification(provider_version: '2')
+ .use_provider_version('2')
+ .create_provider_version_tag('master')
+ .create_verification(provider_version: '3', number: 2)
+ .create_consumer_version('2')
+ .create_pact
+ end
+
+ it "returns the row" do
+ expect(subject[:consumer_name]).to eq 'consumer'
+ expect(subject[:provider_name]).to eq 'provider'
+ expect(subject[:consumer_version_number]).to eq '1'
+ expect(subject[:provider_version_number]).to eq '2'
+ end
+ end
+
+ context "when the specified row does not exist" do
+ it "returns nil" do
+ expect(subject).to be nil
+ end
+ end
+ end
end
end
end