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