6cfd028278
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.
206 lines
6.2 KiB
Ruby
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
|