2015-10-11 05:41:23 -04:00
|
|
|
require 'rails_helper'
|
2013-06-10 15:33:37 -04:00
|
|
|
require 'email/sender'
|
2013-02-05 14:16:51 -05:00
|
|
|
|
2013-06-10 15:33:37 -04:00
|
|
|
describe Email::Sender do
|
2013-02-05 14:16:51 -05:00
|
|
|
|
2014-08-23 05:07:37 -04:00
|
|
|
it "doesn't deliver mail when mails are disabled" do
|
2016-04-08 01:23:16 -04:00
|
|
|
SiteSetting.disable_emails = true
|
2014-10-15 03:04:47 -04:00
|
|
|
Mail::Message.any_instance.expects(:deliver_now).never
|
2014-08-23 05:07:37 -04:00
|
|
|
message = Mail::Message.new(to: "hello@world.com" , body: "hello")
|
2016-02-17 11:31:46 -05:00
|
|
|
expect(Email::Sender.new(message, :hello).send).to eq(nil)
|
|
|
|
end
|
|
|
|
|
2016-04-08 01:23:16 -04:00
|
|
|
it "delivers mail when mails are disabled but the email_type is admin_login" do
|
|
|
|
SiteSetting.disable_emails = true
|
|
|
|
Mail::Message.any_instance.expects(:deliver_now).once
|
|
|
|
message = Mail::Message.new(to: "hello@world.com" , body: "hello")
|
|
|
|
Email::Sender.new(message, :admin_login).send
|
|
|
|
end
|
|
|
|
|
2016-02-17 11:31:46 -05:00
|
|
|
it "doesn't deliver mail when the message is of type NullMail" do
|
|
|
|
Mail::Message.any_instance.expects(:deliver_now).never
|
|
|
|
message = ActionMailer::Base::NullMail.new
|
|
|
|
expect(Email::Sender.new(message, :hello).send).to eq(nil)
|
2014-08-23 05:07:37 -04:00
|
|
|
end
|
|
|
|
|
2013-02-05 14:16:51 -05:00
|
|
|
it "doesn't deliver mail when the message is nil" do
|
2014-10-15 03:04:47 -04:00
|
|
|
Mail::Message.any_instance.expects(:deliver_now).never
|
2013-06-10 15:33:37 -04:00
|
|
|
Email::Sender.new(nil, :hello).send
|
2013-02-05 14:16:51 -05:00
|
|
|
end
|
|
|
|
|
|
|
|
it "doesn't deliver when the to address is nil" do
|
|
|
|
message = Mail::Message.new(body: 'hello')
|
2014-10-15 03:04:47 -04:00
|
|
|
message.expects(:deliver_now).never
|
2013-06-10 15:33:37 -04:00
|
|
|
Email::Sender.new(message, :hello).send
|
2013-02-05 14:16:51 -05:00
|
|
|
end
|
|
|
|
|
|
|
|
it "doesn't deliver when the body is nil" do
|
|
|
|
message = Mail::Message.new(to: 'eviltrout@test.domain')
|
2014-10-15 03:04:47 -04:00
|
|
|
message.expects(:deliver_now).never
|
2013-06-10 15:33:37 -04:00
|
|
|
Email::Sender.new(message, :hello).send
|
2013-02-05 14:16:51 -05:00
|
|
|
end
|
|
|
|
|
2013-07-08 11:48:40 -04:00
|
|
|
context "host_for" do
|
|
|
|
it "defaults to localhost" do
|
2015-01-09 11:34:37 -05:00
|
|
|
expect(Email::Sender.host_for(nil)).to eq("localhost")
|
2013-07-02 14:13:46 -04:00
|
|
|
end
|
|
|
|
|
2013-07-08 11:48:40 -04:00
|
|
|
it "returns localhost for a weird host" do
|
2015-01-09 11:34:37 -05:00
|
|
|
expect(Email::Sender.host_for("this is not a real host")).to eq("localhost")
|
2013-07-02 14:13:46 -04:00
|
|
|
end
|
|
|
|
|
2013-07-08 11:48:40 -04:00
|
|
|
it "parses hosts from urls" do
|
2015-01-09 11:34:37 -05:00
|
|
|
expect(Email::Sender.host_for("http://meta.discourse.org")).to eq("meta.discourse.org")
|
2013-07-02 14:13:46 -04:00
|
|
|
end
|
|
|
|
|
2013-07-08 11:48:40 -04:00
|
|
|
it "downcases hosts" do
|
2015-01-09 11:34:37 -05:00
|
|
|
expect(Email::Sender.host_for("http://ForumSite.com")).to eq("forumsite.com")
|
2013-07-02 14:13:46 -04:00
|
|
|
end
|
|
|
|
|
2013-07-08 11:48:40 -04:00
|
|
|
end
|
|
|
|
|
2013-02-05 14:16:51 -05:00
|
|
|
context 'with a valid message' do
|
|
|
|
|
2013-06-13 10:56:16 -04:00
|
|
|
let(:reply_key) { "abcd" * 8 }
|
|
|
|
|
2013-02-25 11:42:20 -05:00
|
|
|
let(:message) do
|
2013-02-05 14:16:51 -05:00
|
|
|
message = Mail::Message.new to: 'eviltrout@test.domain',
|
|
|
|
body: '**hello**'
|
2014-10-15 03:04:47 -04:00
|
|
|
message.stubs(:deliver_now)
|
2013-02-05 14:16:51 -05:00
|
|
|
message
|
|
|
|
end
|
|
|
|
|
2013-06-10 15:33:37 -04:00
|
|
|
let(:email_sender) { Email::Sender.new(message, :valid_type) }
|
2013-02-05 14:16:51 -05:00
|
|
|
|
|
|
|
it 'calls deliver' do
|
2014-10-15 03:04:47 -04:00
|
|
|
message.expects(:deliver_now).once
|
2013-02-05 14:16:51 -05:00
|
|
|
email_sender.send
|
|
|
|
end
|
|
|
|
|
2016-04-25 14:06:45 -04:00
|
|
|
context "doesn't add return_path when no plus addressing" do
|
|
|
|
before { SiteSetting.reply_by_email_address = '%{reply_key}@test.com' }
|
2016-04-18 03:13:41 -04:00
|
|
|
|
2016-12-12 20:59:38 -05:00
|
|
|
it 'should not set the return_path' do
|
|
|
|
email_sender.send
|
2016-04-25 14:06:45 -04:00
|
|
|
expect(message.header[:return_path].to_s).to eq("")
|
2016-12-12 20:59:38 -05:00
|
|
|
end
|
2016-04-18 03:13:41 -04:00
|
|
|
end
|
|
|
|
|
2016-04-25 14:06:45 -04:00
|
|
|
context "adds return_path with plus addressing" do
|
|
|
|
before { SiteSetting.reply_by_email_address = 'replies+%{reply_key}@test.com' }
|
2016-04-18 03:13:41 -04:00
|
|
|
|
2016-12-12 20:59:38 -05:00
|
|
|
it 'should set the return_path' do
|
|
|
|
email_sender.send
|
2016-04-25 14:06:45 -04:00
|
|
|
expect(message.header[:return_path].to_s).to eq("replies+verp-#{EmailLog.last.bounce_key}@test.com")
|
2016-12-12 20:59:38 -05:00
|
|
|
end
|
2016-04-18 03:13:41 -04:00
|
|
|
end
|
|
|
|
|
2014-10-08 14:09:21 -04:00
|
|
|
context "adds a List-ID header to identify the forum" do
|
2017-02-01 17:02:41 -05:00
|
|
|
let(:category) { Fabricate(:category, name: 'Name With Space') }
|
|
|
|
let(:topic) { Fabricate(:topic, category: category) }
|
|
|
|
let(:post) { Fabricate(:post, topic: topic) }
|
|
|
|
|
2014-10-08 14:09:21 -04:00
|
|
|
before do
|
2017-02-01 17:02:41 -05:00
|
|
|
message.header['X-Discourse-Post-Id'] = post.id
|
2015-10-20 14:30:06 -04:00
|
|
|
message.header['X-Discourse-Topic-Id'] = topic.id
|
2014-10-08 14:09:21 -04:00
|
|
|
end
|
|
|
|
|
2016-12-12 20:59:38 -05:00
|
|
|
it 'should add the right header' do
|
|
|
|
email_sender.send
|
|
|
|
|
|
|
|
expect(message.header['List-ID']).to be_present
|
|
|
|
expect(message.header['List-ID'].to_s).to match('name-with-space')
|
|
|
|
end
|
2014-10-08 14:09:21 -04:00
|
|
|
end
|
2013-07-02 14:13:46 -04:00
|
|
|
|
2015-01-28 04:12:49 -05:00
|
|
|
context "adds a Message-ID header even when topic id is not present" do
|
2016-12-12 20:59:38 -05:00
|
|
|
|
|
|
|
it 'should add the right header' do
|
|
|
|
email_sender.send
|
|
|
|
|
|
|
|
expect(message.header['Message-ID']).to be_present
|
|
|
|
end
|
2015-01-28 04:12:49 -05:00
|
|
|
end
|
|
|
|
|
2014-10-08 15:57:30 -04:00
|
|
|
context "adds Precedence header" do
|
2017-02-01 17:02:41 -05:00
|
|
|
let(:topic) { Fabricate(:topic) }
|
|
|
|
let(:post) { Fabricate(:post, topic: topic) }
|
|
|
|
|
2017-07-27 21:20:09 -04:00
|
|
|
before do
|
2017-02-01 17:02:41 -05:00
|
|
|
message.header['X-Discourse-Post-Id'] = post.id
|
|
|
|
message.header['X-Discourse-Topic-Id'] = topic.id
|
2014-10-08 15:57:30 -04:00
|
|
|
end
|
|
|
|
|
2016-12-12 20:59:38 -05:00
|
|
|
it 'should add the right header' do
|
|
|
|
email_sender.send
|
|
|
|
expect(message.header['Precedence']).to be_present
|
|
|
|
end
|
2014-10-08 15:57:30 -04:00
|
|
|
end
|
|
|
|
|
2015-01-29 06:53:10 -05:00
|
|
|
context "removes custom Discourse headers from topic notification mails" do
|
2017-02-01 17:02:41 -05:00
|
|
|
let(:topic) { Fabricate(:topic) }
|
|
|
|
let(:post) { Fabricate(:post, topic: topic) }
|
|
|
|
|
2015-01-29 06:53:10 -05:00
|
|
|
before do
|
2017-02-01 17:02:41 -05:00
|
|
|
message.header['X-Discourse-Post-Id'] = post.id
|
|
|
|
message.header['X-Discourse-Topic-Id'] = topic.id
|
2015-01-29 06:53:10 -05:00
|
|
|
end
|
|
|
|
|
2016-12-12 20:59:38 -05:00
|
|
|
it 'should remove the right headers' do
|
|
|
|
email_sender.send
|
|
|
|
expect(message.header['X-Discourse-Topic-Id']).not_to be_present
|
|
|
|
expect(message.header['X-Discourse-Post-Id']).not_to be_present
|
|
|
|
expect(message.header['X-Discourse-Reply-Key']).not_to be_present
|
|
|
|
end
|
2015-01-29 06:53:10 -05:00
|
|
|
end
|
|
|
|
|
|
|
|
context "removes custom Discourse headers from digest/registration/other mails" do
|
2016-12-12 20:59:38 -05:00
|
|
|
it 'should remove the right headers' do
|
|
|
|
email_sender.send
|
|
|
|
expect(message.header['X-Discourse-Topic-Id']).not_to be_present
|
|
|
|
expect(message.header['X-Discourse-Post-Id']).not_to be_present
|
|
|
|
expect(message.header['X-Discourse-Reply-Key']).not_to be_present
|
|
|
|
end
|
2015-01-29 06:53:10 -05:00
|
|
|
end
|
|
|
|
|
2016-11-28 08:18:02 -05:00
|
|
|
context "email threading" do
|
|
|
|
let(:topic) { Fabricate(:topic) }
|
|
|
|
|
|
|
|
let(:post_1) { Fabricate(:post, topic: topic, post_number: 1) }
|
|
|
|
let(:post_2) { Fabricate(:post, topic: topic, post_number: 2) }
|
|
|
|
let(:post_3) { Fabricate(:post, topic: topic, post_number: 3) }
|
|
|
|
let(:post_4) { Fabricate(:post, topic: topic, post_number: 4) }
|
|
|
|
|
2017-02-01 17:02:41 -05:00
|
|
|
let!(:post_reply_1_4) { PostReply.create(post: post_1, reply: post_4) }
|
|
|
|
let!(:post_reply_2_4) { PostReply.create(post: post_2, reply: post_4) }
|
|
|
|
let!(:post_reply_3_4) { PostReply.create(post: post_3, reply: post_4) }
|
2016-11-28 08:18:02 -05:00
|
|
|
|
2017-02-01 17:02:41 -05:00
|
|
|
before { message.header['X-Discourse-Topic-Id'] = topic.id }
|
2016-11-28 08:18:02 -05:00
|
|
|
|
|
|
|
it "doesn't set the 'In-Reply-To' and 'References' headers on the first post" do
|
|
|
|
message.header['X-Discourse-Post-Id'] = post_1.id
|
|
|
|
|
|
|
|
email_sender.send
|
|
|
|
|
2017-02-01 17:02:41 -05:00
|
|
|
expect(message.header['Message-Id'].to_s).to eq("<topic/#{topic.id}@test.localhost>")
|
2016-11-28 08:18:02 -05:00
|
|
|
expect(message.header['In-Reply-To'].to_s).to be_blank
|
|
|
|
expect(message.header['References'].to_s).to be_blank
|
|
|
|
end
|
|
|
|
|
|
|
|
it "sets the 'In-Reply-To' header to the topic by default" do
|
|
|
|
message.header['X-Discourse-Post-Id'] = post_2.id
|
|
|
|
|
|
|
|
email_sender.send
|
|
|
|
|
|
|
|
expect(message.header['Message-Id'].to_s).to eq("<topic/#{topic.id}/#{post_2.id}@test.localhost>")
|
|
|
|
expect(message.header['In-Reply-To'].to_s).to eq("<topic/#{topic.id}@test.localhost>")
|
|
|
|
end
|
|
|
|
|
|
|
|
it "sets the 'In-Reply-To' header to the newest replied post" do
|
2017-02-01 17:02:41 -05:00
|
|
|
message.header['X-Discourse-Post-Id'] = post_4.id
|
2016-11-28 08:18:02 -05:00
|
|
|
|
|
|
|
email_sender.send
|
|
|
|
|
2017-02-01 17:02:41 -05:00
|
|
|
expect(message.header['Message-Id'].to_s).to eq("<topic/#{topic.id}/#{post_4.id}@test.localhost>")
|
|
|
|
expect(message.header['In-Reply-To'].to_s).to eq("<topic/#{topic.id}/#{post_3.id}@test.localhost>")
|
2016-11-28 08:18:02 -05:00
|
|
|
end
|
|
|
|
|
|
|
|
it "sets the 'References' header to the topic and all replied posts" do
|
2017-02-01 17:02:41 -05:00
|
|
|
message.header['X-Discourse-Post-Id'] = post_4.id
|
2016-11-28 08:18:02 -05:00
|
|
|
|
|
|
|
email_sender.send
|
|
|
|
|
|
|
|
references = [
|
2018-02-22 05:17:49 -05:00
|
|
|
"<topic/#{topic.id}@test.localhost>",
|
2017-02-01 17:02:41 -05:00
|
|
|
"<topic/#{topic.id}/#{post_3.id}@test.localhost>",
|
2016-11-28 08:18:02 -05:00
|
|
|
"<topic/#{topic.id}/#{post_2.id}@test.localhost>",
|
|
|
|
]
|
|
|
|
|
|
|
|
expect(message.header['References'].to_s).to eq(references.join(" "))
|
|
|
|
end
|
|
|
|
|
|
|
|
it "uses the incoming_email message_id when available" do
|
2017-02-01 17:02:41 -05:00
|
|
|
topic_incoming_email = IncomingEmail.create(topic: topic, post: post_1, message_id: "foo@bar")
|
|
|
|
post_2_incoming_email = IncomingEmail.create(topic: topic, post: post_2, message_id: "bar@foo")
|
|
|
|
post_4_incoming_email = IncomingEmail.create(topic: topic, post: post_4, message_id: "wat@wat")
|
|
|
|
|
2016-11-28 08:18:02 -05:00
|
|
|
message.header['X-Discourse-Post-Id'] = post_4.id
|
|
|
|
|
|
|
|
email_sender.send
|
|
|
|
|
2017-02-01 17:02:41 -05:00
|
|
|
expect(message.header['Message-Id'].to_s).to eq("<#{post_4_incoming_email.message_id}>")
|
|
|
|
|
|
|
|
references = [
|
2018-02-22 05:17:49 -05:00
|
|
|
"<#{topic_incoming_email.message_id}>",
|
2017-02-01 17:02:41 -05:00
|
|
|
"<topic/#{topic.id}/#{post_3.id}@test.localhost>",
|
|
|
|
"<#{post_2_incoming_email.message_id}>",
|
|
|
|
]
|
|
|
|
|
|
|
|
expect(message.header['References'].to_s).to eq(references.join(" "))
|
2016-11-28 08:18:02 -05:00
|
|
|
end
|
|
|
|
|
|
|
|
end
|
|
|
|
|
2016-10-30 06:38:55 -04:00
|
|
|
context "merges custom mandrill header" do
|
|
|
|
before do
|
|
|
|
ActionMailer::Base.smtp_settings[:address] = "smtp.mandrillapp.com"
|
|
|
|
message.header['X-MC-Metadata'] = { foo: "bar" }.to_json
|
|
|
|
end
|
|
|
|
|
2016-12-12 20:59:38 -05:00
|
|
|
it 'should set the right header' do
|
|
|
|
email_sender.send
|
|
|
|
expect(message.header['X-MC-Metadata'].to_s).to match(message.message_id)
|
|
|
|
end
|
2016-10-30 06:38:55 -04:00
|
|
|
end
|
|
|
|
|
|
|
|
context "merges custom sparkpost header" do
|
|
|
|
before do
|
|
|
|
ActionMailer::Base.smtp_settings[:address] = "smtp.sparkpostmail.com"
|
|
|
|
message.header['X-MSYS-API'] = { foo: "bar" }.to_json
|
|
|
|
end
|
|
|
|
|
2016-12-12 20:59:38 -05:00
|
|
|
it 'should set the right header' do
|
|
|
|
email_sender.send
|
|
|
|
expect(message.header['X-MSYS-API'].to_s).to match(message.message_id)
|
|
|
|
end
|
2016-10-30 06:38:55 -04:00
|
|
|
end
|
|
|
|
|
2013-02-05 14:16:51 -05:00
|
|
|
context 'email logs' do
|
2013-06-13 10:56:16 -04:00
|
|
|
let(:email_log) { EmailLog.last }
|
|
|
|
|
2016-12-12 20:59:38 -05:00
|
|
|
it 'should create the right log' do
|
|
|
|
email_sender.send
|
|
|
|
|
|
|
|
expect(email_log).to be_present
|
|
|
|
expect(email_log.email_type).to eq('valid_type')
|
|
|
|
expect(email_log.to_address).to eq('eviltrout@test.domain')
|
|
|
|
expect(email_log.reply_key).to be_blank
|
|
|
|
expect(email_log.user_id).to be_blank
|
|
|
|
end
|
2013-06-13 10:56:16 -04:00
|
|
|
end
|
2013-02-05 14:16:51 -05:00
|
|
|
|
2013-06-13 18:11:10 -04:00
|
|
|
context "email log with a post id and topic id" do
|
2017-02-01 17:02:41 -05:00
|
|
|
let(:topic) { Fabricate(:topic) }
|
|
|
|
let(:post) { Fabricate(:post, topic: topic) }
|
|
|
|
|
2013-06-13 18:11:10 -04:00
|
|
|
before do
|
2017-02-01 17:02:41 -05:00
|
|
|
message.header['X-Discourse-Post-Id'] = post.id
|
|
|
|
message.header['X-Discourse-Topic-Id'] = topic.id
|
2013-06-13 18:11:10 -04:00
|
|
|
end
|
|
|
|
|
|
|
|
let(:email_log) { EmailLog.last }
|
2016-12-12 20:59:38 -05:00
|
|
|
|
|
|
|
it 'should create the right log' do
|
|
|
|
email_sender.send
|
2017-02-01 17:02:41 -05:00
|
|
|
expect(email_log.post_id).to eq(post.id)
|
|
|
|
expect(email_log.topic_id).to eq(topic.id)
|
2016-12-12 20:59:38 -05:00
|
|
|
end
|
2013-06-13 18:11:10 -04:00
|
|
|
end
|
|
|
|
|
2013-06-13 10:56:16 -04:00
|
|
|
context "email log with a reply key" do
|
2013-02-05 14:16:51 -05:00
|
|
|
before do
|
2013-06-18 15:54:02 -04:00
|
|
|
message.header['X-Discourse-Reply-Key'] = reply_key
|
2013-02-05 14:16:51 -05:00
|
|
|
end
|
|
|
|
|
2013-06-13 10:56:16 -04:00
|
|
|
let(:email_log) { EmailLog.last }
|
2016-12-12 20:59:38 -05:00
|
|
|
|
|
|
|
it 'should create the right log' do
|
|
|
|
email_sender.send
|
|
|
|
expect(email_log.reply_key).to eq(reply_key)
|
|
|
|
end
|
2013-02-05 14:16:51 -05:00
|
|
|
end
|
|
|
|
|
2013-06-13 10:56:16 -04:00
|
|
|
context 'email parts' do
|
2016-12-12 20:59:38 -05:00
|
|
|
it 'should contain the right message' do
|
|
|
|
email_sender.send
|
|
|
|
|
|
|
|
expect(message).to be_multipart
|
|
|
|
expect(message.text_part.content_type).to eq('text/plain; charset=UTF-8')
|
|
|
|
expect(message.html_part.content_type).to eq('text/html; charset=UTF-8')
|
|
|
|
expect(message.html_part.body.to_s).to match("<p><strong>hello</strong></p>")
|
|
|
|
end
|
2013-02-05 14:16:51 -05:00
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
context 'with a user' do
|
2013-02-25 11:42:20 -05:00
|
|
|
let(:message) do
|
2013-02-05 14:16:51 -05:00
|
|
|
message = Mail::Message.new to: 'eviltrout@test.domain', body: 'test body'
|
2014-10-15 03:04:47 -04:00
|
|
|
message.stubs(:deliver_now)
|
2013-02-05 14:16:51 -05:00
|
|
|
message
|
|
|
|
end
|
|
|
|
|
|
|
|
let(:user) { Fabricate(:user) }
|
2013-06-10 15:33:37 -04:00
|
|
|
let(:email_sender) { Email::Sender.new(message, :valid_type, user) }
|
2013-02-05 14:16:51 -05:00
|
|
|
|
|
|
|
before do
|
|
|
|
email_sender.send
|
|
|
|
@email_log = EmailLog.last
|
|
|
|
end
|
|
|
|
|
|
|
|
it 'should have the current user_id' do
|
2015-01-09 11:34:37 -05:00
|
|
|
expect(@email_log.user_id).to eq(user.id)
|
2013-02-05 14:16:51 -05:00
|
|
|
end
|
|
|
|
|
|
|
|
end
|
|
|
|
|
|
|
|
end
|