spec/lib/sendgrid_actionmailer_spec.rb in sendgrid-actionmailer-0.2.1 vs spec/lib/sendgrid_actionmailer_spec.rb in sendgrid-actionmailer-2.0.0

- old
+ new

@@ -2,39 +2,70 @@ require 'webmock/rspec' module SendGridActionMailer describe DeliveryMethod do subject(:mailer) do - DeliveryMethod.new(api_user: 'user', api_key: 'key') + DeliveryMethod.new(api_key: 'key') end - class TestClient < SendGrid::Client + class TestClient attr_reader :sent_mail def send(mail) @sent_mail = mail super(mail) end + + def mail() + self + end + + def _(param) + return self if param == 'send' + raise "Unknown param #{param.inspect}" + end + + def post(request_body:) + @sent_mail = request_body + OpenStruct.new(status_code: '200') + end end - describe '#initialize' do - it 'configures the client API user' do - expect(mailer.client.api_user).to eq('user') + describe 'settings' do + it 'has correct api_key' do + m = DeliveryMethod.new(api_key: 'ABCDEFG') + expect(m.settings[:api_key]).to eq('ABCDEFG') end - it 'configures the client API key' do - expect(mailer.client.api_key).to eq('key') + it 'default raise_delivery_errors' do + m = DeliveryMethod.new() + expect(m.settings[:raise_delivery_errors]).to eq(false) end + + it 'sets raise_delivery_errors' do + m = DeliveryMethod.new(raise_delivery_errors: true) + expect(m.settings[:raise_delivery_errors]).to eq(true) + end + + it 'default return_response' do + m = DeliveryMethod.new() + expect(mailer.settings[:return_response]).to eq(nil) + end + + it 'sets return_response' do + m = DeliveryMethod.new(return_response: true) + expect(m.settings[:return_response]).to eq(true) + end end describe '#deliver!' do let(:client) { TestClient.new } let(:mail) do Mail.new( to: 'test@sendgrid.com', from: 'taco@cat.limo', - subject: 'Hello, world!' + subject: 'Hello, world!', ) end before do stub_request(:any, 'https://api.sendgrid.com/api/mail.send.json') @@ -42,402 +73,387 @@ allow(SendGrid::Client).to receive(:new).and_return(client) end it 'sets to' do mailer.deliver!(mail) - expect(client.sent_mail.to).to eq(%w[test@sendgrid.com]) + expect(client.sent_mail['personalizations'][0]).to include({"to"=>[{"email"=>"test@sendgrid.com"}]}) end + it 'returns mailer itself' do + ret = mailer.deliver!(mail) + expect(ret).to eq(mailer) + end + + it 'returns api response' do + m = DeliveryMethod.new(return_response: true, api_key: 'key') + ret = m.deliver!(mail) + expect(ret.status_code).to eq('200') + end + + context 'to with a friendly name' do + before { mail.to = 'Test SendGrid <test@sendgrid.com>' } + + it 'sets to' do + mailer.deliver!(mail) + expect(client.sent_mail['personalizations'][0]).to include({"to"=>[{"email"=>"test@sendgrid.com", "name"=>"Test SendGrid"}]}) + end + end + + context 'to with a friendly name (with quotes)' do + before { mail.to = '"Test SendGrid" <test@sendgrid.com>' } + + it 'sets to' do + mailer.deliver!(mail) + expect(client.sent_mail['personalizations'][0]).to include({"to"=>[{"email"=>"test@sendgrid.com", "name"=>"Test SendGrid"}]}) + end + end + context 'there are ccs' do before { mail.cc = 'burrito@cat.limo' } it 'sets cc' do mailer.deliver!(mail) - expect(client.sent_mail.cc).to eq(%w[burrito@cat.limo]) + expect(client.sent_mail['personalizations'][0]).to include({"to"=>[{"email"=>"test@sendgrid.com"}], "cc"=>[{"email"=>"burrito@cat.limo"}]}) end end context 'there are bccs' do before { mail.bcc = 'nachos@cat.limo' } it 'sets bcc' do mailer.deliver!(mail) - expect(client.sent_mail.bcc).to eq(%w[nachos@cat.limo]) + expect(client.sent_mail['personalizations'][0]).to include({"to"=>[{"email"=>"test@sendgrid.com"}], "bcc"=>[{"email"=>"nachos@cat.limo"}]}) end end - context 'there is a reply to' do - before { mail.reply_to = 'nachos@cat.limo' } + context 'there are bccs with a friendly name' do + before { mail.bcc = 'Taco Cat <nachos@cat.limo>' } - it 'sets reply_to' do + it 'sets bcc' do mailer.deliver!(mail) - expect(client.sent_mail.reply_to).to eq('nachos@cat.limo') + expect(client.sent_mail['personalizations'][0]).to include({"to"=>[{"email"=>"test@sendgrid.com"}], "bcc"=>[{"email"=>"nachos@cat.limo", "name"=>"Taco Cat"}]}) end end - context 'there is a reply to with a friendly name' do - before { mail.reply_to = 'Taco Cat <nachos@cat.limo>' } + context 'there are bccs with a friendly name (with quotes)' do + before { mail.bcc = '"Taco Cat" <nachos@cat.limo>' } - it 'sets reply_to' do + it 'sets bcc' do mailer.deliver!(mail) - expect(client.sent_mail.reply_to).to eq('nachos@cat.limo') + expect(client.sent_mail['personalizations'][0]).to include({"to"=>[{"email"=>"test@sendgrid.com"}], "bcc"=>[{"email"=>"nachos@cat.limo", "name"=>"Taco Cat"}]}) end end - context 'there is a date' do - before { mail.date = Time.utc(2016) } + context 'there is a reply to' do + before { mail.reply_to = 'nachos@cat.limo' } - it 'sets date' do + it 'sets reply_to' do mailer.deliver!(mail) - expect(client.sent_mail.date).to eq("Fri, 01 Jan 2016 00:00:00 +0000") + expect(client.sent_mail['reply_to']).to eq({'email' => 'nachos@cat.limo'}) end end - it 'sets from' do - mailer.deliver!(mail) - expect(client.sent_mail.from).to eq('taco@cat.limo') + context 'there is a reply to with a friendly name' do + before { mail.reply_to = 'Taco Cat <nachos@cat.limo>' } + + it 'sets reply_to' do + mailer.deliver!(mail) + expect(client.sent_mail['reply_to']).to eq('email' => 'nachos@cat.limo', 'name' => 'Taco Cat') + end end context 'from contains a friendly name' do before { mail.from = 'Taco Cat <taco@cat.limo>'} it 'sets from' do mailer.deliver!(mail) - expect(client.sent_mail.from).to eq('taco@cat.limo') + expect(client.sent_mail['from']).to eq('email' => 'taco@cat.limo', 'name' => 'Taco Cat') end + end - it 'sets from_name' do + context 'from contains a friendly name (with quotes)' do + before { mail.from = '"Taco Cat" <taco@cat.limo>'} + + it 'sets from' do mailer.deliver!(mail) - expect(client.sent_mail.from_name).to eq('Taco Cat') + expect(client.sent_mail['from']).to eq('email' => 'taco@cat.limo', 'name' => 'Taco Cat') end end it 'sets subject' do mailer.deliver!(mail) - expect(client.sent_mail.subject).to eq('Hello, world!') + expect(client.sent_mail['subject']).to eq('Hello, world!') end it 'sets a text/plain body' do mail.content_type = 'text/plain' mail.body = 'I heard you like pineapple.' mailer.deliver!(mail) - expect(client.sent_mail.text).to eq('I heard you like pineapple.') + expect(client.sent_mail['content']).to eq([ + { + 'type' => 'text/plain', + 'value' => 'I heard you like pineapple.' + } + ]) end it 'sets a text/html body' do mail.content_type = 'text/html' mail.body = 'I heard you like <b>pineapple</b>.' mailer.deliver!(mail) - expect(client.sent_mail.html).to eq('I heard you like <b>pineapple</b>.') + + expect(client.sent_mail['content']).to eq([ + { + 'type' => 'text/html', + 'value' => 'I heard you like <b>pineapple</b>.' + } + ]) end - context 'multipart/alternative' do - before do - mail.content_type 'multipart/alternative' - mail.part do |part| - part.text_part = Mail::Part.new do - content_type 'text/plain' - body 'I heard you like pineapple.' - end - part.html_part = Mail::Part.new do - content_type 'text/html' - body 'I heard you like <b>pineapple</b>.' - end - end - end - - it 'sets the text body' do + context 'send options' do + it 'sets a template_id' do + mail['template_id'] = '1' mailer.deliver!(mail) - expect(client.sent_mail.text).to eq('I heard you like pineapple.') + expect(client.sent_mail['template_id']).to eq('1') end - it 'sets the html body' do + it 'sets sections' do + mail['sections'] = {'%foo%' => 'bar'} mailer.deliver!(mail) - expect(client.sent_mail.html) - .to eq('I heard you like <b>pineapple</b>.') + expect(client.sent_mail['sections']).to eq({'%foo%' => 'bar'}) end - end - context 'multipart/mixed' do - before do - mail.content_type 'multipart/mixed' - mail.part do |part| - part.text_part = Mail::Part.new do - content_type 'text/plain' - body 'I heard you like pineapple.' - end - part.html_part = Mail::Part.new do - content_type 'text/html' - body 'I heard you like <b>pineapple</b>.' - end - end - mail.attachments['specs.rb'] = File.read(__FILE__) - end - - it 'sets the text body' do + it 'sets headers' do + mail['headers'] = {'X-FOO' => 'bar'} mailer.deliver!(mail) - expect(client.sent_mail.text).to eq('I heard you like pineapple.') + expect(client.sent_mail['headers']).to eq({'X-FOO' => 'bar'}) end - it 'sets the html body' do + it 'sets categories' do + mail['categories'] = ['foo', 'bar'] mailer.deliver!(mail) - expect(client.sent_mail.html) - .to eq('I heard you like <b>pineapple</b>.') + expect(client.sent_mail['categories']).to eq(['foo', 'bar']) end - it 'adds the attachment' do - expect(mail.attachments.first.read).to eq(File.read(__FILE__)) + it 'sets custom_args' do + mail['custom_args'] = {'campaign' => 'welcome'} mailer.deliver!(mail) - attachment = client.sent_mail.attachments.first - expect(attachment[:name]).to eq('specs.rb') - expect(attachment[:file].content_type.to_s).to eq('application/x-ruby') + expect(client.sent_mail['custom_args']).to eq({'campaign' => 'welcome'}) end - end - context 'multipart/related' do - before do - mail.content_type 'multipart/related' - mail.part do |part| - part.text_part = Mail::Part.new do - content_type 'text/plain' - body 'I heard you like pineapple.' - end - part.html_part = Mail::Part.new do - content_type 'text/html' - body 'I heard you like <b>pineapple</b>.' - end - end - mail.attachments.inline['specs.rb'] = File.read(__FILE__) - end - - it 'sets the text body' do + it 'sets send_at and batch_id' do + epoch = Time.now.to_i + mail['send_at'] = epoch + mail['batch_id'] = 3 mailer.deliver!(mail) - expect(client.sent_mail.text).to eq('I heard you like pineapple.') + expect(client.sent_mail['send_at']).to eq(epoch) + expect(client.sent_mail['batch_id']).to eq('3') end - it 'sets the html body' do + it 'sets asm' do + asm = {'group_id' => 99, 'groups_to_display' => [4,5,6,7,8]} + mail['asm'] = asm mailer.deliver!(mail) - expect(client.sent_mail.html) - .to eq('I heard you like <b>pineapple</b>.') + expect(client.sent_mail['asm']).to eq(asm) end - it 'adds the inline attachment' do - expect(mail.attachments.first.read).to eq(File.read(__FILE__)) + it 'sets ip_pool_name' do + mail['ip_pool_name'] = 'marketing' mailer.deliver!(mail) - content = client.sent_mail.contents.first - expect(content[:name]).to eq('specs.rb') - expect(content[:file].content_type.to_s).to eq('application/x-ruby') - expect(content[:cid].class).to eq(String) + expect(client.sent_mail['ip_pool_name']).to eq('marketing') end - end - context 'SMTPAPI' do - context 'it is not JSON' do - before { mail['X-SMTPAPI'] = '<xml>JSON sucks!</xml>' } - - it 'raises a useful error' do - expect { mailer.deliver!(mail) }.to raise_error( - ArgumentError, - "X-SMTPAPI is not JSON: <xml>JSON sucks!</xml>" - ) + context 'parse object' do + it "should parse 1.8 hash" do + asm = {'group_id' => 99, 'groups_to_display' => [4,5,6,7,8]} + mail['asm'] = asm + mailer.deliver!(mail) + expect(client.sent_mail['asm']).to eq({"group_id" => 99, "groups_to_display" => [4,5,6,7,8]}) end - end - context 'filters are present' do - before do - mail['X-SMTPAPI'] = { - filters: { - clicktrack: { - settings: { - enable: 0 - } - }, - dkim: { - settings: { - domain: 'example.com', - use_from: false - } - } - } - }.to_json + it "should parse 1.9 hash" do + asm = { group_id: 99, groups_to_display: [4,5,6,7,8]} + mail['asm'] = asm + mailer.deliver!(mail) + expect(client.sent_mail['asm']).to eq({"group_id" => 99, "groups_to_display" => [4,5,6,7,8]}) end - it 'gets attached' do + it "should parse json" do + asm = {'group_id' => 99, 'groups_to_display' => [4,5,6,7,8]} + mail['asm'] = asm.to_json mailer.deliver!(mail) - expect(client.sent_mail.smtpapi.filters).to eq({ - 'clicktrack' => { - 'settings' => { - 'enable' => 0 - } - }, - 'dkim' => { - 'settings' => { - 'domain' => 'example.com', - 'use_from' => false - } - } - }) + expect(client.sent_mail['asm']).to eq({"group_id" => 99, "groups_to_display" => [4,5,6,7,8]}) end end - context 'a category is present' do - before do - mail['X-SMTPAPI'] = { category: 'food_feline' }.to_json + context 'mail_settings' do + it 'sets bcc' do + bcc = { 'bcc' => { 'enable' => true, 'email' => 'test@example.com' }} + mail['mail_settings'] = bcc + mailer.deliver!(mail) + expect(client.sent_mail['mail_settings']).to eq(bcc) end - it 'gets attached' do + it 'sets bypass_list_management' do + bypass = { 'bypass_list_management' => { 'enable' => true }} + mail['mail_settings'] = bypass mailer.deliver!(mail) - expect(client.sent_mail.smtpapi.category).to eq('food_feline') + expect(client.sent_mail['mail_settings']).to eq(bypass) end - end - context 'multiple categories are present' do - before do - mail['X-SMTPAPI'] = { - category: %w[food_feline cuisine_canine] - }.to_json + it 'sets footer' do + footer = {'footer' => { 'enable' => true, 'text' => 'Footer Text', 'html' => '<html><body>Footer Text</body></html>'}} + mail['mail_settings'] = footer + mailer.deliver!(mail) + expect(client.sent_mail['mail_settings']).to eq(footer) end - it 'attaches them all' do + it 'sets sandbox_mode' do + sandbox = {'sandbox_mode' => { 'enable' => true }} + mail['mail_settings'] = sandbox mailer.deliver!(mail) - expect(client.sent_mail.smtpapi.category).to eq([ - 'food_feline', - 'cuisine_canine', - ]) + expect(client.sent_mail['mail_settings']).to eq(sandbox) end - end - context 'send_at is present' do - before do - mail['X-SMTPAPI'] = { - send_at: 1409348513 - }.to_json - end - - it 'gets attached' do + it 'sets spam_check' do + spam_check = {'spam_check' => { 'enable' => true, 'threshold' => 1, 'post_to_url' => 'https://spamcatcher.sendgrid.com'}} + mail['mail_settings'] = spam_check mailer.deliver!(mail) - expect(client.sent_mail.smtpapi.send_at).to eq(1409348513) + expect(client.sent_mail['mail_settings']).to eq(spam_check) end end - context 'send_each_at is present' do - before do - mail['X-SMTPAPI'] = { - send_each_at: [1409348513, 1409348514] - }.to_json + context 'tracking_settings' do + it 'sets click_tracking' do + tracking = { 'click_tracking' => { 'enable' => false, 'enable_text' => false }} + mail['tracking_settings'] = tracking + mailer.deliver!(mail) + expect(client.sent_mail['tracking_settings']).to eq(tracking) end - it 'gets attached' do + it 'sets open_tracking' do + tracking = { 'open_tracking' => { 'enable' => true, 'substitution_tag' => 'Optional tag to replace with the open image in the body of the message' }} + mail['tracking_settings'] = tracking mailer.deliver!(mail) - expect(client.sent_mail.smtpapi.send_each_at).to eq([1409348513, 1409348514]) + expect(client.sent_mail['tracking_settings']).to eq(tracking) end - end - context 'section is present' do - before do - mail['X-SMTPAPI'] = { - section: { - ":sectionName1" => "section 1 text", - ":sectionName2" => "section 2 text" - } - }.to_json + it 'sets subscription_tracking' do + tracking = { 'subscription_tracking' => { 'enable' => true, 'text' => 'text to insert into the text/plain portion of the message', 'html' => 'html to insert into the text/html portion of the message', 'substitution_tag' => 'Optional tag to replace with the open image in the body of the def message' }} + mail['tracking_settings'] = tracking + mailer.deliver!(mail) + expect(client.sent_mail['tracking_settings']).to eq(tracking) end - it 'gets attached' do + it 'sets ganalytics' do + tracking = { 'ganalytics' => {'enable' => true, 'utm_source' => 'some source', 'utm_medium' => 'some medium', 'utm_term' => 'some term', 'utm_content' => 'some content', 'utm_campaign' => 'some campaign' }} + mail['tracking_settings'] = tracking mailer.deliver!(mail) - expect(client.sent_mail.smtpapi.section).to eq({ - ":sectionName1" => "section 1 text", - ":sectionName2" => "section 2 text" - }) + expect(client.sent_mail['tracking_settings']).to eq(tracking) end end + end - context 'sub is present' do - before do - mail['X-SMTPAPI'] = { - sub: { - "-name-" => [ - "John", - "Jane" - ], - "-customerID-" => [ - "1234", - "5678" - ], - } - }.to_json + context 'multipart/alternative' do + before do + mail.content_type 'multipart/alternative' + mail.part do |part| + part.text_part = Mail::Part.new do + content_type 'text/plain' + body 'I heard you like pineapple.' + end + part.html_part = Mail::Part.new do + content_type 'text/html' + body 'I heard you like <b>pineapple</b>.' + end end + end - it 'gets attached' do - mailer.deliver!(mail) - expect(client.sent_mail.smtpapi.sub).to eq({ - "-name-" => [ - "John", - "Jane" - ], - "-customerID-" => [ - "1234", - "5678" - ], - }) - end + it 'sets the text and html body' do + mailer.deliver!(mail) + expect(client.sent_mail['content']).to include({ + 'type' => 'text/html', + 'value' => 'I heard you like <b>pineapple</b>.' + }) + expect(client.sent_mail['content']).to include({ + 'type' => 'text/plain', + 'value' => 'I heard you like pineapple.' + }) end + end - context 'asm_group_id is present' do - before do - mail['X-SMTPAPI'] = { - asm_group_id: 1 - }.to_json + context 'multipart/mixed' do + before do + mail.content_type 'multipart/mixed' + mail.part do |part| + part.text_part = Mail::Part.new do + content_type 'text/plain' + body 'I heard you like pineapple.' + end + part.html_part = Mail::Part.new do + content_type 'text/html' + body 'I heard you like <b>pineapple</b>.' + end end + mail.attachments['specs.rb'] = File.read(__FILE__) + end - it 'gets attached' do - mailer.deliver!(mail) - expect(client.sent_mail.smtpapi.asm_group_id).to eq(1) - end + it 'sets the text and html body' do + mailer.deliver!(mail) + expect(client.sent_mail['content']).to include({ + 'type' => 'text/html', + 'value' => 'I heard you like <b>pineapple</b>.' + }) + expect(client.sent_mail['content']).to include({ + 'type' => 'text/plain', + 'value' => 'I heard you like pineapple.' + }) end - context 'unique_args are present' do - before do - mail['X-SMTPAPI'] = { - unique_args: { - customerAccountNumber: "55555", - activationAttempt: "1", - } - }.to_json - end + it 'adds the attachment' do + expect(mail.attachments.first.read).to eq(File.read(__FILE__)) + mailer.deliver!(mail) + attachment = client.sent_mail['attachments'].first + expect(attachment['filename']).to eq('specs.rb') + expect(attachment['type']).to eq('application/x-ruby') + end + end - it 'gets attached' do - mailer.deliver!(mail) - expect(client.sent_mail.smtpapi.unique_args).to eq({ - "customerAccountNumber" => "55555", - "activationAttempt" => "1", - }) + context 'multipart/related' do + before do + mail.content_type 'multipart/related' + mail.part do |part| + part.text_part = Mail::Part.new do + content_type 'text/plain' + body 'I heard you like pineapple.' + end + part.html_part = Mail::Part.new do + content_type 'text/html' + body 'I heard you like <b>pineapple</b>.' + end end + mail.attachments.inline['specs.rb'] = File.read(__FILE__) end - context 'ip_pool is present' do - before do - mail['X-SMTPAPI'] = { - ip_pool: "pool_name" - }.to_json - end - - it 'gets attached' do - mailer.deliver!(mail) - expect(client.sent_mail.smtpapi.ip_pool).to eq("pool_name") - end + it 'sets the text and html body' do + mailer.deliver!(mail) + expect(client.sent_mail['content']).to include({ + 'type' => 'text/html', + 'value' => 'I heard you like <b>pineapple</b>.' + }) + expect(client.sent_mail['content']).to include({ + 'type' => 'text/plain', + 'value' => 'I heard you like pineapple.' + }) end - context 'multiple X-SMTPAPI headers are present' do - before do - mail['X-SMTPAPI'] = { category: 'food_canine' }.to_json - mail['X-SMTPAPI'] = { category: 'food_feline' }.to_json - end - - it 'uses the last header' do - mailer.deliver!(mail) - expect(client.sent_mail.smtpapi.category).to eq('food_canine') - end + it 'adds the inline attachment' do + expect(mail.attachments.first.read).to eq(File.read(__FILE__)) + mailer.deliver!(mail) + content = client.sent_mail['attachments'].first + expect(content['filename']).to eq('specs.rb') + expect(content['type']).to eq('application/x-ruby') + expect(content['content_id'].class).to eq(String) end end end end end