require 'pact_broker/client/deployments/record_undeployment' module PactBroker module Client module Deployments describe RecordUndeployment do let(:params) do { pacticipant_name: "Foo", application_instance: application_instance, environment_name: "test" } end let(:application_instance) { "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-deployed-versions' => { href: currently_deployed_versions_url } } } end let(:deployed_versions_hash) do { _embedded: { deployedVersions: [ { target: "customer-1", _links: { self: { href: deployed_version_url_1 } } }, { target: returned_target_2, _links: { self: { href: deployed_version_url_2 } } } ] } } 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_1) { "#{webmock_base_url}/deployed-version-1" } let(:deployed_version_url_2) { "#{webmock_base_url}/deployed-version-2" } 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_1) do stub_request(:patch, deployed_version_url_1).with(body: { currentlyDeployed: false}.to_json).to_return(status: 200, body: deployed_version_hash.to_json, headers: { "Content-Type" => "application/hal+json" }) end let!(:deployed_version_patch_request_2) do stub_request(:patch, deployed_version_url_2).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) } its(:success) { is_expected.to eq true } its(:message) { is_expected.to include "Recorded undeployment of Foo version 2 from test environment (application instance 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 an error returned from one of the deployed version updates (there should only ever be one deployed version, but testing just for the sake of it)" do let!(:deployed_version_patch_request_2) do stub_request(:patch, deployed_version_url_2).to_return(status: 400, body: { errors: { foo: ["some error"]}}.to_json, headers: { "Content-Type" => "application/hal+json" }) end let(:returned_target_2) { "customer-1" } its(:success) { is_expected.to be false } its(:message) { is_expected.to include "Recorded undeployment of Foo version 2" } its(:message) { is_expected.to include "some error" } 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(:application_instance) { "wrong" } let(:expected_message) { "Foo is not currently deployed to application instance 'wrong' in test environment. Please omit the application instance to undeploy from the anonymous instance or specify one of the following application instances 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 provided and there is no deployed version with a matching target and all the application instances are set" do let(:application_instance) { "wrong" } let(:returned_target_2) { "customer-2" } let(:expected_message) { "Foo is not currently deployed to application instance 'wrong' in test environment. Please specify one of the following application instances to record the undeployment from: customer-1, customer-2." } its(:message) { is_expected.to include expected_message } end context "when a target is not provided and there is no deployed verison without a target" do let(:application_instance) { 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 application instances 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) { 404 } its(:success) { is_expected.to be false } its(:message) { is_expected.to include "No pacticipant with name 'Foo' found" } end end end end end end