@@ -27,6 +27,7 class Mailer < ActionMailer::Base | |||||
27 | 'Issue-Id' => issue.id, |
|
27 | 'Issue-Id' => issue.id, | |
28 | 'Issue-Author' => issue.author.login |
|
28 | 'Issue-Author' => issue.author.login | |
29 | redmine_headers 'Issue-Assignee' => issue.assigned_to.login if issue.assigned_to |
|
29 | redmine_headers 'Issue-Assignee' => issue.assigned_to.login if issue.assigned_to | |
|
30 | message_id issue | |||
30 | recipients issue.recipients |
|
31 | recipients issue.recipients | |
31 | cc(issue.watcher_recipients - @recipients) |
|
32 | cc(issue.watcher_recipients - @recipients) | |
32 | subject "[#{issue.project.name} - #{issue.tracker.name} ##{issue.id}] (#{issue.status.name}) #{issue.subject}" |
|
33 | subject "[#{issue.project.name} - #{issue.tracker.name} ##{issue.id}] (#{issue.status.name}) #{issue.subject}" | |
@@ -40,6 +41,8 class Mailer < ActionMailer::Base | |||||
40 | 'Issue-Id' => issue.id, |
|
41 | 'Issue-Id' => issue.id, | |
41 | 'Issue-Author' => issue.author.login |
|
42 | 'Issue-Author' => issue.author.login | |
42 | redmine_headers 'Issue-Assignee' => issue.assigned_to.login if issue.assigned_to |
|
43 | redmine_headers 'Issue-Assignee' => issue.assigned_to.login if issue.assigned_to | |
|
44 | message_id journal | |||
|
45 | references issue | |||
43 | @author = journal.user |
|
46 | @author = journal.user | |
44 | recipients issue.recipients |
|
47 | recipients issue.recipients | |
45 | # Watchers in cc |
|
48 | # Watchers in cc | |
@@ -95,6 +98,7 class Mailer < ActionMailer::Base | |||||
95 |
|
98 | |||
96 | def news_added(news) |
|
99 | def news_added(news) | |
97 | redmine_headers 'Project' => news.project.identifier |
|
100 | redmine_headers 'Project' => news.project.identifier | |
|
101 | message_id news | |||
98 | recipients news.project.recipients |
|
102 | recipients news.project.recipients | |
99 | subject "[#{news.project.name}] #{l(:label_news)}: #{news.title}" |
|
103 | subject "[#{news.project.name}] #{l(:label_news)}: #{news.title}" | |
100 | body :news => news, |
|
104 | body :news => news, | |
@@ -104,6 +108,8 class Mailer < ActionMailer::Base | |||||
104 | def message_posted(message, recipients) |
|
108 | def message_posted(message, recipients) | |
105 | redmine_headers 'Project' => message.project.identifier, |
|
109 | redmine_headers 'Project' => message.project.identifier, | |
106 | 'Topic-Id' => (message.parent_id || message.id) |
|
110 | 'Topic-Id' => (message.parent_id || message.id) | |
|
111 | message_id message | |||
|
112 | references message.parent unless message.parent.nil? | |||
107 | recipients(recipients) |
|
113 | recipients(recipients) | |
108 | subject "[#{message.board.project.name} - #{message.board.name}] #{message.subject}" |
|
114 | subject "[#{message.board.project.name} - #{message.board.name}] #{message.subject}" | |
109 | body :message => message, |
|
115 | body :message => message, | |
@@ -156,7 +162,15 class Mailer < ActionMailer::Base | |||||
156 | return false if (recipients.nil? || recipients.empty?) && |
|
162 | return false if (recipients.nil? || recipients.empty?) && | |
157 | (cc.nil? || cc.empty?) && |
|
163 | (cc.nil? || cc.empty?) && | |
158 | (bcc.nil? || bcc.empty?) |
|
164 | (bcc.nil? || bcc.empty?) | |
159 | super |
|
165 | ||
|
166 | # Set Message-Id and References | |||
|
167 | if @message_id_object | |||
|
168 | mail.message_id = self.class.message_id_for(@message_id_object) | |||
|
169 | end | |||
|
170 | if @references_objects | |||
|
171 | mail.references = @references_objects.collect {|o| self.class.message_id_for(o)} | |||
|
172 | end | |||
|
173 | super(mail) | |||
160 | end |
|
174 | end | |
161 |
|
175 | |||
162 | # Sends reminders to issue assignees |
|
176 | # Sends reminders to issue assignees | |
@@ -250,4 +264,34 class Mailer < ActionMailer::Base | |||||
250 | def self.controller_path |
|
264 | def self.controller_path | |
251 | '' |
|
265 | '' | |
252 | end unless respond_to?('controller_path') |
|
266 | end unless respond_to?('controller_path') | |
|
267 | ||||
|
268 | # Returns a predictable Message-Id for the given object | |||
|
269 | def self.message_id_for(object) | |||
|
270 | # id + timestamp should reduce the odds of a collision | |||
|
271 | # as far as we don't send multiple emails for the same object | |||
|
272 | hash = "redmine.#{object.class.name.demodulize.underscore}-#{object.id}.#{object.created_on.strftime("%Y%m%d%H%M%S")}" | |||
|
273 | host = Setting.mail_from.to_s.gsub(%r{^.*@}, '') | |||
|
274 | host = "#{::Socket.gethostname}.redmine" if host.empty? | |||
|
275 | "<#{hash}@#{host}>" | |||
|
276 | end | |||
|
277 | ||||
|
278 | private | |||
|
279 | ||||
|
280 | def message_id(object) | |||
|
281 | @message_id_object = object | |||
|
282 | end | |||
|
283 | ||||
|
284 | def references(object) | |||
|
285 | @references_objects ||= [] | |||
|
286 | @references_objects << object | |||
|
287 | end | |||
|
288 | end | |||
|
289 | ||||
|
290 | # Patch TMail so that message_id is not overwritten | |||
|
291 | module TMail | |||
|
292 | class Mail | |||
|
293 | def add_message_id( fqdn = nil ) | |||
|
294 | self.message_id ||= ::TMail::new_message_id(fqdn) | |||
|
295 | end | |||
|
296 | end | |||
253 | end |
|
297 | end |
@@ -30,7 +30,7 messages_003: | |||||
30 | replies_count: 0 |
|
30 | replies_count: 0 | |
31 | last_reply_id: |
|
31 | last_reply_id: | |
32 | content: "An other reply" |
|
32 | content: "An other reply" | |
33 | author_id: |
|
33 | author_id: 2 | |
34 | parent_id: 1 |
|
34 | parent_id: 1 | |
35 | board_id: 1 |
|
35 | board_id: 1 | |
36 | messages_004: |
|
36 | messages_004: |
@@ -95,7 +95,45 class MailerTest < Test::Unit::TestCase | |||||
95 | assert !mail.body.include?('<a href="https://mydomain.foo/issues/show/1">Bug #1: Can\'t print recipes</a>') |
|
95 | assert !mail.body.include?('<a href="https://mydomain.foo/issues/show/1">Bug #1: Can\'t print recipes</a>') | |
96 | end |
|
96 | end | |
97 |
|
97 | |||
98 |
|
98 | def test_issue_add_message_id | ||
|
99 | ActionMailer::Base.deliveries.clear | |||
|
100 | issue = Issue.find(1) | |||
|
101 | Mailer.deliver_issue_add(issue) | |||
|
102 | mail = ActionMailer::Base.deliveries.last | |||
|
103 | assert_not_nil mail | |||
|
104 | assert_equal Mailer.message_id_for(issue), mail.message_id | |||
|
105 | assert_nil mail.references | |||
|
106 | end | |||
|
107 | ||||
|
108 | def test_issue_edit_message_id | |||
|
109 | ActionMailer::Base.deliveries.clear | |||
|
110 | journal = Journal.find(1) | |||
|
111 | Mailer.deliver_issue_edit(journal) | |||
|
112 | mail = ActionMailer::Base.deliveries.last | |||
|
113 | assert_not_nil mail | |||
|
114 | assert_equal Mailer.message_id_for(journal), mail.message_id | |||
|
115 | assert_equal Mailer.message_id_for(journal.issue), mail.references.to_s | |||
|
116 | end | |||
|
117 | ||||
|
118 | def test_message_posted_message_id | |||
|
119 | ActionMailer::Base.deliveries.clear | |||
|
120 | message = Message.find(1) | |||
|
121 | Mailer.deliver_message_posted(message, message.author.mail) | |||
|
122 | mail = ActionMailer::Base.deliveries.last | |||
|
123 | assert_not_nil mail | |||
|
124 | assert_equal Mailer.message_id_for(message), mail.message_id | |||
|
125 | assert_nil mail.references | |||
|
126 | end | |||
|
127 | ||||
|
128 | def test_reply_posted_message_id | |||
|
129 | ActionMailer::Base.deliveries.clear | |||
|
130 | message = Message.find(3) | |||
|
131 | Mailer.deliver_message_posted(message, message.author.mail) | |||
|
132 | mail = ActionMailer::Base.deliveries.last | |||
|
133 | assert_not_nil mail | |||
|
134 | assert_equal Mailer.message_id_for(message), mail.message_id | |||
|
135 | assert_equal Mailer.message_id_for(message.parent), mail.references.to_s | |||
|
136 | end | |||
99 |
|
137 | |||
100 | # test mailer methods for each language |
|
138 | # test mailer methods for each language | |
101 | def test_issue_add |
|
139 | def test_issue_add |
General Comments 0
You need to be logged in to leave comments.
Login now