require 'rails_helper'
RSpec.describe LeadmailDelivery do
let(:settings) do
{
api_url: 'https://mail.leadmagnet.dev/api/v1',
token: 'lm_test_token_123'
}
end
let(:delivery) { described_class.new(settings) }
let(:message) do
Mail.new do
from 'sender@example.com'
to 'recipient@example.com'
subject 'Test Subject'
body 'Plain text body'
end
end
describe '#deliver!' do
it 'sends email via LeadMail API' do
stub_request(:post, 'https://mail.leadmagnet.dev/api/v1/emails/send')
.with(
headers: { 'Authorization' => 'Bearer lm_test_token_123' },
body: hash_including(
subject: 'Test Subject',
from: { email: 'sender@example.com' },
to: [{ email: 'recipient@example.com' }]
)
)
.to_return(
status: 202,
body: { success: true, data: { log_id: 12345, status: 'queued' } }.to_json
)
delivery.deliver!(message)
expect(message.header['X-LeadMail-Log-ID'].value).to eq('12345')
end
it 'handles multipart messages (HTML + text)' do
html_message = Mail.new do
from 'sender@example.com'
to 'recipient@example.com'
subject 'HTML Email'
text_part do
body 'Plain text version'
end
html_part do
content_type 'text/html; charset=UTF-8'
body '
HTML version
'
end
end
stub_request(:post, 'https://mail.leadmagnet.dev/api/v1/emails/send')
.to_return(
status: 202,
body: { success: true, data: { log_id: 12346, status: 'queued' } }.to_json
)
delivery.deliver!(html_message)
expect(a_request(:post, 'https://mail.leadmagnet.dev/api/v1/emails/send')
.with { |req| body_hash = JSON.parse(req.body); body_hash['text_body'] == 'Plain text version' && body_hash['html_body'] == 'HTML version
' })
.to have_been_made
end
it 'includes CC and BCC recipients' do
message_with_cc = Mail.new do
from 'sender@example.com'
to 'recipient@example.com'
cc 'cc@example.com'
bcc 'bcc@example.com'
subject 'With CC/BCC'
body 'Test'
end
stub_request(:post, 'https://mail.leadmagnet.dev/api/v1/emails/send')
.to_return(
status: 202,
body: { success: true, data: { log_id: 12347, status: 'queued' } }.to_json
)
delivery.deliver!(message_with_cc)
expect(a_request(:post, 'https://mail.leadmagnet.dev/api/v1/emails/send')
.with { |req| body_hash = JSON.parse(req.body); body_hash['cc'] == [{ 'email' => 'cc@example.com' }] && body_hash['bcc'] == [{ 'email' => 'bcc@example.com' }] })
.to have_been_made
end
it 'handles reply-to header' do
message_with_reply = Mail.new do
from 'sender@example.com'
to 'recipient@example.com'
reply_to 'reply@example.com'
subject 'With Reply-To'
body 'Test'
end
stub_request(:post, 'https://mail.leadmagnet.dev/api/v1/emails/send')
.to_return(
status: 202,
body: { success: true, data: { log_id: 12348, status: 'queued' } }.to_json
)
delivery.deliver!(message_with_reply)
expect(a_request(:post, 'https://mail.leadmagnet.dev/api/v1/emails/send')
.with { |req| body_hash = JSON.parse(req.body); body_hash['reply_to'] == { 'email' => 'reply@example.com' } })
.to have_been_made
end
it 'encodes attachments in base64' do
message_with_attachment = Mail.new do
from 'sender@example.com'
to 'recipient@example.com'
subject 'With Attachment'
body 'Test'
add_file filename: 'test.txt', content: 'File content'
end
stub_request(:post, 'https://mail.leadmagnet.dev/api/v1/emails/send')
.to_return(
status: 202,
body: { success: true, data: { log_id: 12349, status: 'queued' } }.to_json
)
delivery.deliver!(message_with_attachment)
expect(a_request(:post, 'https://mail.leadmagnet.dev/api/v1/emails/send')
.with { |req| body_hash = JSON.parse(req.body); body_hash['attachments'].first['content'].present? })
.to have_been_made
end
it 'raises LeadmailDeliveryError on API failure' do
stub_request(:post, 'https://mail.leadmagnet.dev/api/v1/emails/send')
.to_return(status: 500, body: 'Internal Server Error')
expect { delivery.deliver!(message) }
.to raise_error(LeadmailDeliveryError, /LeadMail API error: 500/)
end
it 'sets default options for verification and disposable emails' do
stub_request(:post, 'https://mail.leadmagnet.dev/api/v1/emails/send')
.to_return(
status: 202,
body: { success: true, data: { log_id: 12350, status: 'queued' } }.to_json
)
delivery.deliver!(message)
expect(a_request(:post, 'https://mail.leadmagnet.dev/api/v1/emails/send')
.with { |req| body_hash = JSON.parse(req.body); body_hash['options']['on_verification_failure'] == 'strip' && body_hash['options']['allow_disposable'] == false })
.to have_been_made
end
it 'logs successful delivery' do
stub_request(:post, 'https://mail.leadmagnet.dev/api/v1/emails/send')
.to_return(
status: 202,
body: { success: true, data: { log_id: 12351, status: 'queued' } }.to_json
)
expect(Rails.logger).to receive(:info).with(match(/Email sent via LeadMail.*log_id=12351/))
delivery.deliver!(message)
end
it 'logs delivery errors' do
stub_request(:post, 'https://mail.leadmagnet.dev/api/v1/emails/send')
.to_raise(StandardError.new('Network error'))
expect(Rails.logger).to receive(:error).with(match(/LeadMail delivery failed/))
expect { delivery.deliver!(message) }.to raise_error(StandardError)
end
end
end