require 'spec_helper'

module VCAP::CloudController
  RSpec.describe 'orphan mitigation' do
    include VCAP::CloudController::BrokerApiHelper

    let(:guid_pattern) { '[[:alnum:]-]+' }
    let(:basic_auth) { ['username', 'password'] }

    before do
      setup_cc
      setup_broker
    end

    after { delete_broker }

    describe 'service provision with timeout' do
      let(:broker_url) { 'broker-url' }
      let(:space_guid) { @space_guid }
      let(:plan_guid) { @plan_guid }

      before do
        stub_request(:put, %r{#{broker_url}/v2/service_instances/#{guid_pattern}}).to_return { |request|
          raise HTTPClient::TimeoutError.new('fake-timeout')
        }

        stub_request(:delete, %r{#{broker_url}/v2/service_instances/#{guid_pattern}}).
          to_return(status: 200, body: '{}')

        post('/v2/service_instances',
        {
          name:              'test-service',
          space_guid:        space_guid,
          service_plan_guid: plan_guid
        }.to_json,
        admin_headers)
      end

      it 'makes the request to the broker and deprovisions' do
        expect(a_request(:put, %r{http://broker-url/v2/service_instances/#{guid_pattern}}).with(basic_auth: basic_auth)).to have_been_made

        execute_all_jobs(expected_successes: 1, expected_failures: 0)

        expect(a_request(:delete, %r{http://broker-url/v2/service_instances/#{guid_pattern}}).with(basic_auth: basic_auth)).to have_been_made
      end

      it 'responds to user with 504' do
        expect(last_response.status).to eq(504)
      end
    end

    describe 'service binding with timeout' do
      let(:service_instance_guid) { @service_instance_guid }
      let(:app_guid) { @app_guid }

      before do
        provision_service
        create_app

        stub_request(:put, %r{/v2/service_instances/#{service_instance_guid}/service_bindings/#{guid_pattern}}).to_return { |request|
          raise HTTPClient::TimeoutError.new('fake-timeout')
        }

        stub_request(:delete, %r{/v2/service_instances/#{service_instance_guid}/service_bindings/#{guid_pattern}}).
          to_return(status: 200, body: '{}')

        post('/v2/service_bindings',
          { app_guid: app_guid, service_instance_guid: service_instance_guid }.to_json,
          admin_headers)
      end

      it 'makes the request to the broker and unbinds' do
        expect(a_request(:put, %r{http://broker-url/v2/service_instances/#{service_instance_guid}/service_bindings/#{guid_pattern}}).with(basic_auth: basic_auth)).
          to have_been_made

        execute_all_jobs(expected_successes: 1, expected_failures: 0)

        expect(a_request(:delete, %r{http://broker-url/v2/service_instances/#{service_instance_guid}/service_bindings/#{guid_pattern}})).
          to have_been_made
      end

      it 'responds to user with 504' do
        expect(last_response).to have_status_code(504)
      end
    end
  end
end
