diff --git a/lib/pact_broker/domain/tag.rb b/lib/pact_broker/domain/tag.rb index 9caf1aa6b..7a07610b3 100644 --- a/lib/pact_broker/domain/tag.rb +++ b/lib/pact_broker/domain/tag.rb @@ -1,10 +1,15 @@ require 'pact_broker/db' +require 'pact_Broker/repositories/helpers' module PactBroker module Domain class Tag < Sequel::Model + dataset_module do + include PactBroker::Repositories::Helpers + end + unrestrict_primary_key associate(:many_to_one, :version, :class => "PactBroker::Domain::Version", :key => :version_id, :primary_key => :id) diff --git a/lib/pact_broker/matrix/repository.rb b/lib/pact_broker/matrix/repository.rb index 7a40ecd8d..fe836eb8b 100644 --- a/lib/pact_broker/matrix/repository.rb +++ b/lib/pact_broker/matrix/repository.rb @@ -37,6 +37,8 @@ def find_compatible_pacticipant_versions selectors # If the version is nil, it means all versions for that pacticipant are to be included # def find_all selectors + selectors = look_up_versions_for_tags(selectors) + query = PactBroker::Pacts::LatestPactPublicationsByConsumerVersion .select_append(:consumer_version_number, :provider_name, :consumer_name, :provider_version_id, :provider_version_number, :success) .select_append(Sequel[:latest_pact_publications_by_consumer_versions][:created_at].as(:pact_created_at)) @@ -55,6 +57,21 @@ def find_all selectors .collect(&:values) end + def look_up_versions_for_tags(selectors) + selectors.collect do | selector | + if selector[:latest_tag] + version = version_repository.find_by_latest_tag(selector[:pacticipant_name], selector[:latest_tag]) + # validation in resource should ensure we always have a version + { + pacticipant_name: selector[:pacticipant_name], + pacticipant_version_number: version.number + } + else + selector + end + end + end + def where_consumer_and_provider_within selectors, query query.where{ Sequel.&( diff --git a/lib/pact_broker/tags/repository.rb b/lib/pact_broker/tags/repository.rb index 9d66e11f0..336377f64 100644 --- a/lib/pact_broker/tags/repository.rb +++ b/lib/pact_broker/tags/repository.rb @@ -14,7 +14,7 @@ def create args def find args PactBroker::Domain::Tag - .select(Sequel.qualify("tags", "name"), Sequel.qualify("tags", "version_id"), Sequel.qualify("tags", "created_at"), Sequel.qualify("tags", "updated_at")) + .select_all_qualified .join(:versions, {id: :version_id}) .join(:pacticipants, {Sequel.qualify("pacticipants", "id") => Sequel.qualify("versions", "pacticipant_id")}) .where(name_like(Sequel.qualify("tags", "name"), args.fetch(:tag_name))) diff --git a/lib/pact_broker/versions/repository.rb b/lib/pact_broker/versions/repository.rb index 1c2551d6a..10553c324 100644 --- a/lib/pact_broker/versions/repository.rb +++ b/lib/pact_broker/versions/repository.rb @@ -12,6 +12,17 @@ def find_by_pacticipant_id_and_number pacticipant_id, number PactBroker::Domain::Version.where(number: number, pacticipant_id: pacticipant_id).single_record end + def find_by_latest_tag pacticipant_name, tag + PactBroker::Domain::Version + .select_all_qualified + .join(:pacticipants, {id: :pacticipant_id}, {implicit_qualifier: :versions}) + .join(:tags, {version_id: :id}, {implicit_qualifier: :versions}) + .where(name_like(Sequel[:tags][:name], tag)) + .where(name_like(Sequel[:pacticipants][:name], pacticipant_name)) + .reverse_order(:order) + .first + end + def find_by_pacticipant_name_and_number pacticipant_name, number PactBroker::Domain::Version .select(Sequel[:versions][:id], Sequel[:versions][:number], Sequel[:versions][:pacticipant_id], Sequel[:versions][:order], Sequel[:versions][:created_at], Sequel[:versions][:updated_at]) diff --git a/lib/pact_broker/versions/service.rb b/lib/pact_broker/versions/service.rb index 3d24cb7de..c21002925 100644 --- a/lib/pact_broker/versions/service.rb +++ b/lib/pact_broker/versions/service.rb @@ -16,13 +16,6 @@ def self.delete version pact_repository.delete_by_version_id version.id version_repository.delete_by_id version.id end - - def self.find_versions_by_selector selectors - selectors.collect do | selector | - pacticipant_name, type, number = selector.split("/") - version_repository.find_by_pacticipant_name_and_number pacticipant_name, number - end - end end end end diff --git a/spec/lib/pact_broker/matrix/repository_spec.rb b/spec/lib/pact_broker/matrix/repository_spec.rb index 45dd867c9..4a1d1050d 100644 --- a/spec/lib/pact_broker/matrix/repository_spec.rb +++ b/spec/lib/pact_broker/matrix/repository_spec.rb @@ -219,6 +219,33 @@ def build_selectors(hash) end end end + + context "when the latest tag is specified for a provider instead of a version" do + before do + td.create_pact_with_hierarchy("A", "1.2.3", "B") + .create_verification(provider_version: "1.0.0") + .use_provider_version("1.0.0") + .create_provider_version_tag("prod") + .create_verification(provider_version: "2.0.0", number: 2) + .use_provider_version("2.0.0") + .create_provider_version_tag("prod") + .create_verification(provider_version: "3.0.0", number: 3) + end + + let(:selectors) do + [ + { pacticipant_name: "A", pacticipant_version_number: "1.2.3" }, + { pacticipant_name: "B", latest_tag: "prod" } + ] + end + + subject { Repository.new.find(selectors) } + + it "returns the row for the version " do + expect(subject.first).to include provider_version_number: "2.0.0" + expect(subject.size).to eq 1 + end + end end describe "#find_for_consumer_and_provider" do diff --git a/spec/lib/pact_broker/versions/repository_spec.rb b/spec/lib/pact_broker/versions/repository_spec.rb index b6299ca5e..313a95521 100644 --- a/spec/lib/pact_broker/versions/repository_spec.rb +++ b/spec/lib/pact_broker/versions/repository_spec.rb @@ -5,9 +5,33 @@ module PactBroker module Versions describe Repository do + let(:td) { TestDataBuilder.new } let(:pacticipant_name) { "test_pacticipant" } let(:version_number) { "1.2.3" } + + describe "#find_by_latest_tag" do + before do + td.create_consumer("Bar") + .create_consumer_version("2.3.4") + .create_consumer_version_tag("prod") + .create_consumer("Foo") + .create_consumer_version("1.2.3") + .create_consumer_version_tag("prod") + .create_consumer_version("2.3.4") + .create_consumer_version_tag("prod") + .create_consumer_version("5.6.7") + end + + subject { Repository.new.find_by_latest_tag("Foo", "prod") } + + it "returns the most recent version that has the specified tag" do + + expect(subject.number).to eq "2.3.4" + expect(subject.pacticipant.name).to eq "Foo" + end + end + describe "#create" do context "when a previous version exists" do diff --git a/spec/lib/pact_broker/versions/service_spec.rb b/spec/lib/pact_broker/versions/service_spec.rb index 7ea028204..58ffa99ae 100644 --- a/spec/lib/pact_broker/versions/service_spec.rb +++ b/spec/lib/pact_broker/versions/service_spec.rb @@ -4,44 +4,6 @@ module PactBroker module Versions describe Service do - - describe ".find_versions_by_selector" do - - context "without a version selector" do - let(:selector) { "Foo" } - end - - context "with a version selector" do - before do - TestDataBuilder.new - .create_pacticipant("Foo") - .create_version("1.2.3") - .create_version("4.5.6") - .create_pacticipant("Bar") - .create_version("1.2.3") - end - - let(:selector) { "Foo/version/1.2.3" } - - subject { Service.find_versions_by_selector [selector] } - - context "when the version exists" do - it "returns the specfied version" do - expect(subject.first.number).to eq "1.2.3" - expect(subject.first.pacticipant.name).to eq "Foo" - end - end - - context "when the version does not exist" do - let(:selector) { "Wiffle/version/0.0.0" } - - it "returns nil" do - expect(subject.first).to eq nil - end - end - end - end - describe ".delete" do let!(:version) do TestDataBuilder.new diff --git a/spec/support/test_data_builder.rb b/spec/support/test_data_builder.rb index 4e2719918..db22aaad4 100644 --- a/spec/support/test_data_builder.rb +++ b/spec/support/test_data_builder.rb @@ -154,6 +154,11 @@ def use_consumer_version version_number self end + def use_provider_version version_number + @provider_version = PactBroker::Domain::Version.where(pacticipant_id: @provider.id, number: version_number).single_record + self + end + def create_tag tag_name @tag = PactBroker::Domain::Tag.create(name: tag_name, version: @version) self @@ -164,6 +169,11 @@ def create_consumer_version_tag tag_name self end + def create_provider_version_tag tag_name + @tag = PactBroker::Domain::Tag.create(name: tag_name, version: @provider_version) + self + end + def create_label label_name @label = PactBroker::Domain::Label.create(name: label_name, pacticipant: @pacticipant) self