diff --git a/lib/pact_broker/pacts/repository.rb b/lib/pact_broker/pacts/repository.rb index ba867cee4..71ef54fb8 100644 --- a/lib/pact_broker/pacts/repository.rb +++ b/lib/pact_broker/pacts/repository.rb @@ -187,13 +187,20 @@ def find_all_revisions consumer_name, consumer_version, provider_name .order(:consumer_version_order, :revision_number).collect(&:to_domain_with_content) end - def find_previous_pact pact - LatestPactPublicationsByConsumerVersion - .eager(:tags) - .consumer(pact.consumer.name) - .provider(pact.provider.name) - .consumer_version_order_before(pact.consumer_version.order) - .latest.collect(&:to_domain_with_content)[0] + def find_previous_pact pact, tag = nil + query = LatestPactPublicationsByConsumerVersion + .eager(:tags) + .consumer(pact.consumer.name) + .provider(pact.provider.name) + + if tag == :untagged + query = query.untagged + elsif tag + query = query.tag(tag) + end + + query.consumer_version_order_before(pact.consumer_version.order) + .latest.collect(&:to_domain_with_content)[0] end def find_next_pact pact diff --git a/lib/pact_broker/pacts/service.rb b/lib/pact_broker/pacts/service.rb index d70336152..bfceb7581 100644 --- a/lib/pact_broker/pacts/service.rb +++ b/lib/pact_broker/pacts/service.rb @@ -104,8 +104,8 @@ def find_distinct_pacts_between consumer, options # TODO also take into account overridden revisions def pact_is_new_or_pact_has_changed_since_previous_version? pact - previous_pact = pact_repository.find_previous_pact pact - previous_pact.nil? || pact.json_content != previous_pact.json_content + previous_pacts = find_previous_pacts pact + previous_pacts.any? { |previous_pact| previous_pact.nil? || pact.json_content != previous_pact.json_content} end private @@ -140,6 +140,14 @@ def trigger_webhooks pact logger.debug "Pact has not changed since previous version, not triggering webhooks" end end + + def find_previous_pacts pact + if pact.consumer_version_tag_names.any? + pact.consumer_version_tag_names.map { |tag| pact_repository.find_previous_pact(pact, tag) } + else + [pact_repository.find_previous_pact(pact, :untagged)] + end + end end end end diff --git a/spec/lib/pact_broker/pacts/repository_spec.rb b/spec/lib/pact_broker/pacts/repository_spec.rb index 0f418a23d..0aa783363 100644 --- a/spec/lib/pact_broker/pacts/repository_spec.rb +++ b/spec/lib/pact_broker/pacts/repository_spec.rb @@ -513,27 +513,74 @@ module Pacts .create_consumer("Consumer") .create_consumer_version("1.2.2") .create_provider("Provider") + .create_consumer_version_tag("a_tag") + .create_pact + .create_consumer_version("1.2.3") .create_pact .create_consumer_version("1.2.4") + .create_consumer_version_tag("another_tag") .create_pact - .create_consumer_version("1.2.6") + .create_consumer_version("1.2.5") + .create_consumer_version_tag("a_tag") + .create_pact + .create_consumer_version("1.2.7") + .create_consumer_version_tag("another_tag") .create_pact .create_provider("Another Provider") - .create_consumer_version("1.2.5") + .create_consumer_version("1.2.6") + .create_consumer_version_tag("a_tag") .create_pact end - let(:pact) { Repository.new.find_latest_pact "Consumer", "Provider" } + context "regardless of tag" do + context "when a previous version with a pact exists" do - subject { Repository.new.find_previous_pact pact } + let(:pact) { Repository.new.find_latest_pact "Consumer", "Provider", "another_tag" } - it "finds the previous pact" do - expect(subject.consumer_version_number).to eq "1.2.4" - expect(subject.consumer_version.number).to eq "1.2.4" + subject { Repository.new.find_previous_pact pact } + + it "finds the previous pact" do + expect(subject.consumer_version_number).to eq "1.2.5" + end + + it "sets the json_content" do + expect(subject.json_content).to_not be nil + end + end end - it "sets the json_content" do - expect(subject.json_content).to_not be nil + context "by tag" do + context "when a previous version with a pact with a specific tag exists" do + + let(:pact) { Repository.new.find_latest_pact "Consumer", "Provider", "a_tag" } + + subject { Repository.new.find_previous_pact pact, "a_tag" } + + it "finds the previous pact" do + expect(subject.consumer_version_number).to eq "1.2.2" + end + + it "sets the json_content" do + expect(subject.json_content).to_not be nil + end + end + end + + context "that is untagged" do + context "when a previous version with a an untagged pact exists" do + + let(:pact) { Repository.new.find_latest_pact "Consumer", "Provider" } + + subject { Repository.new.find_previous_pact pact, :untagged } + + it "finds the previous pact" do + expect(subject.consumer_version_number).to eq "1.2.3" + end + + it "sets the json_content" do + expect(subject.json_content).to_not be nil + end + end end end diff --git a/spec/lib/pact_broker/pacts/service_spec.rb b/spec/lib/pact_broker/pacts/service_spec.rb index 5bbf915ad..8319692cf 100644 --- a/spec/lib/pact_broker/pacts/service_spec.rb +++ b/spec/lib/pact_broker/pacts/service_spec.rb @@ -34,35 +34,83 @@ module Pacts let(:json_content) { { 'some' => 'json'}.to_json } let(:pact) { instance_double(PactBroker::Domain::Pact, json_content: json_content)} - before do - allow_any_instance_of(Pacts::Repository).to receive(:find_previous_pact).and_return(previous_pact) - end - subject { Service.pact_is_new_or_pact_has_changed_since_previous_version? pact } - context "when a previous pact is found" do - let(:previous_pact) { instance_double(PactBroker::Domain::Pact, json_content: previous_json_content)} - let(:previous_json_content) { {'some' => 'json'}.to_json } + context "when consumer version is untagged" do + before do + allow(pact).to receive(:consumer_version_tag_names).and_return([]); + allow_any_instance_of(Pacts::Repository).to receive(:find_previous_pact).with(pact, :untagged).and_return(previous_pact) + end + + context "when a previous pact is found" do + let(:previous_pact) { instance_double(PactBroker::Domain::Pact, json_content: previous_json_content)} + let(:previous_json_content) { {'some' => 'json'}.to_json } - context "when the json_content is the same" do - it "returns false" do - expect(subject).to be_falsey + context "when the json_content is the same" do + it "returns false" do + expect(subject).to be_falsey + end + end + + context "when the json_content is not the same" do + let(:previous_json_content) { {'some-other' => 'json'}.to_json } + it "returns truthy" do + expect(subject).to be_truthy + end end end - context "when the json_content is not the same" do - let(:previous_json_content) { {'some-other' => 'json'}.to_json } - it "returns truthy" do + context "when a previous pact is not found" do + let(:previous_pact) { nil } + + it "returns true" do expect(subject).to be_truthy end end end - context "when a previous pact is not found" do - let(:previous_pact) { nil } + context "when consumer version has two tags" do + before do + allow(pact).to receive(:consumer_version_tag_names).and_return(['tag_1', 'tag_2']); + allow_any_instance_of(Pacts::Repository).to receive(:find_previous_pact).with(pact, 'tag_1').and_return(previous_pact_tag_1) + allow_any_instance_of(Pacts::Repository).to receive(:find_previous_pact).with(pact, 'tag_2').and_return(previous_pact_tag_2) + end + + context "when a previous pact is found for both tags" do + let(:previous_pact_tag_1) { instance_double(PactBroker::Domain::Pact, json_content: previous_json_content_tag_1)} + let(:previous_json_content_tag_1) { {'some' => 'json'}.to_json } + + let(:previous_pact_tag_2) { instance_double(PactBroker::Domain::Pact, json_content: previous_json_content_tag_2)} + let(:previous_json_content_tag_2) { {'some' => 'json'}.to_json } - it "returns true" do - expect(subject).to be_truthy + context "when the json_content of both previous pacts and new pact is the same" do + it "returns false" do + expect(subject).to be_falsey + end + end + + context "when the json_content of first previous pact is not the same" do + let(:previous_json_content_tag_1) { {'some-other' => 'json'}.to_json } + it "returns truthy" do + expect(subject).to be_truthy + end + end + + context "when the json_content of second previous pact not the same" do + let(:previous_json_content_tag_2) { {'some-other' => 'json'}.to_json } + it "returns truthy" do + expect(subject).to be_truthy + end + end + end + + context "when no previous pacts are found" do + let(:previous_pact_tag_1) { nil } + let(:previous_pact_tag_2) { nil } + + it "returns true" do + expect(subject).to be_truthy + end end end end