discourse/spec/components/email/receiver_spec.rb
Benjamin Kampmann 4af2cf3f23 Refactor and clean up New-Topic via Email
With the new email_in admin configuration setting, emails to the email_in_address fetched via POP will now be processed and posted as new topics to the forum.

With the email_in_min_trust you can control the trust level the user needs to have at least to be able to post an email as a new topic.

Also contains tests for the email-in feature and minor clean ups
2014-02-28 16:53:58 +01:00

305 lines
9.5 KiB
Ruby

# -*- encoding : utf-8 -*-
require 'spec_helper'
require 'email/receiver'
describe Email::Receiver do
before do
SiteSetting.stubs(:reply_by_email_address).returns("reply+%{reply_key}@appmail.adventuretime.ooo")
SiteSetting.stubs(:email_in).returns(false)
end
describe "exception raised" do
it "returns error if it encountered an error processing" do
receiver = Email::Receiver.new("some email")
def receiver.parse_body
raise "ERROR HAPPENED!"
end
expect(receiver.process).to eq(Email::Receiver.results[:error])
end
end
describe 'invalid emails' do
it "returns unprocessable if the message is blank" do
expect(Email::Receiver.new("").process).to eq(Email::Receiver.results[:unprocessable])
end
it "returns unprocessable if the message is not an email" do
expect(Email::Receiver.new("asdf" * 30).process).to eq(Email::Receiver.results[:unprocessable])
end
end
describe "with multipart" do
let(:reply_below) { File.read("#{Rails.root}/spec/fixtures/emails/multipart.eml") }
let(:receiver) { Email::Receiver.new(reply_below) }
it "processes correctly" do
receiver.process
expect(receiver.body).to eq(
"So presumably all the quoted garbage and my (proper) signature will get
stripped from my reply?")
end
end
describe "html only" do
let(:reply_below) { File.read("#{Rails.root}/spec/fixtures/emails/html_only.eml") }
let(:receiver) { Email::Receiver.new(reply_below) }
it "processes correctly" do
receiver.process
expect(receiver.body).to eq("The EC2 instance - I've seen that there tends to be odd and " +
"unrecommended settings on the Bitnami installs that I've checked out.")
end
end
describe "it ignores messages it can't parse due to containing weird terms" do
let(:attachment) { File.read("#{Rails.root}/spec/fixtures/emails/attachment.eml") }
let(:receiver) { Email::Receiver.new(attachment) }
it "processes correctly" do
expect(receiver.process).to eq(Email::Receiver.results[:unprocessable])
expect(receiver.body).to be_blank
end
end
describe "it supports a dutch reply" do
let(:dutch) { File.read("#{Rails.root}/spec/fixtures/emails/dutch.eml") }
let(:receiver) { Email::Receiver.new(dutch) }
it "processes correctly" do
receiver.process
expect(receiver.body).to eq("Dit is een antwoord in het Nederlands.")
end
end
describe "It supports a non english reply" do
let(:hebrew) { File.read("#{Rails.root}/spec/fixtures/emails/hebrew.eml") }
let(:receiver) { Email::Receiver.new(hebrew) }
it "processes correctly" do
I18n.expects(:t).with('user_notifications.previous_discussion').returns('כלטוב')
receiver.process
expect(receiver.body).to eq("שלום")
end
end
describe "It supports a non UTF-8 reply" do
let(:big5) { File.read("#{Rails.root}/spec/fixtures/emails/big5.eml") }
let(:receiver) { Email::Receiver.new(big5) }
it "processes correctly" do
I18n.expects(:t).with('user_notifications.previous_discussion').returns('媽!我上電視了!')
receiver.process
expect(receiver.body).to eq("媽!我上電視了!")
end
end
describe "via" do
let(:wrote) { File.read("#{Rails.root}/spec/fixtures/emails/via_line.eml") }
let(:receiver) { Email::Receiver.new(wrote) }
it "removes via lines if we know them" do
receiver.process
expect(receiver.body).to eq("Hello this email has content!")
end
end
describe "if wrote is on a second line" do
let(:wrote) { File.read("#{Rails.root}/spec/fixtures/emails/multiline_wrote.eml") }
let(:receiver) { Email::Receiver.new(wrote) }
it "processes correctly" do
receiver.process
expect(receiver.body).to eq("Thanks!")
end
end
describe "remove previous discussion" do
let(:previous) { File.read("#{Rails.root}/spec/fixtures/emails/previous.eml") }
let(:receiver) { Email::Receiver.new(previous) }
it "processes correctly" do
receiver.process
expect(receiver.body).to eq("This will not include the previous discussion that is present in this email.")
end
end
describe "multiple paragraphs" do
let(:paragraphs) { File.read("#{Rails.root}/spec/fixtures/emails/paragraphs.eml") }
let(:receiver) { Email::Receiver.new(paragraphs) }
it "processes correctly" do
receiver.process
expect(receiver.body).to eq(
"Is there any reason the *old* candy can't be be kept in silos while the new candy
is imported into *new* silos?
The thing about candy is it stays delicious for a long time -- we can just keep
it there without worrying about it too much, imo.
Thanks for listening.")
end
end
describe "with a valid email" do
let(:reply_key) { "59d8df8370b7e95c5a49fbf86aeb2c93" }
let(:valid_reply) { File.read("#{Rails.root}/spec/fixtures/emails/valid_reply.eml") }
let(:receiver) { Email::Receiver.new(valid_reply) }
let(:post) { Fabricate.build(:post) }
let(:user) { Fabricate.build(:user) }
let(:email_log) { EmailLog.new(reply_key: reply_key, post_id: 1234, topic_id: 4567, user_id: 6677, post: post, user: user ) }
let(:reply_body) {
"I could not disagree more. I am obviously biased but adventure time is the
greatest show ever created. Everyone should watch it.
- Jake out" }
describe "email with non-existant email log" do
before do
EmailLog.expects(:for).returns(nil)
end
let!(:result) { receiver.process }
it "returns missing" do
expect(result).to eq(Email::Receiver.results[:missing])
end
end
describe "with an email log" do
before do
EmailLog.expects(:for).with(reply_key).returns(email_log)
creator = mock
PostCreator.expects(:new).with(instance_of(User),
has_entries(raw: reply_body,
cooking_options: {traditional_markdown_linebreaks: true}))
.returns(creator)
creator.expects(:create)
end
let!(:result) { receiver.process }
it "returns a processed result" do
expect(result).to eq(Email::Receiver.results[:processed])
end
it "extracts the body" do
expect(receiver.body).to eq(reply_body)
end
it "looks up the email log" do
expect(receiver.email_log).to eq(email_log)
end
it "extracts the key" do
expect(receiver.reply_key).to eq(reply_key)
end
end
end
describe "processes a valid incoming email" do
before do
SiteSetting.stubs(:email_in_address).returns("discourse-in@appmail.adventuretime.ooo")
SiteSetting.stubs(:email_in_category).returns("42")
SiteSetting.stubs(:email_in).returns(true)
end
let(:incoming_email) { File.read("#{Rails.root}/spec/fixtures/emails/valid_incoming.eml") }
let(:receiver) { Email::Receiver.new(incoming_email) }
let(:user) { Fabricate.build(:user, id: 3456) }
let(:subject) { "We should have a post-by-email-feature." }
let(:email_body) {
"Hey folks,
I was thinking. Wouldn't it be great if we could post topics via email? Yes it would!
Jakie" }
describe "email from non user" do
before do
User.expects(:find_by_email).returns(nil)
end
let!(:result) { receiver.process }
it "returns unprocessable" do
expect(result).to eq(Email::Receiver.results[:unprocessable])
end
end
describe "email from untrusted user" do
before do
User.expects(:find_by_email).with(
"jake@adventuretime.ooo").returns(user)
SiteSetting.stubs(:email_in_min_trust).returns(TrustLevel.levels[:elder].to_s)
end
let!(:result) { receiver.process }
it "returns unprocessable" do
expect(result).to eq(Email::Receiver.results[:unprocessable])
end
end
describe "with proper user" do
before do
SiteSetting.stubs(:email_in_min_trust).returns(TrustLevel.levels[:newuser].to_s)
User.expects(:find_by_email).with(
"jake@adventuretime.ooo").returns(user)
topic_creator = mock()
TopicCreator.expects(:new).with(instance_of(User),
instance_of(Guardian),
has_entries(title: subject,
category: 42))
.returns(topic_creator)
topic_creator.expects(:create).returns(topic_creator)
topic_creator.expects(:id).twice.returns(12345)
post_creator = mock
PostCreator.expects(:new).with(instance_of(User),
has_entries(raw: email_body,
topic_id: 12345,
cooking_options: {traditional_markdown_linebreaks: true}))
.returns(post_creator)
post_creator.expects(:create)
EmailLog.expects(:create).with(has_entries(
email_type: 'topic_via_incoming_email',
to_address: "discourse-in@appmail.adventuretime.ooo",
user_id: 3456,
topic_id: 12345
))
end
let!(:result) { receiver.process }
it "returns a processed result" do
expect(result).to eq(Email::Receiver.results[:processed])
end
it "extracts the body" do
expect(receiver.body).to eq(email_body)
end
end
end
end