Patch #1616 » feature_277_mailing_list_forum_integration_with_test_fixtures.diff
| test/unit/mail_handler_test.rb (working copy) | ||
|---|---|---|
| 26 | 26 |
:trackers, |
| 27 | 27 |
:projects_trackers, |
| 28 | 28 |
:enumerations, |
| 29 |
:issue_categories |
|
| 29 |
:issue_categories, |
|
| 30 |
:boards |
|
| 30 | 31 |
|
| 31 | 32 |
FIXTURES_PATH = File.dirname(__FILE__) + '/../fixtures/mail_handler' |
| 32 | 33 |
|
| ... | ... | |
| 97 | 98 |
assert_equal Issue.find(2), journal.journalized |
| 98 | 99 |
assert_equal 'This is reply', journal.notes |
| 99 | 100 |
end |
| 101 |
|
|
| 102 |
def test_add_forum_message |
|
| 103 |
# This email subject contains: [eCookbook - Discussion] A new message on a forum |
|
| 104 |
message = submit_email('message_on_given_project.eml')
|
|
| 105 |
assert message.is_a?(Message) |
|
| 106 |
assert !message.new_record? |
|
| 107 |
message.reload |
|
| 108 |
assert_equal 'A new message on a forum', message.subject |
|
| 109 |
assert_equal User.find_by_login('jsmith'), message.author
|
|
| 110 |
assert_equal Board.find(2), message.board |
|
| 111 |
assert message.content.include?('Lorem ipsum dolor sit amet, consectetuer adipiscing elit.')
|
|
| 112 |
end |
|
| 113 |
|
|
| 114 |
def test_add_forum_message_reply |
|
| 115 |
# This email subject contains: Re: [eCookbook - Help] First post |
|
| 116 |
message = submit_email('message_reply.eml')
|
|
| 117 |
assert message.is_a?(Message) |
|
| 118 |
assert !message.new_record? |
|
| 119 |
message.reload |
|
| 120 |
assert_equal 'Re: First post', message.subject |
|
| 121 |
assert_equal User.find_by_login('jsmith'), message.author
|
|
| 122 |
assert_equal Board.find(1), message.board |
|
| 123 |
assert_equal Message.find(1).id, message.parent_id |
|
| 124 |
assert message.content.include?('Lorem ipsum dolor sit amet, consectetuer adipiscing elit.')
|
|
| 125 |
end |
|
| 126 |
|
|
| 127 |
def test_reject_invalid_message_project |
|
| 128 |
# This email subject contains: [Bad Project Name - Discussion] |
|
| 129 |
message = submit_email('message_invalid_project.eml')
|
|
| 130 |
assert !message |
|
| 131 |
end |
|
| 132 |
|
|
| 133 |
def test_reject_invalid_message_board |
|
| 134 |
# This email subject contains: [eCookbook - Invalid Board Name] |
|
| 135 |
message = submit_email('message_invalid_board.eml')
|
|
| 136 |
assert !message |
|
| 137 |
end |
|
| 138 |
|
|
| 139 |
def test_reject_invalid_user_email |
|
| 140 |
# This email is from: not_a_valid_user_email@somenet.foo |
|
| 141 |
message = submit_email('message_invalid_user_email.eml')
|
|
| 142 |
assert !message |
|
| 143 |
end |
|
| 100 | 144 | |
| 145 |
def test_reject_unsupported_email |
|
| 146 |
# This email is from a valid user but has no content for an issue or message |
|
| 147 |
message = submit_email('unsupported_email.eml')
|
|
| 148 |
assert !message |
|
| 149 |
end |
|
| 150 |
|
|
| 101 | 151 |
private |
| 102 | 152 |
|
| 103 | 153 |
def submit_email(filename, options={})
|
| test/fixtures/mail_handler/message_on_given_project.eml (revision 0) | ||
|---|---|---|
| 1 |
Return-Path: <jsmith@somenet.foo> |
|
| 2 |
Received: from osiris ([127.0.0.1]) |
|
| 3 |
by OSIRIS |
|
| 4 |
with hMailServer ; Sun, 22 Jun 2008 12:28:07 +0200 |
|
| 5 |
Message-ID: <000501c8d452$a95cd7e0$0a00a8c0@osiris> |
|
| 6 |
From: "John Smith" <jsmith@somenet.foo> |
|
| 7 |
To: <redmine@somenet.foo> |
|
| 8 |
Subject: [eCookbook - Discussion] A new message on a forum |
|
| 9 |
Date: Sun, 22 Jun 2008 12:28:07 +0200 |
|
| 10 |
MIME-Version: 1.0 |
|
| 11 |
Content-Type: text/plain; |
|
| 12 |
format=flowed; |
|
| 13 |
charset="iso-8859-1"; |
|
| 14 |
reply-type=original |
|
| 15 |
Content-Transfer-Encoding: 7bit |
|
| 16 |
X-Priority: 3 |
|
| 17 |
X-MSMail-Priority: Normal |
|
| 18 |
X-Mailer: Microsoft Outlook Express 6.00.2900.2869 |
|
| 19 |
X-MimeOLE: Produced By Microsoft MimeOLE V6.00.2900.2869 |
|
| 20 |
|
|
| 21 |
Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Maecenas imperdiet |
|
| 22 |
turpis et odio. Integer eget pede vel dolor euismod varius. Phasellus |
|
| 23 |
blandit eleifend augue. Nulla facilisi. Duis id diam. Class aptent taciti |
|
| 24 |
sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. In |
|
| 25 |
in urna sed tellus aliquet lobortis. Morbi scelerisque tortor in dolor. Cras |
|
| 26 |
sagittis odio eu lacus. Aliquam sem tortor, consequat sit amet, vestibulum |
|
| 27 |
id, iaculis at, lectus. Fusce tortor libero, congue ut, euismod nec, luctus |
|
| 28 |
eget, eros. Pellentesque tortor enim, feugiat in, dignissim eget, tristique |
|
| 29 |
sed, mauris. Pellentesque habitant morbi tristique senectus et netus et |
|
| 30 |
malesuada fames ac turpis egestas. Quisque sit amet libero. In hac habitasse |
|
| 31 |
platea dictumst. |
|
| test/fixtures/mail_handler/message_invalid_user_email.eml (revision 0) | ||
|---|---|---|
| 1 |
Return-Path: <not_a_valid_user_email@somenet.foo> |
|
| 2 |
Received: from osiris ([127.0.0.1]) |
|
| 3 |
by OSIRIS |
|
| 4 |
with hMailServer ; Sun, 28 Jun 2008 09:28:07 +0200 |
|
| 5 |
Message-ID: <000501c8d452$a95cd7e0$0a00a8c0@osiris> |
|
| 6 |
From: "John Doe" <not_a_valid_user_email@somenet.foo> |
|
| 7 |
To: <redmine@somenet.foo> |
|
| 8 |
Subject: [eCookbook - Discussion] Message from an unauthorized user |
|
| 9 |
Date: Sun, 28 Jun 2008 09:28:07 +0200 |
|
| 10 |
MIME-Version: 1.0 |
|
| 11 |
Content-Type: text/plain; |
|
| 12 |
format=flowed; |
|
| 13 |
charset="iso-8859-1"; |
|
| 14 |
reply-type=original |
|
| 15 |
Content-Transfer-Encoding: 7bit |
|
| 16 |
X-Priority: 3 |
|
| 17 |
X-MSMail-Priority: Normal |
|
| 18 |
X-Mailer: Microsoft Outlook Express 6.00.2900.2869 |
|
| 19 |
X-MimeOLE: Produced By Microsoft MimeOLE V6.00.2900.2869 |
|
| 20 |
|
|
| 21 |
Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Maecenas imperdiet |
|
| 22 |
turpis et odio. Integer eget pede vel dolor euismod varius. Phasellus |
|
| 23 |
blandit eleifend augue. Nulla facilisi. Duis id diam. Class aptent taciti |
|
| 24 |
sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. In |
|
| 25 |
in urna sed tellus aliquet lobortis. |
|
| test/fixtures/mail_handler/message_reply.eml (revision 0) | ||
|---|---|---|
| 1 |
Return-Path: <jsmith@somenet.foo> |
|
| 2 |
Received: from osiris ([127.0.0.1]) |
|
| 3 |
by OSIRIS |
|
| 4 |
with hMailServer ; Sun, 22 Jun 2008 12:28:07 +0200 |
|
| 5 |
Message-ID: <000501c8d452$a95cd7e0$0a00a8c0@osiris> |
|
| 6 |
From: "John Smith" <jsmith@somenet.foo> |
|
| 7 |
To: <redmine@somenet.foo> |
|
| 8 |
Subject: Re: [eCookbook - Help] First post |
|
| 9 |
Date: Mon, 7 Jun 2008 10:28:07 +0200 |
|
| 10 |
MIME-Version: 1.0 |
|
| 11 |
Content-Type: text/plain; |
|
| 12 |
format=flowed; |
|
| 13 |
charset="iso-8859-1"; |
|
| 14 |
reply-type=original |
|
| 15 |
Content-Transfer-Encoding: 7bit |
|
| 16 |
X-Priority: 3 |
|
| 17 |
X-MSMail-Priority: Normal |
|
| 18 |
X-Mailer: Microsoft Outlook Express 6.00.2900.2869 |
|
| 19 |
X-MimeOLE: Produced By Microsoft MimeOLE V6.00.2900.2869 |
|
| 20 |
|
|
| 21 |
Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Maecenas imperdiet |
|
| 22 |
turpis et odio. Integer eget pede vel dolor euismod varius. Phasellus |
|
| 23 |
blandit eleifend augue. Nulla facilisi. Duis id diam. Class aptent taciti |
|
| 24 |
sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. In |
|
| 25 |
in urna sed tellus aliquet lobortis. Morbi scelerisque tortor in dolor. Cras |
|
| 26 |
sagittis odio eu lacus. Aliquam sem tortor, consequat sit amet, vestibulum |
|
| 27 |
id, iaculis at, lectus. Fusce tortor libero, congue ut, euismod nec, luctus |
|
| 28 |
eget, eros. Pellentesque tortor enim, feugiat in, dignissim eget, tristique |
|
| 29 |
sed, mauris. Pellentesque habitant morbi tristique senectus et netus et |
|
| 30 |
malesuada fames ac turpis egestas. Quisque sit amet libero. In hac habitasse |
|
| 31 |
platea dictumst. |
|
| test/fixtures/mail_handler/unsupported_email.eml (revision 0) | ||
|---|---|---|
| 1 |
Return-Path: <jsmith@somenet.foo> |
|
| 2 |
Received: from osiris ([127.0.0.1]) |
|
| 3 |
by OSIRIS |
|
| 4 |
with hMailServer ; Sun, 28 Jun 2008 09:28:07 +0200 |
|
| 5 |
Message-ID: <000501c8d452$a95cd7e0$0a00a8c0@osiris> |
|
| 6 |
From: "John Smith" <jsmith@somenet.foo> |
|
| 7 |
To: <redmine@somenet.foo> |
|
| 8 |
Subject: Unsupported email from valid user |
|
| 9 |
Date: Sun, 28 Jun 2008 09:28:07 +0200 |
|
| 10 |
MIME-Version: 1.0 |
|
| 11 |
Content-Type: text/plain; |
|
| 12 |
format=flowed; |
|
| 13 |
charset="iso-8859-1"; |
|
| 14 |
reply-type=original |
|
| 15 |
Content-Transfer-Encoding: 7bit |
|
| 16 |
X-Priority: 3 |
|
| 17 |
X-MSMail-Priority: Normal |
|
| 18 |
X-Mailer: Microsoft Outlook Express 6.00.2900.2869 |
|
| 19 |
X-MimeOLE: Produced By Microsoft MimeOLE V6.00.2900.2869 |
|
| 20 |
|
|
| 21 |
Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Maecenas imperdiet |
|
| 22 |
turpis et odio. Integer eget pede vel dolor euismod varius. Phasellus |
|
| 23 |
blandit eleifend augue. Nulla facilisi. Duis id diam. Class aptent taciti |
|
| 24 |
sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. In |
|
| 25 |
in urna sed tellus aliquet lobortis. |
|
| test/fixtures/mail_handler/message_invalid_project.eml (revision 0) | ||
|---|---|---|
| 1 |
Return-Path: <jsmith@somenet.foo> |
|
| 2 |
Received: from osiris ([127.0.0.1]) |
|
| 3 |
by OSIRIS |
|
| 4 |
with hMailServer ; Sun, 28 Jun 2008 09:28:07 +0200 |
|
| 5 |
Message-ID: <000501c8d452$a95cd7e0$0a00a8c0@osiris> |
|
| 6 |
From: "John Smith" <jsmith@somenet.foo> |
|
| 7 |
To: <redmine@somenet.foo> |
|
| 8 |
Subject: [Bad Project Name - Discussion] Message to an invalid project |
|
| 9 |
Date: Sun, 28 Jun 2008 09:28:07 +0200 |
|
| 10 |
MIME-Version: 1.0 |
|
| 11 |
Content-Type: text/plain; |
|
| 12 |
format=flowed; |
|
| 13 |
charset="iso-8859-1"; |
|
| 14 |
reply-type=original |
|
| 15 |
Content-Transfer-Encoding: 7bit |
|
| 16 |
X-Priority: 3 |
|
| 17 |
X-MSMail-Priority: Normal |
|
| 18 |
X-Mailer: Microsoft Outlook Express 6.00.2900.2869 |
|
| 19 |
X-MimeOLE: Produced By Microsoft MimeOLE V6.00.2900.2869 |
|
| 20 |
|
|
| 21 |
Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Maecenas imperdiet |
|
| 22 |
turpis et odio. Integer eget pede vel dolor euismod varius. Phasellus |
|
| 23 |
blandit eleifend augue. Nulla facilisi. Duis id diam. Class aptent taciti |
|
| 24 |
sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. In |
|
| 25 |
in urna sed tellus aliquet lobortis. |
|
| test/fixtures/mail_handler/message_invalid_board.eml (revision 0) | ||
|---|---|---|
| 1 |
Return-Path: <jsmith@somenet.foo> |
|
| 2 |
Received: from osiris ([127.0.0.1]) |
|
| 3 |
by OSIRIS |
|
| 4 |
with hMailServer ; Sun, 28 Jun 2008 09:28:07 +0200 |
|
| 5 |
Message-ID: <000501c8d452$a95cd7e0$0a00a8c0@osiris> |
|
| 6 |
From: "John Smith" <jsmith@somenet.foo> |
|
| 7 |
To: <redmine@somenet.foo> |
|
| 8 |
Subject: [eCookbook - Invalid Board Name] Message to an invalid project |
|
| 9 |
Date: Sun, 28 Jun 2008 09:28:07 +0200 |
|
| 10 |
MIME-Version: 1.0 |
|
| 11 |
Content-Type: text/plain; |
|
| 12 |
format=flowed; |
|
| 13 |
charset="iso-8859-1"; |
|
| 14 |
reply-type=original |
|
| 15 |
Content-Transfer-Encoding: 7bit |
|
| 16 |
X-Priority: 3 |
|
| 17 |
X-MSMail-Priority: Normal |
|
| 18 |
X-Mailer: Microsoft Outlook Express 6.00.2900.2869 |
|
| 19 |
X-MimeOLE: Produced By Microsoft MimeOLE V6.00.2900.2869 |
|
| 20 |
|
|
| 21 |
Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Maecenas imperdiet |
|
| 22 |
turpis et odio. Integer eget pede vel dolor euismod varius. Phasellus |
|
| 23 |
blandit eleifend augue. Nulla facilisi. Duis id diam. Class aptent taciti |
|
| 24 |
sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. In |
|
| 25 |
in urna sed tellus aliquet lobortis. |
|
| app/models/mail_handler.rb (working copy) | ||
|---|---|---|
| 51 | 51 |
private |
| 52 | 52 | |
| 53 | 53 |
ISSUE_REPLY_SUBJECT_RE = %r{\[[^\]]+#(\d+)\]}
|
| 54 |
FORUM_MESSAGE_SUBJECT = %r{(\[.*)(#.*\])}
|
|
| 55 |
FORUM_MESSAGE_SUBJECT_RE = %r{re: }i
|
|
| 56 |
FORUM_MESSAGE_SUBJECT_SPLIT = %r{(\[)(.*)( - )(.*)(\])}
|
|
| 54 | 57 |
|
| 55 | 58 |
def dispatch |
| 56 | 59 |
if m = email.subject.match(ISSUE_REPLY_SUBJECT_RE) |
| 57 | 60 |
receive_issue_update(m[1].to_i) |
| 61 |
elsif !email.subject.match(FORUM_MESSAGE_SUBJECT) && email.subject.match(/\[/) |
|
| 62 |
if email.subject.match(FORUM_MESSAGE_SUBJECT_RE) |
|
| 63 |
receive_forum_message_reply |
|
| 64 |
else |
|
| 65 |
receive_forum_message |
|
| 66 |
end |
|
| 58 | 67 |
else |
| 59 | 68 |
receive_issue |
| 60 | 69 |
end |
| ... | ... | |
| 89 | 98 |
issue |
| 90 | 99 |
end |
| 91 | 100 |
|
| 101 |
# Creates a new forum message |
|
| 102 |
def receive_forum_message |
|
| 103 |
project = target_project |
|
| 104 |
board = target_board |
|
| 105 |
# check permission |
|
| 106 |
raise UnauthorizedAction unless user.allowed_to?(:edit_messages, project) |
|
| 107 |
message = Message.new(:author => user, :board => board) |
|
| 108 |
message.subject = email.subject.split(FORUM_MESSAGE_SUBJECT_SPLIT)[6].strip |
|
| 109 |
message.content = email.plain_text_body.chomp |
|
| 110 |
message.save! |
|
| 111 |
logger.info "MailHandler: message ##{message.id} - #{message.subject} created by #{user}" if logger && logger.info
|
|
| 112 |
#Mailer.deliver_message_posted(message) if Setting.notified_events.include?('message_posted')
|
|
| 113 |
message |
|
| 114 |
end |
|
| 115 |
|
|
| 116 |
# Creates a reply to an existing forum message |
|
| 117 |
def receive_forum_message_reply |
|
| 118 |
project = target_project |
|
| 119 |
board = target_board |
|
| 120 |
# check permission |
|
| 121 |
raise UnauthorizedAction unless user.allowed_to?(:edit_messages, project) |
|
| 122 |
message = Message.new(:author => user, :board => board) |
|
| 123 |
subject = email.subject.split(FORUM_MESSAGE_SUBJECT_SPLIT)[6].gsub(FORUM_MESSAGE_SUBJECT_RE, "").strip |
|
| 124 |
message.parent_id = Message.find(:first, |
|
| 125 |
:conditions => [ "board_id = ? AND subject = ?", |
|
| 126 |
board, subject ], |
|
| 127 |
:order => "created_on DESC").id |
|
| 128 |
message.subject = "Re: " + subject |
|
| 129 |
message.content = email.plain_text_body.chomp |
|
| 130 |
message.save! |
|
| 131 |
logger.info "MailHandler: message ##{message.id} - #{message.subject} created by #{user} in reply to message ##{message.parent_id}" if logger && logger.info
|
|
| 132 |
#Mailer.deliver_message_posted(message) if Setting.notified_events.include?('message_posted')
|
|
| 133 |
message |
|
| 134 |
end |
|
| 135 |
|
|
| 92 | 136 |
def target_project |
| 93 | 137 |
# TODO: other ways to specify project: |
| 94 | 138 |
# * parse the email To field |
| 95 | 139 |
# * specific project (eg. Setting.mail_handler_target_project) |
| 96 |
target = Project.find_by_identifier(get_keyword(:project)) |
|
| 140 |
unless target = Project.find_by_identifier(get_keyword(:project)) |
|
| 141 |
target = Project.find_by_name(email.subject.split(FORUM_MESSAGE_SUBJECT_SPLIT)[2]) |
|
| 142 |
end |
|
| 97 | 143 |
raise MissingInformation.new('Unable to determine target project') if target.nil?
|
| 98 | 144 |
target |
| 99 | 145 |
end |
| 100 | 146 |
|
| 147 |
def target_board |
|
| 148 |
target = Board.find_by_name(email.subject.split(FORUM_MESSAGE_SUBJECT_SPLIT)[4].strip) |
|
| 149 |
raise MissingInformation.new('Unable to determine target board/forum') if target.nil?
|
|
| 150 |
target |
|
| 151 |
end |
|
| 152 |
|
|
| 101 | 153 |
# Adds a note to an existing issue |
| 102 | 154 |
def receive_issue_update(issue_id) |
| 103 | 155 |
issue = Issue.find_by_id(issue_id) |
| app/models/mailer.rb (working copy) | ||
|---|---|---|
| 99 | 99 |
def message_posted(message, recipients) |
| 100 | 100 |
redmine_headers 'Project' => message.project.identifier, |
| 101 | 101 |
'Topic-Id' => (message.parent_id || message.id) |
| 102 |
from Setting.forum_mail_from unless Setting.forum_mail_from.empty? |
|
| 102 | 103 |
recipients(recipients) |
| 103 | 104 |
subject "[#{message.board.project.name} - #{message.board.name}] #{message.subject}"
|
| 104 | 105 |
body :message => message, |
| app/views/settings/_notifications.rhtml (working copy) | ||
|---|---|---|
| 5 | 5 |
<p><label><%= l(:setting_mail_from) %></label> |
| 6 | 6 |
<%= text_field_tag 'settings[mail_from]', Setting.mail_from, :size => 60 %></p> |
| 7 | 7 | |
| 8 |
<p><label><%= l(:setting_forum_mail_from) %></label> |
|
| 9 |
<%= text_field_tag 'settings[forum_mail_from]', Setting.forum_mail_from, :size => 60 %></p> |
|
| 10 | ||
| 8 | 11 |
<p><label><%= l(:setting_bcc_recipients) %></label> |
| 9 | 12 |
<%= check_box_tag 'settings[bcc_recipients]', 1, Setting.bcc_recipients? %> |
| 10 | 13 |
<%= hidden_field_tag 'settings[bcc_recipients]', 0 %></p> |
| lang/en.yml (working copy) | ||
|---|---|---|
| 192 | 192 |
setting_attachment_max_size: Attachment max. size |
| 193 | 193 |
setting_issues_export_limit: Issues export limit |
| 194 | 194 |
setting_mail_from: Emission email address |
| 195 |
setting_forum_mail_from: Forum emission email address |
|
| 195 | 196 |
setting_bcc_recipients: Blind carbon copy recipients (bcc) |
| 196 | 197 |
setting_host_name: Host name |
| 197 | 198 |
setting_text_formatting: Text formatting |
| config/settings.yml (working copy) | ||
|---|---|---|
| 44 | 44 |
default: '25,50,100' |
| 45 | 45 |
mail_from: |
| 46 | 46 |
default: redmine@somenet.foo |
| 47 |
forum_mail_from: |
|
| 48 |
default: "" |
|
| 47 | 49 |
bcc_recipients: |
| 48 | 50 |
default: 1 |
| 49 | 51 |
text_formatting: |