require_relative './helpers'

describe BeefCake::Role do
  include_context 'with example roles'

  describe('all') do
    let(:method) { -> { described_class.all } }
    let(:twirp_method) { :get_roles }
    let(:twirp_request) do
      Twitch::Fulton::Beefcake::GetRolesRequest.new
    end
    let(:twirp_data) do
      res = Twitch::Fulton::Beefcake::GetRolesResponse.new
      res.roles.replace([
                          Twitch::Fulton::Beefcake::GetRolesResponse::Role.new(
                            id: role_id,
                            name: role_name
                          )
                        ])
      res
    end
    let(:expected) { [BeefCake::Role.from_attributes(id: role_id, name: role_name)] }

    it_behaves_like 'a twirp backed service'
  end

  describe('find') do
    let(:method) { -> { described_class.find(role_id) } }
    let(:twirp_method) { :get_role }
    let(:twirp_request) do
      Twitch::Fulton::Beefcake::GetRoleRequest.new(id: role_id)
    end
    let(:twirp_data) { twirp_role }
    let(:expected) { role }

    it_behaves_like 'a twirp backed service'
  end

  describe('save') do
    context('persisted') do
      let(:method) { -> { persist(role).save } }
      let(:twirp_method) { :update_role }
      let(:twirp_request) do
        req = Twitch::Fulton::Beefcake::UpdateRoleRequest.new(
          id: role_id,
          name: Google::Protobuf::StringValue.new(value: role_name)
        )
        req.legacy_permission_ids = Twitch::Fulton::Beefcake::StringArrayValue.new
        req.legacy_permission_ids.value.replace([perm_id])
        req
      end
      let(:twirp_data) { twirp_role }
      let(:expected) { true }

      it_behaves_like 'a twirp backed service'
    end

    context('not persisted') do
      let(:method) { -> { role.save } }
      let(:twirp_method) { :create_role }
      let(:twirp_request) do
        Twitch::Fulton::Beefcake::CreateRoleRequest.new(
          name: role_name
        )
      end
      let(:twirp_data) { twirp_role }
      let(:expected) { true }

      before(:each) do
        allow_any_instance_of(described_class).to receive(:add_permission)
          .with(perm_id)
      end

      it_behaves_like 'a twirp backed service'
    end
  end

  describe('destroy') do
    let(:method) { -> { role.destroy } }
    let(:twirp_method) { :delete_role }
    let(:twirp_request) do
      Twitch::Fulton::Beefcake::DeleteRoleRequest.new(id: role_id)
    end
    let(:twirp_data) { twirp_role }
    let(:expected) { true }

    it_behaves_like 'a twirp backed service'
  end

  describe('remove_user') do
    let(:user_id) { 'USER_ID' }
    let(:method) { -> { role.remove_user(user_id) } }
    let(:twirp_method) { :remove_user_from_role }
    let(:twirp_request) do
      Twitch::Fulton::Beefcake::RemoveUserFromRoleRequest.new(role_id: role_id, user_id: user_id)
    end
    let(:twirp_data) { twirp_role }
    let(:expected) { true }

    it_behaves_like 'a twirp backed service'
  end

  describe('bulk_operations') do
    let(:realm) { BeefCake::Realm::TITAN_SUPPORT }
    let(:user_id) { 'user@support.titan.xarth.tv' }
    let(:user_uri) { "#{BeefCake::Realm::TITAN_SUPPORT.id}:#{user_id}" }
    let(:twirp_data) { twirp_role }
    let(:expected) { true }

    describe('bulk_add_realm_users') do
      let(:method) { -> { role.bulk_add_realm_users(realm, [user_id]) } }
      let(:twirp_method) { :add_user_to_role }
      let(:twirp_request) do
        Twitch::Fulton::Beefcake::AddUserToRoleRequest.new(role_id: role_id, user_id: user_uri)
      end

      it_behaves_like 'a twirp backed service'
    end

    describe('bulk_remove_realm_users') do
      let(:method) { -> { role.bulk_remove_realm_users(realm, [user_id]) } }
      let(:twirp_method) { :remove_user_from_role }
      let(:twirp_request) do
        Twitch::Fulton::Beefcake::RemoveUserFromRoleRequest.new(role_id: role_id, user_id: user_uri)
      end

      it_behaves_like 'a twirp backed service'
    end
  end
end
