discourse/spec/components/email/processor_spec.rb

169 lines
5.0 KiB
Ruby

require "rails_helper"
require "email/processor"
describe Email::Processor do
let(:from) { "foo@bar.com" }
context "when reply via email is too short" do
let(:mail) { file_from_fixtures("email_reply_3.eml", "emails").read }
let(:post) { Fabricate(:post) }
let!(:user) { Fabricate(:user, email: "three@foo.com") }
let!(:email_log) do
Fabricate(:email_log,
message_id: "35@foo.bar.mail", # don't change, based on fixture file "email_reply_3.eml"
email_type: "user_posted",
post_id: post.id,
to_address: "asdas@dasdfd.com"
)
end
before do
SiteSetting.min_post_length = 1000
SiteSetting.find_related_post_with_key = false
end
it "rejects reply and sends an email with custom error message" do
begin
receiver = Email::Receiver.new(mail)
receiver.process!
rescue Email::Receiver::TooShortPost => e
error = e
end
expect(error.class).to eq(Email::Receiver::TooShortPost)
processor = Email::Processor.new(mail)
processor.process!
rejection_raw = processor.send(:handle_failure, mail, error).body.raw_source
count = SiteSetting.min_post_length
destination = receiver.mail.to
former_title = receiver.mail.subject
expect(rejection_raw.gsub(/\r/, "")).to eq(
I18n.t("system_messages.email_reject_post_too_short.text_body_template",
count: count,
destination: destination,
former_title: former_title
).gsub(/\r/, "")
)
end
end
describe "rate limits" do
let(:mail) { "From: #{from}\nTo: bar@foo.com\nSubject: FOO BAR\n\nFoo foo bar bar?" }
let(:limit_exceeded) { RateLimiter::LimitExceeded.new(10) }
before do
Email::Receiver.any_instance.expects(:process!).raises(limit_exceeded)
end
it "enqueues a background job by default" do
Jobs.expects(:enqueue).with(:process_email, mail: mail)
Email::Processor.process!(mail)
end
it "doesn't enqueue a background job when retry is disabled" do
Jobs.expects(:enqueue).with(:process_email, mail: mail).never
expect { Email::Processor.process!(mail, false) }.to raise_error(limit_exceeded)
end
end
context "known error" do
let(:mail) { "From: #{from}\nTo: bar@foo.com" }
let(:mail2) { "From: #{from}\nTo: foo@foo.com" }
let(:mail3) { "From: #{from}\nTo: foobar@foo.com" }
it "only sends one rejection email per day" do
key = "rejection_email:#{[from]}:email_reject_empty:#{Date.today}"
$redis.expire(key, 0)
expect {
Email::Processor.process!(mail)
}.to change { EmailLog.count }.by(1)
expect {
Email::Processor.process!(mail2)
}.to change { EmailLog.count }.by(0)
freeze_time(Date.today + 1)
key = "rejection_email:#{[from]}:email_reject_empty:#{Date.today}"
$redis.expire(key, 0)
expect {
Email::Processor.process!(mail3)
}.to change { EmailLog.count }.by(1)
end
end
context "unrecognized error" do
let(:mail) { "From: #{from}\nTo: bar@foo.com\nSubject: FOO BAR\n\nFoo foo bar bar?" }
let(:mail2) { "From: #{from}\nTo: foo@foo.com\nSubject: BAR BAR\n\nBar bar bar bar?" }
it "sends a rejection email on an unrecognized error" do
Email::Processor.any_instance.stubs(:can_send_rejection_email?).returns(true)
Email::Receiver.any_instance.stubs(:process_internal).raises("boom")
Rails.logger.expects(:error)
Email::Processor.process!(mail)
expect(IncomingEmail.last.error).to eq("boom")
expect(IncomingEmail.last.rejection_message).to be_present
expect(EmailLog.last.email_type).to eq("email_reject_unrecognized_error")
end
it "sends more than one rejection email per day" do
Email::Receiver.any_instance.stubs(:process_internal).raises("boom")
key = "rejection_email:#{[from]}:email_reject_unrecognized_error:#{Date.today}"
$redis.expire(key, 0)
expect {
Email::Processor.process!(mail)
}.to change { EmailLog.count }.by(1)
expect {
Email::Processor.process!(mail2)
}.to change { EmailLog.count }.by(1)
end
end
context "from reply to email address" do
let(:mail) { "From: reply@bar.com\nTo: reply@bar.com\nSubject: FOO BAR\n\nFoo foo bar bar?" }
it "ignores the email" do
Email::Receiver.any_instance.stubs(:process_internal).raises(Email::Receiver::FromReplyByAddressError.new)
expect {
Email::Processor.process!(mail)
}.to change { EmailLog.count }.by(0)
end
end
context "mailinglist mirror" do
before do
SiteSetting.email_in = true
Fabricate(:mailinglist_mirror_category)
end
it "does not send rejection email" do
Email::Receiver.any_instance.stubs(:process_internal).raises("boom")
email = <<~EMAIL
From: foo@example.com
To: list@example.com
Subject: Hello world
EMAIL
expect { Email::Processor.process!(email) }.to_not change { EmailLog.count }
end
end
end