gitlab-org--gitlab-foss/spec/lib/gitlab/email/receiver_spec.rb
Lin Jen-Shin 6cfd028278 Implement #3243 New Issue by email
So we extend Gitlab::Email::Receiver for this new behaviour,
however we might want to split it into another class for better
testing it.

Another issue is that, currently it's using this to parse project
identifier:

    Gitlab::IncomingEmail.key_from_address

Which is using:

    Gitlab.config.incoming_email.address

for the receiver name. This is probably `reply` because it's used
for replying to a specific issue. We might want to introduce another
config for this, or just use `reply` instead of `incoming`.

I'll prefer to introduce a new config for this, or just change
`reply` to `incoming` because it would make sense for replying to
there, too.

The email template used in tests were copied and modified from:
`emails/valid_reply.eml` which I hope is ok.
2016-05-16 21:27:16 +00:00

206 lines
6.2 KiB
Ruby

require "spec_helper"
describe Gitlab::Email::Receiver, lib: true do
before do
stub_incoming_email_setting(enabled: true, address: "reply+%{key}@appmail.adventuretime.ooo")
stub_config_setting(host: 'localhost')
end
let(:reply_key) { "59d8df8370b7e95c5a49fbf86aeb2c93" }
let(:email_raw) { fixture_file('emails/valid_reply.eml') }
let(:project) { create(:project, :public) }
let(:noteable) { create(:issue, project: project) }
let(:user) { create(:user) }
let!(:sent_notification) { SentNotification.record(noteable, user.id, reply_key) }
let(:receiver) { described_class.new(email_raw) }
let(:markdown) { "![image](uploads/image.png)" }
def setup_attachment
allow_any_instance_of(Gitlab::Email::AttachmentUploader).to receive(:execute).and_return(
[
{
url: "uploads/image.png",
is_image: true,
alt: "image",
markdown: markdown
}
]
)
end
context "when the recipient address doesn't include a reply key" do
let(:email_raw) { fixture_file('emails/valid_reply.eml').gsub(reply_key, "") }
it "raises a SentNotificationNotFoundError" do
expect { receiver.execute }.to raise_error(Gitlab::Email::Receiver::SentNotificationNotFoundError)
end
end
context "when no sent notification for the reply key could be found" do
let(:email_raw) { fixture_file('emails/wrong_reply_key.eml') }
it "raises a SentNotificationNotFoundError" do
expect { receiver.execute }.to raise_error(Gitlab::Email::Receiver::SentNotificationNotFoundError)
end
end
context "when the email is blank" do
let(:email_raw) { "" }
it "raises an EmptyEmailError" do
expect { receiver.execute }.to raise_error(Gitlab::Email::Receiver::EmptyEmailError)
end
end
context "when the email was auto generated" do
let!(:reply_key) { '636ca428858779856c226bb145ef4fad' }
let!(:email_raw) { fixture_file("emails/auto_reply.eml") }
it "raises an AutoGeneratedEmailError" do
expect { receiver.execute }.to raise_error(Gitlab::Email::Receiver::AutoGeneratedEmailError)
end
end
context "when the user could not be found" do
before do
user.destroy
end
it "raises a UserNotFoundError" do
expect { receiver.execute }.to raise_error(Gitlab::Email::Receiver::UserNotFoundError)
end
end
context "when the user has been blocked" do
before do
user.block
end
it "raises a UserBlockedError" do
expect { receiver.execute }.to raise_error(Gitlab::Email::Receiver::UserBlockedError)
end
end
context "when the user is not authorized to create a note" do
before do
project.update_attribute(:visibility_level, Project::PRIVATE)
end
it "raises a UserNotAuthorizedError" do
expect { receiver.execute }.to raise_error(Gitlab::Email::Receiver::UserNotAuthorizedError)
end
end
context "when the noteable could not be found" do
before do
noteable.destroy
end
it "raises a NoteableNotFoundError" do
expect { receiver.execute }.to raise_error(Gitlab::Email::Receiver::NoteableNotFoundError)
end
end
context "when the reply is blank" do
let!(:email_raw) { fixture_file("emails/no_content_reply.eml") }
it "raises an EmptyEmailError" do
expect { receiver.execute }.to raise_error(Gitlab::Email::Receiver::EmptyEmailError)
end
end
context "when the note could not be saved" do
before do
allow_any_instance_of(Note).to receive(:persisted?).and_return(false)
end
it "raises an InvalidNoteError" do
expect { receiver.execute }.to raise_error(Gitlab::Email::Receiver::InvalidNoteError)
end
end
context "when everything is fine" do
before do
setup_attachment
end
it "creates a comment" do
expect { receiver.execute }.to change { noteable.notes.count }.by(1)
note = noteable.notes.last
expect(note.author).to eq(sent_notification.recipient)
expect(note.note).to include("I could not disagree more.")
end
it "adds all attachments" do
receiver.execute
note = noteable.notes.last
expect(note.note).to include(markdown)
end
context 'when sub-addressing is not supported' do
before do
stub_incoming_email_setting(enabled: true, address: nil)
end
shared_examples 'an email that contains a reply key' do |header|
it "fetches the reply key from the #{header} header and creates a comment" do
expect { receiver.execute }.to change { noteable.notes.count }.by(1)
note = noteable.notes.last
expect(note.author).to eq(sent_notification.recipient)
expect(note.note).to include('I could not disagree more.')
end
end
context 'reply key is in the References header' do
let(:email_raw) { fixture_file('emails/reply_without_subaddressing_and_key_inside_references.eml') }
it_behaves_like 'an email that contains a reply key', 'References'
end
end
end
context "when it's trying to create a new issue" do
before do
setup_attachment
stub_incoming_email_setting(enabled: true, address: "incoming+%{key}@appmail.adventuretime.ooo")
end
let(:sent_notification) {}
let!(:user) { create(:user, email: 'jake@adventuretime.ooo') }
let(:namespace) { create(:namespace, path: 'gitlabhq') }
let(:project) { create(:project, :public, namespace: namespace) }
let(:email_raw) { fixture_file('emails/valid_new_issue.eml') }
context "when everything is fine" do
it "creates a new issue" do
expect { receiver.execute }.to change { project.issues.count }.by(1)
issue = project.issues.last
expect(issue.author).to eq(user)
expect(issue.title).to eq('New Issue by email')
expect(issue.description).to include('reply by email')
expect(issue.description).to include(markdown)
end
end
context "something is wrong" do
context "when the issue could not be saved" do
before do
project
allow_any_instance_of(Issue).to receive(:persisted?).and_return(false)
end
it "raises an InvalidIssueError" do
expect { receiver.execute }.to raise_error(Gitlab::Email::Receiver::InvalidIssueError)
end
end
end
end
end