From f02a1ca03678ea9d9f1a0919c1eb97b9ea666084 Mon Sep 17 00:00:00 2001 From: Beth Skurrie Date: Tue, 27 Aug 2019 08:20:34 +1000 Subject: [PATCH] feat: add resource to get latest verification for a pact --- lib/pact_broker/api.rb | 2 + .../extended_verification_decorator.rb | 16 +++++++ .../api/decorators/pact_decorator.rb | 6 +++ .../api/decorators/verification_decorator.rb | 1 - lib/pact_broker/api/pact_broker_urls.rb | 8 ++++ .../resources/latest_verification_for_pact.rb | 19 +++++++++ ...test_verifications_for_consumer_version.rb | 1 - lib/pact_broker/api/resources/pact.rb | 2 +- lib/pact_broker/api/resources/verification.rb | 15 ++++++- lib/pact_broker/verifications/repository.rb | 4 ++ lib/pact_broker/verifications/service.rb | 4 ++ .../get_latest_verification_for_pact_spec.rb | 42 +++++++++++++++++++ 12 files changed, 116 insertions(+), 4 deletions(-) create mode 100644 lib/pact_broker/api/decorators/extended_verification_decorator.rb create mode 100644 lib/pact_broker/api/resources/latest_verification_for_pact.rb create mode 100644 spec/features/get_latest_verification_for_pact_spec.rb diff --git a/lib/pact_broker/api.rb b/lib/pact_broker/api.rb index 57d98969d..ab5730760 100644 --- a/lib/pact_broker/api.rb +++ b/lib/pact_broker/api.rb @@ -26,6 +26,8 @@ module PactBroker # Verifications add ['pacts', 'provider', :provider_name, 'consumer', :consumer_name, 'pact-version', :pact_version_sha, 'verification-results'], Api::Resources::Verifications, {resource_name: "verification_results"} add ['pacts', 'provider', :provider_name, 'consumer', :consumer_name, 'pact-version', :pact_version_sha, 'metadata', :metadata, 'verification-results'], Api::Resources::Verifications, {resource_name: "verification_results"} + add ['pacts', 'provider', :provider_name, 'consumer', :consumer_name, 'version', :consumer_version_number, 'verification-results', 'latest'], Api::Resources::LatestVerificationForPact, {resource_name: "latest_verification_results_for_pact_publication"} + add ['pacts', 'provider', :provider_name, 'consumer', :consumer_name, 'pact-version', :pact_version_sha, 'verification-results', 'latest'], Api::Resources::LatestVerificationForPact, {resource_name: "latest_verification_results_for_pact_version"} add ['pacts', 'provider', :provider_name, 'consumer', :consumer_name, 'pact-version', :pact_version_sha, 'verification-results', :verification_number], Api::Resources::Verification, {resource_name: "verification_result"} add ['pacts', 'provider', :provider_name, 'consumer', :consumer_name, 'pact-version', :pact_version_sha, 'verification-results', :verification_number, 'triggered-webhooks'], Api::Resources::VerificationTriggeredWebhooks, {resource_name: "verification_result_triggered_webhooks"} add ['verification-results', 'consumer', :consumer_name, 'version', :consumer_version_number,'latest'], Api::Resources::LatestVerificationsForConsumerVersion, {resource_name: "verification_results_for_consumer_version"} diff --git a/lib/pact_broker/api/decorators/extended_verification_decorator.rb b/lib/pact_broker/api/decorators/extended_verification_decorator.rb new file mode 100644 index 000000000..3a09e3b50 --- /dev/null +++ b/lib/pact_broker/api/decorators/extended_verification_decorator.rb @@ -0,0 +1,16 @@ +require 'pact_broker/api/decorators/verification_decorator' + +module PactBroker + module Api + module Decorators + class ExtendedVerificationDecorator < VerificationDecorator + class TagDecorator < BaseDecorator + property :name + property :latest?, as: :latest + end + + collection :provider_version_tags, as: :tags, embedded: true, extend: TagDecorator + end + end + end +end diff --git a/lib/pact_broker/api/decorators/pact_decorator.rb b/lib/pact_broker/api/decorators/pact_decorator.rb index 53efe6140..affffe15b 100644 --- a/lib/pact_broker/api/decorators/pact_decorator.rb +++ b/lib/pact_broker/api/decorators/pact_decorator.rb @@ -146,6 +146,12 @@ def to_hash(options = {}) } end + link :'pb:latest-verification-results' do | options | + { + href: latest_verification_for_pact_url(represented, options.fetch(:base_url)) + } + end + link :'pb:triggered-webhooks' do | options | { title: "Webhooks triggered by the publication of this pact", diff --git a/lib/pact_broker/api/decorators/verification_decorator.rb b/lib/pact_broker/api/decorators/verification_decorator.rb index 5f465ce42..6baf3825b 100644 --- a/lib/pact_broker/api/decorators/verification_decorator.rb +++ b/lib/pact_broker/api/decorators/verification_decorator.rb @@ -15,7 +15,6 @@ class TagDecorator < BaseDecorator property :execution_date, as: :verificationDate property :build_url, as: :buildUrl property :test_results, as: :testResults - collection :provider_version_tags, as: :tags, embedded: true, extend: TagDecorator link :self do | options | { diff --git a/lib/pact_broker/api/pact_broker_urls.rb b/lib/pact_broker/api/pact_broker_urls.rb index 1dacdb5a3..143cfaed6 100644 --- a/lib/pact_broker/api/pact_broker_urls.rb +++ b/lib/pact_broker/api/pact_broker_urls.rb @@ -157,6 +157,14 @@ def latest_verifications_for_consumer_version_url version, base_url "#{base_url}/verification-results/consumer/#{url_encode(version.pacticipant.name)}/version/#{version.number}/latest" end + def latest_verification_for_pact_url pact, base_url + verification_url_from_params( + provider_name: pact.provider_name, + consumer_name: pact.consumer_name, + pact_version_sha: pact.pact_version_sha, + verification_number: 'latest') + end + def verification_triggered_webhooks_url verification, base_url = '' "#{verification_url(verification, base_url)}/triggered-webhooks" end diff --git a/lib/pact_broker/api/resources/latest_verification_for_pact.rb b/lib/pact_broker/api/resources/latest_verification_for_pact.rb new file mode 100644 index 000000000..678b05099 --- /dev/null +++ b/lib/pact_broker/api/resources/latest_verification_for_pact.rb @@ -0,0 +1,19 @@ +require 'pact_broker/api/resources/verification' + +module PactBroker + module Api + module Resources + class LatestVerificationForPact < Verification + private + + def pact + @pact ||= pact_service.find_pact(pact_params) + end + + def verification + @verification ||= pact && verification_service.find_latest_for_pact(pact) + end + end + end + end +end diff --git a/lib/pact_broker/api/resources/latest_verifications_for_consumer_version.rb b/lib/pact_broker/api/resources/latest_verifications_for_consumer_version.rb index a116e5b97..094d37f01 100644 --- a/lib/pact_broker/api/resources/latest_verifications_for_consumer_version.rb +++ b/lib/pact_broker/api/resources/latest_verifications_for_consumer_version.rb @@ -7,7 +7,6 @@ module PactBroker module Api module Resources - class LatestVerificationsForConsumerVersion < BaseResource def allowed_methods diff --git a/lib/pact_broker/api/resources/pact.rb b/lib/pact_broker/api/resources/pact.rb index e08bad373..985445412 100644 --- a/lib/pact_broker/api/resources/pact.rb +++ b/lib/pact_broker/api/resources/pact.rb @@ -28,7 +28,7 @@ def content_types_provided [["application/hal+json", :to_json], ["application/json", :to_json], ["text/html", :to_html], - ["application/vnd.pactbroker.v1+json", :to_extended_json] + ["application/vnd.pactbrokerextended.v1+json", :to_extended_json] ] end diff --git a/lib/pact_broker/api/resources/verification.rb b/lib/pact_broker/api/resources/verification.rb index 985aa2f35..bd4ed4590 100644 --- a/lib/pact_broker/api/resources/verification.rb +++ b/lib/pact_broker/api/resources/verification.rb @@ -3,13 +3,18 @@ require 'pact_broker/domain/verification' require 'pact_broker/api/contracts/verification_contract' require 'pact_broker/api/decorators/verification_decorator' +require 'pact_broker/api/decorators/extended_verification_decorator' module PactBroker module Api module Resources class Verification < BaseResource def content_types_provided - [["application/hal+json", :to_json], ["application/json", :to_json]] + [ + ["application/hal+json", :to_json], + ["application/json", :to_json], + ["application/vnd.pactbrokerextended.v1+json", :to_extended_json] + ] end # Remember to update latest_verification_id_for_pact_version_and_provider_version @@ -26,6 +31,10 @@ def to_json decorator_for(verification).to_json(user_options: {base_url: base_url}) end + def to_extended_json + extended_decorator_for(verification).to_json(user_options: {base_url: base_url}) + end + private def verification @@ -35,6 +44,10 @@ def verification def decorator_for model PactBroker::Api::Decorators::VerificationDecorator.new(model) end + + def extended_decorator_for model + PactBroker::Api::Decorators::ExtendedVerificationDecorator.new(model) + end end end end diff --git a/lib/pact_broker/verifications/repository.rb b/lib/pact_broker/verifications/repository.rb index a2c204f36..48924360c 100644 --- a/lib/pact_broker/verifications/repository.rb +++ b/lib/pact_broker/verifications/repository.rb @@ -54,6 +54,10 @@ def find consumer_name, provider_name, pact_version_sha, verification_number .verification_number(verification_number).single_record end + def find_latest_for_pact(pact) + PactBroker::Pacts::PactPublication.where(id: pact.id).single_record.latest_verification + end + def search_for_latest consumer_name, provider_name query = LatestVerificationForPactVersion .select_all_qualified diff --git a/lib/pact_broker/verifications/service.rb b/lib/pact_broker/verifications/service.rb index 80e90785c..0dedf4e84 100644 --- a/lib/pact_broker/verifications/service.rb +++ b/lib/pact_broker/verifications/service.rb @@ -49,6 +49,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_latest_for_pact(pact) + verification_repository.find_latest_for_pact(pact) + end + def find_by_id id PactBroker::Domain::Verification.find(id: id) end diff --git a/spec/features/get_latest_verification_for_pact_spec.rb b/spec/features/get_latest_verification_for_pact_spec.rb new file mode 100644 index 000000000..cd3705db0 --- /dev/null +++ b/spec/features/get_latest_verification_for_pact_spec.rb @@ -0,0 +1,42 @@ +require 'spec/support/test_data_builder' + +describe "Get latest verification for pact" do + before do + td + .create_consumer("Consumer") + .create_consumer_version("1.2.3") + .create_provider("Another provider") + .create_pact + .create_verification(number: 1, provider_version: "5") + .create_provider("Provider") + .create_pact + .create_verification(number: 1, provider_version: "3") + .create_verification(number: 2, provider_version: "4") + end + + let(:last_response_body) { JSON.parse(subject.body, symbolize_names: true) } + let(:content_type) { "application/vnd.pactbrokerextended.v1+json" } + + subject { get(path, nil, "HTTP_ACCEPT" => content_type) } + + context "by pact version" do + let!(:path) { "/pacts/provider/Provider/consumer/Consumer/pact-version/#{td.pact.pact_version_sha}/verification-results/latest" } + + it "returns a 200 OK" do + expect(subject.status).to eq 200 + expect(subject.headers['Content-Type']).to include content_type + end + + it "returns the verification" do + expect(last_response_body[:providerApplicationVersion]).to eq "4" + end + end + + context "by consumer version" do + let(:path) { "/pacts/provider/Provider/consumer/Consumer/version/1.2.3/verification-results/latest" } + + it "returns the verification" do + expect(last_response_body[:providerApplicationVersion]).to eq "4" + end + end +end