From 3c29735d7c5ee871b643a6c93c1f88ac5787f376 Mon Sep 17 00:00:00 2001 From: Beth Skurrie Date: Thu, 17 Dec 2020 09:12:18 +1100 Subject: [PATCH] chore(pacts for verification): store resolved consumer version number with selector --- lib/pact_broker/domain/version.rb | 19 ++++++---- lib/pact_broker/pacts/repository.rb | 25 +++++-------- lib/pact_broker/pacts/selector.rb | 21 +++++++++++ lib/pact_broker/pacts/selectors.rb | 4 +++ ...ory_find_for_verification_fallback_spec.rb | 4 +-- .../repository_find_for_verification_spec.rb | 35 ++++++++++++------- 6 files changed, 72 insertions(+), 36 deletions(-) diff --git a/lib/pact_broker/domain/version.rb b/lib/pact_broker/domain/version.rb index e32423be9..dda352ced 100644 --- a/lib/pact_broker/domain/version.rb +++ b/lib/pact_broker/domain/version.rb @@ -47,13 +47,20 @@ class Version < Sequel::Model dataset_module do include PactBroker::Repositories::Helpers + def for(pacticipant_name, version_number) + where_pacticipant_name(pacticipant_name).where_number(version_number).single_record + end + def where_pacticipant_name(pacticipant_name) - join(:pacticipants) do | p | - Sequel.&( - { Sequel[first_source_alias][:pacticipant_id] => Sequel[p][:id] }, - name_like(Sequel[p][:name], pacticipant_name) - ) - end + where(pacticipant_id: db[:pacticipants].select(:id).where(name_like(:name, pacticipant_name))) + # If we do a join, we get the extra columns from the pacticipant table that then + # make == not work + # join(:pacticipants) do | p | + # Sequel.&( + # { Sequel[first_source_alias][:pacticipant_id] => Sequel[p][:id] }, + # name_like(Sequel[p][:name], pacticipant_name) + # ) + # end end def where_tag(tag) diff --git a/lib/pact_broker/pacts/repository.rb b/lib/pact_broker/pacts/repository.rb index 55cc6ff85..faf32f1ee 100644 --- a/lib/pact_broker/pacts/repository.rb +++ b/lib/pact_broker/pacts/repository.rb @@ -428,7 +428,7 @@ def find_pacts_for_which_the_latest_version_is_required(provider_name, consumer_ .order_ignore_case(:consumer_name) .collect do | latest_pact_publication | pact_publication = PactPublication.find(id: latest_pact_publication.id) - SelectedPact.new(pact_publication.to_domain, Selectors.create_for_overall_latest) + SelectedPact.new(pact_publication.to_domain, Selectors.create_for_overall_latest.resolve(pact_publication.consumer_version)) end else selectors_for_overall_latest = consumer_version_selectors.select(&:overall_latest?) @@ -438,7 +438,7 @@ def find_pacts_for_which_the_latest_version_is_required(provider_name, consumer_ query.collect do | latest_pact_publication | pact_publication = PactPublication.find(id: latest_pact_publication.id) resolved_selector = selector.consumer ? Selector.latest_for_consumer(selector.consumer) : Selector.overall_latest - SelectedPact.new(pact_publication.to_domain, Selectors.new(resolved_selector)) + SelectedPact.new(pact_publication.to_domain, Selectors.new(resolved_selector).resolve(pact_publication.consumer_version)) end end end @@ -453,26 +453,19 @@ def find_pacts_for_which_the_latest_version_for_the_tag_is_required(provider_nam query = query.consumer(selector.consumer) if selector.consumer query.all.collect do | latest_tagged_pact_publication | pact_publication = PactPublication.find(id: latest_tagged_pact_publication.id) - resolved_pact = selector.consumer ? Selector.latest_for_tag_and_consumer(selector.tag, selector.consumer) : Selector.latest_for_tag(selector.tag) + resolved_selector = if selector.consumer + Selector.latest_for_tag_and_consumer(selector.tag, selector.consumer).resolve(pact_publication.consumer_version) + else + Selector.latest_for_tag(selector.tag).resolve(pact_publication.consumer_version) + end SelectedPact.new( pact_publication.to_domain, - Selectors.new(resolved_pact) + Selectors.new(resolved_selector) ) end end end - def create_fallback_selected_pact(pact_publications, consumer_version_selectors) - selector_tag_names = pact_publications.collect(&:tag_name) - selectors = Selectors.create_for_latest_fallback_of_each_tag(selector_tag_names) - last_pact_publication = pact_publications.sort_by(&:consumer_version_order).last - pact_publication = unscoped(PactPublication).find(id: last_pact_publication.id) - SelectedPact.new( - pact_publication.to_domain, - selectors - ) - end - def find_pacts_for_which_the_latest_version_for_the_fallback_tag_is_required(provider_name, selectors) selectors.collect do | selector | query = scope_for(LatestTaggedPactPublications).provider(provider_name).where(tag_name: selector.fallback_tag) @@ -482,7 +475,7 @@ def find_pacts_for_which_the_latest_version_for_the_fallback_tag_is_required(pro pact_publication = unscoped(PactPublication).find(id: latest_tagged_pact_publication.id) SelectedPact.new( pact_publication.to_domain, - Selectors.new(selector) + Selectors.new(selector.resolve(pact_publication.consumer_version)) ) end end.flatten diff --git a/lib/pact_broker/pacts/selector.rb b/lib/pact_broker/pacts/selector.rb index 1a0e03be1..da28e1115 100644 --- a/lib/pact_broker/pacts/selector.rb +++ b/lib/pact_broker/pacts/selector.rb @@ -5,6 +5,10 @@ def initialize(options = {}) merge!(options) end + def resolve(consumer_version) + ResolvedSelector.new(self.to_h, consumer_version) + end + def tag= tag self[:tag] = tag end @@ -94,6 +98,10 @@ def all_for_tag? !!(tag && !latest?) end + def == other + other.class == self.class && super + end + def <=> other if overall_latest? || other.overall_latest? if overall_latest? == other.overall_latest? @@ -124,5 +132,18 @@ def latest? !!self[:latest] end end + + class ResolvedSelector < Selector + attr_reader :consumer_version + + def initialize(options = {}, consumer_version) + super(options) + @consumer_version = consumer_version + end + + def == other + super && consumer_version == other.consumer_version + end + end end end diff --git a/lib/pact_broker/pacts/selectors.rb b/lib/pact_broker/pacts/selectors.rb index a31926dcd..592131842 100644 --- a/lib/pact_broker/pacts/selectors.rb +++ b/lib/pact_broker/pacts/selectors.rb @@ -19,6 +19,10 @@ def self.create_for_overall_latest Selectors.new([Selector.overall_latest]) end + def resolve(consumer_version) + Selectors.new(collect{ |selector| selector.resolve(consumer_version) }) + end + def + other Selectors.new(super) end diff --git a/spec/lib/pact_broker/pacts/repository_find_for_verification_fallback_spec.rb b/spec/lib/pact_broker/pacts/repository_find_for_verification_fallback_spec.rb index 823ea1272..b3a9966f6 100644 --- a/spec/lib/pact_broker/pacts/repository_find_for_verification_fallback_spec.rb +++ b/spec/lib/pact_broker/pacts/repository_find_for_verification_fallback_spec.rb @@ -30,7 +30,7 @@ def find_by_consumer_name_and_consumer_version_number(consumer_name, consumer_ve context "when a pact exists for the main tag" do it "returns the pact with the main tag" do expect(find_by_consumer_version_number("2")).to_not be nil - expect(find_by_consumer_version_number("2").selectors.first).to eq Selector.latest_for_tag(tag) + expect(find_by_consumer_version_number("2").selectors.first).to eq Selector.latest_for_tag(tag).resolve(PactBroker::Domain::Version.for("Foo", "2")) end it "does not set the fallback_tag on the selector" do @@ -67,7 +67,7 @@ def find_by_consumer_name_and_consumer_version_number(consumer_name, consumer_ve it "only returns the pacts for the consumer" do expect(subject.size).to eq 1 expect(subject.first.consumer.name).to eq "Foo" - expect(subject.first.selectors.first).to eq selector + expect(subject.first.selectors.first).to eq selector.resolve(PactBroker::Domain::Version.for("Foo", "1")) end end end diff --git a/spec/lib/pact_broker/pacts/repository_find_for_verification_spec.rb b/spec/lib/pact_broker/pacts/repository_find_for_verification_spec.rb index 410c43282..ba4ef5908 100644 --- a/spec/lib/pact_broker/pacts/repository_find_for_verification_spec.rb +++ b/spec/lib/pact_broker/pacts/repository_find_for_verification_spec.rb @@ -3,8 +3,6 @@ module PactBroker module Pacts describe Repository do - let(:td) { TestDataBuilder.new } - describe "#find_for_verification" do def find_by_consumer_version_number(consumer_version_number) subject.find{ |pact| pact.consumer_version_number == consumer_version_number } @@ -55,8 +53,8 @@ def find_by_consumer_name_and_consumer_version_number(consumer_name, consumer_ve it "returns the latest pact for each consumer" do expect(subject.size).to eq 2 - expect(find_by_consumer_name_and_consumer_version_number("Foo1", "2").selectors).to eq [Selector.overall_latest] - expect(find_by_consumer_name_and_consumer_version_number("Foo2", "3").selectors).to eq [Selector.overall_latest] + expect(find_by_consumer_name_and_consumer_version_number("Foo1", "2").selectors).to eq [Selector.overall_latest.resolve(PactBroker::Domain::Version.find(number: "2"))] + expect(find_by_consumer_name_and_consumer_version_number("Foo2", "3").selectors).to eq [Selector.overall_latest.resolve(PactBroker::Domain::Version.find(number: "3"))] end end @@ -76,7 +74,7 @@ def find_by_consumer_name_and_consumer_version_number(consumer_name, consumer_ve it "returns the latest pact for each consumer" do expect(subject.size).to eq 1 - expect(find_by_consumer_name_and_consumer_version_number("Foo1", "2").selectors).to eq [pact_selector_1] + expect(find_by_consumer_name_and_consumer_version_number("Foo1", "2").selectors).to eq [pact_selector_1.resolve(PactBroker::Domain::Version.find(number: "2"))] end end @@ -98,7 +96,8 @@ def find_by_consumer_name_and_consumer_version_number(consumer_name, consumer_ve it "returns the latest pact for each consumer" do expect(subject.size).to eq 1 - expect(find_by_consumer_name_and_consumer_version_number("Foo1", "1").selectors).to eq [pact_selector_1] + expected_consumer_version = PactBroker::Domain::Version.where_pacticipant_name("Foo1").where(number: "1").single_record + expect(find_by_consumer_name_and_consumer_version_number("Foo1", "1").selectors).to eq [pact_selector_1.resolve(expected_consumer_version)] end end @@ -122,11 +121,17 @@ def find_by_consumer_name_and_consumer_version_number(consumer_name, consumer_ve let(:consumer_version_selectors) do Selectors.new(pact_selector_1, pact_selector_2) end + let(:expected_sorted_selectors) do + [ + ResolvedSelector.new({ tag: 'dev', latest: true }, PactBroker::Domain::Version.for("Baz", "baz-latest-dev-version")), + ResolvedSelector.new({ tag: 'prod', latest: true }, PactBroker::Domain::Version.for("Baz", "baz-latest-dev-version")) + ] + end it "returns the latest pact with the specified tags for each consumer" do - expect(find_by_consumer_version_number("foo-latest-prod-version").selectors).to eq [Selector.latest_for_tag('prod')] - expect(find_by_consumer_version_number("foo-latest-dev-version").selectors).to eq [Selector.latest_for_tag('dev')] - expect(find_by_consumer_version_number("baz-latest-dev-version").selectors.sort_by{ |s| s[:tag] }).to eq [{ tag: 'dev', latest: true }, { tag: 'prod', latest: true }] + expect(find_by_consumer_version_number("foo-latest-prod-version").selectors).to eq [Selector.latest_for_tag('prod').resolve(PactBroker::Domain::Version.for("Foo", "foo-latest-prod-version"))] + expect(find_by_consumer_version_number("foo-latest-dev-version").selectors).to eq [Selector.latest_for_tag('dev').resolve(PactBroker::Domain::Version.for("Foo", "foo-latest-dev-version"))] + expect(find_by_consumer_version_number("baz-latest-dev-version").selectors.sort_by{ |s| s[:tag] }).to eq expected_sorted_selectors expect(subject.size).to eq 3 end @@ -134,12 +139,18 @@ def find_by_consumer_name_and_consumer_version_number(consumer_name, consumer_ve expect(find_by_consumer_version_number("foo-latest-prod-version").selectors.collect(&:tag)).to eq ['prod'] end - context "when a consumer name is specified", pending: "not yet implemented, but will do" do + context "when a consumer name is specified" do + before do + td.create_pact_with_hierarchy("Foo", "2", "Bar") + .create_consumer_version_tag("prod") + .create_pact_with_hierarchy("Foo", "3", "Bar") + .create_consumer_version_tag("prod") + end let(:consumer_version_selectors) do Selectors.new(Selector.all_for_tag_and_consumer('prod', 'Foo')) end - it "only returns the pacts for that consumer" do + it "returns all the pacts with that tag for that consumer" do expect(subject.size).to eq 3 expect(find_by_consumer_version_number("foo-latest-prod-version").selectors).to eq [Selector.all_for_tag_and_consumer('prod', 'Foo')] end @@ -246,7 +257,7 @@ def find_by_consumer_name_and_consumer_version_number(consumer_name, consumer_ve end it "does not set the tag name" do - expect(find_by_consumer_version_number("foo-latest-dev-version").selectors).to eq [{ latest: true }] + expect(find_by_consumer_version_number("foo-latest-dev-version").selectors).to eq [ResolvedSelector.new({ latest: true }, PactBroker::Domain::Version.find(number: "foo-latest-dev-version"))] expect(find_by_consumer_version_number("foo-latest-dev-version").overall_latest?).to be true end end