require 'pact_broker/client/deployments/record_deployment' module PactBroker module Client module Deployments describe RecordDeployment do describe ".call" do let(:broker_base_url) { "http://broker" } let(:index_body_hash) do { _links: { "pb:environments" => { href: "#{broker_base_url}/environments" }, "pb:pacticipant-version" => { href: "#{broker_base_url}/pacticipants/{pacticipant}/versions/{version}" } } } end let(:version_body_hash) do { "_links" => { "pb:record-deployment" => [ { name: "test", href: "#{broker_base_url}/record-deployment" } ] } } end let(:environments_body_hash) do { "_links" => { "pb:environments" => [ { "name" => "test", "href" => "" } ] } } end let(:record_deployment_body_hash) do { "some" => "response" } end let(:index_headers) { { "Content-Type" => "application/hal+json" } } let!(:index_request) do stub_request(:get, broker_base_url).to_return(status: 200, body: index_body_hash.to_json, headers: index_headers ) end let!(:version_request) do stub_request(:get, broker_base_url + "/pacticipants/Foo/versions/1").to_return(status: 200, body: version_body_hash.to_json, headers: { "Content-Type" => "application/hal+json" } ) end let!(:environments_request) do stub_request(:get, "http://broker/environments"). with(headers: { 'Accept'=>'application/hal+json' }). to_return(status: 200, body: environments_body_hash.to_json, headers: { "Content-Type" => "application/hal+json" }) end let!(:record_deployment_request) do stub_request(:post, "http://broker/record-deployment"). to_return(status: 200, body: record_deployment_body_hash.to_json , headers: {}) end let(:application_instance) { "blue" } let(:params) do { pacticipant_name: "Foo", version_number: "1", environment_name: "test", application_instance: application_instance } end let(:options) do { output: output, verbose: true } end let(:output) { "text" } let(:pact_broker_client_options) { { pact_broker_base_url: broker_base_url} } subject { RecordDeployment.call(params, options, pact_broker_client_options) } context "when the pb:environments relation does not exist" do let(:index_body_hash) do { "_links" => {} } end it "returns an error response" do expect(subject.success).to be false expect(subject.message).to include "does not support" end context "when the server is PactFlow" do let(:index_headers) { { "Content-Type" => "application/hal+json", "Pactflow-Something" => "foo" } } it "returns an error response" do expect(subject.message).to include "permission" expect(subject.message).to include "does not support" end end end context "when the specified version does not exist" do let!(:version_request) do stub_request(:get, broker_base_url + "/pacticipants/Foo/versions/1").to_return(status: 404) end it "returns an error response" do expect(subject.success).to be false expect(subject.message).to include "Foo version 1 not found" end end context "when the pacticipant version does not support recording deployments" do let(:version_body_hash) do { "_links" => {} } end it "returns an error response" do expect(subject.success).to be false expect(subject.message).to include "does not support" end end context "when the specified environment is not available for recording a deployment" do let(:version_body_hash) do { "_links" => { "pb:record-deployment" => [ { "name" => "prod", "href" => "" } ] } } end context "when the environment does not exist" do let(:environments_body_hash) do { "_links" => { "pb:environments" => [ { "name" => "prod", "href" => "" },{ "name" => "uat", "href" => "" } ] } } end it "returns an error response" do expect(subject.success).to be false expect(subject.message).to include "No environment found with name 'test'. Available options: prod" end context "when the server is PactFlow" do let(:index_headers) { { "Content-Type" => "application/hal+json", "X-Pactflow-Sha" => "123" } } it "returns a customised message" do expect(subject.message).to include "Environment 'test' is not an available option for recording a deployment of Foo" expect(subject.message).to include "permissions" end end end context "when the environment does exist" do it "returns an error response" do expect(subject.success).to be false expect(subject.message).to include "Environment 'test' is not an available option for recording a deployment of Foo. Available options: prod" end end end context "when the output is json" do let(:output) { "json" } it "returns the JSON payload" do expect(JSON.parse(subject.message)).to eq record_deployment_body_hash end end context "when the response headers contain PactFlow" do before do allow_any_instance_of(RecordDeployment).to receive(:check_if_command_supported) allow_any_instance_of(RecordDeployment).to receive(:check_environment_exists) allow_any_instance_of(RecordDeployment).to receive(:record_action) allow_any_instance_of(RecordDeployment).to receive(:index_resource).and_return(index_resource) end let(:response_headers) { { "X-Pactflow-Sha" => "abc" } } let(:index_resource) do double('PactBroker::Client::Hal::Entity', response: double('response', headers: response_headers) ) end it "indicates the API was PactFlow" do expect(subject.message).to include "Recorded deployment of Foo version 1 to test environment (application instance blue) in PactFlow" end context "when application_instance is nil" do let(:application_instance) { nil } it "does not include the application_instance in the result message" do expect(subject.message).to include "Recorded deployment of Foo version 1 to test environment in" end end end end end end end end