From 042a16129f97e8c0375ca59234d2064436f52b91 Mon Sep 17 00:00:00 2001 From: Beth Skurrie Date: Mon, 12 Jul 2021 13:26:58 +1000 Subject: [PATCH] feat: support the deployedOrReleased: true consumer version selector --- .../verifiable_pacts_json_query_schema.rb | 14 +++++++++-- .../verifiable_pacts_query_schema.rb | 1 - .../verifiable_pacts_query_decorator.rb | 23 +++++++++++++++++++ .../pacts/verifiable_pact_messages.rb | 2 ++ ...cts_json_query_schema_combinations_spec.rb | 3 +++ .../verifiable_pacts_query_decorator_spec.rb | 12 ++++++++++ 6 files changed, 52 insertions(+), 3 deletions(-) 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 d4cc2e4a1..e61caab8b 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 @@ -37,6 +37,7 @@ class VerifiablePactsJSONQuerySchema optional(:consumer).filled(:str?, :not_blank?) optional(:deployed).filled(included_in?: [true]) optional(:released).filled(included_in?: [true]) + optional(:deployedOrReleased).filled(included_in?: [true]) optional(:environment).filled(:str?) # rule(fallbackTagMustBeForLatest: [:fallbackTag, :latest]) do | fallback_tag, latest | @@ -92,8 +93,9 @@ def self.validate_consumer_version_selector(selector, index) not_provided?(selector[:environment]) && selector[:deployed] != true && selector[:released] != true && + selector[:deployedOrReleased] != true && selector[:latest] != true - errors << "must specify a value for environment or tag, or specify latest=true, or specify deployed=true or released=true (at index #{index})" + errors << "must specify a value for environment or tag or branch, or specify latest=true, deployed=true, released=true or deployedOrReleased=true (at index #{index})" end if selector[:tag] && selector[:branch] @@ -116,8 +118,16 @@ def self.validate_consumer_version_selector(selector, index) errors << "cannot specify both deployed=true and released=true (at index #{index})" end + if selector[:deployed] && selector[:deployedOrReleased] + errors << "cannot specify both deployed=true and deployedOrReleased=true (at index #{index})" + end + + if selector[:released] && selector[:deployedOrReleased] + errors << "cannot specify both released=true and deployedOrReleased=true (at index #{index})" + end + non_environment_fields = selector.slice(:latest, :tag, :fallbackTag, :branch, :fallbackBranch).keys.sort - environment_related_fields = selector.slice(:environment, :deployed, :released).keys.sort + environment_related_fields = selector.slice(:environment, :deployed, :released, :deployedOrReleased).keys.sort if (non_environment_fields.any? && environment_related_fields.any?) errors << "cannot specify the #{pluralize("field", non_environment_fields.count)} #{non_environment_fields.join("/")} with the #{pluralize("field", environment_related_fields.count)} #{environment_related_fields.join("/")} (at index #{index})" diff --git a/lib/pact_broker/api/contracts/verifiable_pacts_query_schema.rb b/lib/pact_broker/api/contracts/verifiable_pacts_query_schema.rb index 47bd875fb..27f0e98b4 100644 --- a/lib/pact_broker/api/contracts/verifiable_pacts_query_schema.rb +++ b/lib/pact_broker/api/contracts/verifiable_pacts_query_schema.rb @@ -30,7 +30,6 @@ class VerifiablePactsQuerySchema def self.call(params) select_first_message(flatten_indexed_messages(SCHEMA.call(params&.symbolize_keys).messages(full: true))) end - end end end diff --git a/lib/pact_broker/api/decorators/verifiable_pacts_query_decorator.rb b/lib/pact_broker/api/decorators/verifiable_pacts_query_decorator.rb index 02b684bd0..269f67df6 100644 --- a/lib/pact_broker/api/decorators/verifiable_pacts_query_decorator.rb +++ b/lib/pact_broker/api/decorators/verifiable_pacts_query_decorator.rb @@ -30,6 +30,11 @@ class VerifiablePactsQueryDecorator < BaseDecorator property :environment_name, as: :environment property :currently_deployed, as: :deployed property :currently_supported, as: :released + property :deployed_or_released, + setter: ->(fragment:, represented:, **) { + represented.currently_deployed = true + represented.currently_supported = true + } end property :include_pending_status, default: false, @@ -45,11 +50,29 @@ class VerifiablePactsQueryDecorator < BaseDecorator def from_hash(hash) # This handles both the snakecase keys from the GET query and the camelcase JSON POST body result = super(hash&.snakecase_keys) + + result.consumer_version_selectors = split_out_deployed_or_released_selectors(result.consumer_version_selectors) + if result.consumer_version_selectors && !result.consumer_version_selectors.is_a?(PactBroker::Pacts::Selectors) result.consumer_version_selectors = PactBroker::Pacts::Selectors.new(result.consumer_version_selectors) end result end + + private + + def split_out_deployed_or_released_selectors(consumer_version_selectors) + consumer_version_selectors.flat_map do | selector | + if selector.currently_deployed && selector.currently_supported + [ + PactBroker::Pacts::Selector.new(selector.to_hash.without(:currently_supported)), + PactBroker::Pacts::Selector.new(selector.to_hash.without(:currently_deployed)) + ] + else + [selector] + end + end + end end end end diff --git a/lib/pact_broker/pacts/verifiable_pact_messages.rb b/lib/pact_broker/pacts/verifiable_pact_messages.rb index 9fbabd7c6..1cd7cdced 100644 --- a/lib/pact_broker/pacts/verifiable_pact_messages.rb +++ b/lib/pact_broker/pacts/verifiable_pact_messages.rb @@ -253,6 +253,8 @@ def short_selector_description selector "one of #{selector.tag}" elsif selector.currently_deployed? "deployed to #{selector.environment.name}" + elsif selector.currently_supported? + "released in #{selector.environment.name}" else selector.to_json end diff --git a/spec/lib/pact_broker/api/contracts/verifiable_pacts_json_query_schema_combinations_spec.rb b/spec/lib/pact_broker/api/contracts/verifiable_pacts_json_query_schema_combinations_spec.rb index 4a23663fc..683405457 100644 --- a/spec/lib/pact_broker/api/contracts/verifiable_pacts_json_query_schema_combinations_spec.rb +++ b/spec/lib/pact_broker/api/contracts/verifiable_pacts_json_query_schema_combinations_spec.rb @@ -13,6 +13,7 @@ module Contracts environment: "environment", deployed: true, released: true, + deployedOrReleased: true, consumer: "consumer" } @@ -29,6 +30,8 @@ module Contracts [:environment, :released], [:deployed], [:released], + [:deployedOrReleased], + [:environment, :deployedOrReleased] ] VALID_KEY_COMBINATIONS.each do | valid_key_combination | diff --git a/spec/lib/pact_broker/api/decorators/verifiable_pacts_query_decorator_spec.rb b/spec/lib/pact_broker/api/decorators/verifiable_pacts_query_decorator_spec.rb index 1efeffa8f..e912d83eb 100644 --- a/spec/lib/pact_broker/api/decorators/verifiable_pacts_query_decorator_spec.rb +++ b/spec/lib/pact_broker/api/decorators/verifiable_pacts_query_decorator_spec.rb @@ -113,6 +113,18 @@ module Decorators expect(subject.consumer_version_selectors.first.currently_deployed).to be true end end + + context "when deployedOrReleased is set to true" do + let(:consumer_version_selectors) do + [{ "deployedOrReleased" => true }] + end + + it "creates two selectors - one for deployed and one for released" do + expect(subject.consumer_version_selectors.size).to eq 2 + expect(subject.consumer_version_selectors.first).to eq PactBroker::Pacts::Selector.for_currently_deployed + expect(subject.consumer_version_selectors.last).to eq PactBroker::Pacts::Selector.for_currently_supported + end + end end context "when parsing query string params" do