From dcad5fb577ef99d3bf697c9b78c00f169967d8fa Mon Sep 17 00:00:00 2001 From: Beth Skurrie Date: Mon, 1 Mar 2021 14:48:45 +1100 Subject: [PATCH] feat(environments): validate environment name in can-i-deploy and matrix queries --- .../contracts/dry_validation_predicates.rb | 5 +++ lib/pact_broker/locale/en.yml | 2 + .../matrix/can_i_deploy_query_schema.rb | 8 +++- lib/pact_broker/matrix/service.rb | 4 ++ .../matrix/can_i_deploy_query_schema_spec.rb | 37 +++++++++++++++++++ spec/lib/pact_broker/matrix/service_spec.rb | 19 ++++++++++ 6 files changed, 74 insertions(+), 1 deletion(-) diff --git a/lib/pact_broker/api/contracts/dry_validation_predicates.rb b/lib/pact_broker/api/contracts/dry_validation_predicates.rb index 4cac4d866..864615f97 100644 --- a/lib/pact_broker/api/contracts/dry_validation_predicates.rb +++ b/lib/pact_broker/api/contracts/dry_validation_predicates.rb @@ -21,6 +21,11 @@ module DryValidationPredicates predicate(:no_spaces?) do | value | value && value.is_a?(String) && !value.include?(" ") end + + predicate(:environment_with_name_exists?) do | value | + require 'pact_broker/deployments/environment_service' + !!PactBroker::Deployments::EnvironmentService.find_by_name(value) + end end end end diff --git a/lib/pact_broker/locale/en.yml b/lib/pact_broker/locale/en.yml index b37389b66..757fd0242 100644 --- a/lib/pact_broker/locale/en.yml +++ b/lib/pact_broker/locale/en.yml @@ -11,6 +11,7 @@ en: pacticipant_exists?: "does not match an existing pacticipant" single_line?: "cannot contain multiple lines" no_spaces?: "cannot contain spaces" + environment_with_name_exists?: "with name '%{value}' does not exist" pact_broker: messages: @@ -50,6 +51,7 @@ en: environment_name_must_be_unique: Another environment with name '%{name}' already exists. cannot_specify_tag_and_environment: Cannot specify both a 'to' tag and an environment. cannot_specify_latest_and_environment: Cannot specify both latest=true and an environment. + environment_with_name_not_found: "Environment with name '%{name}' does not exist" duplicate_pacticipant: | This is the first time a pact has been published for "%{new_name}". The name "%{new_name}" is very similar to the following existing consumers/providers: diff --git a/lib/pact_broker/matrix/can_i_deploy_query_schema.rb b/lib/pact_broker/matrix/can_i_deploy_query_schema.rb index d7f14a23d..e6587319a 100644 --- a/lib/pact_broker/matrix/can_i_deploy_query_schema.rb +++ b/lib/pact_broker/matrix/can_i_deploy_query_schema.rb @@ -1,5 +1,7 @@ require 'dry-validation' require 'pact_broker/messages' +require 'pact_broker/api/contracts/dry_validation_predicates' +require 'pact_broker/project_root' module PactBroker module Api @@ -8,10 +10,14 @@ class CanIDeployQuerySchema extend PactBroker::Messages SCHEMA = Dry::Validation.Schema do + configure do + predicates(DryValidationPredicates) + config.messages_file = PactBroker.project_root.join("lib", "pact_broker", "locale", "en.yml") + end required(:pacticipant).filled(:str?) required(:version).filled(:str?) optional(:to).filled(:str?) - optional(:environment).filled(:str?) + optional(:environment).filled(:str?, :environment_with_name_exists?) end def self.call(params) diff --git a/lib/pact_broker/matrix/service.rb b/lib/pact_broker/matrix/service.rb index 7c18602e8..ac18e5610 100644 --- a/lib/pact_broker/matrix/service.rb +++ b/lib/pact_broker/matrix/service.rb @@ -83,6 +83,10 @@ def validate_selectors selectors, options = {} error_messages << message("errors.validation.cannot_specify_latest_and_environment") end + if options[:environment_name]&.not_blank? && environment_service.find_by_name(options[:environment_name]).nil? + error_messages << message("errors.validation.environment_with_name_not_found", name: options[:environment_name]) + end + error_messages end end diff --git a/spec/lib/pact_broker/matrix/can_i_deploy_query_schema_spec.rb b/spec/lib/pact_broker/matrix/can_i_deploy_query_schema_spec.rb index 6d55607c9..d7548f428 100644 --- a/spec/lib/pact_broker/matrix/can_i_deploy_query_schema_spec.rb +++ b/spec/lib/pact_broker/matrix/can_i_deploy_query_schema_spec.rb @@ -19,6 +19,10 @@ module Contracts end context "with a to tag and an environment specified" do + before do + allow(PactBroker::Deployments::EnvironmentService).to receive(:find_by_name).and_return(double("environment")) + end + let(:params) do { pacticipant: "foo", @@ -27,8 +31,41 @@ module Contracts to: "prod" } end + it { is_expected.to_not be_empty } end + + context "when the environment does exist" do + before do + allow(PactBroker::Deployments::EnvironmentService).to receive(:find_by_name).and_return(double("environment")) + end + + let(:params) do + { + pacticipant: "foo", + version: "1", + environment: "prod" + } + end + + it { is_expected.to be_empty } + end + + context "when the environment does not exist" do + before do + allow(PactBroker::Deployments::EnvironmentService).to receive(:find_by_name).and_return(nil) + end + + let(:params) do + { + pacticipant: "foo", + version: "1", + environment: "prod" + } + end + + its([:environment, 0]) { is_expected.to eq "environment with name 'prod' does not exist" } + end end end end diff --git a/spec/lib/pact_broker/matrix/service_spec.rb b/spec/lib/pact_broker/matrix/service_spec.rb index 52a8ee14d..1e62c0f8b 100644 --- a/spec/lib/pact_broker/matrix/service_spec.rb +++ b/spec/lib/pact_broker/matrix/service_spec.rb @@ -5,6 +5,10 @@ module PactBroker module Matrix describe Service do describe "validate_selectors" do + before do + allow(PactBroker::Deployments::EnvironmentService).to receive(:find_by_name).and_return(environment) + end + let(:environment) { double('environment') } subject { Service.validate_selectors(selectors, options) } let(:options) { {} } @@ -111,6 +115,21 @@ module Matrix expect(subject.last).to include "Cannot specify both latest" end end + + context "when the environment does not exist" do + let(:selectors) { [] } + let(:environment) { nil } + + let(:options) do + { + environment_name: "prod" + } + end + + it "returns an error message" do + expect(subject.last).to include "Environment with name 'prod' does not exist" + end + end end describe "find_for_consumer_and_provider_with_tags integration test" do