From 0c0dd15e1ce4f86da739b644dfa05f834ba9f940 Mon Sep 17 00:00:00 2001 From: Beth Skurrie Date: Wed, 9 Jun 2021 19:36:11 +1000 Subject: [PATCH] feat: update record-undeployment (feature toggled off) --- .../client/deployments/record_undeployment.rb | 55 +++-- .../deployments/record_undeployment_spec.rb | 206 ++++++++++++++++++ .../record_undeployment_spec.rb | 7 +- 3 files changed, 248 insertions(+), 20 deletions(-) create mode 100644 spec/lib/pact_broker/client/deployments/record_undeployment_spec.rb diff --git a/lib/pact_broker/client/deployments/record_undeployment.rb b/lib/pact_broker/client/deployments/record_undeployment.rb index 9ca5ce86..c735f8c3 100644 --- a/lib/pact_broker/client/deployments/record_undeployment.rb +++ b/lib/pact_broker/client/deployments/record_undeployment.rb @@ -15,8 +15,7 @@ def initialize(params, options, pact_broker_client_options) def do_call if undeployed_versions_resources.empty? - check_pacticipant_exists! - PactBroker::Client::CommandResult.new(false, deployed_version_not_found_error_message) + PactBroker::Client::CommandResult.new(false, error_result_message) else PactBroker::Client::CommandResult.new(undeployed_versions_resources.all?(&:success?), result_message) end @@ -28,12 +27,18 @@ def currently_deployed_versions_link environment_resource._link("pb:currently-deployed-versions") or raise PactBroker::Client::Error.new(not_supported_message) end - def currently_deployed_versions_resource - @deployed_version_links ||= currently_deployed_versions_link.get!(pacticipant: pacticipant_name, target: target) + def currently_deployed_version_entities_for_pacticipant + @deployed_version_links ||= currently_deployed_versions_link.get!(pacticipant: pacticipant_name).embedded_entities!("deployedVersions") + end + + def currently_deployed_version_entities_for_pacticipant_and_target + currently_deployed_version_entities_for_pacticipant.select do | entity | + entity.target == target + end end def undeployed_versions_resources - @undeployed_versions_resources ||= currently_deployed_versions_resource.embedded_entities!("deployedVersions").collect do | entity | + @undeployed_versions_resources ||= currently_deployed_version_entities_for_pacticipant_and_target.collect do | entity | entity._link!("self").patch(currentlyDeployed: false) end end @@ -51,12 +56,6 @@ def environment_resource .get! end - def check_pacticipant_exists! - if index_resource._link!("pb:pacticipant").expand(pacticipant: pacticipant_name).get.does_not_exist? - raise PactBroker::Client::Error.new("No pacticipant with name '#{pacticipant_name}' found") - end - end - def result_message if json_output? undeployed_versions_resources.collect{ | resource | resource.response.body }.to_a.to_json @@ -80,14 +79,32 @@ def success_result_text_message(undeployed_versions_resource) message end - def deployed_version_not_found_error_message - target_bit = target ? " with target '#{target}'" : "" - message = "#{pacticipant_name} is not currently deployed to #{environment_name}#{target_bit}. Cannot record undeployment." - + def error_result_message if json_output? - { error: message }.to_json + { error: { message: error_text } }.to_json else - red(message) + red(error_text) + end + end + + def error_text + if pacticipant_does_not_exist? + "No pacticipant with name '#{pacticipant_name}' found" + else + if currently_deployed_version_entities_for_pacticipant.any? + target_does_not_match_message + else + "#{pacticipant_name} is not currently deployed to #{environment_name} environment. Cannot record undeployment." + end + end + end + + def target_does_not_match_message + potential_targets = currently_deployed_version_entities_for_pacticipant.collect(&:target).collect { |target| target || ""} + if target + "#{pacticipant_name} is not currently deployed to target '#{target}' in #{environment_name} environment. Please specify one of the following targets to record the undeployment from: #{potential_targets.join(", ")}" + else + "Please specify one of the following targets to record the undeployment from: #{potential_targets.join(", ")}" end end @@ -95,6 +112,10 @@ def not_supported_message "This version of the Pact Broker does not support recording undeployments. Please upgrade to version 2.80.0 or later." end + def pacticipant_does_not_exist? + index_resource._link("pb:pacticipant") && index_resource._link("pb:pacticipant").expand(pacticipant: pacticipant_name).get.does_not_exist? + end + def check_if_command_supported unless index_resource.can?("pb:environments") raise PactBroker::Client::Error.new(not_supported_message) diff --git a/spec/lib/pact_broker/client/deployments/record_undeployment_spec.rb b/spec/lib/pact_broker/client/deployments/record_undeployment_spec.rb new file mode 100644 index 00000000..be7d1931 --- /dev/null +++ b/spec/lib/pact_broker/client/deployments/record_undeployment_spec.rb @@ -0,0 +1,206 @@ +require 'pact_broker/client/deployments/record_undeployment' + +module PactBroker + module Client + module Deployments + describe RecordUndeployment do + let(:params) do + { + pacticipant_name: "Foo", + target: target, + environment_name: "test" + } + end + let(:target) { "customer-1" } + let(:output) { "text" } + let(:options) { { output: output, verbose: true } } + let(:pact_broker_base_url) { "http://broker" } + let(:pact_broker_client_options) { { pact_broker_base_url: pact_broker_base_url } } + + let(:index_body_hash) do + { + _links: { + :'pb:environments' => { + href: environments_url + }, + :'pb:pacticipant' => { + href: pacticipant_url + } + } + } + end + + let(:environments_hash) do + { + _links: { + :'pb:environments' => [ + { + name: "test", + href: test_environment_url + } + ] + } + } + end + + let(:environment_hash) do + { + _links: { + :'pb:currently-deployed-versions' => { + href: currently_deployed_versions_url + } + } + } + end + + let(:deployed_versions_hash) do + { + _embedded: { + deployedVersions: [ + { + target: "customer-1", + _links: { + self: { + href: deployed_version_url + } + } + }, + { + target: returned_target_2, + _links: { + self: { + href: deployed_version_url + } + } + } + ] + } + } + end + + let(:returned_target_2) { nil } + let(:deployed_version_hash) do + { + _embedded: { + version: { + number: "2" + } + } + } + end + + let(:environments_url) { "#{webmock_base_url}/environments" } + let(:test_environment_url) { "#{webmock_base_url}/environments/1234" } + let(:currently_deployed_versions_url) { "#{webmock_base_url}/currently-deployed-versions" } + let(:deployed_version_url) { "#{webmock_base_url}/deployed-version" } + let(:pacticipant_url) { "#{webmock_base_url}/pacticipant" } + + let(:webmock_base_url) { "http://broker" } + + let!(:index_request) do + stub_request(:get, "http://broker").to_return(status: 200, body: index_body_hash.to_json, headers: { "Content-Type" => "application/hal+json" } ) + end + + let!(:environments_request) do + stub_request(:get, "http://broker/environments").to_return(status: 200, body: environments_hash.to_json, headers: { "Content-Type" => "application/hal+json" } ) + end + + let!(:environment_request) do + stub_request(:get, test_environment_url).to_return(status: 200, body: environment_hash.to_json, headers: { "Content-Type" => "application/hal+json" } ) + end + + let!(:deployed_versions_request) do + stub_request(:get, currently_deployed_versions_url + "?pacticipant=Foo").to_return(status: 200, body: deployed_versions_hash.to_json, headers: { "Content-Type" => "application/hal+json" } ) + end + + let!(:deployed_version_patch_request) do + stub_request(:patch, deployed_version_url).with(body: { currentlyDeployed: false}.to_json).to_return(status: 200, body: deployed_version_hash.to_json, headers: { "Content-Type" => "application/hal+json" }) + end + + let!(:pacticipant_request) do + stub_request(:get, pacticipant_url).to_return(status: pacticipant_request_status, body: {}.to_json, headers: { "Content-Type" => "application/hal+json" }) + end + + let(:pacticipant_request_status) { 200 } + + subject { RecordUndeployment.call(params, options, pact_broker_client_options) } + + it "" do + puts subject.message + end + + its(:success) { is_expected.to eq true } + its(:message) { is_expected.to include "Recorded undeployment of Foo version 2 from test environment (target customer-1) in the Pact Broker" } + + context "when there is no pb:environments relation in the index" do + let(:index_body_hash) do + { + _links: {} + } + end + + its(:success) { is_expected.to be false } + its(:message) { is_expected.to include "support" } + end + + context "when output is json" do + let(:output) { "json" } + its(:message) { is_expected.to eq [deployed_version_hash].to_json } + end + + context "when there is no currently-deployed-versions relation in the environment resource" do + let(:environment_hash) do + { + _links: {} + } + end + + its(:success) { is_expected.to be false } + its(:message) { is_expected.to include "support" } + end + + context "when a target is provided and there is no deployed version with a matching target" do + let(:target) { "wrong" } + let(:expected_message) { "Foo is not currently deployed to target 'wrong' in test environment. Please specify one of the following targets to record the undeployment from: customer-1, " } + + its(:success) { is_expected.to be false } + its(:message) { is_expected.to include expected_message } + + context "when output is json" do + let(:output) { "json" } + + its(:message) { is_expected.to eq({ error: { message: expected_message } }.to_json) } + end + end + + context "when a target is not provided and there is no deployed verison without a target" do + let(:target) { nil } + let(:returned_target_2) { "customer-2" } + + its(:success) { is_expected.to be false } + its(:message) { is_expected.to include "Please specify one of the following targets to record the undeployment from: customer-1, customer-2" } + end + + context "when there are no deployed versions for the pacticipant" do + let(:deployed_versions_hash) do + { + _embedded: { + deployedVersions: [] + } + } + end + + its(:success) { is_expected.to be false } + its(:message) { is_expected.to include "Foo is not currently deployed to test environment. Cannot record undeployment." } + + context "when the pacticipant does not exist" do + let(:pacticipant_request_status) { 200 } + + its(:success) { is_expected.to be false } + its(:message) { is_expected.to include "Foo is not currently deployed to test environment. Cannot record undeployment." } + end + end + end + end + end +end diff --git a/spec/service_providers/record_undeployment_spec.rb b/spec/service_providers/record_undeployment_spec.rb index e2c2275c..0f855c94 100644 --- a/spec/service_providers/record_undeployment_spec.rb +++ b/spec/service_providers/record_undeployment_spec.rb @@ -92,7 +92,7 @@ def mock_deployed_versions_search_results .with( method: "GET", path: currently_deployed_versions_placeholder_path, - query: { pacticipant: pacticipant_name, target: target }, + query: { pacticipant: pacticipant_name }, headers: get_request_headers ) .will_respond_with( @@ -102,6 +102,7 @@ def mock_deployed_versions_search_results _embedded: { deployedVersions: [ { + target: target, _links: { self: { href: Pact.term(pact_broker.mock_service_base_url + deployed_version_placeholder_path, /^http/) @@ -136,7 +137,7 @@ def mock_mark_deployed_version_as_undeployed "currentlyDeployed" => false, "_embedded" => { "version" => { - "number" => "2" + "number" => Pact.like("2") } } } @@ -158,7 +159,7 @@ def mock_mark_deployed_version_as_undeployed let(:output) { "json" } it "returns the JSON payload" do - expect(JSON.parse(subject.message)).to eq [deployed_version_hash] + expect(JSON.parse(subject.message)).to eq [Pact::Reification.from_term(deployed_version_hash)] end end end