require 'spec_helper'

RSpec.describe 'SharedDomains' do
  let(:user) { VCAP::CloudController::User.make }
  let(:space) { VCAP::CloudController::Space.make }

  before do
    space.organization.add_user(user)
    space.add_developer(user)

    UAARequests.stub_all

    stub_request(:get, 'http://localhost:3000/routing/v1/router_groups').
      to_return(status: 200, body: '{}', headers: {})
  end

  describe 'GET /v2/shared_domains' do
    let!(:domain) { VCAP::CloudController::SharedDomain.make(name: 'my-domain.edu', router_group_guid: 'tcp-group') }

    it 'lists all shared domains' do
      get '/v2/shared_domains', nil, headers_for(user)

      expect(last_response.status).to eq(200)

      parsed_response = Oj.load(last_response.body)
      expect(parsed_response).to be_a_response_like(
        {
          'total_results' => 3,
          'total_pages' => 1,
          'prev_url' => nil,
          'next_url' => nil,
          'resources' => [
            {
              'metadata' => {
                'guid' => /\w+/,
                'url' => %r{/v2/shared_domains/},
                'created_at' => iso8601,
                'updated_at' => iso8601
              },
              'entity' => {
                'name' => 'customer-app-domain1.com',
                'internal' => false,
                'router_group_guid' => nil,
                'router_group_type' => nil
              }
            },
            {
              'metadata' => {
                'guid' => /\w+/,
                'url' => %r{/v2/shared_domains/},
                'created_at' => iso8601,
                'updated_at' => iso8601
              },
              'entity' => {
                'name' => 'customer-app-domain2.com',
                'internal' => false,
                'router_group_guid' => nil,
                'router_group_type' => nil
              }
            },
            {
              'metadata' => {
                'guid' => domain.guid,
                'url' => "/v2/shared_domains/#{domain.guid}",
                'created_at' => iso8601,
                'updated_at' => iso8601
              },
              'entity' => {
                'name' => domain.name,
                'internal' => false,
                'router_group_guid' => 'tcp-group',
                'router_group_type' => nil
              }
            }
          ]
        }
      )
    end
  end

  describe 'GET /v2/shared_domains/:guid' do
    let!(:domain) { VCAP::CloudController::SharedDomain.make(router_group_guid: 'tcp-group') }

    it 'shows the shared domain' do
      get "/v2/shared_domains/#{domain.guid}", nil, headers_for(user)
      expect(last_response.status).to eq(200)

      parsed_response = Oj.load(last_response.body)
      expect(parsed_response).to be_a_response_like(
        {
          'metadata' => {
            'guid' => domain.guid,
            'url' => "/v2/shared_domains/#{domain.guid}",
            'created_at' => iso8601,
            'updated_at' => iso8601
          },
          'entity' => {
            'name' => domain.name,
            'internal' => false,
            'router_group_guid' => 'tcp-group',
            'router_group_type' => nil
          }
        }
      )
    end
  end

  describe 'POST /v2/shared_domains' do
    it 'makes a shared domain' do
      post '/v2/shared_domains', '{"name": "meow.mc.meowerson.com"}', admin_headers_for(user)

      expect(last_response.status).to be(201)

      domain = VCAP::CloudController::SharedDomain.last

      parsed_response = Oj.load(last_response.body)
      expect(parsed_response).to be_a_response_like({
                                                      'metadata' => {
                                                        'guid' => domain.guid,
                                                        'url' => "/v2/shared_domains/#{domain.guid}",
                                                        'created_at' => iso8601,
                                                        'updated_at' => iso8601
                                                      },
                                                      'entity' => {
                                                        'name' => 'meow.mc.meowerson.com',
                                                        'internal' => false,
                                                        'router_group_guid' => nil,
                                                        'router_group_type' => nil
                                                      }
                                                    })
    end

    context 'router groups' do
      before do
        stub_request(:get, 'http://localhost:3000/routing/v1/router_groups').
          to_return(status: 200, body:
            '[{ "guid": "abc123",
                "name": "default-tcp",
                "reservable_ports":"1024-65535",
                "type": "http"
              },
              { "guid": "9876",
                "name": "default-tcp",
                "reservable_ports":"1024-65535",
                "type": "tcp"
              }]',
                    headers: {})
      end

      it 'makes a shared domain with HTTP router group' do
        post '/v2/shared_domains', '{"name": "meow.mc.meowerson.com", "router_group_guid": "abc123"}', admin_headers_for(user)

        expect(last_response.status).to be(201)

        domain = VCAP::CloudController::SharedDomain.last

        parsed_response = Oj.load(last_response.body)
        expect(parsed_response).to be_a_response_like({
                                                        'metadata' => {
                                                          'guid' => domain.guid,
                                                          'url' => "/v2/shared_domains/#{domain.guid}",
                                                          'created_at' => iso8601,
                                                          'updated_at' => iso8601
                                                        },
                                                        'entity' => {
                                                          'name' => 'meow.mc.meowerson.com',
                                                          'internal' => false,
                                                          'router_group_guid' => 'abc123',
                                                          'router_group_type' => 'http'
                                                        }
                                                      })
      end

      it 'makes a TCP shared domain with TCP router group' do
        post '/v2/shared_domains', '{"name": "meow.mc.meowerson.com", "router_group_guid": "9876"}', admin_headers_for(user)

        expect(last_response.status).to be(201)

        domain = VCAP::CloudController::SharedDomain.last

        parsed_response = Oj.load(last_response.body)
        expect(parsed_response).to be_a_response_like({
                                                        'metadata' => {
                                                          'guid' => domain.guid,
                                                          'url' => "/v2/shared_domains/#{domain.guid}",
                                                          'created_at' => iso8601,
                                                          'updated_at' => iso8601
                                                        },
                                                        'entity' => {
                                                          'name' => 'meow.mc.meowerson.com',
                                                          'internal' => false,
                                                          'router_group_guid' => '9876',
                                                          'router_group_type' => 'tcp'
                                                        }
                                                      })
      end
    end
  end

  describe 'PUT /v2/shared_domains/:guid' do
    let!(:domain) { VCAP::CloudController::SharedDomain.make(name: 'my-domain.edu', router_group_guid: 'tcp-group') }

    it 'ignores everything and returns the original object, suckers!' do
      put "/v2/shared_domains/#{domain.guid}", '{"name": "meow.com", "route_group_guid": "a-guid"}', admin_headers_for(user)

      expect(last_response.status).to eq(201)
      parsed_response = Oj.load(last_response.body)

      expect(parsed_response).to be_a_response_like({
                                                      'metadata' => {
                                                        'guid' => domain.guid,
                                                        'url' => "/v2/shared_domains/#{domain.guid}",
                                                        'created_at' => iso8601,
                                                        'updated_at' => iso8601
                                                      },
                                                      'entity' => {
                                                        'name' => 'my-domain.edu',
                                                        'internal' => false,
                                                        'router_group_guid' => 'tcp-group',
                                                        'router_group_type' => nil
                                                      }
                                                    })
    end
  end

  describe 'DELETE /v2/shared_domains/:guid' do
    let!(:domain) { VCAP::CloudController::SharedDomain.make(name: 'my-domain.edu', router_group_guid: 'tcp-group') }

    it 'deletes the shared_domain' do
      delete "/v2/shared_domains/#{domain.guid}", nil, admin_headers_for(user)
      expect(last_response.status).to be(204)
      expect(last_response.body).to eq('')
    end
  end
end
