##// END OF EJS Templates
Backported r9687 from trunk....
Jean-Philippe Lang -
r9505:5a1be1d8df72
parent child
Show More
@@ -1,498 +1,499
1 # Redmine - project management software
1 # Redmine - project management software
2 # Copyright (C) 2006-2011 Jean-Philippe Lang
2 # Copyright (C) 2006-2011 Jean-Philippe Lang
3 #
3 #
4 # This program is free software; you can redistribute it and/or
4 # This program is free software; you can redistribute it and/or
5 # modify it under the terms of the GNU General Public License
5 # modify it under the terms of the GNU General Public License
6 # as published by the Free Software Foundation; either version 2
6 # as published by the Free Software Foundation; either version 2
7 # of the License, or (at your option) any later version.
7 # of the License, or (at your option) any later version.
8 #
8 #
9 # This program is distributed in the hope that it will be useful,
9 # This program is distributed in the hope that it will be useful,
10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 # GNU General Public License for more details.
12 # GNU General Public License for more details.
13 #
13 #
14 # You should have received a copy of the GNU General Public License
14 # You should have received a copy of the GNU General Public License
15 # along with this program; if not, write to the Free Software
15 # along with this program; if not, write to the Free Software
16 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
16 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17
17
18 class Mailer < ActionMailer::Base
18 class Mailer < ActionMailer::Base
19 layout 'mailer'
19 layout 'mailer'
20 helper :application
20 helper :application
21 helper :issues
21 helper :issues
22 helper :custom_fields
22 helper :custom_fields
23
23
24 include ActionController::UrlWriter
24 include ActionController::UrlWriter
25 include Redmine::I18n
25 include Redmine::I18n
26
26
27 def self.default_url_options
27 def self.default_url_options
28 h = Setting.host_name
28 h = Setting.host_name
29 h = h.to_s.gsub(%r{\/.*$}, '') unless Redmine::Utils.relative_url_root.blank?
29 h = h.to_s.gsub(%r{\/.*$}, '') unless Redmine::Utils.relative_url_root.blank?
30 { :host => h, :protocol => Setting.protocol }
30 { :host => h, :protocol => Setting.protocol }
31 end
31 end
32
32
33 # Builds a tmail object used to email recipients of the added issue.
33 # Builds a tmail object used to email recipients of the added issue.
34 #
34 #
35 # Example:
35 # Example:
36 # issue_add(issue) => tmail object
36 # issue_add(issue) => tmail object
37 # Mailer.deliver_issue_add(issue) => sends an email to issue recipients
37 # Mailer.deliver_issue_add(issue) => sends an email to issue recipients
38 def issue_add(issue)
38 def issue_add(issue)
39 redmine_headers 'Project' => issue.project.identifier,
39 redmine_headers 'Project' => issue.project.identifier,
40 'Issue-Id' => issue.id,
40 'Issue-Id' => issue.id,
41 'Issue-Author' => issue.author.login
41 'Issue-Author' => issue.author.login
42 redmine_headers 'Issue-Assignee' => issue.assigned_to.login if issue.assigned_to
42 redmine_headers 'Issue-Assignee' => issue.assigned_to.login if issue.assigned_to
43 message_id issue
43 message_id issue
44 @author = issue.author
44 @author = issue.author
45 recipients issue.recipients
45 recipients issue.recipients
46 cc(issue.watcher_recipients - @recipients)
46 cc(issue.watcher_recipients - @recipients)
47 subject "[#{issue.project.name} - #{issue.tracker.name} ##{issue.id}] (#{issue.status.name}) #{issue.subject}"
47 subject "[#{issue.project.name} - #{issue.tracker.name} ##{issue.id}] (#{issue.status.name}) #{issue.subject}"
48 body :issue => issue,
48 body :issue => issue,
49 :issue_url => url_for(:controller => 'issues', :action => 'show', :id => issue)
49 :issue_url => url_for(:controller => 'issues', :action => 'show', :id => issue)
50 render_multipart('issue_add', body)
50 render_multipart('issue_add', body)
51 end
51 end
52
52
53 # Builds a tmail object used to email recipients of the edited issue.
53 # Builds a tmail object used to email recipients of the edited issue.
54 #
54 #
55 # Example:
55 # Example:
56 # issue_edit(journal) => tmail object
56 # issue_edit(journal) => tmail object
57 # Mailer.deliver_issue_edit(journal) => sends an email to issue recipients
57 # Mailer.deliver_issue_edit(journal) => sends an email to issue recipients
58 def issue_edit(journal)
58 def issue_edit(journal)
59 issue = journal.journalized.reload
59 issue = journal.journalized.reload
60 redmine_headers 'Project' => issue.project.identifier,
60 redmine_headers 'Project' => issue.project.identifier,
61 'Issue-Id' => issue.id,
61 'Issue-Id' => issue.id,
62 'Issue-Author' => issue.author.login
62 'Issue-Author' => issue.author.login
63 redmine_headers 'Issue-Assignee' => issue.assigned_to.login if issue.assigned_to
63 redmine_headers 'Issue-Assignee' => issue.assigned_to.login if issue.assigned_to
64 message_id journal
64 message_id journal
65 references issue
65 references issue
66 @author = journal.user
66 @author = journal.user
67 recipients issue.recipients
67 recipients issue.recipients
68 # Watchers in cc
68 # Watchers in cc
69 cc(issue.watcher_recipients - @recipients)
69 cc(issue.watcher_recipients - @recipients)
70 s = "[#{issue.project.name} - #{issue.tracker.name} ##{issue.id}] "
70 s = "[#{issue.project.name} - #{issue.tracker.name} ##{issue.id}] "
71 s << "(#{issue.status.name}) " if journal.new_value_for('status_id')
71 s << "(#{issue.status.name}) " if journal.new_value_for('status_id')
72 s << issue.subject
72 s << issue.subject
73 subject s
73 subject s
74 body :issue => issue,
74 body :issue => issue,
75 :journal => journal,
75 :journal => journal,
76 :issue_url => url_for(:controller => 'issues', :action => 'show', :id => issue, :anchor => "change-#{journal.id}")
76 :issue_url => url_for(:controller => 'issues', :action => 'show', :id => issue, :anchor => "change-#{journal.id}")
77
77
78 render_multipart('issue_edit', body)
78 render_multipart('issue_edit', body)
79 end
79 end
80
80
81 def reminder(user, issues, days)
81 def reminder(user, issues, days)
82 set_language_if_valid user.language
82 set_language_if_valid user.language
83 recipients user.mail
83 recipients user.mail
84 subject l(:mail_subject_reminder, :count => issues.size, :days => days)
84 subject l(:mail_subject_reminder, :count => issues.size, :days => days)
85 body :issues => issues,
85 body :issues => issues,
86 :days => days,
86 :days => days,
87 :issues_url => url_for(:controller => 'issues', :action => 'index',
87 :issues_url => url_for(:controller => 'issues', :action => 'index',
88 :set_filter => 1, :assigned_to_id => user.id,
88 :set_filter => 1, :assigned_to_id => user.id,
89 :sort => 'due_date:asc')
89 :sort => 'due_date:asc')
90 render_multipart('reminder', body)
90 render_multipart('reminder', body)
91 end
91 end
92
92
93 # Builds a tmail object used to email users belonging to the added document's project.
93 # Builds a tmail object used to email users belonging to the added document's project.
94 #
94 #
95 # Example:
95 # Example:
96 # document_added(document) => tmail object
96 # document_added(document) => tmail object
97 # Mailer.deliver_document_added(document) => sends an email to the document's project recipients
97 # Mailer.deliver_document_added(document) => sends an email to the document's project recipients
98 def document_added(document)
98 def document_added(document)
99 redmine_headers 'Project' => document.project.identifier
99 redmine_headers 'Project' => document.project.identifier
100 recipients document.recipients
100 recipients document.recipients
101 @author = User.current
101 @author = User.current
102 subject "[#{document.project.name}] #{l(:label_document_new)}: #{document.title}"
102 subject "[#{document.project.name}] #{l(:label_document_new)}: #{document.title}"
103 body :document => document,
103 body :document => document,
104 :document_url => url_for(:controller => 'documents', :action => 'show', :id => document)
104 :document_url => url_for(:controller => 'documents', :action => 'show', :id => document)
105 render_multipart('document_added', body)
105 render_multipart('document_added', body)
106 end
106 end
107
107
108 # Builds a tmail object used to email recipients of a project when an attachements are added.
108 # Builds a tmail object used to email recipients of a project when an attachements are added.
109 #
109 #
110 # Example:
110 # Example:
111 # attachments_added(attachments) => tmail object
111 # attachments_added(attachments) => tmail object
112 # Mailer.deliver_attachments_added(attachments) => sends an email to the project's recipients
112 # Mailer.deliver_attachments_added(attachments) => sends an email to the project's recipients
113 def attachments_added(attachments)
113 def attachments_added(attachments)
114 container = attachments.first.container
114 container = attachments.first.container
115 added_to = ''
115 added_to = ''
116 added_to_url = ''
116 added_to_url = ''
117 @author = attachments.first.author
117 @author = attachments.first.author
118 case container.class.name
118 case container.class.name
119 when 'Project'
119 when 'Project'
120 added_to_url = url_for(:controller => 'files', :action => 'index', :project_id => container)
120 added_to_url = url_for(:controller => 'files', :action => 'index', :project_id => container)
121 added_to = "#{l(:label_project)}: #{container}"
121 added_to = "#{l(:label_project)}: #{container}"
122 recipients container.project.notified_users.select {|user| user.allowed_to?(:view_files, container.project)}.collect {|u| u.mail}
122 recipients container.project.notified_users.select {|user| user.allowed_to?(:view_files, container.project)}.collect {|u| u.mail}
123 when 'Version'
123 when 'Version'
124 added_to_url = url_for(:controller => 'files', :action => 'index', :project_id => container.project)
124 added_to_url = url_for(:controller => 'files', :action => 'index', :project_id => container.project)
125 added_to = "#{l(:label_version)}: #{container.name}"
125 added_to = "#{l(:label_version)}: #{container.name}"
126 recipients container.project.notified_users.select {|user| user.allowed_to?(:view_files, container.project)}.collect {|u| u.mail}
126 recipients container.project.notified_users.select {|user| user.allowed_to?(:view_files, container.project)}.collect {|u| u.mail}
127 when 'Document'
127 when 'Document'
128 added_to_url = url_for(:controller => 'documents', :action => 'show', :id => container.id)
128 added_to_url = url_for(:controller => 'documents', :action => 'show', :id => container.id)
129 added_to = "#{l(:label_document)}: #{container.title}"
129 added_to = "#{l(:label_document)}: #{container.title}"
130 recipients container.recipients
130 recipients container.recipients
131 end
131 end
132 redmine_headers 'Project' => container.project.identifier
132 redmine_headers 'Project' => container.project.identifier
133 subject "[#{container.project.name}] #{l(:label_attachment_new)}"
133 subject "[#{container.project.name}] #{l(:label_attachment_new)}"
134 body :attachments => attachments,
134 body :attachments => attachments,
135 :added_to => added_to,
135 :added_to => added_to,
136 :added_to_url => added_to_url
136 :added_to_url => added_to_url
137 render_multipart('attachments_added', body)
137 render_multipart('attachments_added', body)
138 end
138 end
139
139
140 # Builds a tmail object used to email recipients of a news' project when a news item is added.
140 # Builds a tmail object used to email recipients of a news' project when a news item is added.
141 #
141 #
142 # Example:
142 # Example:
143 # news_added(news) => tmail object
143 # news_added(news) => tmail object
144 # Mailer.deliver_news_added(news) => sends an email to the news' project recipients
144 # Mailer.deliver_news_added(news) => sends an email to the news' project recipients
145 def news_added(news)
145 def news_added(news)
146 redmine_headers 'Project' => news.project.identifier
146 redmine_headers 'Project' => news.project.identifier
147 @author = news.author
147 @author = news.author
148 message_id news
148 message_id news
149 recipients news.recipients
149 recipients news.recipients
150 subject "[#{news.project.name}] #{l(:label_news)}: #{news.title}"
150 subject "[#{news.project.name}] #{l(:label_news)}: #{news.title}"
151 body :news => news,
151 body :news => news,
152 :news_url => url_for(:controller => 'news', :action => 'show', :id => news)
152 :news_url => url_for(:controller => 'news', :action => 'show', :id => news)
153 render_multipart('news_added', body)
153 render_multipart('news_added', body)
154 end
154 end
155
155
156 # Builds a tmail object used to email recipients of a news' project when a news comment is added.
156 # Builds a tmail object used to email recipients of a news' project when a news comment is added.
157 #
157 #
158 # Example:
158 # Example:
159 # news_comment_added(comment) => tmail object
159 # news_comment_added(comment) => tmail object
160 # Mailer.news_comment_added(comment) => sends an email to the news' project recipients
160 # Mailer.news_comment_added(comment) => sends an email to the news' project recipients
161 def news_comment_added(comment)
161 def news_comment_added(comment)
162 news = comment.commented
162 news = comment.commented
163 redmine_headers 'Project' => news.project.identifier
163 redmine_headers 'Project' => news.project.identifier
164 @author = comment.author
164 @author = comment.author
165 message_id comment
165 message_id comment
166 recipients news.recipients
166 recipients news.recipients
167 cc news.watcher_recipients
167 cc news.watcher_recipients
168 subject "Re: [#{news.project.name}] #{l(:label_news)}: #{news.title}"
168 subject "Re: [#{news.project.name}] #{l(:label_news)}: #{news.title}"
169 body :news => news,
169 body :news => news,
170 :comment => comment,
170 :comment => comment,
171 :news_url => url_for(:controller => 'news', :action => 'show', :id => news)
171 :news_url => url_for(:controller => 'news', :action => 'show', :id => news)
172 render_multipart('news_comment_added', body)
172 render_multipart('news_comment_added', body)
173 end
173 end
174
174
175 # Builds a tmail object used to email the recipients of the specified message that was posted.
175 # Builds a tmail object used to email the recipients of the specified message that was posted.
176 #
176 #
177 # Example:
177 # Example:
178 # message_posted(message) => tmail object
178 # message_posted(message) => tmail object
179 # Mailer.deliver_message_posted(message) => sends an email to the recipients
179 # Mailer.deliver_message_posted(message) => sends an email to the recipients
180 def message_posted(message)
180 def message_posted(message)
181 redmine_headers 'Project' => message.project.identifier,
181 redmine_headers 'Project' => message.project.identifier,
182 'Topic-Id' => (message.parent_id || message.id)
182 'Topic-Id' => (message.parent_id || message.id)
183 @author = message.author
183 @author = message.author
184 message_id message
184 message_id message
185 references message.parent unless message.parent.nil?
185 references message.parent unless message.parent.nil?
186 recipients(message.recipients)
186 recipients(message.recipients)
187 cc((message.root.watcher_recipients + message.board.watcher_recipients).uniq - @recipients)
187 cc((message.root.watcher_recipients + message.board.watcher_recipients).uniq - @recipients)
188 subject "[#{message.board.project.name} - #{message.board.name} - msg#{message.root.id}] #{message.subject}"
188 subject "[#{message.board.project.name} - #{message.board.name} - msg#{message.root.id}] #{message.subject}"
189 body :message => message,
189 body :message => message,
190 :message_url => url_for(message.event_url)
190 :message_url => url_for(message.event_url)
191 render_multipart('message_posted', body)
191 render_multipart('message_posted', body)
192 end
192 end
193
193
194 # Builds a tmail object used to email the recipients of a project of the specified wiki content was added.
194 # Builds a tmail object used to email the recipients of a project of the specified wiki content was added.
195 #
195 #
196 # Example:
196 # Example:
197 # wiki_content_added(wiki_content) => tmail object
197 # wiki_content_added(wiki_content) => tmail object
198 # Mailer.deliver_wiki_content_added(wiki_content) => sends an email to the project's recipients
198 # Mailer.deliver_wiki_content_added(wiki_content) => sends an email to the project's recipients
199 def wiki_content_added(wiki_content)
199 def wiki_content_added(wiki_content)
200 redmine_headers 'Project' => wiki_content.project.identifier,
200 redmine_headers 'Project' => wiki_content.project.identifier,
201 'Wiki-Page-Id' => wiki_content.page.id
201 'Wiki-Page-Id' => wiki_content.page.id
202 @author = wiki_content.author
202 @author = wiki_content.author
203 message_id wiki_content
203 message_id wiki_content
204 recipients wiki_content.recipients
204 recipients wiki_content.recipients
205 cc(wiki_content.page.wiki.watcher_recipients - recipients)
205 cc(wiki_content.page.wiki.watcher_recipients - recipients)
206 subject "[#{wiki_content.project.name}] #{l(:mail_subject_wiki_content_added, :id => wiki_content.page.pretty_title)}"
206 subject "[#{wiki_content.project.name}] #{l(:mail_subject_wiki_content_added, :id => wiki_content.page.pretty_title)}"
207 body :wiki_content => wiki_content,
207 body :wiki_content => wiki_content,
208 :wiki_content_url => url_for(:controller => 'wiki', :action => 'show',
208 :wiki_content_url => url_for(:controller => 'wiki', :action => 'show',
209 :project_id => wiki_content.project,
209 :project_id => wiki_content.project,
210 :id => wiki_content.page.title)
210 :id => wiki_content.page.title)
211 render_multipart('wiki_content_added', body)
211 render_multipart('wiki_content_added', body)
212 end
212 end
213
213
214 # Builds a tmail object used to email the recipients of a project of the specified wiki content was updated.
214 # Builds a tmail object used to email the recipients of a project of the specified wiki content was updated.
215 #
215 #
216 # Example:
216 # Example:
217 # wiki_content_updated(wiki_content) => tmail object
217 # wiki_content_updated(wiki_content) => tmail object
218 # Mailer.deliver_wiki_content_updated(wiki_content) => sends an email to the project's recipients
218 # Mailer.deliver_wiki_content_updated(wiki_content) => sends an email to the project's recipients
219 def wiki_content_updated(wiki_content)
219 def wiki_content_updated(wiki_content)
220 redmine_headers 'Project' => wiki_content.project.identifier,
220 redmine_headers 'Project' => wiki_content.project.identifier,
221 'Wiki-Page-Id' => wiki_content.page.id
221 'Wiki-Page-Id' => wiki_content.page.id
222 @author = wiki_content.author
222 @author = wiki_content.author
223 message_id wiki_content
223 message_id wiki_content
224 recipients wiki_content.recipients
224 recipients wiki_content.recipients
225 cc(wiki_content.page.wiki.watcher_recipients + wiki_content.page.watcher_recipients - recipients)
225 cc(wiki_content.page.wiki.watcher_recipients + wiki_content.page.watcher_recipients - recipients)
226 subject "[#{wiki_content.project.name}] #{l(:mail_subject_wiki_content_updated, :id => wiki_content.page.pretty_title)}"
226 subject "[#{wiki_content.project.name}] #{l(:mail_subject_wiki_content_updated, :id => wiki_content.page.pretty_title)}"
227 body :wiki_content => wiki_content,
227 body :wiki_content => wiki_content,
228 :wiki_content_url => url_for(:controller => 'wiki', :action => 'show',
228 :wiki_content_url => url_for(:controller => 'wiki', :action => 'show',
229 :project_id => wiki_content.project,
229 :project_id => wiki_content.project,
230 :id => wiki_content.page.title),
230 :id => wiki_content.page.title),
231 :wiki_diff_url => url_for(:controller => 'wiki', :action => 'diff',
231 :wiki_diff_url => url_for(:controller => 'wiki', :action => 'diff',
232 :project_id => wiki_content.project, :id => wiki_content.page.title,
232 :project_id => wiki_content.project, :id => wiki_content.page.title,
233 :version => wiki_content.version)
233 :version => wiki_content.version)
234 render_multipart('wiki_content_updated', body)
234 render_multipart('wiki_content_updated', body)
235 end
235 end
236
236
237 # Builds a tmail object used to email the specified user their account information.
237 # Builds a tmail object used to email the specified user their account information.
238 #
238 #
239 # Example:
239 # Example:
240 # account_information(user, password) => tmail object
240 # account_information(user, password) => tmail object
241 # Mailer.deliver_account_information(user, password) => sends account information to the user
241 # Mailer.deliver_account_information(user, password) => sends account information to the user
242 def account_information(user, password)
242 def account_information(user, password)
243 set_language_if_valid user.language
243 set_language_if_valid user.language
244 recipients user.mail
244 recipients user.mail
245 subject l(:mail_subject_register, Setting.app_title)
245 subject l(:mail_subject_register, Setting.app_title)
246 body :user => user,
246 body :user => user,
247 :password => password,
247 :password => password,
248 :login_url => url_for(:controller => 'account', :action => 'login')
248 :login_url => url_for(:controller => 'account', :action => 'login')
249 render_multipart('account_information', body)
249 render_multipart('account_information', body)
250 end
250 end
251
251
252 # Builds a tmail object used to email all active administrators of an account activation request.
252 # Builds a tmail object used to email all active administrators of an account activation request.
253 #
253 #
254 # Example:
254 # Example:
255 # account_activation_request(user) => tmail object
255 # account_activation_request(user) => tmail object
256 # Mailer.deliver_account_activation_request(user)=> sends an email to all active administrators
256 # Mailer.deliver_account_activation_request(user)=> sends an email to all active administrators
257 def account_activation_request(user)
257 def account_activation_request(user)
258 # Send the email to all active administrators
258 # Send the email to all active administrators
259 recipients User.active.find(:all, :conditions => {:admin => true}).collect { |u| u.mail }.compact
259 recipients User.active.find(:all, :conditions => {:admin => true}).collect { |u| u.mail }.compact
260 subject l(:mail_subject_account_activation_request, Setting.app_title)
260 subject l(:mail_subject_account_activation_request, Setting.app_title)
261 body :user => user,
261 body :user => user,
262 :url => url_for(:controller => 'users', :action => 'index',
262 :url => url_for(:controller => 'users', :action => 'index',
263 :status => User::STATUS_REGISTERED,
263 :status => User::STATUS_REGISTERED,
264 :sort_key => 'created_on', :sort_order => 'desc')
264 :sort_key => 'created_on', :sort_order => 'desc')
265 render_multipart('account_activation_request', body)
265 render_multipart('account_activation_request', body)
266 end
266 end
267
267
268 # Builds a tmail object used to email the specified user that their account was activated by an administrator.
268 # Builds a tmail object used to email the specified user that their account was activated by an administrator.
269 #
269 #
270 # Example:
270 # Example:
271 # account_activated(user) => tmail object
271 # account_activated(user) => tmail object
272 # Mailer.deliver_account_activated(user) => sends an email to the registered user
272 # Mailer.deliver_account_activated(user) => sends an email to the registered user
273 def account_activated(user)
273 def account_activated(user)
274 set_language_if_valid user.language
274 set_language_if_valid user.language
275 recipients user.mail
275 recipients user.mail
276 subject l(:mail_subject_register, Setting.app_title)
276 subject l(:mail_subject_register, Setting.app_title)
277 body :user => user,
277 body :user => user,
278 :login_url => url_for(:controller => 'account', :action => 'login')
278 :login_url => url_for(:controller => 'account', :action => 'login')
279 render_multipart('account_activated', body)
279 render_multipart('account_activated', body)
280 end
280 end
281
281
282 def lost_password(token)
282 def lost_password(token)
283 set_language_if_valid(token.user.language)
283 set_language_if_valid(token.user.language)
284 recipients token.user.mail
284 recipients token.user.mail
285 subject l(:mail_subject_lost_password, Setting.app_title)
285 subject l(:mail_subject_lost_password, Setting.app_title)
286 body :token => token,
286 body :token => token,
287 :url => url_for(:controller => 'account', :action => 'lost_password', :token => token.value)
287 :url => url_for(:controller => 'account', :action => 'lost_password', :token => token.value)
288 render_multipart('lost_password', body)
288 render_multipart('lost_password', body)
289 end
289 end
290
290
291 def register(token)
291 def register(token)
292 set_language_if_valid(token.user.language)
292 set_language_if_valid(token.user.language)
293 recipients token.user.mail
293 recipients token.user.mail
294 subject l(:mail_subject_register, Setting.app_title)
294 subject l(:mail_subject_register, Setting.app_title)
295 body :token => token,
295 body :token => token,
296 :url => url_for(:controller => 'account', :action => 'activate', :token => token.value)
296 :url => url_for(:controller => 'account', :action => 'activate', :token => token.value)
297 render_multipart('register', body)
297 render_multipart('register', body)
298 end
298 end
299
299
300 def test_email(user)
300 def test_email(user)
301 set_language_if_valid(user.language)
301 set_language_if_valid(user.language)
302 recipients user.mail
302 recipients user.mail
303 subject 'Redmine test'
303 subject 'Redmine test'
304 body :url => url_for(:controller => 'welcome')
304 body :url => url_for(:controller => 'welcome')
305 render_multipart('test_email', body)
305 render_multipart('test_email', body)
306 end
306 end
307
307
308 # Overrides default deliver! method to prevent from sending an email
308 # Overrides default deliver! method to prevent from sending an email
309 # with no recipient, cc or bcc
309 # with no recipient, cc or bcc
310 def deliver!(mail = @mail)
310 def deliver!(mail = @mail)
311 set_language_if_valid @initial_language
311 set_language_if_valid @initial_language
312 return false if (recipients.nil? || recipients.empty?) &&
312 return false if (recipients.nil? || recipients.empty?) &&
313 (cc.nil? || cc.empty?) &&
313 (cc.nil? || cc.empty?) &&
314 (bcc.nil? || bcc.empty?)
314 (bcc.nil? || bcc.empty?)
315
315
316 # Set Message-Id and References
316 # Set Message-Id and References
317 if @message_id_object
317 if @message_id_object
318 mail.message_id = self.class.message_id_for(@message_id_object)
318 mail.message_id = self.class.message_id_for(@message_id_object)
319 end
319 end
320 if @references_objects
320 if @references_objects
321 mail.references = @references_objects.collect {|o| self.class.message_id_for(o)}
321 mail.references = @references_objects.collect {|o| self.class.message_id_for(o)}
322 end
322 end
323
323
324 # Log errors when raise_delivery_errors is set to false, Rails does not
324 # Log errors when raise_delivery_errors is set to false, Rails does not
325 raise_errors = self.class.raise_delivery_errors
325 raise_errors = self.class.raise_delivery_errors
326 self.class.raise_delivery_errors = true
326 self.class.raise_delivery_errors = true
327 begin
327 begin
328 return super(mail)
328 return super(mail)
329 rescue Exception => e
329 rescue Exception => e
330 if raise_errors
330 if raise_errors
331 raise e
331 raise e
332 elsif mylogger
332 elsif mylogger
333 mylogger.error "The following error occured while sending email notification: \"#{e.message}\". Check your configuration in config/configuration.yml."
333 mylogger.error "The following error occured while sending email notification: \"#{e.message}\". Check your configuration in config/configuration.yml."
334 end
334 end
335 ensure
335 ensure
336 self.class.raise_delivery_errors = raise_errors
336 self.class.raise_delivery_errors = raise_errors
337 end
337 end
338 end
338 end
339
339
340 # Sends reminders to issue assignees
340 # Sends reminders to issue assignees
341 # Available options:
341 # Available options:
342 # * :days => how many days in the future to remind about (defaults to 7)
342 # * :days => how many days in the future to remind about (defaults to 7)
343 # * :tracker => id of tracker for filtering issues (defaults to all trackers)
343 # * :tracker => id of tracker for filtering issues (defaults to all trackers)
344 # * :project => id or identifier of project to process (defaults to all projects)
344 # * :project => id or identifier of project to process (defaults to all projects)
345 # * :users => array of user ids who should be reminded
345 # * :users => array of user ids who should be reminded
346 def self.reminders(options={})
346 def self.reminders(options={})
347 days = options[:days] || 7
347 days = options[:days] || 7
348 project = options[:project] ? Project.find(options[:project]) : nil
348 project = options[:project] ? Project.find(options[:project]) : nil
349 tracker = options[:tracker] ? Tracker.find(options[:tracker]) : nil
349 tracker = options[:tracker] ? Tracker.find(options[:tracker]) : nil
350 user_ids = options[:users]
350 user_ids = options[:users]
351
351
352 scope = Issue.open.scoped(:conditions => ["#{Issue.table_name}.assigned_to_id IS NOT NULL" +
352 scope = Issue.open.scoped(:conditions => ["#{Issue.table_name}.assigned_to_id IS NOT NULL" +
353 " AND #{Project.table_name}.status = #{Project::STATUS_ACTIVE}" +
353 " AND #{Project.table_name}.status = #{Project::STATUS_ACTIVE}" +
354 " AND #{Issue.table_name}.due_date <= ?", days.day.from_now.to_date]
354 " AND #{Issue.table_name}.due_date <= ?", days.day.from_now.to_date]
355 )
355 )
356 scope = scope.scoped(:conditions => {:assigned_to_id => user_ids}) if user_ids.present?
356 scope = scope.scoped(:conditions => {:assigned_to_id => user_ids}) if user_ids.present?
357 scope = scope.scoped(:conditions => {:project_id => project.id}) if project
357 scope = scope.scoped(:conditions => {:project_id => project.id}) if project
358 scope = scope.scoped(:conditions => {:tracker_id => tracker.id}) if tracker
358 scope = scope.scoped(:conditions => {:tracker_id => tracker.id}) if tracker
359
359
360 issues_by_assignee = scope.all(:include => [:status, :assigned_to, :project, :tracker]).group_by(&:assigned_to)
360 issues_by_assignee = scope.all(:include => [:status, :assigned_to, :project, :tracker]).group_by(&:assigned_to)
361 issues_by_assignee.each do |assignee, issues|
361 issues_by_assignee.each do |assignee, issues|
362 deliver_reminder(assignee, issues, days) if assignee.is_a?(User) && assignee.active?
362 deliver_reminder(assignee, issues, days) if assignee.is_a?(User) && assignee.active?
363 end
363 end
364 end
364 end
365
365
366 # Activates/desactivates email deliveries during +block+
366 # Activates/desactivates email deliveries during +block+
367 def self.with_deliveries(enabled = true, &block)
367 def self.with_deliveries(enabled = true, &block)
368 was_enabled = ActionMailer::Base.perform_deliveries
368 was_enabled = ActionMailer::Base.perform_deliveries
369 ActionMailer::Base.perform_deliveries = !!enabled
369 ActionMailer::Base.perform_deliveries = !!enabled
370 yield
370 yield
371 ensure
371 ensure
372 ActionMailer::Base.perform_deliveries = was_enabled
372 ActionMailer::Base.perform_deliveries = was_enabled
373 end
373 end
374
374
375 # Sends emails synchronously in the given block
375 # Sends emails synchronously in the given block
376 def self.with_synched_deliveries(&block)
376 def self.with_synched_deliveries(&block)
377 saved_method = ActionMailer::Base.delivery_method
377 saved_method = ActionMailer::Base.delivery_method
378 if m = saved_method.to_s.match(%r{^async_(.+)$})
378 if m = saved_method.to_s.match(%r{^async_(.+)$})
379 ActionMailer::Base.delivery_method = m[1].to_sym
379 ActionMailer::Base.delivery_method = m[1].to_sym
380 end
380 end
381 yield
381 yield
382 ensure
382 ensure
383 ActionMailer::Base.delivery_method = saved_method
383 ActionMailer::Base.delivery_method = saved_method
384 end
384 end
385
385
386 private
386 private
387 def initialize_defaults(method_name)
387 def initialize_defaults(method_name)
388 super
388 super
389 @initial_language = current_language
389 @initial_language = current_language
390 set_language_if_valid Setting.default_language
390 set_language_if_valid Setting.default_language
391 from Setting.mail_from
391 from Setting.mail_from
392
392
393 # Common headers
393 # Common headers
394 headers 'X-Mailer' => 'Redmine',
394 headers 'X-Mailer' => 'Redmine',
395 'X-Redmine-Host' => Setting.host_name,
395 'X-Redmine-Host' => Setting.host_name,
396 'X-Redmine-Site' => Setting.app_title,
396 'X-Redmine-Site' => Setting.app_title,
397 'X-Auto-Response-Suppress' => 'OOF',
397 'X-Auto-Response-Suppress' => 'OOF',
398 'Auto-Submitted' => 'auto-generated'
398 'Auto-Submitted' => 'auto-generated',
399 'List-Id' => "<#{Setting.mail_from.to_s.gsub('@', '.')}>"
399 end
400 end
400
401
401 # Appends a Redmine header field (name is prepended with 'X-Redmine-')
402 # Appends a Redmine header field (name is prepended with 'X-Redmine-')
402 def redmine_headers(h)
403 def redmine_headers(h)
403 h.each { |k,v| headers["X-Redmine-#{k}"] = v.to_s }
404 h.each { |k,v| headers["X-Redmine-#{k}"] = v.to_s }
404 end
405 end
405
406
406 # Overrides the create_mail method
407 # Overrides the create_mail method
407 def create_mail
408 def create_mail
408 # Removes the author from the recipients and cc
409 # Removes the author from the recipients and cc
409 # if he doesn't want to receive notifications about what he does
410 # if he doesn't want to receive notifications about what he does
410 if @author && @author.logged? && @author.pref[:no_self_notified]
411 if @author && @author.logged? && @author.pref[:no_self_notified]
411 if recipients
412 if recipients
412 recipients((recipients.is_a?(Array) ? recipients : [recipients]) - [@author.mail])
413 recipients((recipients.is_a?(Array) ? recipients : [recipients]) - [@author.mail])
413 end
414 end
414 if cc
415 if cc
415 cc((cc.is_a?(Array) ? cc : [cc]) - [@author.mail])
416 cc((cc.is_a?(Array) ? cc : [cc]) - [@author.mail])
416 end
417 end
417 end
418 end
418
419
419 if @author && @author.logged?
420 if @author && @author.logged?
420 redmine_headers 'Sender' => @author.login
421 redmine_headers 'Sender' => @author.login
421 end
422 end
422
423
423 notified_users = [recipients, cc].flatten.compact.uniq
424 notified_users = [recipients, cc].flatten.compact.uniq
424 # Rails would log recipients only, not cc and bcc
425 # Rails would log recipients only, not cc and bcc
425 mylogger.info "Sending email notification to: #{notified_users.join(', ')}" if mylogger
426 mylogger.info "Sending email notification to: #{notified_users.join(', ')}" if mylogger
426
427
427 # Blind carbon copy recipients
428 # Blind carbon copy recipients
428 if Setting.bcc_recipients?
429 if Setting.bcc_recipients?
429 bcc(notified_users)
430 bcc(notified_users)
430 recipients []
431 recipients []
431 cc []
432 cc []
432 end
433 end
433 super
434 super
434 end
435 end
435
436
436 # Rails 2.3 has problems rendering implicit multipart messages with
437 # Rails 2.3 has problems rendering implicit multipart messages with
437 # layouts so this method will wrap an multipart messages with
438 # layouts so this method will wrap an multipart messages with
438 # explicit parts.
439 # explicit parts.
439 #
440 #
440 # https://rails.lighthouseapp.com/projects/8994/tickets/2338-actionmailer-mailer-views-and-content-type
441 # https://rails.lighthouseapp.com/projects/8994/tickets/2338-actionmailer-mailer-views-and-content-type
441 # https://rails.lighthouseapp.com/projects/8994/tickets/1799-actionmailer-doesnt-set-template_format-when-rendering-layouts
442 # https://rails.lighthouseapp.com/projects/8994/tickets/1799-actionmailer-doesnt-set-template_format-when-rendering-layouts
442
443
443 def render_multipart(method_name, body)
444 def render_multipart(method_name, body)
444 if Setting.plain_text_mail?
445 if Setting.plain_text_mail?
445 content_type "text/plain"
446 content_type "text/plain"
446 body render(:file => "#{method_name}.text.erb",
447 body render(:file => "#{method_name}.text.erb",
447 :body => body,
448 :body => body,
448 :layout => 'mailer.text.erb')
449 :layout => 'mailer.text.erb')
449 else
450 else
450 content_type "multipart/alternative"
451 content_type "multipart/alternative"
451 part :content_type => "text/plain",
452 part :content_type => "text/plain",
452 :body => render(:file => "#{method_name}.text.erb",
453 :body => render(:file => "#{method_name}.text.erb",
453 :body => body, :layout => 'mailer.text.erb')
454 :body => body, :layout => 'mailer.text.erb')
454 part :content_type => "text/html",
455 part :content_type => "text/html",
455 :body => render_message("#{method_name}.html.erb", body)
456 :body => render_message("#{method_name}.html.erb", body)
456 end
457 end
457 end
458 end
458
459
459 # Makes partial rendering work with Rails 1.2 (retro-compatibility)
460 # Makes partial rendering work with Rails 1.2 (retro-compatibility)
460 def self.controller_path
461 def self.controller_path
461 ''
462 ''
462 end unless respond_to?('controller_path')
463 end unless respond_to?('controller_path')
463
464
464 # Returns a predictable Message-Id for the given object
465 # Returns a predictable Message-Id for the given object
465 def self.message_id_for(object)
466 def self.message_id_for(object)
466 # id + timestamp should reduce the odds of a collision
467 # id + timestamp should reduce the odds of a collision
467 # as far as we don't send multiple emails for the same object
468 # as far as we don't send multiple emails for the same object
468 timestamp = object.send(object.respond_to?(:created_on) ? :created_on : :updated_on)
469 timestamp = object.send(object.respond_to?(:created_on) ? :created_on : :updated_on)
469 hash = "redmine.#{object.class.name.demodulize.underscore}-#{object.id}.#{timestamp.strftime("%Y%m%d%H%M%S")}"
470 hash = "redmine.#{object.class.name.demodulize.underscore}-#{object.id}.#{timestamp.strftime("%Y%m%d%H%M%S")}"
470 host = Setting.mail_from.to_s.gsub(%r{^.*@}, '')
471 host = Setting.mail_from.to_s.gsub(%r{^.*@}, '')
471 host = "#{::Socket.gethostname}.redmine" if host.empty?
472 host = "#{::Socket.gethostname}.redmine" if host.empty?
472 "<#{hash}@#{host}>"
473 "<#{hash}@#{host}>"
473 end
474 end
474
475
475 private
476 private
476
477
477 def message_id(object)
478 def message_id(object)
478 @message_id_object = object
479 @message_id_object = object
479 end
480 end
480
481
481 def references(object)
482 def references(object)
482 @references_objects ||= []
483 @references_objects ||= []
483 @references_objects << object
484 @references_objects << object
484 end
485 end
485
486
486 def mylogger
487 def mylogger
487 Rails.logger
488 Rails.logger
488 end
489 end
489 end
490 end
490
491
491 # Patch TMail so that message_id is not overwritten
492 # Patch TMail so that message_id is not overwritten
492 module TMail
493 module TMail
493 class Mail
494 class Mail
494 def add_message_id( fqdn = nil )
495 def add_message_id( fqdn = nil )
495 self.message_id ||= ::TMail::new_message_id(fqdn)
496 self.message_id ||= ::TMail::new_message_id(fqdn)
496 end
497 end
497 end
498 end
498 end
499 end
@@ -1,550 +1,551
1 # Redmine - project management software
1 # Redmine - project management software
2 # Copyright (C) 2006-2011 Jean-Philippe Lang
2 # Copyright (C) 2006-2011 Jean-Philippe Lang
3 #
3 #
4 # This program is free software; you can redistribute it and/or
4 # This program is free software; you can redistribute it and/or
5 # modify it under the terms of the GNU General Public License
5 # modify it under the terms of the GNU General Public License
6 # as published by the Free Software Foundation; either version 2
6 # as published by the Free Software Foundation; either version 2
7 # of the License, or (at your option) any later version.
7 # of the License, or (at your option) any later version.
8 #
8 #
9 # This program is distributed in the hope that it will be useful,
9 # This program is distributed in the hope that it will be useful,
10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 # GNU General Public License for more details.
12 # GNU General Public License for more details.
13 #
13 #
14 # You should have received a copy of the GNU General Public License
14 # You should have received a copy of the GNU General Public License
15 # along with this program; if not, write to the Free Software
15 # along with this program; if not, write to the Free Software
16 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
16 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17
17
18 require File.expand_path('../../test_helper', __FILE__)
18 require File.expand_path('../../test_helper', __FILE__)
19
19
20 class MailerTest < ActiveSupport::TestCase
20 class MailerTest < ActiveSupport::TestCase
21 include Redmine::I18n
21 include Redmine::I18n
22 include ActionController::Assertions::SelectorAssertions
22 include ActionController::Assertions::SelectorAssertions
23 fixtures :projects, :enabled_modules, :issues, :users, :members,
23 fixtures :projects, :enabled_modules, :issues, :users, :members,
24 :member_roles, :roles, :documents, :attachments, :news,
24 :member_roles, :roles, :documents, :attachments, :news,
25 :tokens, :journals, :journal_details, :changesets, :trackers,
25 :tokens, :journals, :journal_details, :changesets, :trackers,
26 :issue_statuses, :enumerations, :messages, :boards, :repositories,
26 :issue_statuses, :enumerations, :messages, :boards, :repositories,
27 :wikis, :wiki_pages, :wiki_contents, :wiki_content_versions,
27 :wikis, :wiki_pages, :wiki_contents, :wiki_content_versions,
28 :versions,
28 :versions,
29 :comments
29 :comments
30
30
31 def setup
31 def setup
32 ActionMailer::Base.deliveries.clear
32 ActionMailer::Base.deliveries.clear
33 Setting.host_name = 'mydomain.foo'
33 Setting.host_name = 'mydomain.foo'
34 Setting.protocol = 'http'
34 Setting.protocol = 'http'
35 Setting.plain_text_mail = '0'
35 Setting.plain_text_mail = '0'
36 end
36 end
37
37
38 def test_generated_links_in_emails
38 def test_generated_links_in_emails
39 Setting.default_language = 'en'
39 Setting.default_language = 'en'
40 Setting.host_name = 'mydomain.foo'
40 Setting.host_name = 'mydomain.foo'
41 Setting.protocol = 'https'
41 Setting.protocol = 'https'
42
42
43 journal = Journal.find(3)
43 journal = Journal.find(3)
44 assert Mailer.deliver_issue_edit(journal)
44 assert Mailer.deliver_issue_edit(journal)
45
45
46 mail = last_email
46 mail = last_email
47 assert_not_nil mail
47 assert_not_nil mail
48
48
49 assert_select_email do
49 assert_select_email do
50 # link to the main ticket
50 # link to the main ticket
51 assert_select 'a[href=?]',
51 assert_select 'a[href=?]',
52 'https://mydomain.foo/issues/2#change-3',
52 'https://mydomain.foo/issues/2#change-3',
53 :text => 'Feature request #2: Add ingredients categories'
53 :text => 'Feature request #2: Add ingredients categories'
54 # link to a referenced ticket
54 # link to a referenced ticket
55 assert_select 'a[href=?][title=?]',
55 assert_select 'a[href=?][title=?]',
56 'https://mydomain.foo/issues/1',
56 'https://mydomain.foo/issues/1',
57 'Can\'t print recipes (New)',
57 'Can\'t print recipes (New)',
58 :text => '#1'
58 :text => '#1'
59 # link to a changeset
59 # link to a changeset
60 assert_select 'a[href=?][title=?]',
60 assert_select 'a[href=?][title=?]',
61 'https://mydomain.foo/projects/ecookbook/repository/revisions/2',
61 'https://mydomain.foo/projects/ecookbook/repository/revisions/2',
62 'This commit fixes #1, #2 and references #1 &amp; #3',
62 'This commit fixes #1, #2 and references #1 &amp; #3',
63 :text => 'r2'
63 :text => 'r2'
64 # link to a description diff
64 # link to a description diff
65 assert_select 'a[href=?][title=?]',
65 assert_select 'a[href=?][title=?]',
66 'https://mydomain.foo/journals/diff/3?detail_id=4',
66 'https://mydomain.foo/journals/diff/3?detail_id=4',
67 'View differences',
67 'View differences',
68 :text => 'diff'
68 :text => 'diff'
69 # link to an attachment
69 # link to an attachment
70 assert_select 'a[href=?]',
70 assert_select 'a[href=?]',
71 'https://mydomain.foo/attachments/download/4/source.rb',
71 'https://mydomain.foo/attachments/download/4/source.rb',
72 :text => 'source.rb'
72 :text => 'source.rb'
73 end
73 end
74 end
74 end
75
75
76 def test_generated_links_with_prefix
76 def test_generated_links_with_prefix
77 Setting.default_language = 'en'
77 Setting.default_language = 'en'
78 relative_url_root = Redmine::Utils.relative_url_root
78 relative_url_root = Redmine::Utils.relative_url_root
79 Setting.host_name = 'mydomain.foo/rdm'
79 Setting.host_name = 'mydomain.foo/rdm'
80 Setting.protocol = 'http'
80 Setting.protocol = 'http'
81 Redmine::Utils.relative_url_root = '/rdm'
81 Redmine::Utils.relative_url_root = '/rdm'
82
82
83 journal = Journal.find(3)
83 journal = Journal.find(3)
84 assert Mailer.deliver_issue_edit(journal)
84 assert Mailer.deliver_issue_edit(journal)
85
85
86 mail = last_email
86 mail = last_email
87 assert_not_nil mail
87 assert_not_nil mail
88
88
89 assert_select_email do
89 assert_select_email do
90 # link to the main ticket
90 # link to the main ticket
91 assert_select 'a[href=?]',
91 assert_select 'a[href=?]',
92 'http://mydomain.foo/rdm/issues/2#change-3',
92 'http://mydomain.foo/rdm/issues/2#change-3',
93 :text => 'Feature request #2: Add ingredients categories'
93 :text => 'Feature request #2: Add ingredients categories'
94 # link to a referenced ticket
94 # link to a referenced ticket
95 assert_select 'a[href=?][title=?]',
95 assert_select 'a[href=?][title=?]',
96 'http://mydomain.foo/rdm/issues/1',
96 'http://mydomain.foo/rdm/issues/1',
97 'Can\'t print recipes (New)',
97 'Can\'t print recipes (New)',
98 :text => '#1'
98 :text => '#1'
99 # link to a changeset
99 # link to a changeset
100 assert_select 'a[href=?][title=?]',
100 assert_select 'a[href=?][title=?]',
101 'http://mydomain.foo/rdm/projects/ecookbook/repository/revisions/2',
101 'http://mydomain.foo/rdm/projects/ecookbook/repository/revisions/2',
102 'This commit fixes #1, #2 and references #1 &amp; #3',
102 'This commit fixes #1, #2 and references #1 &amp; #3',
103 :text => 'r2'
103 :text => 'r2'
104 # link to a description diff
104 # link to a description diff
105 assert_select 'a[href=?][title=?]',
105 assert_select 'a[href=?][title=?]',
106 'http://mydomain.foo/rdm/journals/diff/3?detail_id=4',
106 'http://mydomain.foo/rdm/journals/diff/3?detail_id=4',
107 'View differences',
107 'View differences',
108 :text => 'diff'
108 :text => 'diff'
109 # link to an attachment
109 # link to an attachment
110 assert_select 'a[href=?]',
110 assert_select 'a[href=?]',
111 'http://mydomain.foo/rdm/attachments/download/4/source.rb',
111 'http://mydomain.foo/rdm/attachments/download/4/source.rb',
112 :text => 'source.rb'
112 :text => 'source.rb'
113 end
113 end
114 ensure
114 ensure
115 # restore it
115 # restore it
116 Redmine::Utils.relative_url_root = relative_url_root
116 Redmine::Utils.relative_url_root = relative_url_root
117 end
117 end
118
118
119 def test_generated_links_with_prefix_and_no_relative_url_root
119 def test_generated_links_with_prefix_and_no_relative_url_root
120 Setting.default_language = 'en'
120 Setting.default_language = 'en'
121 relative_url_root = Redmine::Utils.relative_url_root
121 relative_url_root = Redmine::Utils.relative_url_root
122 Setting.host_name = 'mydomain.foo/rdm'
122 Setting.host_name = 'mydomain.foo/rdm'
123 Setting.protocol = 'http'
123 Setting.protocol = 'http'
124 Redmine::Utils.relative_url_root = nil
124 Redmine::Utils.relative_url_root = nil
125
125
126 journal = Journal.find(3)
126 journal = Journal.find(3)
127 assert Mailer.deliver_issue_edit(journal)
127 assert Mailer.deliver_issue_edit(journal)
128
128
129 mail = last_email
129 mail = last_email
130 assert_not_nil mail
130 assert_not_nil mail
131
131
132 assert_select_email do
132 assert_select_email do
133 # link to the main ticket
133 # link to the main ticket
134 assert_select 'a[href=?]',
134 assert_select 'a[href=?]',
135 'http://mydomain.foo/rdm/issues/2#change-3',
135 'http://mydomain.foo/rdm/issues/2#change-3',
136 :text => 'Feature request #2: Add ingredients categories'
136 :text => 'Feature request #2: Add ingredients categories'
137 # link to a referenced ticket
137 # link to a referenced ticket
138 assert_select 'a[href=?][title=?]',
138 assert_select 'a[href=?][title=?]',
139 'http://mydomain.foo/rdm/issues/1',
139 'http://mydomain.foo/rdm/issues/1',
140 'Can\'t print recipes (New)',
140 'Can\'t print recipes (New)',
141 :text => '#1'
141 :text => '#1'
142 # link to a changeset
142 # link to a changeset
143 assert_select 'a[href=?][title=?]',
143 assert_select 'a[href=?][title=?]',
144 'http://mydomain.foo/rdm/projects/ecookbook/repository/revisions/2',
144 'http://mydomain.foo/rdm/projects/ecookbook/repository/revisions/2',
145 'This commit fixes #1, #2 and references #1 &amp; #3',
145 'This commit fixes #1, #2 and references #1 &amp; #3',
146 :text => 'r2'
146 :text => 'r2'
147 # link to a description diff
147 # link to a description diff
148 assert_select 'a[href=?][title=?]',
148 assert_select 'a[href=?][title=?]',
149 'http://mydomain.foo/rdm/journals/diff/3?detail_id=4',
149 'http://mydomain.foo/rdm/journals/diff/3?detail_id=4',
150 'View differences',
150 'View differences',
151 :text => 'diff'
151 :text => 'diff'
152 # link to an attachment
152 # link to an attachment
153 assert_select 'a[href=?]',
153 assert_select 'a[href=?]',
154 'http://mydomain.foo/rdm/attachments/download/4/source.rb',
154 'http://mydomain.foo/rdm/attachments/download/4/source.rb',
155 :text => 'source.rb'
155 :text => 'source.rb'
156 end
156 end
157 ensure
157 ensure
158 # restore it
158 # restore it
159 Redmine::Utils.relative_url_root = relative_url_root
159 Redmine::Utils.relative_url_root = relative_url_root
160 end
160 end
161
161
162 def test_email_headers
162 def test_email_headers
163 issue = Issue.find(1)
163 issue = Issue.find(1)
164 Mailer.deliver_issue_add(issue)
164 Mailer.deliver_issue_add(issue)
165 mail = last_email
165 mail = last_email
166 assert_not_nil mail
166 assert_not_nil mail
167 assert_equal 'OOF', mail.header_string('X-Auto-Response-Suppress')
167 assert_equal 'OOF', mail.header_string('X-Auto-Response-Suppress')
168 assert_equal 'auto-generated', mail.header_string('Auto-Submitted')
168 assert_equal 'auto-generated', mail.header_string('Auto-Submitted')
169 assert_equal '<redmine.example.net>', mail.header_string('List-Id')
169 end
170 end
170
171
171 def test_email_headers_should_include_sender
172 def test_email_headers_should_include_sender
172 issue = Issue.find(1)
173 issue = Issue.find(1)
173 Mailer.deliver_issue_add(issue)
174 Mailer.deliver_issue_add(issue)
174 mail = last_email
175 mail = last_email
175 assert_equal issue.author.login, mail.header_string('X-Redmine-Sender')
176 assert_equal issue.author.login, mail.header_string('X-Redmine-Sender')
176 end
177 end
177
178
178 def test_plain_text_mail
179 def test_plain_text_mail
179 Setting.plain_text_mail = 1
180 Setting.plain_text_mail = 1
180 journal = Journal.find(2)
181 journal = Journal.find(2)
181 Mailer.deliver_issue_edit(journal)
182 Mailer.deliver_issue_edit(journal)
182 mail = last_email
183 mail = last_email
183 assert_equal "text/plain", mail.content_type
184 assert_equal "text/plain", mail.content_type
184 assert_equal 0, mail.parts.size
185 assert_equal 0, mail.parts.size
185 assert !mail.encoded.include?('href')
186 assert !mail.encoded.include?('href')
186 end
187 end
187
188
188 def test_html_mail
189 def test_html_mail
189 Setting.plain_text_mail = 0
190 Setting.plain_text_mail = 0
190 journal = Journal.find(2)
191 journal = Journal.find(2)
191 Mailer.deliver_issue_edit(journal)
192 Mailer.deliver_issue_edit(journal)
192 mail = last_email
193 mail = last_email
193 assert_equal 2, mail.parts.size
194 assert_equal 2, mail.parts.size
194 assert mail.encoded.include?('href')
195 assert mail.encoded.include?('href')
195 end
196 end
196
197
197 def test_from_header
198 def test_from_header
198 with_settings :mail_from => 'redmine@example.net' do
199 with_settings :mail_from => 'redmine@example.net' do
199 Mailer.deliver_test_email(User.find(1))
200 Mailer.deliver_test_email(User.find(1))
200 end
201 end
201 mail = last_email
202 mail = last_email
202 assert_equal 'redmine@example.net', mail.from_addrs.first.address
203 assert_equal 'redmine@example.net', mail.from_addrs.first.address
203 end
204 end
204
205
205 def test_from_header_with_phrase
206 def test_from_header_with_phrase
206 with_settings :mail_from => 'Redmine app <redmine@example.net>' do
207 with_settings :mail_from => 'Redmine app <redmine@example.net>' do
207 Mailer.deliver_test_email(User.find(1))
208 Mailer.deliver_test_email(User.find(1))
208 end
209 end
209 mail = last_email
210 mail = last_email
210 assert_equal 'redmine@example.net', mail.from_addrs.first.address
211 assert_equal 'redmine@example.net', mail.from_addrs.first.address
211 assert_equal 'Redmine app', mail.from_addrs.first.name
212 assert_equal 'Redmine app', mail.from_addrs.first.name
212 end
213 end
213
214
214 def test_should_not_send_email_without_recipient
215 def test_should_not_send_email_without_recipient
215 news = News.find(:first)
216 news = News.find(:first)
216 user = news.author
217 user = news.author
217 # Remove members except news author
218 # Remove members except news author
218 news.project.memberships.each {|m| m.destroy unless m.user == user}
219 news.project.memberships.each {|m| m.destroy unless m.user == user}
219
220
220 user.pref[:no_self_notified] = false
221 user.pref[:no_self_notified] = false
221 user.pref.save
222 user.pref.save
222 User.current = user
223 User.current = user
223 Mailer.deliver_news_added(news.reload)
224 Mailer.deliver_news_added(news.reload)
224 assert_equal 1, last_email.bcc.size
225 assert_equal 1, last_email.bcc.size
225
226
226 # nobody to notify
227 # nobody to notify
227 user.pref[:no_self_notified] = true
228 user.pref[:no_self_notified] = true
228 user.pref.save
229 user.pref.save
229 User.current = user
230 User.current = user
230 ActionMailer::Base.deliveries.clear
231 ActionMailer::Base.deliveries.clear
231 Mailer.deliver_news_added(news.reload)
232 Mailer.deliver_news_added(news.reload)
232 assert ActionMailer::Base.deliveries.empty?
233 assert ActionMailer::Base.deliveries.empty?
233 end
234 end
234
235
235 def test_issue_add_message_id
236 def test_issue_add_message_id
236 issue = Issue.find(1)
237 issue = Issue.find(1)
237 Mailer.deliver_issue_add(issue)
238 Mailer.deliver_issue_add(issue)
238 mail = last_email
239 mail = last_email
239 assert_equal Mailer.message_id_for(issue), mail.message_id
240 assert_equal Mailer.message_id_for(issue), mail.message_id
240 assert_nil mail.references
241 assert_nil mail.references
241 end
242 end
242
243
243 def test_issue_edit_message_id
244 def test_issue_edit_message_id
244 journal = Journal.find(1)
245 journal = Journal.find(1)
245 Mailer.deliver_issue_edit(journal)
246 Mailer.deliver_issue_edit(journal)
246 mail = last_email
247 mail = last_email
247 assert_equal Mailer.message_id_for(journal), mail.message_id
248 assert_equal Mailer.message_id_for(journal), mail.message_id
248 assert_equal Mailer.message_id_for(journal.issue), mail.references.first.to_s
249 assert_equal Mailer.message_id_for(journal.issue), mail.references.first.to_s
249 assert_select_email do
250 assert_select_email do
250 # link to the update
251 # link to the update
251 assert_select "a[href=?]",
252 assert_select "a[href=?]",
252 "http://mydomain.foo/issues/#{journal.journalized_id}#change-#{journal.id}"
253 "http://mydomain.foo/issues/#{journal.journalized_id}#change-#{journal.id}"
253 end
254 end
254 end
255 end
255
256
256 def test_message_posted_message_id
257 def test_message_posted_message_id
257 message = Message.find(1)
258 message = Message.find(1)
258 Mailer.deliver_message_posted(message)
259 Mailer.deliver_message_posted(message)
259 mail = last_email
260 mail = last_email
260 assert_equal Mailer.message_id_for(message), mail.message_id
261 assert_equal Mailer.message_id_for(message), mail.message_id
261 assert_nil mail.references
262 assert_nil mail.references
262 assert_select_email do
263 assert_select_email do
263 # link to the message
264 # link to the message
264 assert_select "a[href=?]",
265 assert_select "a[href=?]",
265 "http://mydomain.foo/boards/#{message.board.id}/topics/#{message.id}",
266 "http://mydomain.foo/boards/#{message.board.id}/topics/#{message.id}",
266 :text => message.subject
267 :text => message.subject
267 end
268 end
268 end
269 end
269
270
270 def test_reply_posted_message_id
271 def test_reply_posted_message_id
271 message = Message.find(3)
272 message = Message.find(3)
272 Mailer.deliver_message_posted(message)
273 Mailer.deliver_message_posted(message)
273 mail = last_email
274 mail = last_email
274 assert_equal Mailer.message_id_for(message), mail.message_id
275 assert_equal Mailer.message_id_for(message), mail.message_id
275 assert_equal Mailer.message_id_for(message.parent), mail.references.first.to_s
276 assert_equal Mailer.message_id_for(message.parent), mail.references.first.to_s
276 assert_select_email do
277 assert_select_email do
277 # link to the reply
278 # link to the reply
278 assert_select "a[href=?]",
279 assert_select "a[href=?]",
279 "http://mydomain.foo/boards/#{message.board.id}/topics/#{message.root.id}?r=#{message.id}#message-#{message.id}",
280 "http://mydomain.foo/boards/#{message.board.id}/topics/#{message.root.id}?r=#{message.id}#message-#{message.id}",
280 :text => message.subject
281 :text => message.subject
281 end
282 end
282 end
283 end
283
284
284 context("#issue_add") do
285 context("#issue_add") do
285 setup do
286 setup do
286 ActionMailer::Base.deliveries.clear
287 ActionMailer::Base.deliveries.clear
287 Setting.bcc_recipients = '1'
288 Setting.bcc_recipients = '1'
288 @issue = Issue.find(1)
289 @issue = Issue.find(1)
289 end
290 end
290
291
291 should "notify project members" do
292 should "notify project members" do
292 assert Mailer.deliver_issue_add(@issue)
293 assert Mailer.deliver_issue_add(@issue)
293 assert last_email.bcc.include?('dlopper@somenet.foo')
294 assert last_email.bcc.include?('dlopper@somenet.foo')
294 end
295 end
295
296
296 should "not notify project members that are not allow to view the issue" do
297 should "not notify project members that are not allow to view the issue" do
297 Role.find(2).remove_permission!(:view_issues)
298 Role.find(2).remove_permission!(:view_issues)
298 assert Mailer.deliver_issue_add(@issue)
299 assert Mailer.deliver_issue_add(@issue)
299 assert !last_email.bcc.include?('dlopper@somenet.foo')
300 assert !last_email.bcc.include?('dlopper@somenet.foo')
300 end
301 end
301
302
302 should "notify issue watchers" do
303 should "notify issue watchers" do
303 user = User.find(9)
304 user = User.find(9)
304 # minimal email notification options
305 # minimal email notification options
305 user.pref[:no_self_notified] = '1'
306 user.pref[:no_self_notified] = '1'
306 user.pref.save
307 user.pref.save
307 user.mail_notification = false
308 user.mail_notification = false
308 user.save
309 user.save
309
310
310 Watcher.create!(:watchable => @issue, :user => user)
311 Watcher.create!(:watchable => @issue, :user => user)
311 assert Mailer.deliver_issue_add(@issue)
312 assert Mailer.deliver_issue_add(@issue)
312 assert last_email.bcc.include?(user.mail)
313 assert last_email.bcc.include?(user.mail)
313 end
314 end
314
315
315 should "not notify watchers not allowed to view the issue" do
316 should "not notify watchers not allowed to view the issue" do
316 user = User.find(9)
317 user = User.find(9)
317 Watcher.create!(:watchable => @issue, :user => user)
318 Watcher.create!(:watchable => @issue, :user => user)
318 Role.non_member.remove_permission!(:view_issues)
319 Role.non_member.remove_permission!(:view_issues)
319 assert Mailer.deliver_issue_add(@issue)
320 assert Mailer.deliver_issue_add(@issue)
320 assert !last_email.bcc.include?(user.mail)
321 assert !last_email.bcc.include?(user.mail)
321 end
322 end
322 end
323 end
323
324
324 # test mailer methods for each language
325 # test mailer methods for each language
325 def test_issue_add
326 def test_issue_add
326 issue = Issue.find(1)
327 issue = Issue.find(1)
327 valid_languages.each do |lang|
328 valid_languages.each do |lang|
328 Setting.default_language = lang.to_s
329 Setting.default_language = lang.to_s
329 assert Mailer.deliver_issue_add(issue)
330 assert Mailer.deliver_issue_add(issue)
330 end
331 end
331 end
332 end
332
333
333 def test_issue_edit
334 def test_issue_edit
334 journal = Journal.find(1)
335 journal = Journal.find(1)
335 valid_languages.each do |lang|
336 valid_languages.each do |lang|
336 Setting.default_language = lang.to_s
337 Setting.default_language = lang.to_s
337 assert Mailer.deliver_issue_edit(journal)
338 assert Mailer.deliver_issue_edit(journal)
338 end
339 end
339 end
340 end
340
341
341 def test_document_added
342 def test_document_added
342 document = Document.find(1)
343 document = Document.find(1)
343 valid_languages.each do |lang|
344 valid_languages.each do |lang|
344 Setting.default_language = lang.to_s
345 Setting.default_language = lang.to_s
345 assert Mailer.deliver_document_added(document)
346 assert Mailer.deliver_document_added(document)
346 end
347 end
347 end
348 end
348
349
349 def test_attachments_added
350 def test_attachments_added
350 attachements = [ Attachment.find_by_container_type('Document') ]
351 attachements = [ Attachment.find_by_container_type('Document') ]
351 valid_languages.each do |lang|
352 valid_languages.each do |lang|
352 Setting.default_language = lang.to_s
353 Setting.default_language = lang.to_s
353 assert Mailer.deliver_attachments_added(attachements)
354 assert Mailer.deliver_attachments_added(attachements)
354 end
355 end
355 end
356 end
356
357
357 def test_version_file_added
358 def test_version_file_added
358 attachements = [ Attachment.find_by_container_type('Version') ]
359 attachements = [ Attachment.find_by_container_type('Version') ]
359 assert Mailer.deliver_attachments_added(attachements)
360 assert Mailer.deliver_attachments_added(attachements)
360 assert_not_nil last_email.bcc
361 assert_not_nil last_email.bcc
361 assert last_email.bcc.any?
362 assert last_email.bcc.any?
362 assert_select_email do
363 assert_select_email do
363 assert_select "a[href=?]", "http://mydomain.foo/projects/ecookbook/files"
364 assert_select "a[href=?]", "http://mydomain.foo/projects/ecookbook/files"
364 end
365 end
365 end
366 end
366
367
367 def test_project_file_added
368 def test_project_file_added
368 attachements = [ Attachment.find_by_container_type('Project') ]
369 attachements = [ Attachment.find_by_container_type('Project') ]
369 assert Mailer.deliver_attachments_added(attachements)
370 assert Mailer.deliver_attachments_added(attachements)
370 assert_not_nil last_email.bcc
371 assert_not_nil last_email.bcc
371 assert last_email.bcc.any?
372 assert last_email.bcc.any?
372 assert_select_email do
373 assert_select_email do
373 assert_select "a[href=?]", "http://mydomain.foo/projects/ecookbook/files"
374 assert_select "a[href=?]", "http://mydomain.foo/projects/ecookbook/files"
374 end
375 end
375 end
376 end
376
377
377 def test_news_added
378 def test_news_added
378 news = News.find(:first)
379 news = News.find(:first)
379 valid_languages.each do |lang|
380 valid_languages.each do |lang|
380 Setting.default_language = lang.to_s
381 Setting.default_language = lang.to_s
381 assert Mailer.deliver_news_added(news)
382 assert Mailer.deliver_news_added(news)
382 end
383 end
383 end
384 end
384
385
385 def test_news_comment_added
386 def test_news_comment_added
386 comment = Comment.find(2)
387 comment = Comment.find(2)
387 valid_languages.each do |lang|
388 valid_languages.each do |lang|
388 Setting.default_language = lang.to_s
389 Setting.default_language = lang.to_s
389 assert Mailer.deliver_news_comment_added(comment)
390 assert Mailer.deliver_news_comment_added(comment)
390 end
391 end
391 end
392 end
392
393
393 def test_message_posted
394 def test_message_posted
394 message = Message.find(:first)
395 message = Message.find(:first)
395 recipients = ([message.root] + message.root.children).collect {|m| m.author.mail if m.author}
396 recipients = ([message.root] + message.root.children).collect {|m| m.author.mail if m.author}
396 recipients = recipients.compact.uniq
397 recipients = recipients.compact.uniq
397 valid_languages.each do |lang|
398 valid_languages.each do |lang|
398 Setting.default_language = lang.to_s
399 Setting.default_language = lang.to_s
399 assert Mailer.deliver_message_posted(message)
400 assert Mailer.deliver_message_posted(message)
400 end
401 end
401 end
402 end
402
403
403 def test_wiki_content_added
404 def test_wiki_content_added
404 content = WikiContent.find(1)
405 content = WikiContent.find(1)
405 valid_languages.each do |lang|
406 valid_languages.each do |lang|
406 Setting.default_language = lang.to_s
407 Setting.default_language = lang.to_s
407 assert_difference 'ActionMailer::Base.deliveries.size' do
408 assert_difference 'ActionMailer::Base.deliveries.size' do
408 assert Mailer.deliver_wiki_content_added(content)
409 assert Mailer.deliver_wiki_content_added(content)
409 end
410 end
410 end
411 end
411 end
412 end
412
413
413 def test_wiki_content_updated
414 def test_wiki_content_updated
414 content = WikiContent.find(1)
415 content = WikiContent.find(1)
415 valid_languages.each do |lang|
416 valid_languages.each do |lang|
416 Setting.default_language = lang.to_s
417 Setting.default_language = lang.to_s
417 assert_difference 'ActionMailer::Base.deliveries.size' do
418 assert_difference 'ActionMailer::Base.deliveries.size' do
418 assert Mailer.deliver_wiki_content_updated(content)
419 assert Mailer.deliver_wiki_content_updated(content)
419 end
420 end
420 end
421 end
421 end
422 end
422
423
423 def test_account_information
424 def test_account_information
424 user = User.find(2)
425 user = User.find(2)
425 valid_languages.each do |lang|
426 valid_languages.each do |lang|
426 user.update_attribute :language, lang.to_s
427 user.update_attribute :language, lang.to_s
427 user.reload
428 user.reload
428 assert Mailer.deliver_account_information(user, 'pAsswORd')
429 assert Mailer.deliver_account_information(user, 'pAsswORd')
429 end
430 end
430 end
431 end
431
432
432 def test_lost_password
433 def test_lost_password
433 token = Token.find(2)
434 token = Token.find(2)
434 valid_languages.each do |lang|
435 valid_languages.each do |lang|
435 token.user.update_attribute :language, lang.to_s
436 token.user.update_attribute :language, lang.to_s
436 token.reload
437 token.reload
437 assert Mailer.deliver_lost_password(token)
438 assert Mailer.deliver_lost_password(token)
438 end
439 end
439 end
440 end
440
441
441 def test_register
442 def test_register
442 token = Token.find(1)
443 token = Token.find(1)
443 Setting.host_name = 'redmine.foo'
444 Setting.host_name = 'redmine.foo'
444 Setting.protocol = 'https'
445 Setting.protocol = 'https'
445
446
446 valid_languages.each do |lang|
447 valid_languages.each do |lang|
447 token.user.update_attribute :language, lang.to_s
448 token.user.update_attribute :language, lang.to_s
448 token.reload
449 token.reload
449 ActionMailer::Base.deliveries.clear
450 ActionMailer::Base.deliveries.clear
450 assert Mailer.deliver_register(token)
451 assert Mailer.deliver_register(token)
451 mail = last_email
452 mail = last_email
452 assert_select_email do
453 assert_select_email do
453 assert_select "a[href=?]",
454 assert_select "a[href=?]",
454 "https://redmine.foo/account/activate?token=#{token.value}",
455 "https://redmine.foo/account/activate?token=#{token.value}",
455 :text => "https://redmine.foo/account/activate?token=#{token.value}"
456 :text => "https://redmine.foo/account/activate?token=#{token.value}"
456 end
457 end
457 end
458 end
458 end
459 end
459
460
460 def test_test
461 def test_test
461 user = User.find(1)
462 user = User.find(1)
462 valid_languages.each do |lang|
463 valid_languages.each do |lang|
463 user.update_attribute :language, lang.to_s
464 user.update_attribute :language, lang.to_s
464 assert Mailer.deliver_test_email(user)
465 assert Mailer.deliver_test_email(user)
465 end
466 end
466 end
467 end
467
468
468 def test_reminders
469 def test_reminders
469 Mailer.reminders(:days => 42)
470 Mailer.reminders(:days => 42)
470 assert_equal 1, ActionMailer::Base.deliveries.size
471 assert_equal 1, ActionMailer::Base.deliveries.size
471 mail = last_email
472 mail = last_email
472 assert mail.bcc.include?('dlopper@somenet.foo')
473 assert mail.bcc.include?('dlopper@somenet.foo')
473 assert_mail_body_match 'Bug #3: Error 281 when updating a recipe', mail
474 assert_mail_body_match 'Bug #3: Error 281 when updating a recipe', mail
474 assert_equal '1 issue(s) due in the next 42 days', mail.subject
475 assert_equal '1 issue(s) due in the next 42 days', mail.subject
475 end
476 end
476
477
477 def test_reminders_should_not_include_closed_issues
478 def test_reminders_should_not_include_closed_issues
478 with_settings :default_language => 'en' do
479 with_settings :default_language => 'en' do
479 Issue.create!(:project_id => 1, :tracker_id => 1, :status_id => 5,
480 Issue.create!(:project_id => 1, :tracker_id => 1, :status_id => 5,
480 :subject => 'Closed issue', :assigned_to_id => 3,
481 :subject => 'Closed issue', :assigned_to_id => 3,
481 :due_date => 5.days.from_now,
482 :due_date => 5.days.from_now,
482 :author_id => 2)
483 :author_id => 2)
483 ActionMailer::Base.deliveries.clear
484 ActionMailer::Base.deliveries.clear
484
485
485 Mailer.reminders(:days => 42)
486 Mailer.reminders(:days => 42)
486 assert_equal 1, ActionMailer::Base.deliveries.size
487 assert_equal 1, ActionMailer::Base.deliveries.size
487 mail = last_email
488 mail = last_email
488 assert mail.bcc.include?('dlopper@somenet.foo')
489 assert mail.bcc.include?('dlopper@somenet.foo')
489 assert_mail_body_no_match 'Closed issue', mail
490 assert_mail_body_no_match 'Closed issue', mail
490 end
491 end
491 end
492 end
492
493
493 def test_reminders_for_users
494 def test_reminders_for_users
494 Mailer.reminders(:days => 42, :users => ['5'])
495 Mailer.reminders(:days => 42, :users => ['5'])
495 assert_equal 0, ActionMailer::Base.deliveries.size # No mail for dlopper
496 assert_equal 0, ActionMailer::Base.deliveries.size # No mail for dlopper
496 Mailer.reminders(:days => 42, :users => ['3'])
497 Mailer.reminders(:days => 42, :users => ['3'])
497 assert_equal 1, ActionMailer::Base.deliveries.size # No mail for dlopper
498 assert_equal 1, ActionMailer::Base.deliveries.size # No mail for dlopper
498 mail = last_email
499 mail = last_email
499 assert mail.bcc.include?('dlopper@somenet.foo')
500 assert mail.bcc.include?('dlopper@somenet.foo')
500 assert_mail_body_match 'Bug #3: Error 281 when updating a recipe', mail
501 assert_mail_body_match 'Bug #3: Error 281 when updating a recipe', mail
501 end
502 end
502
503
503 def last_email
504 def last_email
504 mail = ActionMailer::Base.deliveries.last
505 mail = ActionMailer::Base.deliveries.last
505 assert_not_nil mail
506 assert_not_nil mail
506 mail
507 mail
507 end
508 end
508
509
509 def test_mailer_should_not_change_locale
510 def test_mailer_should_not_change_locale
510 Setting.default_language = 'en'
511 Setting.default_language = 'en'
511 # Set current language to italian
512 # Set current language to italian
512 set_language_if_valid 'it'
513 set_language_if_valid 'it'
513 # Send an email to a french user
514 # Send an email to a french user
514 user = User.find(1)
515 user = User.find(1)
515 user.language = 'fr'
516 user.language = 'fr'
516 Mailer.deliver_account_activated(user)
517 Mailer.deliver_account_activated(user)
517 mail = last_email
518 mail = last_email
518 assert_mail_body_match 'Votre compte', mail
519 assert_mail_body_match 'Votre compte', mail
519
520
520 assert_equal :it, current_language
521 assert_equal :it, current_language
521 end
522 end
522
523
523 def test_with_deliveries_off
524 def test_with_deliveries_off
524 Mailer.with_deliveries false do
525 Mailer.with_deliveries false do
525 Mailer.deliver_test_email(User.find(1))
526 Mailer.deliver_test_email(User.find(1))
526 end
527 end
527 assert ActionMailer::Base.deliveries.empty?
528 assert ActionMailer::Base.deliveries.empty?
528 # should restore perform_deliveries
529 # should restore perform_deliveries
529 assert ActionMailer::Base.perform_deliveries
530 assert ActionMailer::Base.perform_deliveries
530 end
531 end
531
532
532 def test_tmail_to_header_field_should_not_include_blank_lines
533 def test_tmail_to_header_field_should_not_include_blank_lines
533 mail = TMail::Mail.new
534 mail = TMail::Mail.new
534 mail.to = ["a.user@example.com", "v.user2@example.com", "e.smith@example.com", "info@example.com", "v.pupkin@example.com",
535 mail.to = ["a.user@example.com", "v.user2@example.com", "e.smith@example.com", "info@example.com", "v.pupkin@example.com",
535 "b.user@example.com", "w.user2@example.com", "f.smith@example.com", "info2@example.com", "w.pupkin@example.com"]
536 "b.user@example.com", "w.user2@example.com", "f.smith@example.com", "info2@example.com", "w.pupkin@example.com"]
536
537
537 assert !mail.encoded.strip.split("\r\n").detect(&:blank?), "#{mail.encoded} malformed"
538 assert !mail.encoded.strip.split("\r\n").detect(&:blank?), "#{mail.encoded} malformed"
538 end
539 end
539
540
540 def test_layout_should_include_the_emails_header
541 def test_layout_should_include_the_emails_header
541 with_settings :emails_header => "*Header content*" do
542 with_settings :emails_header => "*Header content*" do
542 assert Mailer.deliver_test_email(User.find(1))
543 assert Mailer.deliver_test_email(User.find(1))
543 assert_select_email do
544 assert_select_email do
544 assert_select ".header" do
545 assert_select ".header" do
545 assert_select "strong", :text => "Header content"
546 assert_select "strong", :text => "Header content"
546 end
547 end
547 end
548 end
548 end
549 end
549 end
550 end
550 end
551 end
General Comments 0
You need to be logged in to leave comments. Login now