diff --git a/lib/pact_broker/api/contracts/verifiable_pacts_json_query_schema.rb b/lib/pact_broker/api/contracts/verifiable_pacts_json_query_schema.rb index 773044088..ef903d0dc 100644 --- a/lib/pact_broker/api/contracts/verifiable_pacts_json_query_schema.rb +++ b/lib/pact_broker/api/contracts/verifiable_pacts_json_query_schema.rb @@ -39,7 +39,30 @@ class VerifiablePactsJSONQuerySchema end def self.call(params) - select_first_message(flatten_indexed_messages(SCHEMA.call(params&.symbolize_keys).messages(full: true))) + symbolized_params = params&.symbolize_keys + results = select_first_message(flatten_indexed_messages(SCHEMA.call(symbolized_params).messages(full: true))) + add_cross_field_validation_errors(symbolized_params, results) + results + end + + def self.add_cross_field_validation_errors(params, results) + # This is a ducking joke. Need to get rid of dry-validation + if params[:consumerVersionSelectors].is_a?(Array) + errors = [] + params[:consumerVersionSelectors].each_with_index do | selector, index | + if selector[:fallbackTag] && !selector[:latest] + errors << "fallbackTag can only be set if latest is true (at index #{index})" + end + + if selector[:consumer] && selector[:latest] + errors << "specifying a consumer with latest == true is not yet supported (at index #{index})" + end + end + if errors.any? + results[:consumerVersionSelectors] ||= [] + results[:consumerVersionSelectors].concat(errors) + end + end end end end diff --git a/spec/lib/pact_broker/api/contracts/verifiable_pacts_json_query_schema_spec.rb b/spec/lib/pact_broker/api/contracts/verifiable_pacts_json_query_schema_spec.rb index d07fb3b77..34ec8b2c6 100644 --- a/spec/lib/pact_broker/api/contracts/verifiable_pacts_json_query_schema_spec.rb +++ b/spec/lib/pact_broker/api/contracts/verifiable_pacts_json_query_schema_spec.rb @@ -43,7 +43,7 @@ module Contracts end end - context "when latest is not specified", pending: true do + context "when latest is not specified" do let(:consumer_version_selectors) do [{ tag: "feat-x", @@ -52,7 +52,21 @@ module Contracts end it "has an error" do - expect(subject[:consumerVersionSelectors].first).to include "not allowed" + expect(subject[:consumerVersionSelectors].first).to match /can only be set.*index 0/ + end + + context "when there are multiple errors" do + let(:consumer_version_selectors) do + [{ + consumer: "", + tag: "feat-x", + fallbackTag: "master" + }] + end + + it "merges the array" do + expect(subject[:consumerVersionSelectors].size).to be 2 + end end end end @@ -126,6 +140,20 @@ module Contracts expect(subject[:consumerVersionSelectors].first).to include "blank" end end + + context "when a consumer name is specified with a latest tag" do + let(:consumer_version_selectors) do + [{ + latest: true, + tag: "feat-x", + consumer: "foo" + }] + end + + it "has an error" do + expect(subject[:consumerVersionSelectors].first).to include "not yet supported" + end + end 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 4d37f2168..18f322d5d 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 @@ -72,6 +72,17 @@ def find_by_consumer_name_and_consumer_version_number(consumer_name, consumer_ve it "sets the latest_consumer_version_tag_names" do 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 + 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 + 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 + end end context "when all versions with a given tag are requested" do