require 'spec_helper'

module VCAP::CloudController
  RSpec.describe AppEventAccess, type: :access do
    subject(:access) { AppEventAccess.new(Security::AccessContext.new) }
    let(:token) { { 'scope' => ['cloud_controller.read', 'cloud_controller.write'] } }

    let(:user) { VCAP::CloudController::User.make }
    let(:org) { VCAP::CloudController::Organization.make }
    let(:space) { VCAP::CloudController::Space.make(organization: org) }
    let(:process) { VCAP::CloudController::ProcessModelFactory.make(space:) }
    let(:object) { VCAP::CloudController::AppEvent.make(app: process) }

    before do
      SecurityContext.set(user, token)
    end

    after do
      SecurityContext.clear
    end

    it_behaves_like 'admin full access'
    it_behaves_like 'admin read only access'

    context 'organization manager' do
      before { org.add_manager(user) }

      it_behaves_like 'read only access'
    end

    context 'organization user' do
      before { org.add_user(user) }

      it_behaves_like 'no access'
    end

    context 'organization auditor' do
      before { org.add_auditor(user) }

      it_behaves_like 'no access'
    end

    context 'billing manager' do
      before { org.add_billing_manager(user) }

      it_behaves_like 'no access'
    end

    context 'space developer' do
      before do
        org.add_user(user)
        space.add_developer(user)
      end

      it_behaves_like 'read only access'
    end

    context 'space manager' do
      before do
        org.add_user(user)
        space.add_manager(user)
      end

      it_behaves_like 'read only access'
    end

    context 'space auditor' do
      before do
        org.add_user(user)
        space.add_auditor(user)
      end

      it_behaves_like 'read only access'
    end

    context 'user in a different organization (defensive)' do
      before do
        different_organization = VCAP::CloudController::Organization.make
        different_organization.add_user(user)
      end

      it_behaves_like 'no access'
    end

    context 'manager in a different organization (defensive)' do
      before do
        different_organization = VCAP::CloudController::Organization.make
        different_organization.add_manager(user)
      end

      it_behaves_like 'no access'
    end

    context 'a user that isnt logged in (defensive)' do
      let(:user) { nil }

      it_behaves_like 'no access'
    end

    context 'any user using client without cloud_controller.write' do
      let(:token) { { 'scope' => ['cloud_controller.read'] } }

      before do
        org.add_user(user)
        org.add_manager(user)
        org.add_billing_manager(user)
        org.add_auditor(user)
        space.add_manager(user)
        space.add_developer(user)
        space.add_auditor(user)
      end

      it_behaves_like 'read only access'
    end

    context 'any user using client without cloud_controller.read' do
      let(:token) { { 'scope' => [] } }

      before do
        org.add_user(user)
        org.add_manager(user)
        org.add_billing_manager(user)
        org.add_auditor(user)
        space.add_manager(user)
        space.add_developer(user)
        space.add_auditor(user)
      end

      it_behaves_like 'no access'
    end
  end
end
