##// END OF EJS Templates
Renamed Mailer#test to Mailer#test_email....
Jean-Philippe Lang -
r8960:d862843c9d58
parent child
Show More
@@ -1,86 +1,86
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 AdminController < ApplicationController
18 class AdminController < ApplicationController
19 layout 'admin'
19 layout 'admin'
20 menu_item :projects, :only => :projects
20 menu_item :projects, :only => :projects
21 menu_item :plugins, :only => :plugins
21 menu_item :plugins, :only => :plugins
22 menu_item :info, :only => :info
22 menu_item :info, :only => :info
23
23
24 before_filter :require_admin
24 before_filter :require_admin
25 helper :sort
25 helper :sort
26 include SortHelper
26 include SortHelper
27
27
28 def index
28 def index
29 @no_configuration_data = Redmine::DefaultData::Loader::no_data?
29 @no_configuration_data = Redmine::DefaultData::Loader::no_data?
30 end
30 end
31
31
32 def projects
32 def projects
33 @status = params[:status] || 1
33 @status = params[:status] || 1
34
34
35 scope = Project.status(@status)
35 scope = Project.status(@status)
36 scope = scope.like(params[:name]) if params[:name].present?
36 scope = scope.like(params[:name]) if params[:name].present?
37
37
38 @projects = scope.all(:order => 'lft')
38 @projects = scope.all(:order => 'lft')
39
39
40 render :action => "projects", :layout => false if request.xhr?
40 render :action => "projects", :layout => false if request.xhr?
41 end
41 end
42
42
43 def plugins
43 def plugins
44 @plugins = Redmine::Plugin.all
44 @plugins = Redmine::Plugin.all
45 end
45 end
46
46
47 # Loads the default configuration
47 # Loads the default configuration
48 # (roles, trackers, statuses, workflow, enumerations)
48 # (roles, trackers, statuses, workflow, enumerations)
49 def default_configuration
49 def default_configuration
50 if request.post?
50 if request.post?
51 begin
51 begin
52 Redmine::DefaultData::Loader::load(params[:lang])
52 Redmine::DefaultData::Loader::load(params[:lang])
53 flash[:notice] = l(:notice_default_data_loaded)
53 flash[:notice] = l(:notice_default_data_loaded)
54 rescue Exception => e
54 rescue Exception => e
55 flash[:error] = l(:error_can_t_load_default_data, e.message)
55 flash[:error] = l(:error_can_t_load_default_data, e.message)
56 end
56 end
57 end
57 end
58 redirect_to :action => 'index'
58 redirect_to :action => 'index'
59 end
59 end
60
60
61 def test_email
61 def test_email
62 raise_delivery_errors = ActionMailer::Base.raise_delivery_errors
62 raise_delivery_errors = ActionMailer::Base.raise_delivery_errors
63 # Force ActionMailer to raise delivery errors so we can catch it
63 # Force ActionMailer to raise delivery errors so we can catch it
64 ActionMailer::Base.raise_delivery_errors = true
64 ActionMailer::Base.raise_delivery_errors = true
65 begin
65 begin
66 @test = Mailer.deliver_test(User.current)
66 @test = Mailer.deliver_test_email(User.current)
67 flash[:notice] = l(:notice_email_sent, User.current.mail)
67 flash[:notice] = l(:notice_email_sent, User.current.mail)
68 rescue Exception => e
68 rescue Exception => e
69 flash[:error] = l(:notice_email_error, e.message)
69 flash[:error] = l(:notice_email_error, e.message)
70 end
70 end
71 ActionMailer::Base.raise_delivery_errors = raise_delivery_errors
71 ActionMailer::Base.raise_delivery_errors = raise_delivery_errors
72 redirect_to :controller => 'settings', :action => 'edit', :tab => 'notifications'
72 redirect_to :controller => 'settings', :action => 'edit', :tab => 'notifications'
73 end
73 end
74
74
75 def info
75 def info
76 @db_adapter_name = ActiveRecord::Base.connection.adapter_name
76 @db_adapter_name = ActiveRecord::Base.connection.adapter_name
77 @checklist = [
77 @checklist = [
78 [:text_default_administrator_account_changed,
78 [:text_default_administrator_account_changed,
79 User.find(:first,
79 User.find(:first,
80 :conditions => ["login=? and hashed_password=?", 'admin', User.hash_password('admin')]).nil?],
80 :conditions => ["login=? and hashed_password=?", 'admin', User.hash_password('admin')]).nil?],
81 [:text_file_repository_writable, File.writable?(Attachment.storage_path)],
81 [:text_file_repository_writable, File.writable?(Attachment.storage_path)],
82 [:text_plugin_assets_writable, File.writable?(Redmine::Plugin.public_directory)],
82 [:text_plugin_assets_writable, File.writable?(Redmine::Plugin.public_directory)],
83 [:text_rmagick_available, Object.const_defined?(:Magick)]
83 [:text_rmagick_available, Object.const_defined?(:Magick)]
84 ]
84 ]
85 end
85 end
86 end
86 end
@@ -1,477 +1,477
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 subject "[#{document.project.name}] #{l(:label_document_new)}: #{document.title}"
101 subject "[#{document.project.name}] #{l(:label_document_new)}: #{document.title}"
102 body :document => document,
102 body :document => document,
103 :document_url => url_for(:controller => 'documents', :action => 'show', :id => document)
103 :document_url => url_for(:controller => 'documents', :action => 'show', :id => document)
104 render_multipart('document_added', body)
104 render_multipart('document_added', body)
105 end
105 end
106
106
107 # Builds a tmail object used to email recipients of a project when an attachements are added.
107 # Builds a tmail object used to email recipients of a project when an attachements are added.
108 #
108 #
109 # Example:
109 # Example:
110 # attachments_added(attachments) => tmail object
110 # attachments_added(attachments) => tmail object
111 # Mailer.deliver_attachments_added(attachments) => sends an email to the project's recipients
111 # Mailer.deliver_attachments_added(attachments) => sends an email to the project's recipients
112 def attachments_added(attachments)
112 def attachments_added(attachments)
113 container = attachments.first.container
113 container = attachments.first.container
114 added_to = ''
114 added_to = ''
115 added_to_url = ''
115 added_to_url = ''
116 case container.class.name
116 case container.class.name
117 when 'Project'
117 when 'Project'
118 added_to_url = url_for(:controller => 'files', :action => 'index', :project_id => container)
118 added_to_url = url_for(:controller => 'files', :action => 'index', :project_id => container)
119 added_to = "#{l(:label_project)}: #{container}"
119 added_to = "#{l(:label_project)}: #{container}"
120 recipients container.project.notified_users.select {|user| user.allowed_to?(:view_files, container.project)}.collect {|u| u.mail}
120 recipients container.project.notified_users.select {|user| user.allowed_to?(:view_files, container.project)}.collect {|u| u.mail}
121 when 'Version'
121 when 'Version'
122 added_to_url = url_for(:controller => 'files', :action => 'index', :project_id => container.project)
122 added_to_url = url_for(:controller => 'files', :action => 'index', :project_id => container.project)
123 added_to = "#{l(:label_version)}: #{container.name}"
123 added_to = "#{l(:label_version)}: #{container.name}"
124 recipients container.project.notified_users.select {|user| user.allowed_to?(:view_files, container.project)}.collect {|u| u.mail}
124 recipients container.project.notified_users.select {|user| user.allowed_to?(:view_files, container.project)}.collect {|u| u.mail}
125 when 'Document'
125 when 'Document'
126 added_to_url = url_for(:controller => 'documents', :action => 'show', :id => container.id)
126 added_to_url = url_for(:controller => 'documents', :action => 'show', :id => container.id)
127 added_to = "#{l(:label_document)}: #{container.title}"
127 added_to = "#{l(:label_document)}: #{container.title}"
128 recipients container.recipients
128 recipients container.recipients
129 end
129 end
130 redmine_headers 'Project' => container.project.identifier
130 redmine_headers 'Project' => container.project.identifier
131 subject "[#{container.project.name}] #{l(:label_attachment_new)}"
131 subject "[#{container.project.name}] #{l(:label_attachment_new)}"
132 body :attachments => attachments,
132 body :attachments => attachments,
133 :added_to => added_to,
133 :added_to => added_to,
134 :added_to_url => added_to_url
134 :added_to_url => added_to_url
135 render_multipart('attachments_added', body)
135 render_multipart('attachments_added', body)
136 end
136 end
137
137
138 # Builds a tmail object used to email recipients of a news' project when a news item is added.
138 # Builds a tmail object used to email recipients of a news' project when a news item is added.
139 #
139 #
140 # Example:
140 # Example:
141 # news_added(news) => tmail object
141 # news_added(news) => tmail object
142 # Mailer.deliver_news_added(news) => sends an email to the news' project recipients
142 # Mailer.deliver_news_added(news) => sends an email to the news' project recipients
143 def news_added(news)
143 def news_added(news)
144 redmine_headers 'Project' => news.project.identifier
144 redmine_headers 'Project' => news.project.identifier
145 message_id news
145 message_id news
146 recipients news.recipients
146 recipients news.recipients
147 subject "[#{news.project.name}] #{l(:label_news)}: #{news.title}"
147 subject "[#{news.project.name}] #{l(:label_news)}: #{news.title}"
148 body :news => news,
148 body :news => news,
149 :news_url => url_for(:controller => 'news', :action => 'show', :id => news)
149 :news_url => url_for(:controller => 'news', :action => 'show', :id => news)
150 render_multipart('news_added', body)
150 render_multipart('news_added', body)
151 end
151 end
152
152
153 # Builds a tmail object used to email recipients of a news' project when a news comment is added.
153 # Builds a tmail object used to email recipients of a news' project when a news comment is added.
154 #
154 #
155 # Example:
155 # Example:
156 # news_comment_added(comment) => tmail object
156 # news_comment_added(comment) => tmail object
157 # Mailer.news_comment_added(comment) => sends an email to the news' project recipients
157 # Mailer.news_comment_added(comment) => sends an email to the news' project recipients
158 def news_comment_added(comment)
158 def news_comment_added(comment)
159 news = comment.commented
159 news = comment.commented
160 redmine_headers 'Project' => news.project.identifier
160 redmine_headers 'Project' => news.project.identifier
161 message_id comment
161 message_id comment
162 recipients news.recipients
162 recipients news.recipients
163 cc news.watcher_recipients
163 cc news.watcher_recipients
164 subject "Re: [#{news.project.name}] #{l(:label_news)}: #{news.title}"
164 subject "Re: [#{news.project.name}] #{l(:label_news)}: #{news.title}"
165 body :news => news,
165 body :news => news,
166 :comment => comment,
166 :comment => comment,
167 :news_url => url_for(:controller => 'news', :action => 'show', :id => news)
167 :news_url => url_for(:controller => 'news', :action => 'show', :id => news)
168 render_multipart('news_comment_added', body)
168 render_multipart('news_comment_added', body)
169 end
169 end
170
170
171 # Builds a tmail object used to email the recipients of the specified message that was posted.
171 # Builds a tmail object used to email the recipients of the specified message that was posted.
172 #
172 #
173 # Example:
173 # Example:
174 # message_posted(message) => tmail object
174 # message_posted(message) => tmail object
175 # Mailer.deliver_message_posted(message) => sends an email to the recipients
175 # Mailer.deliver_message_posted(message) => sends an email to the recipients
176 def message_posted(message)
176 def message_posted(message)
177 redmine_headers 'Project' => message.project.identifier,
177 redmine_headers 'Project' => message.project.identifier,
178 'Topic-Id' => (message.parent_id || message.id)
178 'Topic-Id' => (message.parent_id || message.id)
179 message_id message
179 message_id message
180 references message.parent unless message.parent.nil?
180 references message.parent unless message.parent.nil?
181 recipients(message.recipients)
181 recipients(message.recipients)
182 cc((message.root.watcher_recipients + message.board.watcher_recipients).uniq - @recipients)
182 cc((message.root.watcher_recipients + message.board.watcher_recipients).uniq - @recipients)
183 subject "[#{message.board.project.name} - #{message.board.name} - msg#{message.root.id}] #{message.subject}"
183 subject "[#{message.board.project.name} - #{message.board.name} - msg#{message.root.id}] #{message.subject}"
184 body :message => message,
184 body :message => message,
185 :message_url => url_for(message.event_url)
185 :message_url => url_for(message.event_url)
186 render_multipart('message_posted', body)
186 render_multipart('message_posted', body)
187 end
187 end
188
188
189 # Builds a tmail object used to email the recipients of a project of the specified wiki content was added.
189 # Builds a tmail object used to email the recipients of a project of the specified wiki content was added.
190 #
190 #
191 # Example:
191 # Example:
192 # wiki_content_added(wiki_content) => tmail object
192 # wiki_content_added(wiki_content) => tmail object
193 # Mailer.deliver_wiki_content_added(wiki_content) => sends an email to the project's recipients
193 # Mailer.deliver_wiki_content_added(wiki_content) => sends an email to the project's recipients
194 def wiki_content_added(wiki_content)
194 def wiki_content_added(wiki_content)
195 redmine_headers 'Project' => wiki_content.project.identifier,
195 redmine_headers 'Project' => wiki_content.project.identifier,
196 'Wiki-Page-Id' => wiki_content.page.id
196 'Wiki-Page-Id' => wiki_content.page.id
197 message_id wiki_content
197 message_id wiki_content
198 recipients wiki_content.recipients
198 recipients wiki_content.recipients
199 cc(wiki_content.page.wiki.watcher_recipients - recipients)
199 cc(wiki_content.page.wiki.watcher_recipients - recipients)
200 subject "[#{wiki_content.project.name}] #{l(:mail_subject_wiki_content_added, :id => wiki_content.page.pretty_title)}"
200 subject "[#{wiki_content.project.name}] #{l(:mail_subject_wiki_content_added, :id => wiki_content.page.pretty_title)}"
201 body :wiki_content => wiki_content,
201 body :wiki_content => wiki_content,
202 :wiki_content_url => url_for(:controller => 'wiki', :action => 'show',
202 :wiki_content_url => url_for(:controller => 'wiki', :action => 'show',
203 :project_id => wiki_content.project,
203 :project_id => wiki_content.project,
204 :id => wiki_content.page.title)
204 :id => wiki_content.page.title)
205 render_multipart('wiki_content_added', body)
205 render_multipart('wiki_content_added', body)
206 end
206 end
207
207
208 # Builds a tmail object used to email the recipients of a project of the specified wiki content was updated.
208 # Builds a tmail object used to email the recipients of a project of the specified wiki content was updated.
209 #
209 #
210 # Example:
210 # Example:
211 # wiki_content_updated(wiki_content) => tmail object
211 # wiki_content_updated(wiki_content) => tmail object
212 # Mailer.deliver_wiki_content_updated(wiki_content) => sends an email to the project's recipients
212 # Mailer.deliver_wiki_content_updated(wiki_content) => sends an email to the project's recipients
213 def wiki_content_updated(wiki_content)
213 def wiki_content_updated(wiki_content)
214 redmine_headers 'Project' => wiki_content.project.identifier,
214 redmine_headers 'Project' => wiki_content.project.identifier,
215 'Wiki-Page-Id' => wiki_content.page.id
215 'Wiki-Page-Id' => wiki_content.page.id
216 message_id wiki_content
216 message_id wiki_content
217 recipients wiki_content.recipients
217 recipients wiki_content.recipients
218 cc(wiki_content.page.wiki.watcher_recipients + wiki_content.page.watcher_recipients - recipients)
218 cc(wiki_content.page.wiki.watcher_recipients + wiki_content.page.watcher_recipients - recipients)
219 subject "[#{wiki_content.project.name}] #{l(:mail_subject_wiki_content_updated, :id => wiki_content.page.pretty_title)}"
219 subject "[#{wiki_content.project.name}] #{l(:mail_subject_wiki_content_updated, :id => wiki_content.page.pretty_title)}"
220 body :wiki_content => wiki_content,
220 body :wiki_content => wiki_content,
221 :wiki_content_url => url_for(:controller => 'wiki', :action => 'show',
221 :wiki_content_url => url_for(:controller => 'wiki', :action => 'show',
222 :project_id => wiki_content.project,
222 :project_id => wiki_content.project,
223 :id => wiki_content.page.title),
223 :id => wiki_content.page.title),
224 :wiki_diff_url => url_for(:controller => 'wiki', :action => 'diff',
224 :wiki_diff_url => url_for(:controller => 'wiki', :action => 'diff',
225 :project_id => wiki_content.project, :id => wiki_content.page.title,
225 :project_id => wiki_content.project, :id => wiki_content.page.title,
226 :version => wiki_content.version)
226 :version => wiki_content.version)
227 render_multipart('wiki_content_updated', body)
227 render_multipart('wiki_content_updated', body)
228 end
228 end
229
229
230 # Builds a tmail object used to email the specified user their account information.
230 # Builds a tmail object used to email the specified user their account information.
231 #
231 #
232 # Example:
232 # Example:
233 # account_information(user, password) => tmail object
233 # account_information(user, password) => tmail object
234 # Mailer.deliver_account_information(user, password) => sends account information to the user
234 # Mailer.deliver_account_information(user, password) => sends account information to the user
235 def account_information(user, password)
235 def account_information(user, password)
236 set_language_if_valid user.language
236 set_language_if_valid user.language
237 recipients user.mail
237 recipients user.mail
238 subject l(:mail_subject_register, Setting.app_title)
238 subject l(:mail_subject_register, Setting.app_title)
239 body :user => user,
239 body :user => user,
240 :password => password,
240 :password => password,
241 :login_url => url_for(:controller => 'account', :action => 'login')
241 :login_url => url_for(:controller => 'account', :action => 'login')
242 render_multipart('account_information', body)
242 render_multipart('account_information', body)
243 end
243 end
244
244
245 # Builds a tmail object used to email all active administrators of an account activation request.
245 # Builds a tmail object used to email all active administrators of an account activation request.
246 #
246 #
247 # Example:
247 # Example:
248 # account_activation_request(user) => tmail object
248 # account_activation_request(user) => tmail object
249 # Mailer.deliver_account_activation_request(user)=> sends an email to all active administrators
249 # Mailer.deliver_account_activation_request(user)=> sends an email to all active administrators
250 def account_activation_request(user)
250 def account_activation_request(user)
251 # Send the email to all active administrators
251 # Send the email to all active administrators
252 recipients User.active.find(:all, :conditions => {:admin => true}).collect { |u| u.mail }.compact
252 recipients User.active.find(:all, :conditions => {:admin => true}).collect { |u| u.mail }.compact
253 subject l(:mail_subject_account_activation_request, Setting.app_title)
253 subject l(:mail_subject_account_activation_request, Setting.app_title)
254 body :user => user,
254 body :user => user,
255 :url => url_for(:controller => 'users', :action => 'index',
255 :url => url_for(:controller => 'users', :action => 'index',
256 :status => User::STATUS_REGISTERED,
256 :status => User::STATUS_REGISTERED,
257 :sort_key => 'created_on', :sort_order => 'desc')
257 :sort_key => 'created_on', :sort_order => 'desc')
258 render_multipart('account_activation_request', body)
258 render_multipart('account_activation_request', body)
259 end
259 end
260
260
261 # Builds a tmail object used to email the specified user that their account was activated by an administrator.
261 # Builds a tmail object used to email the specified user that their account was activated by an administrator.
262 #
262 #
263 # Example:
263 # Example:
264 # account_activated(user) => tmail object
264 # account_activated(user) => tmail object
265 # Mailer.deliver_account_activated(user) => sends an email to the registered user
265 # Mailer.deliver_account_activated(user) => sends an email to the registered user
266 def account_activated(user)
266 def account_activated(user)
267 set_language_if_valid user.language
267 set_language_if_valid user.language
268 recipients user.mail
268 recipients user.mail
269 subject l(:mail_subject_register, Setting.app_title)
269 subject l(:mail_subject_register, Setting.app_title)
270 body :user => user,
270 body :user => user,
271 :login_url => url_for(:controller => 'account', :action => 'login')
271 :login_url => url_for(:controller => 'account', :action => 'login')
272 render_multipart('account_activated', body)
272 render_multipart('account_activated', body)
273 end
273 end
274
274
275 def lost_password(token)
275 def lost_password(token)
276 set_language_if_valid(token.user.language)
276 set_language_if_valid(token.user.language)
277 recipients token.user.mail
277 recipients token.user.mail
278 subject l(:mail_subject_lost_password, Setting.app_title)
278 subject l(:mail_subject_lost_password, Setting.app_title)
279 body :token => token,
279 body :token => token,
280 :url => url_for(:controller => 'account', :action => 'lost_password', :token => token.value)
280 :url => url_for(:controller => 'account', :action => 'lost_password', :token => token.value)
281 render_multipart('lost_password', body)
281 render_multipart('lost_password', body)
282 end
282 end
283
283
284 def register(token)
284 def register(token)
285 set_language_if_valid(token.user.language)
285 set_language_if_valid(token.user.language)
286 recipients token.user.mail
286 recipients token.user.mail
287 subject l(:mail_subject_register, Setting.app_title)
287 subject l(:mail_subject_register, Setting.app_title)
288 body :token => token,
288 body :token => token,
289 :url => url_for(:controller => 'account', :action => 'activate', :token => token.value)
289 :url => url_for(:controller => 'account', :action => 'activate', :token => token.value)
290 render_multipart('register', body)
290 render_multipart('register', body)
291 end
291 end
292
292
293 def test(user)
293 def test_email(user)
294 set_language_if_valid(user.language)
294 set_language_if_valid(user.language)
295 recipients user.mail
295 recipients user.mail
296 subject 'Redmine test'
296 subject 'Redmine test'
297 body :url => url_for(:controller => 'welcome')
297 body :url => url_for(:controller => 'welcome')
298 render_multipart('test', body)
298 render_multipart('test_email', body)
299 end
299 end
300
300
301 # Overrides default deliver! method to prevent from sending an email
301 # Overrides default deliver! method to prevent from sending an email
302 # with no recipient, cc or bcc
302 # with no recipient, cc or bcc
303 def deliver!(mail = @mail)
303 def deliver!(mail = @mail)
304 set_language_if_valid @initial_language
304 set_language_if_valid @initial_language
305 return false if (recipients.nil? || recipients.empty?) &&
305 return false if (recipients.nil? || recipients.empty?) &&
306 (cc.nil? || cc.empty?) &&
306 (cc.nil? || cc.empty?) &&
307 (bcc.nil? || bcc.empty?)
307 (bcc.nil? || bcc.empty?)
308
308
309 # Set Message-Id and References
309 # Set Message-Id and References
310 if @message_id_object
310 if @message_id_object
311 mail.message_id = self.class.message_id_for(@message_id_object)
311 mail.message_id = self.class.message_id_for(@message_id_object)
312 end
312 end
313 if @references_objects
313 if @references_objects
314 mail.references = @references_objects.collect {|o| self.class.message_id_for(o)}
314 mail.references = @references_objects.collect {|o| self.class.message_id_for(o)}
315 end
315 end
316
316
317 # Log errors when raise_delivery_errors is set to false, Rails does not
317 # Log errors when raise_delivery_errors is set to false, Rails does not
318 raise_errors = self.class.raise_delivery_errors
318 raise_errors = self.class.raise_delivery_errors
319 self.class.raise_delivery_errors = true
319 self.class.raise_delivery_errors = true
320 begin
320 begin
321 return super(mail)
321 return super(mail)
322 rescue Exception => e
322 rescue Exception => e
323 if raise_errors
323 if raise_errors
324 raise e
324 raise e
325 elsif mylogger
325 elsif mylogger
326 mylogger.error "The following error occured while sending email notification: \"#{e.message}\". Check your configuration in config/configuration.yml."
326 mylogger.error "The following error occured while sending email notification: \"#{e.message}\". Check your configuration in config/configuration.yml."
327 end
327 end
328 ensure
328 ensure
329 self.class.raise_delivery_errors = raise_errors
329 self.class.raise_delivery_errors = raise_errors
330 end
330 end
331 end
331 end
332
332
333 # Sends reminders to issue assignees
333 # Sends reminders to issue assignees
334 # Available options:
334 # Available options:
335 # * :days => how many days in the future to remind about (defaults to 7)
335 # * :days => how many days in the future to remind about (defaults to 7)
336 # * :tracker => id of tracker for filtering issues (defaults to all trackers)
336 # * :tracker => id of tracker for filtering issues (defaults to all trackers)
337 # * :project => id or identifier of project to process (defaults to all projects)
337 # * :project => id or identifier of project to process (defaults to all projects)
338 # * :users => array of user ids who should be reminded
338 # * :users => array of user ids who should be reminded
339 def self.reminders(options={})
339 def self.reminders(options={})
340 days = options[:days] || 7
340 days = options[:days] || 7
341 project = options[:project] ? Project.find(options[:project]) : nil
341 project = options[:project] ? Project.find(options[:project]) : nil
342 tracker = options[:tracker] ? Tracker.find(options[:tracker]) : nil
342 tracker = options[:tracker] ? Tracker.find(options[:tracker]) : nil
343 user_ids = options[:users]
343 user_ids = options[:users]
344
344
345 scope = Issue.open.scoped(:conditions => ["#{Issue.table_name}.assigned_to_id IS NOT NULL" +
345 scope = Issue.open.scoped(:conditions => ["#{Issue.table_name}.assigned_to_id IS NOT NULL" +
346 " AND #{Project.table_name}.status = #{Project::STATUS_ACTIVE}" +
346 " AND #{Project.table_name}.status = #{Project::STATUS_ACTIVE}" +
347 " AND #{Issue.table_name}.due_date <= ?", days.day.from_now.to_date]
347 " AND #{Issue.table_name}.due_date <= ?", days.day.from_now.to_date]
348 )
348 )
349 scope = scope.scoped(:conditions => {:assigned_to_id => user_ids}) if user_ids.present?
349 scope = scope.scoped(:conditions => {:assigned_to_id => user_ids}) if user_ids.present?
350 scope = scope.scoped(:conditions => {:project_id => project.id}) if project
350 scope = scope.scoped(:conditions => {:project_id => project.id}) if project
351 scope = scope.scoped(:conditions => {:tracker_id => tracker.id}) if tracker
351 scope = scope.scoped(:conditions => {:tracker_id => tracker.id}) if tracker
352
352
353 issues_by_assignee = scope.all(:include => [:status, :assigned_to, :project, :tracker]).group_by(&:assigned_to)
353 issues_by_assignee = scope.all(:include => [:status, :assigned_to, :project, :tracker]).group_by(&:assigned_to)
354 issues_by_assignee.each do |assignee, issues|
354 issues_by_assignee.each do |assignee, issues|
355 deliver_reminder(assignee, issues, days) if assignee && assignee.active?
355 deliver_reminder(assignee, issues, days) if assignee && assignee.active?
356 end
356 end
357 end
357 end
358
358
359 # Activates/desactivates email deliveries during +block+
359 # Activates/desactivates email deliveries during +block+
360 def self.with_deliveries(enabled = true, &block)
360 def self.with_deliveries(enabled = true, &block)
361 was_enabled = ActionMailer::Base.perform_deliveries
361 was_enabled = ActionMailer::Base.perform_deliveries
362 ActionMailer::Base.perform_deliveries = !!enabled
362 ActionMailer::Base.perform_deliveries = !!enabled
363 yield
363 yield
364 ensure
364 ensure
365 ActionMailer::Base.perform_deliveries = was_enabled
365 ActionMailer::Base.perform_deliveries = was_enabled
366 end
366 end
367
367
368 private
368 private
369 def initialize_defaults(method_name)
369 def initialize_defaults(method_name)
370 super
370 super
371 @initial_language = current_language
371 @initial_language = current_language
372 set_language_if_valid Setting.default_language
372 set_language_if_valid Setting.default_language
373 from Setting.mail_from
373 from Setting.mail_from
374
374
375 # Common headers
375 # Common headers
376 headers 'X-Mailer' => 'Redmine',
376 headers 'X-Mailer' => 'Redmine',
377 'X-Redmine-Host' => Setting.host_name,
377 'X-Redmine-Host' => Setting.host_name,
378 'X-Redmine-Site' => Setting.app_title,
378 'X-Redmine-Site' => Setting.app_title,
379 'X-Auto-Response-Suppress' => 'OOF',
379 'X-Auto-Response-Suppress' => 'OOF',
380 'Auto-Submitted' => 'auto-generated'
380 'Auto-Submitted' => 'auto-generated'
381 end
381 end
382
382
383 # Appends a Redmine header field (name is prepended with 'X-Redmine-')
383 # Appends a Redmine header field (name is prepended with 'X-Redmine-')
384 def redmine_headers(h)
384 def redmine_headers(h)
385 h.each { |k,v| headers["X-Redmine-#{k}"] = v.to_s }
385 h.each { |k,v| headers["X-Redmine-#{k}"] = v.to_s }
386 end
386 end
387
387
388 # Overrides the create_mail method
388 # Overrides the create_mail method
389 def create_mail
389 def create_mail
390 # Removes the current user from the recipients and cc
390 # Removes the current user from the recipients and cc
391 # if he doesn't want to receive notifications about what he does
391 # if he doesn't want to receive notifications about what he does
392 @author ||= User.current
392 @author ||= User.current
393 if @author.pref[:no_self_notified]
393 if @author.pref[:no_self_notified]
394 recipients.delete(@author.mail) if recipients
394 recipients.delete(@author.mail) if recipients
395 cc.delete(@author.mail) if cc
395 cc.delete(@author.mail) if cc
396 end
396 end
397
397
398 if @author.logged?
398 if @author.logged?
399 redmine_headers 'Sender' => @author.login
399 redmine_headers 'Sender' => @author.login
400 end
400 end
401
401
402 notified_users = [recipients, cc].flatten.compact.uniq
402 notified_users = [recipients, cc].flatten.compact.uniq
403 # Rails would log recipients only, not cc and bcc
403 # Rails would log recipients only, not cc and bcc
404 mylogger.info "Sending email notification to: #{notified_users.join(', ')}" if mylogger
404 mylogger.info "Sending email notification to: #{notified_users.join(', ')}" if mylogger
405
405
406 # Blind carbon copy recipients
406 # Blind carbon copy recipients
407 if Setting.bcc_recipients?
407 if Setting.bcc_recipients?
408 bcc(notified_users)
408 bcc(notified_users)
409 recipients []
409 recipients []
410 cc []
410 cc []
411 end
411 end
412 super
412 super
413 end
413 end
414
414
415 # Rails 2.3 has problems rendering implicit multipart messages with
415 # Rails 2.3 has problems rendering implicit multipart messages with
416 # layouts so this method will wrap an multipart messages with
416 # layouts so this method will wrap an multipart messages with
417 # explicit parts.
417 # explicit parts.
418 #
418 #
419 # https://rails.lighthouseapp.com/projects/8994/tickets/2338-actionmailer-mailer-views-and-content-type
419 # https://rails.lighthouseapp.com/projects/8994/tickets/2338-actionmailer-mailer-views-and-content-type
420 # https://rails.lighthouseapp.com/projects/8994/tickets/1799-actionmailer-doesnt-set-template_format-when-rendering-layouts
420 # https://rails.lighthouseapp.com/projects/8994/tickets/1799-actionmailer-doesnt-set-template_format-when-rendering-layouts
421
421
422 def render_multipart(method_name, body)
422 def render_multipart(method_name, body)
423 if Setting.plain_text_mail?
423 if Setting.plain_text_mail?
424 content_type "text/plain"
424 content_type "text/plain"
425 body render(:file => "#{method_name}.text.erb",
425 body render(:file => "#{method_name}.text.erb",
426 :body => body,
426 :body => body,
427 :layout => 'mailer.text.erb')
427 :layout => 'mailer.text.erb')
428 else
428 else
429 content_type "multipart/alternative"
429 content_type "multipart/alternative"
430 part :content_type => "text/plain",
430 part :content_type => "text/plain",
431 :body => render(:file => "#{method_name}.text.erb",
431 :body => render(:file => "#{method_name}.text.erb",
432 :body => body, :layout => 'mailer.text.erb')
432 :body => body, :layout => 'mailer.text.erb')
433 part :content_type => "text/html",
433 part :content_type => "text/html",
434 :body => render_message("#{method_name}.html.erb", body)
434 :body => render_message("#{method_name}.html.erb", body)
435 end
435 end
436 end
436 end
437
437
438 # Makes partial rendering work with Rails 1.2 (retro-compatibility)
438 # Makes partial rendering work with Rails 1.2 (retro-compatibility)
439 def self.controller_path
439 def self.controller_path
440 ''
440 ''
441 end unless respond_to?('controller_path')
441 end unless respond_to?('controller_path')
442
442
443 # Returns a predictable Message-Id for the given object
443 # Returns a predictable Message-Id for the given object
444 def self.message_id_for(object)
444 def self.message_id_for(object)
445 # id + timestamp should reduce the odds of a collision
445 # id + timestamp should reduce the odds of a collision
446 # as far as we don't send multiple emails for the same object
446 # as far as we don't send multiple emails for the same object
447 timestamp = object.send(object.respond_to?(:created_on) ? :created_on : :updated_on)
447 timestamp = object.send(object.respond_to?(:created_on) ? :created_on : :updated_on)
448 hash = "redmine.#{object.class.name.demodulize.underscore}-#{object.id}.#{timestamp.strftime("%Y%m%d%H%M%S")}"
448 hash = "redmine.#{object.class.name.demodulize.underscore}-#{object.id}.#{timestamp.strftime("%Y%m%d%H%M%S")}"
449 host = Setting.mail_from.to_s.gsub(%r{^.*@}, '')
449 host = Setting.mail_from.to_s.gsub(%r{^.*@}, '')
450 host = "#{::Socket.gethostname}.redmine" if host.empty?
450 host = "#{::Socket.gethostname}.redmine" if host.empty?
451 "<#{hash}@#{host}>"
451 "<#{hash}@#{host}>"
452 end
452 end
453
453
454 private
454 private
455
455
456 def message_id(object)
456 def message_id(object)
457 @message_id_object = object
457 @message_id_object = object
458 end
458 end
459
459
460 def references(object)
460 def references(object)
461 @references_objects ||= []
461 @references_objects ||= []
462 @references_objects << object
462 @references_objects << object
463 end
463 end
464
464
465 def mylogger
465 def mylogger
466 Rails.logger
466 Rails.logger
467 end
467 end
468 end
468 end
469
469
470 # Patch TMail so that message_id is not overwritten
470 # Patch TMail so that message_id is not overwritten
471 module TMail
471 module TMail
472 class Mail
472 class Mail
473 def add_message_id( fqdn = nil )
473 def add_message_id( fqdn = nil )
474 self.message_id ||= ::TMail::new_message_id(fqdn)
474 self.message_id ||= ::TMail::new_message_id(fqdn)
475 end
475 end
476 end
476 end
477 end
477 end
1 NO CONTENT: file renamed from app/views/mailer/test.html.erb to app/views/mailer/test_email.html.erb
NO CONTENT: file renamed from app/views/mailer/test.html.erb to app/views/mailer/test_email.html.erb
1 NO CONTENT: file renamed from app/views/mailer/test.text.erb to app/views/mailer/test_email.text.erb
NO CONTENT: file renamed from app/views/mailer/test.text.erb to app/views/mailer/test_email.text.erb
@@ -1,186 +1,186
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 namespace :redmine do
18 namespace :redmine do
19 namespace :email do
19 namespace :email do
20
20
21 desc <<-END_DESC
21 desc <<-END_DESC
22 Read an email from standard input.
22 Read an email from standard input.
23
23
24 General options:
24 General options:
25 unknown_user=ACTION how to handle emails from an unknown user
25 unknown_user=ACTION how to handle emails from an unknown user
26 ACTION can be one of the following values:
26 ACTION can be one of the following values:
27 ignore: email is ignored (default)
27 ignore: email is ignored (default)
28 accept: accept as anonymous user
28 accept: accept as anonymous user
29 create: create a user account
29 create: create a user account
30 no_permission_check=1 disable permission checking when receiving
30 no_permission_check=1 disable permission checking when receiving
31 the email
31 the email
32
32
33 Issue attributes control options:
33 Issue attributes control options:
34 project=PROJECT identifier of the target project
34 project=PROJECT identifier of the target project
35 status=STATUS name of the target status
35 status=STATUS name of the target status
36 tracker=TRACKER name of the target tracker
36 tracker=TRACKER name of the target tracker
37 category=CATEGORY name of the target category
37 category=CATEGORY name of the target category
38 priority=PRIORITY name of the target priority
38 priority=PRIORITY name of the target priority
39 allow_override=ATTRS allow email content to override attributes
39 allow_override=ATTRS allow email content to override attributes
40 specified by previous options
40 specified by previous options
41 ATTRS is a comma separated list of attributes
41 ATTRS is a comma separated list of attributes
42
42
43 Examples:
43 Examples:
44 # No project specified. Emails MUST contain the 'Project' keyword:
44 # No project specified. Emails MUST contain the 'Project' keyword:
45 rake redmine:email:read RAILS_ENV="production" < raw_email
45 rake redmine:email:read RAILS_ENV="production" < raw_email
46
46
47 # Fixed project and default tracker specified, but emails can override
47 # Fixed project and default tracker specified, but emails can override
48 # both tracker and priority attributes:
48 # both tracker and priority attributes:
49 rake redmine:email:read RAILS_ENV="production" \\
49 rake redmine:email:read RAILS_ENV="production" \\
50 project=foo \\
50 project=foo \\
51 tracker=bug \\
51 tracker=bug \\
52 allow_override=tracker,priority < raw_email
52 allow_override=tracker,priority < raw_email
53 END_DESC
53 END_DESC
54
54
55 task :read => :environment do
55 task :read => :environment do
56 options = { :issue => {} }
56 options = { :issue => {} }
57 %w(project status tracker category priority).each { |a| options[:issue][a.to_sym] = ENV[a] if ENV[a] }
57 %w(project status tracker category priority).each { |a| options[:issue][a.to_sym] = ENV[a] if ENV[a] }
58 options[:allow_override] = ENV['allow_override'] if ENV['allow_override']
58 options[:allow_override] = ENV['allow_override'] if ENV['allow_override']
59 options[:unknown_user] = ENV['unknown_user'] if ENV['unknown_user']
59 options[:unknown_user] = ENV['unknown_user'] if ENV['unknown_user']
60 options[:no_permission_check] = ENV['no_permission_check'] if ENV['no_permission_check']
60 options[:no_permission_check] = ENV['no_permission_check'] if ENV['no_permission_check']
61
61
62 MailHandler.receive(STDIN.read, options)
62 MailHandler.receive(STDIN.read, options)
63 end
63 end
64
64
65 desc <<-END_DESC
65 desc <<-END_DESC
66 Read emails from an IMAP server.
66 Read emails from an IMAP server.
67
67
68 General options:
68 General options:
69 unknown_user=ACTION how to handle emails from an unknown user
69 unknown_user=ACTION how to handle emails from an unknown user
70 ACTION can be one of the following values:
70 ACTION can be one of the following values:
71 ignore: email is ignored (default)
71 ignore: email is ignored (default)
72 accept: accept as anonymous user
72 accept: accept as anonymous user
73 create: create a user account
73 create: create a user account
74 no_permission_check=1 disable permission checking when receiving
74 no_permission_check=1 disable permission checking when receiving
75 the email
75 the email
76
76
77 Available IMAP options:
77 Available IMAP options:
78 host=HOST IMAP server host (default: 127.0.0.1)
78 host=HOST IMAP server host (default: 127.0.0.1)
79 port=PORT IMAP server port (default: 143)
79 port=PORT IMAP server port (default: 143)
80 ssl=SSL Use SSL? (default: false)
80 ssl=SSL Use SSL? (default: false)
81 username=USERNAME IMAP account
81 username=USERNAME IMAP account
82 password=PASSWORD IMAP password
82 password=PASSWORD IMAP password
83 folder=FOLDER IMAP folder to read (default: INBOX)
83 folder=FOLDER IMAP folder to read (default: INBOX)
84
84
85 Issue attributes control options:
85 Issue attributes control options:
86 project=PROJECT identifier of the target project
86 project=PROJECT identifier of the target project
87 status=STATUS name of the target status
87 status=STATUS name of the target status
88 tracker=TRACKER name of the target tracker
88 tracker=TRACKER name of the target tracker
89 category=CATEGORY name of the target category
89 category=CATEGORY name of the target category
90 priority=PRIORITY name of the target priority
90 priority=PRIORITY name of the target priority
91 allow_override=ATTRS allow email content to override attributes
91 allow_override=ATTRS allow email content to override attributes
92 specified by previous options
92 specified by previous options
93 ATTRS is a comma separated list of attributes
93 ATTRS is a comma separated list of attributes
94
94
95 Processed emails control options:
95 Processed emails control options:
96 move_on_success=MAILBOX move emails that were successfully received
96 move_on_success=MAILBOX move emails that were successfully received
97 to MAILBOX instead of deleting them
97 to MAILBOX instead of deleting them
98 move_on_failure=MAILBOX move emails that were ignored to MAILBOX
98 move_on_failure=MAILBOX move emails that were ignored to MAILBOX
99
99
100 Examples:
100 Examples:
101 # No project specified. Emails MUST contain the 'Project' keyword:
101 # No project specified. Emails MUST contain the 'Project' keyword:
102
102
103 rake redmine:email:receive_imap RAILS_ENV="production" \\
103 rake redmine:email:receive_imap RAILS_ENV="production" \\
104 host=imap.foo.bar username=redmine@example.net password=xxx
104 host=imap.foo.bar username=redmine@example.net password=xxx
105
105
106
106
107 # Fixed project and default tracker specified, but emails can override
107 # Fixed project and default tracker specified, but emails can override
108 # both tracker and priority attributes:
108 # both tracker and priority attributes:
109
109
110 rake redmine:email:receive_imap RAILS_ENV="production" \\
110 rake redmine:email:receive_imap RAILS_ENV="production" \\
111 host=imap.foo.bar username=redmine@example.net password=xxx ssl=1 \\
111 host=imap.foo.bar username=redmine@example.net password=xxx ssl=1 \\
112 project=foo \\
112 project=foo \\
113 tracker=bug \\
113 tracker=bug \\
114 allow_override=tracker,priority
114 allow_override=tracker,priority
115 END_DESC
115 END_DESC
116
116
117 task :receive_imap => :environment do
117 task :receive_imap => :environment do
118 imap_options = {:host => ENV['host'],
118 imap_options = {:host => ENV['host'],
119 :port => ENV['port'],
119 :port => ENV['port'],
120 :ssl => ENV['ssl'],
120 :ssl => ENV['ssl'],
121 :username => ENV['username'],
121 :username => ENV['username'],
122 :password => ENV['password'],
122 :password => ENV['password'],
123 :folder => ENV['folder'],
123 :folder => ENV['folder'],
124 :move_on_success => ENV['move_on_success'],
124 :move_on_success => ENV['move_on_success'],
125 :move_on_failure => ENV['move_on_failure']}
125 :move_on_failure => ENV['move_on_failure']}
126
126
127 options = { :issue => {} }
127 options = { :issue => {} }
128 %w(project status tracker category priority).each { |a| options[:issue][a.to_sym] = ENV[a] if ENV[a] }
128 %w(project status tracker category priority).each { |a| options[:issue][a.to_sym] = ENV[a] if ENV[a] }
129 options[:allow_override] = ENV['allow_override'] if ENV['allow_override']
129 options[:allow_override] = ENV['allow_override'] if ENV['allow_override']
130 options[:unknown_user] = ENV['unknown_user'] if ENV['unknown_user']
130 options[:unknown_user] = ENV['unknown_user'] if ENV['unknown_user']
131 options[:no_permission_check] = ENV['no_permission_check'] if ENV['no_permission_check']
131 options[:no_permission_check] = ENV['no_permission_check'] if ENV['no_permission_check']
132
132
133 Redmine::IMAP.check(imap_options, options)
133 Redmine::IMAP.check(imap_options, options)
134 end
134 end
135
135
136 desc <<-END_DESC
136 desc <<-END_DESC
137 Read emails from an POP3 server.
137 Read emails from an POP3 server.
138
138
139 Available POP3 options:
139 Available POP3 options:
140 host=HOST POP3 server host (default: 127.0.0.1)
140 host=HOST POP3 server host (default: 127.0.0.1)
141 port=PORT POP3 server port (default: 110)
141 port=PORT POP3 server port (default: 110)
142 username=USERNAME POP3 account
142 username=USERNAME POP3 account
143 password=PASSWORD POP3 password
143 password=PASSWORD POP3 password
144 apop=1 use APOP authentication (default: false)
144 apop=1 use APOP authentication (default: false)
145 delete_unprocessed=1 delete messages that could not be processed
145 delete_unprocessed=1 delete messages that could not be processed
146 successfully from the server (default
146 successfully from the server (default
147 behaviour is to leave them on the server)
147 behaviour is to leave them on the server)
148
148
149 See redmine:email:receive_imap for more options and examples.
149 See redmine:email:receive_imap for more options and examples.
150 END_DESC
150 END_DESC
151
151
152 task :receive_pop3 => :environment do
152 task :receive_pop3 => :environment do
153 pop_options = {:host => ENV['host'],
153 pop_options = {:host => ENV['host'],
154 :port => ENV['port'],
154 :port => ENV['port'],
155 :apop => ENV['apop'],
155 :apop => ENV['apop'],
156 :username => ENV['username'],
156 :username => ENV['username'],
157 :password => ENV['password'],
157 :password => ENV['password'],
158 :delete_unprocessed => ENV['delete_unprocessed']}
158 :delete_unprocessed => ENV['delete_unprocessed']}
159
159
160 options = { :issue => {} }
160 options = { :issue => {} }
161 %w(project status tracker category priority).each { |a| options[:issue][a.to_sym] = ENV[a] if ENV[a] }
161 %w(project status tracker category priority).each { |a| options[:issue][a.to_sym] = ENV[a] if ENV[a] }
162 options[:allow_override] = ENV['allow_override'] if ENV['allow_override']
162 options[:allow_override] = ENV['allow_override'] if ENV['allow_override']
163 options[:unknown_user] = ENV['unknown_user'] if ENV['unknown_user']
163 options[:unknown_user] = ENV['unknown_user'] if ENV['unknown_user']
164 options[:no_permission_check] = ENV['no_permission_check'] if ENV['no_permission_check']
164 options[:no_permission_check] = ENV['no_permission_check'] if ENV['no_permission_check']
165
165
166 Redmine::POP3.check(pop_options, options)
166 Redmine::POP3.check(pop_options, options)
167 end
167 end
168
168
169 desc "Send a test email to the user with the provided login name"
169 desc "Send a test email to the user with the provided login name"
170 task :test, [:login] => :environment do |task, args|
170 task :test, [:login] => :environment do |task, args|
171 include Redmine::I18n
171 include Redmine::I18n
172 abort l(:notice_email_error, "Please include the user login to test with. Example: rake redmine:email:test[login]") if args[:login].blank?
172 abort l(:notice_email_error, "Please include the user login to test with. Example: rake redmine:email:test[login]") if args[:login].blank?
173
173
174 user = User.find_by_login(args[:login])
174 user = User.find_by_login(args[:login])
175 abort l(:notice_email_error, "User #{args[:login]} not found") unless user && user.logged?
175 abort l(:notice_email_error, "User #{args[:login]} not found") unless user && user.logged?
176
176
177 ActionMailer::Base.raise_delivery_errors = true
177 ActionMailer::Base.raise_delivery_errors = true
178 begin
178 begin
179 Mailer.deliver_test(User.current)
179 Mailer.deliver_test_email(User.current)
180 puts l(:notice_email_sent, user.mail)
180 puts l(:notice_email_sent, user.mail)
181 rescue Exception => e
181 rescue Exception => e
182 abort l(:notice_email_error, e.message)
182 abort l(:notice_email_error, e.message)
183 end
183 end
184 end
184 end
185 end
185 end
186 end
186 end
@@ -1,157 +1,157
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 require 'admin_controller'
19 require 'admin_controller'
20
20
21 # Re-raise errors caught by the controller.
21 # Re-raise errors caught by the controller.
22 class AdminController; def rescue_action(e) raise e end; end
22 class AdminController; def rescue_action(e) raise e end; end
23
23
24 class AdminControllerTest < ActionController::TestCase
24 class AdminControllerTest < ActionController::TestCase
25 fixtures :projects, :users, :roles
25 fixtures :projects, :users, :roles
26
26
27 def setup
27 def setup
28 @controller = AdminController.new
28 @controller = AdminController.new
29 @request = ActionController::TestRequest.new
29 @request = ActionController::TestRequest.new
30 @response = ActionController::TestResponse.new
30 @response = ActionController::TestResponse.new
31 User.current = nil
31 User.current = nil
32 @request.session[:user_id] = 1 # admin
32 @request.session[:user_id] = 1 # admin
33 end
33 end
34
34
35 def test_index
35 def test_index
36 get :index
36 get :index
37 assert_no_tag :tag => 'div',
37 assert_no_tag :tag => 'div',
38 :attributes => { :class => /nodata/ }
38 :attributes => { :class => /nodata/ }
39 end
39 end
40
40
41 def test_index_with_no_configuration_data
41 def test_index_with_no_configuration_data
42 delete_configuration_data
42 delete_configuration_data
43 get :index
43 get :index
44 assert_tag :tag => 'div',
44 assert_tag :tag => 'div',
45 :attributes => { :class => /nodata/ }
45 :attributes => { :class => /nodata/ }
46 end
46 end
47
47
48 def test_projects
48 def test_projects
49 get :projects
49 get :projects
50 assert_response :success
50 assert_response :success
51 assert_template 'projects'
51 assert_template 'projects'
52 assert_not_nil assigns(:projects)
52 assert_not_nil assigns(:projects)
53 # active projects only
53 # active projects only
54 assert_nil assigns(:projects).detect {|u| !u.active?}
54 assert_nil assigns(:projects).detect {|u| !u.active?}
55 end
55 end
56
56
57 def test_projects_with_status_filter
57 def test_projects_with_status_filter
58 get :projects, :status => 1
58 get :projects, :status => 1
59 assert_response :success
59 assert_response :success
60 assert_template 'projects'
60 assert_template 'projects'
61 assert_not_nil assigns(:projects)
61 assert_not_nil assigns(:projects)
62 # active projects only
62 # active projects only
63 assert_nil assigns(:projects).detect {|u| !u.active?}
63 assert_nil assigns(:projects).detect {|u| !u.active?}
64 end
64 end
65
65
66 def test_projects_with_name_filter
66 def test_projects_with_name_filter
67 get :projects, :name => 'store', :status => ''
67 get :projects, :name => 'store', :status => ''
68 assert_response :success
68 assert_response :success
69 assert_template 'projects'
69 assert_template 'projects'
70 projects = assigns(:projects)
70 projects = assigns(:projects)
71 assert_not_nil projects
71 assert_not_nil projects
72 assert_equal 1, projects.size
72 assert_equal 1, projects.size
73 assert_equal 'OnlineStore', projects.first.name
73 assert_equal 'OnlineStore', projects.first.name
74 end
74 end
75
75
76 def test_load_default_configuration_data
76 def test_load_default_configuration_data
77 delete_configuration_data
77 delete_configuration_data
78 post :default_configuration, :lang => 'fr'
78 post :default_configuration, :lang => 'fr'
79 assert_response :redirect
79 assert_response :redirect
80 assert_nil flash[:error]
80 assert_nil flash[:error]
81 assert IssueStatus.find_by_name('Nouveau')
81 assert IssueStatus.find_by_name('Nouveau')
82 end
82 end
83
83
84 def test_test_email
84 def test_test_email
85 get :test_email
85 get :test_email
86 assert_redirected_to '/settings/edit?tab=notifications'
86 assert_redirected_to '/settings/edit?tab=notifications'
87 mail = ActionMailer::Base.deliveries.last
87 mail = ActionMailer::Base.deliveries.last
88 assert_not_nil mail
88 assert_not_nil mail
89 user = User.find(1)
89 user = User.find(1)
90 assert_equal [user.mail], mail.bcc
90 assert_equal [user.mail], mail.bcc
91 end
91 end
92
92
93 def test_test_email_failure_should_display_the_error
93 def test_test_email_failure_should_display_the_error
94 Mailer.stubs(:deliver_test).raises(Exception, 'Some error message')
94 Mailer.stubs(:deliver_test_email).raises(Exception, 'Some error message')
95 get :test_email
95 get :test_email
96 assert_redirected_to '/settings/edit?tab=notifications'
96 assert_redirected_to '/settings/edit?tab=notifications'
97 assert_match /Some error message/, flash[:error]
97 assert_match /Some error message/, flash[:error]
98 end
98 end
99
99
100 def test_no_plugins
100 def test_no_plugins
101 Redmine::Plugin.clear
101 Redmine::Plugin.clear
102
102
103 get :plugins
103 get :plugins
104 assert_response :success
104 assert_response :success
105 assert_template 'plugins'
105 assert_template 'plugins'
106 end
106 end
107
107
108 def test_plugins
108 def test_plugins
109 # Register a few plugins
109 # Register a few plugins
110 Redmine::Plugin.register :foo do
110 Redmine::Plugin.register :foo do
111 name 'Foo plugin'
111 name 'Foo plugin'
112 author 'John Smith'
112 author 'John Smith'
113 description 'This is a test plugin'
113 description 'This is a test plugin'
114 version '0.0.1'
114 version '0.0.1'
115 settings :default => {'sample_setting' => 'value', 'foo'=>'bar'}, :partial => 'foo/settings'
115 settings :default => {'sample_setting' => 'value', 'foo'=>'bar'}, :partial => 'foo/settings'
116 end
116 end
117 Redmine::Plugin.register :bar do
117 Redmine::Plugin.register :bar do
118 end
118 end
119
119
120 get :plugins
120 get :plugins
121 assert_response :success
121 assert_response :success
122 assert_template 'plugins'
122 assert_template 'plugins'
123
123
124 assert_tag :td, :child => { :tag => 'span', :content => 'Foo plugin' }
124 assert_tag :td, :child => { :tag => 'span', :content => 'Foo plugin' }
125 assert_tag :td, :child => { :tag => 'span', :content => 'Bar' }
125 assert_tag :td, :child => { :tag => 'span', :content => 'Bar' }
126 end
126 end
127
127
128 def test_info
128 def test_info
129 get :info
129 get :info
130 assert_response :success
130 assert_response :success
131 assert_template 'info'
131 assert_template 'info'
132 end
132 end
133
133
134 def test_admin_menu_plugin_extension
134 def test_admin_menu_plugin_extension
135 Redmine::MenuManager.map :admin_menu do |menu|
135 Redmine::MenuManager.map :admin_menu do |menu|
136 menu.push :test_admin_menu_plugin_extension, '/foo/bar', :caption => 'Test'
136 menu.push :test_admin_menu_plugin_extension, '/foo/bar', :caption => 'Test'
137 end
137 end
138
138
139 get :index
139 get :index
140 assert_response :success
140 assert_response :success
141 assert_tag :a, :attributes => { :href => '/foo/bar' },
141 assert_tag :a, :attributes => { :href => '/foo/bar' },
142 :content => 'Test'
142 :content => 'Test'
143
143
144 Redmine::MenuManager.map :admin_menu do |menu|
144 Redmine::MenuManager.map :admin_menu do |menu|
145 menu.delete :test_admin_menu_plugin_extension
145 menu.delete :test_admin_menu_plugin_extension
146 end
146 end
147 end
147 end
148
148
149 private
149 private
150
150
151 def delete_configuration_data
151 def delete_configuration_data
152 Role.delete_all('builtin = 0')
152 Role.delete_all('builtin = 0')
153 Tracker.delete_all
153 Tracker.delete_all
154 IssueStatus.delete_all
154 IssueStatus.delete_all
155 Enumeration.delete_all
155 Enumeration.delete_all
156 end
156 end
157 end
157 end
@@ -1,550 +1,550
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 end
169 end
170
170
171 def test_email_headers_should_include_sender
171 def test_email_headers_should_include_sender
172 issue = Issue.find(1)
172 issue = Issue.find(1)
173 Mailer.deliver_issue_add(issue)
173 Mailer.deliver_issue_add(issue)
174 mail = last_email
174 mail = last_email
175 assert_equal issue.author.login, mail.header_string('X-Redmine-Sender')
175 assert_equal issue.author.login, mail.header_string('X-Redmine-Sender')
176 end
176 end
177
177
178 def test_plain_text_mail
178 def test_plain_text_mail
179 Setting.plain_text_mail = 1
179 Setting.plain_text_mail = 1
180 journal = Journal.find(2)
180 journal = Journal.find(2)
181 Mailer.deliver_issue_edit(journal)
181 Mailer.deliver_issue_edit(journal)
182 mail = last_email
182 mail = last_email
183 assert_equal "text/plain", mail.content_type
183 assert_equal "text/plain", mail.content_type
184 assert_equal 0, mail.parts.size
184 assert_equal 0, mail.parts.size
185 assert !mail.encoded.include?('href')
185 assert !mail.encoded.include?('href')
186 end
186 end
187
187
188 def test_html_mail
188 def test_html_mail
189 Setting.plain_text_mail = 0
189 Setting.plain_text_mail = 0
190 journal = Journal.find(2)
190 journal = Journal.find(2)
191 Mailer.deliver_issue_edit(journal)
191 Mailer.deliver_issue_edit(journal)
192 mail = last_email
192 mail = last_email
193 assert_equal 2, mail.parts.size
193 assert_equal 2, mail.parts.size
194 assert mail.encoded.include?('href')
194 assert mail.encoded.include?('href')
195 end
195 end
196
196
197 def test_from_header
197 def test_from_header
198 with_settings :mail_from => 'redmine@example.net' do
198 with_settings :mail_from => 'redmine@example.net' do
199 Mailer.deliver_test(User.find(1))
199 Mailer.deliver_test_email(User.find(1))
200 end
200 end
201 mail = last_email
201 mail = last_email
202 assert_equal 'redmine@example.net', mail.from_addrs.first.address
202 assert_equal 'redmine@example.net', mail.from_addrs.first.address
203 end
203 end
204
204
205 def test_from_header_with_phrase
205 def test_from_header_with_phrase
206 with_settings :mail_from => 'Redmine app <redmine@example.net>' do
206 with_settings :mail_from => 'Redmine app <redmine@example.net>' do
207 Mailer.deliver_test(User.find(1))
207 Mailer.deliver_test_email(User.find(1))
208 end
208 end
209 mail = last_email
209 mail = last_email
210 assert_equal 'redmine@example.net', mail.from_addrs.first.address
210 assert_equal 'redmine@example.net', mail.from_addrs.first.address
211 assert_equal 'Redmine app', mail.from_addrs.first.name
211 assert_equal 'Redmine app', mail.from_addrs.first.name
212 end
212 end
213
213
214 def test_should_not_send_email_without_recipient
214 def test_should_not_send_email_without_recipient
215 news = News.find(:first)
215 news = News.find(:first)
216 user = news.author
216 user = news.author
217 # Remove members except news author
217 # Remove members except news author
218 news.project.memberships.each {|m| m.destroy unless m.user == user}
218 news.project.memberships.each {|m| m.destroy unless m.user == user}
219
219
220 user.pref[:no_self_notified] = false
220 user.pref[:no_self_notified] = false
221 user.pref.save
221 user.pref.save
222 User.current = user
222 User.current = user
223 Mailer.deliver_news_added(news.reload)
223 Mailer.deliver_news_added(news.reload)
224 assert_equal 1, last_email.bcc.size
224 assert_equal 1, last_email.bcc.size
225
225
226 # nobody to notify
226 # nobody to notify
227 user.pref[:no_self_notified] = true
227 user.pref[:no_self_notified] = true
228 user.pref.save
228 user.pref.save
229 User.current = user
229 User.current = user
230 ActionMailer::Base.deliveries.clear
230 ActionMailer::Base.deliveries.clear
231 Mailer.deliver_news_added(news.reload)
231 Mailer.deliver_news_added(news.reload)
232 assert ActionMailer::Base.deliveries.empty?
232 assert ActionMailer::Base.deliveries.empty?
233 end
233 end
234
234
235 def test_issue_add_message_id
235 def test_issue_add_message_id
236 issue = Issue.find(1)
236 issue = Issue.find(1)
237 Mailer.deliver_issue_add(issue)
237 Mailer.deliver_issue_add(issue)
238 mail = last_email
238 mail = last_email
239 assert_equal Mailer.message_id_for(issue), mail.message_id
239 assert_equal Mailer.message_id_for(issue), mail.message_id
240 assert_nil mail.references
240 assert_nil mail.references
241 end
241 end
242
242
243 def test_issue_edit_message_id
243 def test_issue_edit_message_id
244 journal = Journal.find(1)
244 journal = Journal.find(1)
245 Mailer.deliver_issue_edit(journal)
245 Mailer.deliver_issue_edit(journal)
246 mail = last_email
246 mail = last_email
247 assert_equal Mailer.message_id_for(journal), mail.message_id
247 assert_equal Mailer.message_id_for(journal), mail.message_id
248 assert_equal Mailer.message_id_for(journal.issue), mail.references.first.to_s
248 assert_equal Mailer.message_id_for(journal.issue), mail.references.first.to_s
249 assert_select_email do
249 assert_select_email do
250 # link to the update
250 # link to the update
251 assert_select "a[href=?]",
251 assert_select "a[href=?]",
252 "http://mydomain.foo/issues/#{journal.journalized_id}#change-#{journal.id}"
252 "http://mydomain.foo/issues/#{journal.journalized_id}#change-#{journal.id}"
253 end
253 end
254 end
254 end
255
255
256 def test_message_posted_message_id
256 def test_message_posted_message_id
257 message = Message.find(1)
257 message = Message.find(1)
258 Mailer.deliver_message_posted(message)
258 Mailer.deliver_message_posted(message)
259 mail = last_email
259 mail = last_email
260 assert_equal Mailer.message_id_for(message), mail.message_id
260 assert_equal Mailer.message_id_for(message), mail.message_id
261 assert_nil mail.references
261 assert_nil mail.references
262 assert_select_email do
262 assert_select_email do
263 # link to the message
263 # link to the message
264 assert_select "a[href=?]",
264 assert_select "a[href=?]",
265 "http://mydomain.foo/boards/#{message.board.id}/topics/#{message.id}",
265 "http://mydomain.foo/boards/#{message.board.id}/topics/#{message.id}",
266 :text => message.subject
266 :text => message.subject
267 end
267 end
268 end
268 end
269
269
270 def test_reply_posted_message_id
270 def test_reply_posted_message_id
271 message = Message.find(3)
271 message = Message.find(3)
272 Mailer.deliver_message_posted(message)
272 Mailer.deliver_message_posted(message)
273 mail = last_email
273 mail = last_email
274 assert_equal Mailer.message_id_for(message), mail.message_id
274 assert_equal Mailer.message_id_for(message), mail.message_id
275 assert_equal Mailer.message_id_for(message.parent), mail.references.first.to_s
275 assert_equal Mailer.message_id_for(message.parent), mail.references.first.to_s
276 assert_select_email do
276 assert_select_email do
277 # link to the reply
277 # link to the reply
278 assert_select "a[href=?]",
278 assert_select "a[href=?]",
279 "http://mydomain.foo/boards/#{message.board.id}/topics/#{message.root.id}?r=#{message.id}#message-#{message.id}",
279 "http://mydomain.foo/boards/#{message.board.id}/topics/#{message.root.id}?r=#{message.id}#message-#{message.id}",
280 :text => message.subject
280 :text => message.subject
281 end
281 end
282 end
282 end
283
283
284 context("#issue_add") do
284 context("#issue_add") do
285 setup do
285 setup do
286 ActionMailer::Base.deliveries.clear
286 ActionMailer::Base.deliveries.clear
287 Setting.bcc_recipients = '1'
287 Setting.bcc_recipients = '1'
288 @issue = Issue.find(1)
288 @issue = Issue.find(1)
289 end
289 end
290
290
291 should "notify project members" do
291 should "notify project members" do
292 assert Mailer.deliver_issue_add(@issue)
292 assert Mailer.deliver_issue_add(@issue)
293 assert last_email.bcc.include?('dlopper@somenet.foo')
293 assert last_email.bcc.include?('dlopper@somenet.foo')
294 end
294 end
295
295
296 should "not notify project members that are not allow to view the issue" do
296 should "not notify project members that are not allow to view the issue" do
297 Role.find(2).remove_permission!(:view_issues)
297 Role.find(2).remove_permission!(:view_issues)
298 assert Mailer.deliver_issue_add(@issue)
298 assert Mailer.deliver_issue_add(@issue)
299 assert !last_email.bcc.include?('dlopper@somenet.foo')
299 assert !last_email.bcc.include?('dlopper@somenet.foo')
300 end
300 end
301
301
302 should "notify issue watchers" do
302 should "notify issue watchers" do
303 user = User.find(9)
303 user = User.find(9)
304 # minimal email notification options
304 # minimal email notification options
305 user.pref[:no_self_notified] = '1'
305 user.pref[:no_self_notified] = '1'
306 user.pref.save
306 user.pref.save
307 user.mail_notification = false
307 user.mail_notification = false
308 user.save
308 user.save
309
309
310 Watcher.create!(:watchable => @issue, :user => user)
310 Watcher.create!(:watchable => @issue, :user => user)
311 assert Mailer.deliver_issue_add(@issue)
311 assert Mailer.deliver_issue_add(@issue)
312 assert last_email.bcc.include?(user.mail)
312 assert last_email.bcc.include?(user.mail)
313 end
313 end
314
314
315 should "not notify watchers not allowed to view the issue" do
315 should "not notify watchers not allowed to view the issue" do
316 user = User.find(9)
316 user = User.find(9)
317 Watcher.create!(:watchable => @issue, :user => user)
317 Watcher.create!(:watchable => @issue, :user => user)
318 Role.non_member.remove_permission!(:view_issues)
318 Role.non_member.remove_permission!(:view_issues)
319 assert Mailer.deliver_issue_add(@issue)
319 assert Mailer.deliver_issue_add(@issue)
320 assert !last_email.bcc.include?(user.mail)
320 assert !last_email.bcc.include?(user.mail)
321 end
321 end
322 end
322 end
323
323
324 # test mailer methods for each language
324 # test mailer methods for each language
325 def test_issue_add
325 def test_issue_add
326 issue = Issue.find(1)
326 issue = Issue.find(1)
327 valid_languages.each do |lang|
327 valid_languages.each do |lang|
328 Setting.default_language = lang.to_s
328 Setting.default_language = lang.to_s
329 assert Mailer.deliver_issue_add(issue)
329 assert Mailer.deliver_issue_add(issue)
330 end
330 end
331 end
331 end
332
332
333 def test_issue_edit
333 def test_issue_edit
334 journal = Journal.find(1)
334 journal = Journal.find(1)
335 valid_languages.each do |lang|
335 valid_languages.each do |lang|
336 Setting.default_language = lang.to_s
336 Setting.default_language = lang.to_s
337 assert Mailer.deliver_issue_edit(journal)
337 assert Mailer.deliver_issue_edit(journal)
338 end
338 end
339 end
339 end
340
340
341 def test_document_added
341 def test_document_added
342 document = Document.find(1)
342 document = Document.find(1)
343 valid_languages.each do |lang|
343 valid_languages.each do |lang|
344 Setting.default_language = lang.to_s
344 Setting.default_language = lang.to_s
345 assert Mailer.deliver_document_added(document)
345 assert Mailer.deliver_document_added(document)
346 end
346 end
347 end
347 end
348
348
349 def test_attachments_added
349 def test_attachments_added
350 attachements = [ Attachment.find_by_container_type('Document') ]
350 attachements = [ Attachment.find_by_container_type('Document') ]
351 valid_languages.each do |lang|
351 valid_languages.each do |lang|
352 Setting.default_language = lang.to_s
352 Setting.default_language = lang.to_s
353 assert Mailer.deliver_attachments_added(attachements)
353 assert Mailer.deliver_attachments_added(attachements)
354 end
354 end
355 end
355 end
356
356
357 def test_version_file_added
357 def test_version_file_added
358 attachements = [ Attachment.find_by_container_type('Version') ]
358 attachements = [ Attachment.find_by_container_type('Version') ]
359 assert Mailer.deliver_attachments_added(attachements)
359 assert Mailer.deliver_attachments_added(attachements)
360 assert_not_nil last_email.bcc
360 assert_not_nil last_email.bcc
361 assert last_email.bcc.any?
361 assert last_email.bcc.any?
362 assert_select_email do
362 assert_select_email do
363 assert_select "a[href=?]", "http://mydomain.foo/projects/ecookbook/files"
363 assert_select "a[href=?]", "http://mydomain.foo/projects/ecookbook/files"
364 end
364 end
365 end
365 end
366
366
367 def test_project_file_added
367 def test_project_file_added
368 attachements = [ Attachment.find_by_container_type('Project') ]
368 attachements = [ Attachment.find_by_container_type('Project') ]
369 assert Mailer.deliver_attachments_added(attachements)
369 assert Mailer.deliver_attachments_added(attachements)
370 assert_not_nil last_email.bcc
370 assert_not_nil last_email.bcc
371 assert last_email.bcc.any?
371 assert last_email.bcc.any?
372 assert_select_email do
372 assert_select_email do
373 assert_select "a[href=?]", "http://mydomain.foo/projects/ecookbook/files"
373 assert_select "a[href=?]", "http://mydomain.foo/projects/ecookbook/files"
374 end
374 end
375 end
375 end
376
376
377 def test_news_added
377 def test_news_added
378 news = News.find(:first)
378 news = News.find(:first)
379 valid_languages.each do |lang|
379 valid_languages.each do |lang|
380 Setting.default_language = lang.to_s
380 Setting.default_language = lang.to_s
381 assert Mailer.deliver_news_added(news)
381 assert Mailer.deliver_news_added(news)
382 end
382 end
383 end
383 end
384
384
385 def test_news_comment_added
385 def test_news_comment_added
386 comment = Comment.find(2)
386 comment = Comment.find(2)
387 valid_languages.each do |lang|
387 valid_languages.each do |lang|
388 Setting.default_language = lang.to_s
388 Setting.default_language = lang.to_s
389 assert Mailer.deliver_news_comment_added(comment)
389 assert Mailer.deliver_news_comment_added(comment)
390 end
390 end
391 end
391 end
392
392
393 def test_message_posted
393 def test_message_posted
394 message = Message.find(:first)
394 message = Message.find(:first)
395 recipients = ([message.root] + message.root.children).collect {|m| m.author.mail if m.author}
395 recipients = ([message.root] + message.root.children).collect {|m| m.author.mail if m.author}
396 recipients = recipients.compact.uniq
396 recipients = recipients.compact.uniq
397 valid_languages.each do |lang|
397 valid_languages.each do |lang|
398 Setting.default_language = lang.to_s
398 Setting.default_language = lang.to_s
399 assert Mailer.deliver_message_posted(message)
399 assert Mailer.deliver_message_posted(message)
400 end
400 end
401 end
401 end
402
402
403 def test_wiki_content_added
403 def test_wiki_content_added
404 content = WikiContent.find(1)
404 content = WikiContent.find(1)
405 valid_languages.each do |lang|
405 valid_languages.each do |lang|
406 Setting.default_language = lang.to_s
406 Setting.default_language = lang.to_s
407 assert_difference 'ActionMailer::Base.deliveries.size' do
407 assert_difference 'ActionMailer::Base.deliveries.size' do
408 assert Mailer.deliver_wiki_content_added(content)
408 assert Mailer.deliver_wiki_content_added(content)
409 end
409 end
410 end
410 end
411 end
411 end
412
412
413 def test_wiki_content_updated
413 def test_wiki_content_updated
414 content = WikiContent.find(1)
414 content = WikiContent.find(1)
415 valid_languages.each do |lang|
415 valid_languages.each do |lang|
416 Setting.default_language = lang.to_s
416 Setting.default_language = lang.to_s
417 assert_difference 'ActionMailer::Base.deliveries.size' do
417 assert_difference 'ActionMailer::Base.deliveries.size' do
418 assert Mailer.deliver_wiki_content_updated(content)
418 assert Mailer.deliver_wiki_content_updated(content)
419 end
419 end
420 end
420 end
421 end
421 end
422
422
423 def test_account_information
423 def test_account_information
424 user = User.find(2)
424 user = User.find(2)
425 valid_languages.each do |lang|
425 valid_languages.each do |lang|
426 user.update_attribute :language, lang.to_s
426 user.update_attribute :language, lang.to_s
427 user.reload
427 user.reload
428 assert Mailer.deliver_account_information(user, 'pAsswORd')
428 assert Mailer.deliver_account_information(user, 'pAsswORd')
429 end
429 end
430 end
430 end
431
431
432 def test_lost_password
432 def test_lost_password
433 token = Token.find(2)
433 token = Token.find(2)
434 valid_languages.each do |lang|
434 valid_languages.each do |lang|
435 token.user.update_attribute :language, lang.to_s
435 token.user.update_attribute :language, lang.to_s
436 token.reload
436 token.reload
437 assert Mailer.deliver_lost_password(token)
437 assert Mailer.deliver_lost_password(token)
438 end
438 end
439 end
439 end
440
440
441 def test_register
441 def test_register
442 token = Token.find(1)
442 token = Token.find(1)
443 Setting.host_name = 'redmine.foo'
443 Setting.host_name = 'redmine.foo'
444 Setting.protocol = 'https'
444 Setting.protocol = 'https'
445
445
446 valid_languages.each do |lang|
446 valid_languages.each do |lang|
447 token.user.update_attribute :language, lang.to_s
447 token.user.update_attribute :language, lang.to_s
448 token.reload
448 token.reload
449 ActionMailer::Base.deliveries.clear
449 ActionMailer::Base.deliveries.clear
450 assert Mailer.deliver_register(token)
450 assert Mailer.deliver_register(token)
451 mail = last_email
451 mail = last_email
452 assert_select_email do
452 assert_select_email do
453 assert_select "a[href=?]",
453 assert_select "a[href=?]",
454 "https://redmine.foo/account/activate?token=#{token.value}",
454 "https://redmine.foo/account/activate?token=#{token.value}",
455 :text => "https://redmine.foo/account/activate?token=#{token.value}"
455 :text => "https://redmine.foo/account/activate?token=#{token.value}"
456 end
456 end
457 end
457 end
458 end
458 end
459
459
460 def test_test
460 def test_test
461 user = User.find(1)
461 user = User.find(1)
462 valid_languages.each do |lang|
462 valid_languages.each do |lang|
463 user.update_attribute :language, lang.to_s
463 user.update_attribute :language, lang.to_s
464 assert Mailer.deliver_test(user)
464 assert Mailer.deliver_test_email(user)
465 end
465 end
466 end
466 end
467
467
468 def test_reminders
468 def test_reminders
469 Mailer.reminders(:days => 42)
469 Mailer.reminders(:days => 42)
470 assert_equal 1, ActionMailer::Base.deliveries.size
470 assert_equal 1, ActionMailer::Base.deliveries.size
471 mail = last_email
471 mail = last_email
472 assert mail.bcc.include?('dlopper@somenet.foo')
472 assert mail.bcc.include?('dlopper@somenet.foo')
473 assert mail.body.include?('Bug #3: Error 281 when updating a recipe')
473 assert mail.body.include?('Bug #3: Error 281 when updating a recipe')
474 assert_equal '1 issue(s) due in the next 42 days', mail.subject
474 assert_equal '1 issue(s) due in the next 42 days', mail.subject
475 end
475 end
476
476
477 def test_reminders_should_not_include_closed_issues
477 def test_reminders_should_not_include_closed_issues
478 with_settings :default_language => 'en' do
478 with_settings :default_language => 'en' do
479 Issue.create!(:project_id => 1, :tracker_id => 1, :status_id => 5,
479 Issue.create!(:project_id => 1, :tracker_id => 1, :status_id => 5,
480 :subject => 'Closed issue', :assigned_to_id => 3,
480 :subject => 'Closed issue', :assigned_to_id => 3,
481 :due_date => 5.days.from_now,
481 :due_date => 5.days.from_now,
482 :author_id => 2)
482 :author_id => 2)
483 ActionMailer::Base.deliveries.clear
483 ActionMailer::Base.deliveries.clear
484
484
485 Mailer.reminders(:days => 42)
485 Mailer.reminders(:days => 42)
486 assert_equal 1, ActionMailer::Base.deliveries.size
486 assert_equal 1, ActionMailer::Base.deliveries.size
487 mail = last_email
487 mail = last_email
488 assert mail.bcc.include?('dlopper@somenet.foo')
488 assert mail.bcc.include?('dlopper@somenet.foo')
489 assert !mail.body.include?('Closed issue')
489 assert !mail.body.include?('Closed issue')
490 end
490 end
491 end
491 end
492
492
493 def test_reminders_for_users
493 def test_reminders_for_users
494 Mailer.reminders(:days => 42, :users => ['5'])
494 Mailer.reminders(:days => 42, :users => ['5'])
495 assert_equal 0, ActionMailer::Base.deliveries.size # No mail for dlopper
495 assert_equal 0, ActionMailer::Base.deliveries.size # No mail for dlopper
496 Mailer.reminders(:days => 42, :users => ['3'])
496 Mailer.reminders(:days => 42, :users => ['3'])
497 assert_equal 1, ActionMailer::Base.deliveries.size # No mail for dlopper
497 assert_equal 1, ActionMailer::Base.deliveries.size # No mail for dlopper
498 mail = last_email
498 mail = last_email
499 assert mail.bcc.include?('dlopper@somenet.foo')
499 assert mail.bcc.include?('dlopper@somenet.foo')
500 assert mail.body.include?('Bug #3: Error 281 when updating a recipe')
500 assert mail.body.include?('Bug #3: Error 281 when updating a recipe')
501 end
501 end
502
502
503 def last_email
503 def last_email
504 mail = ActionMailer::Base.deliveries.last
504 mail = ActionMailer::Base.deliveries.last
505 assert_not_nil mail
505 assert_not_nil mail
506 mail
506 mail
507 end
507 end
508
508
509 def test_mailer_should_not_change_locale
509 def test_mailer_should_not_change_locale
510 Setting.default_language = 'en'
510 Setting.default_language = 'en'
511 # Set current language to italian
511 # Set current language to italian
512 set_language_if_valid 'it'
512 set_language_if_valid 'it'
513 # Send an email to a french user
513 # Send an email to a french user
514 user = User.find(1)
514 user = User.find(1)
515 user.language = 'fr'
515 user.language = 'fr'
516 Mailer.deliver_account_activated(user)
516 Mailer.deliver_account_activated(user)
517 mail = last_email
517 mail = last_email
518 assert mail.body.include?('Votre compte')
518 assert mail.body.include?('Votre compte')
519
519
520 assert_equal :it, current_language
520 assert_equal :it, current_language
521 end
521 end
522
522
523 def test_with_deliveries_off
523 def test_with_deliveries_off
524 Mailer.with_deliveries false do
524 Mailer.with_deliveries false do
525 Mailer.deliver_test(User.find(1))
525 Mailer.deliver_test_email(User.find(1))
526 end
526 end
527 assert ActionMailer::Base.deliveries.empty?
527 assert ActionMailer::Base.deliveries.empty?
528 # should restore perform_deliveries
528 # should restore perform_deliveries
529 assert ActionMailer::Base.perform_deliveries
529 assert ActionMailer::Base.perform_deliveries
530 end
530 end
531
531
532 def test_tmail_to_header_field_should_not_include_blank_lines
532 def test_tmail_to_header_field_should_not_include_blank_lines
533 mail = TMail::Mail.new
533 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",
534 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"]
535 "b.user@example.com", "w.user2@example.com", "f.smith@example.com", "info2@example.com", "w.pupkin@example.com"]
536
536
537 assert !mail.encoded.strip.split("\r\n").detect(&:blank?), "#{mail.encoded} malformed"
537 assert !mail.encoded.strip.split("\r\n").detect(&:blank?), "#{mail.encoded} malformed"
538 end
538 end
539
539
540 def test_layout_should_include_the_emails_header
540 def test_layout_should_include_the_emails_header
541 with_settings :emails_header => "*Header content*" do
541 with_settings :emails_header => "*Header content*" do
542 assert Mailer.deliver_test(User.find(1))
542 assert Mailer.deliver_test_email(User.find(1))
543 assert_select_email do
543 assert_select_email do
544 assert_select ".header" do
544 assert_select ".header" do
545 assert_select "strong", :text => "Header content"
545 assert_select "strong", :text => "Header content"
546 end
546 end
547 end
547 end
548 end
548 end
549 end
549 end
550 end
550 end
General Comments 0
You need to be logged in to leave comments. Login now