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