Skip to content

Commit

Permalink
feat: support the deployedOrReleased: true consumer version selector
Browse files Browse the repository at this point in the history
  • Loading branch information
bethesque committed Jul 12, 2021
1 parent c17adbe commit 042a161
Show file tree
Hide file tree
Showing 6 changed files with 52 additions and 3 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -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 |
Expand Down Expand Up @@ -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]
Expand All @@ -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})"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
23 changes: 23 additions & 0 deletions lib/pact_broker/api/decorators/verifiable_pacts_query_decorator.rb
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand All @@ -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
Expand Down
2 changes: 2 additions & 0 deletions lib/pact_broker/pacts/verifiable_pact_messages.rb
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ module Contracts
environment: "environment",
deployed: true,
released: true,
deployedOrReleased: true,
consumer: "consumer"
}

Expand All @@ -29,6 +30,8 @@ module Contracts
[:environment, :released],
[:deployed],
[:released],
[:deployedOrReleased],
[:environment, :deployedOrReleased]
]

VALID_KEY_COMBINATIONS.each do | valid_key_combination |
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down

0 comments on commit 042a161

Please sign in to comment.