# frozen_string_literal: true

require 'ptt/amqp_client'

RSpec.describe PTT::AMQPClient do
  subject { described_class.new(logger) }

  let(:logger) { spy }

  before { subject.connect }

  after { subject.disconnect }

  describe '#direct_exchange' do
    let(:name) { 'amq.direct' }

    it 'returns a direct exchange' do
      exchange = subject.direct_exchange(name)

      expect(exchange.type).to eq(:direct)
      expect(exchange.name).to eq(name)
      expect(exchange).to be_durable
    end
  end

  describe '#topic_exchange' do
    let(:name) { 'amq.topic' }

    it 'returns a topic exchange' do
      exchange = subject.topic_exchange(name)

      expect(exchange.type).to eq(:topic)
      expect(exchange.name).to eq(name)
      expect(exchange).to be_durable
    end
  end

  describe '#queue_for' do
    let(:exchange) { subject.direct_exchange('amq.direct') }

    it 'creates a durable queue' do
      queue = subject.queue_for(exchange, 'foo')

      expect(queue).to be_durable
    end

    context 'a queue name is set' do
      it 'uses the given queue name' do
        queue = subject.queue_for(exchange, 'foo', 'sync')

        expect(queue.name).to eq('sync')
      end
    end
  end

  describe '#retry_queue_for' do
    let(:exchange) { subject.direct_exchange('amq.direct') }

    it 'creates a durable queue' do
      queue = subject.retry_queue_for(exchange, 'foo')

      expect(queue).to be_durable
    end

    it 'adds ".retry" suffix to the given routing key' do
      queue = subject.retry_queue_for(exchange, 'foo')

      expect(queue.name).to eq('foo.retry')
    end

    it 'configures the queue for dead lettering' do
      queue = subject.retry_queue_for(exchange, 'foo')

      expect(queue.arguments).to include({
        'x-dead-letter-exchange' => exchange.name,
        'x-dead-letter-routing-key' => 'foo'
      })
    end

    context 'a queue name is set' do
      it 'uses the given queue name' do
        queue = subject.retry_queue_for(exchange, 'foo', 'sync')

        expect(queue.name).to eq('sync.retry')
      end
    end
  end
end
