demarches-normaliennes/spec/lib/balancer_delivery_method_spec.rb
Colin Darie 05b517a847
fix(mailer): observers on balancer and balanced delivery methods
- Les observers doivent être déclarés *avant*
  le chargement de nos delivery methods (Sendinblue & Dolist),
  sinon ils seront ignorés par ces derniers

- dans le balancer, on ne peut pas appeler `.deliver` une seconde fois,
  sinon les observers (et interceptors) sont invoqués deux fois.
2023-01-11 00:57:16 +01:00

111 lines
2.7 KiB
Ruby

RSpec.describe BalancerDeliveryMethod do
class ExampleMailer < ApplicationMailer
def greet(name)
mail(to: "smtp_to", from: "smtp_from", body: "Hello #{name}")
end
end
class TestMail
def self.deliveries
@deliveries ||= []
end
def self.deliveries=(val)
@deliveries = val
end
attr_accessor :settings
def initialize(values)
@settings = values.dup
end
def deliver!(mail)
Mail::CheckDeliveryParams.check(mail)
self.class.deliveries << mail
end
end
class MockSmtp < TestMail; end
class MockSendmail < TestMail; end
class FixedSequence
def initialize(sequence)
@enumerator = sequence.each
end
def rand(_)
@enumerator.next
end
end
before do
ActionMailer::Base.add_delivery_method :mock_smtp, MockSmtp
ActionMailer::Base.add_delivery_method :mock_sendmail, MockSendmail
ActionMailer::Base.add_delivery_method :balancer, BalancerDeliveryMethod
ExampleMailer.delivery_method = :balancer
end
context 'when a single delivery method is provided' do
before do
ActionMailer::Base.balancer_settings = { mock_smtp: 10 }
end
it 'sends emails to the selected delivery method' do
mail = ExampleMailer.greet('Joshua').deliver_now
expect(mail).to have_been_delivered_using(MockSmtp)
end
end
context 'when multiple delivery methods are provided' do
before do
ActionMailer::Base.balancer_settings = { mock_smtp: 10, mock_sendmail: 5 }
rng_sequence = [3, 14, 1]
BalancerDeliveryMethod.random = FixedSequence.new(rng_sequence)
end
after do
BalancerDeliveryMethod.random = Random.new
end
it 'sends emails randomly, given the provided weights' do
mail1 = ExampleMailer.greet('Lucia').deliver_now
expect(mail1).to have_been_delivered_using(MockSmtp)
mail2 = ExampleMailer.greet('Damian').deliver_now
expect(mail2).to have_been_delivered_using(MockSendmail)
mail3 = ExampleMailer.greet('Rahwa').deliver_now
expect(mail3).to have_been_delivered_using(MockSmtp)
end
end
context 'when observers are configured' do
let(:observer) { double("Observer") }
before do
allow(observer).to receive(:delivered_email)
ActionMailer::Base.register_observer(observer)
end
after do
ActionMailer::Base.unregister_observer(observer)
end
it 'invoke the observer exactly once' do
mail = ExampleMailer.greet('Joshua').deliver_now
expect(observer).to have_received(:delivered_email).with(mail).once
end
end
# Helpers
def have_been_delivered_using(delivery_class)
satisfy("have been delivered using #{delivery_class}") do |mail|
delivery_class.deliveries.include?(mail)
end
end
end