diff --git a/lib/pact_broker/api.rb b/lib/pact_broker/api.rb index 4b9813a13..f33827a59 100644 --- a/lib/pact_broker/api.rb +++ b/lib/pact_broker/api.rb @@ -44,6 +44,8 @@ module PactBroker add ['pacticipants', :name], Api::Resources::Pacticipant, {resource_name: "pacticipant"} add ['pacticipants', :pacticipant_name, 'versions'], Api::Resources::Versions, {resource_name: "pacticipant_versions"} add ['pacticipants', :pacticipant_name, 'versions', :pacticipant_version_number], Api::Resources::Version, {resource_name: "pacticipant_version"} + add ['pacticipants', :pacticipant_name, 'versions', 'latest', :tag], Api::Resources::Version, {resource_name: "latest_tagged_pacticipant_version"} + add ['pacticipants', :pacticipant_name, 'versions', 'latest'], Api::Resources::Version, {resource_name: "latest_pacticipant_version"} add ['pacticipants', :pacticipant_name, 'versions', :pacticipant_version_number, 'tags', :tag_name], Api::Resources::Tag, {resource_name: "pacticipant_version_tag"} add ['pacticipants', :pacticipant_name, 'labels', :label_name], Api::Resources::Label, {resource_name: "pacticipant_label"} diff --git a/lib/pact_broker/api/resources/index.rb b/lib/pact_broker/api/resources/index.rb index 1db0da84c..608440e2b 100644 --- a/lib/pact_broker/api/resources/index.rb +++ b/lib/pact_broker/api/resources/index.rb @@ -50,11 +50,20 @@ def to_json 'pb:latest-provider-pacts-with-tag' => { href: base_url + '/pacts/provider/{provider}/latest/{tag}', - title: 'Latest pacts by provider with a specified tag', + title: 'Latest pacts by provider with the specified tag', templated: true }, - 'pb:webhooks' => - { + 'pb:latest-version' => { + href: base_url + '/pacticipants/{pacticipant}/versions/latest', + title: 'Latest pacticipant version', + templated: true + }, + 'pb:latest-tagged-version' => { + href: base_url + '/pacticipants/{pacticipant}/versions/latest/{tag}', + title: 'Latest pacticipant version with the specified tag', + templated: true + }, + 'pb:webhooks' => { href: base_url + '/webhooks', title: 'Webhooks', templated: false diff --git a/lib/pact_broker/api/resources/version.rb b/lib/pact_broker/api/resources/version.rb index e551a0125..dfa9943f3 100644 --- a/lib/pact_broker/api/resources/version.rb +++ b/lib/pact_broker/api/resources/version.rb @@ -32,11 +32,15 @@ def delete_resource private def version - @version ||= version_service.find_by_pacticipant_name_and_number path_info + if path_info[:tag] + @version ||= version_service.find_by_pacticpant_name_and_latest_tag(path_info[:pacticipant_name], path_info[:tag]) + elsif path_info[:number] + @version ||= version_service.find_by_pacticipant_name_and_number path_info + else + @version ||= version_service.find_latest_by_pacticpant_name path_info + end end - end end - end end diff --git a/lib/pact_broker/versions/service.rb b/lib/pact_broker/versions/service.rb index 5bc3d5ad3..89f7a7619 100644 --- a/lib/pact_broker/versions/service.rb +++ b/lib/pact_broker/versions/service.rb @@ -7,6 +7,10 @@ class Service extend PactBroker::Repositories + def self.find_latest_by_pacticpant_name params + version_repository.find_latest_by_pacticpant_name params.fetch(:pacticipant_name) + end + def self.find_by_pacticipant_name_and_number params version_repository.find_by_pacticipant_name_and_number params.fetch(:pacticipant_name), params.fetch(:pacticipant_version_number) end diff --git a/spec/service_consumers/hal_relation_proxy_app.rb b/spec/service_consumers/hal_relation_proxy_app.rb new file mode 100644 index 000000000..f2a91d876 --- /dev/null +++ b/spec/service_consumers/hal_relation_proxy_app.rb @@ -0,0 +1,36 @@ +class HalRelationProxyApp + + # This hash allows us to do a dodgy "generators" implementation + # It means we can use placeholder URLS for the relations in our consumer tests so that + # the consumer does not need to know the actual URLs. + PATH_REPLACEMENTS = { + '/HAL-REL-PLACEHOLDER-INDEX-PB-LATEST-TAGGED-VERSION-Condor-production' => + '/pacticipants/Condor/versions/latest/production', + '/HAL-REL-PLACEHOLDER-INDEX-PB-LATEST-VERSION-Condor' => + '/pacticipants/Condor/versions/latest' + } + + RESPONSE_BODY_REPLACEMENTS = { + } + + def initialize(app) + @app = app + end + + def call env + env_with_modified_path = env + PATH_REPLACEMENTS.each do | (find, replace) | + env_with_modified_path['PATH_INFO'] = env_with_modified_path['PATH_INFO'].gsub(find, replace) + end + + response = @app.call(env_with_modified_path) + + modified_response_body = response.last.join + RESPONSE_BODY_REPLACEMENTS.each do | (find, replace) | + modified_response_body = modified_response_body.gsub(find, replace) + end + + [response[0], response[1], [modified_response_body]] + end + +end diff --git a/spec/service_consumers/pact_helper.rb b/spec/service_consumers/pact_helper.rb index 3fd1badc9..4b5471119 100644 --- a/spec/service_consumers/pact_helper.rb +++ b/spec/service_consumers/pact_helper.rb @@ -6,12 +6,32 @@ PactBroker::DB.connection = PactBroker::Database.database = DB::PACT_BROKER_DB require 'spec/support/database_cleaner' -require 'pact_broker/api' +require 'pact_broker' +require 'pact_broker/app' +require_relative 'hal_relation_proxy_app' require_relative 'provider_states_for_pact_broker_client' +pact_broker = PactBroker::App.new { |c| c.database_connection = DB::PACT_BROKER_DB } +app_to_verify = HalRelationProxyApp.new(pact_broker) + +module Rack + module PactBroker + class DatabaseTransaction + def do_not_rollback? response + # Dodgey hack to stop exceptions raising a Rollback error while verifying + # Otherwise the provider states that deliberately raise exceptions + # end up raising exceptions that break the verification tests + true + end + end + end +end + Pact.service_provider "Pact Broker" do + app { HalRelationProxyApp.new(app_to_verify) } + honours_pact_with "Pact Broker Client" do pact_uri "https://raw.githubusercontent.com/pact-foundation/pact_broker-client/master/spec/pacts/pact_broker_client-pact_broker.json" end diff --git a/spec/service_consumers/provider_states_for_pact_broker_client.rb b/spec/service_consumers/provider_states_for_pact_broker_client.rb index a9ba3d01f..e78c37e1b 100644 --- a/spec/service_consumers/provider_states_for_pact_broker_client.rb +++ b/spec/service_consumers/provider_states_for_pact_broker_client.rb @@ -2,6 +2,33 @@ Pact.provider_states_for "Pact Broker Client" do + provider_state "the pb:latest-tagged-version relation exists in the index resource" do + no_op + end + + provider_state "'Condor' exists in the pact-broker with the latest tagged 'production' version 1.2.3" do + set_up do + TestDataBuilder.new + .create_consumer("Condor") + .create_consumer_version("1.2.3") + .create_consumer_version_tag("production") + .create_consumer_version("2.0.0") + end + end + + provider_state "the pb:latest-version relation exists in the index resource" do + no_op + end + + provider_state "'Condor' exists in the pact-broker with the latest version 1.2.3" do + set_up do + TestDataBuilder.new + .create_consumer("Condor") + .create_consumer_version("1.0.0") + .create_consumer_version("1.2.3") + end + end + provider_state "the pact for Foo Thing version 1.2.3 has been verified by Bar version 4.5.6" do set_up do TestDataBuilder.new