##// END OF EJS Templates
code layout cleanup unit mail handler test fixtures...
Toshi MARUYAMA -
r8618:682efe399dcc
parent child
Show More
@@ -1,546 +1,534
1 # encoding: utf-8
1 # encoding: utf-8
2 #
2 #
3 # Redmine - project management software
3 # Redmine - project management software
4 # Copyright (C) 2006-2011 Jean-Philippe Lang
4 # Copyright (C) 2006-2011 Jean-Philippe Lang
5 #
5 #
6 # This program is free software; you can redistribute it and/or
6 # This program is free software; you can redistribute it and/or
7 # modify it under the terms of the GNU General Public License
7 # modify it under the terms of the GNU General Public License
8 # as published by the Free Software Foundation; either version 2
8 # as published by the Free Software Foundation; either version 2
9 # of the License, or (at your option) any later version.
9 # of the License, or (at your option) any later version.
10 #
10 #
11 # This program is distributed in the hope that it will be useful,
11 # This program is distributed in the hope that it will be useful,
12 # but WITHOUT ANY WARRANTY; without even the implied warranty of
12 # but WITHOUT ANY WARRANTY; without even the implied warranty of
13 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 # GNU General Public License for more details.
14 # GNU General Public License for more details.
15 #
15 #
16 # You should have received a copy of the GNU General Public License
16 # You should have received a copy of the GNU General Public License
17 # along with this program; if not, write to the Free Software
17 # along with this program; if not, write to the Free Software
18 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
18 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
19
19
20 require File.expand_path('../../test_helper', __FILE__)
20 require File.expand_path('../../test_helper', __FILE__)
21
21
22 class MailHandlerTest < ActiveSupport::TestCase
22 class MailHandlerTest < ActiveSupport::TestCase
23 fixtures :users, :projects,
23 fixtures :users, :projects, :enabled_modules, :roles,
24 :enabled_modules,
24 :members, :member_roles, :users,
25 :roles,
25 :issues, :issue_statuses,
26 :members,
26 :workflows, :trackers, :projects_trackers,
27 :member_roles,
27 :versions, :enumerations, :issue_categories,
28 :users,
28 :custom_fields, :custom_fields_trackers, :custom_fields_projects,
29 :issues,
29 :boards, :messages
30 :issue_statuses,
31 :workflows,
32 :trackers,
33 :projects_trackers,
34 :versions,
35 :enumerations,
36 :issue_categories,
37 :custom_fields,
38 :custom_fields_trackers,
39 :custom_fields_projects,
40 :boards,
41 :messages
42
30
43 FIXTURES_PATH = File.dirname(__FILE__) + '/../fixtures/mail_handler'
31 FIXTURES_PATH = File.dirname(__FILE__) + '/../fixtures/mail_handler'
44
32
45 def setup
33 def setup
46 ActionMailer::Base.deliveries.clear
34 ActionMailer::Base.deliveries.clear
47 Setting.notified_events = Redmine::Notifiable.all.collect(&:name)
35 Setting.notified_events = Redmine::Notifiable.all.collect(&:name)
48 end
36 end
49
37
50 def test_add_issue
38 def test_add_issue
51 ActionMailer::Base.deliveries.clear
39 ActionMailer::Base.deliveries.clear
52 # This email contains: 'Project: onlinestore'
40 # This email contains: 'Project: onlinestore'
53 issue = submit_email('ticket_on_given_project.eml')
41 issue = submit_email('ticket_on_given_project.eml')
54 assert issue.is_a?(Issue)
42 assert issue.is_a?(Issue)
55 assert !issue.new_record?
43 assert !issue.new_record?
56 issue.reload
44 issue.reload
57 assert_equal Project.find(2), issue.project
45 assert_equal Project.find(2), issue.project
58 assert_equal issue.project.trackers.first, issue.tracker
46 assert_equal issue.project.trackers.first, issue.tracker
59 assert_equal 'New ticket on a given project', issue.subject
47 assert_equal 'New ticket on a given project', issue.subject
60 assert_equal User.find_by_login('jsmith'), issue.author
48 assert_equal User.find_by_login('jsmith'), issue.author
61 assert_equal IssueStatus.find_by_name('Resolved'), issue.status
49 assert_equal IssueStatus.find_by_name('Resolved'), issue.status
62 assert issue.description.include?('Lorem ipsum dolor sit amet, consectetuer adipiscing elit.')
50 assert issue.description.include?('Lorem ipsum dolor sit amet, consectetuer adipiscing elit.')
63 assert_equal '2010-01-01', issue.start_date.to_s
51 assert_equal '2010-01-01', issue.start_date.to_s
64 assert_equal '2010-12-31', issue.due_date.to_s
52 assert_equal '2010-12-31', issue.due_date.to_s
65 assert_equal User.find_by_login('jsmith'), issue.assigned_to
53 assert_equal User.find_by_login('jsmith'), issue.assigned_to
66 assert_equal Version.find_by_name('Alpha'), issue.fixed_version
54 assert_equal Version.find_by_name('Alpha'), issue.fixed_version
67 assert_equal 2.5, issue.estimated_hours
55 assert_equal 2.5, issue.estimated_hours
68 assert_equal 30, issue.done_ratio
56 assert_equal 30, issue.done_ratio
69 assert_equal [issue.id, 1, 2], [issue.root_id, issue.lft, issue.rgt]
57 assert_equal [issue.id, 1, 2], [issue.root_id, issue.lft, issue.rgt]
70 # keywords should be removed from the email body
58 # keywords should be removed from the email body
71 assert !issue.description.match(/^Project:/i)
59 assert !issue.description.match(/^Project:/i)
72 assert !issue.description.match(/^Status:/i)
60 assert !issue.description.match(/^Status:/i)
73 assert !issue.description.match(/^Start Date:/i)
61 assert !issue.description.match(/^Start Date:/i)
74 # Email notification should be sent
62 # Email notification should be sent
75 mail = ActionMailer::Base.deliveries.last
63 mail = ActionMailer::Base.deliveries.last
76 assert_not_nil mail
64 assert_not_nil mail
77 assert mail.subject.include?('New ticket on a given project')
65 assert mail.subject.include?('New ticket on a given project')
78 end
66 end
79
67
80 def test_add_issue_with_default_tracker
68 def test_add_issue_with_default_tracker
81 # This email contains: 'Project: onlinestore'
69 # This email contains: 'Project: onlinestore'
82 issue = submit_email('ticket_on_given_project.eml', :issue => {:tracker => 'Support request'})
70 issue = submit_email('ticket_on_given_project.eml', :issue => {:tracker => 'Support request'})
83 assert issue.is_a?(Issue)
71 assert issue.is_a?(Issue)
84 assert !issue.new_record?
72 assert !issue.new_record?
85 issue.reload
73 issue.reload
86 assert_equal 'Support request', issue.tracker.name
74 assert_equal 'Support request', issue.tracker.name
87 end
75 end
88
76
89 def test_add_issue_with_status
77 def test_add_issue_with_status
90 # This email contains: 'Project: onlinestore' and 'Status: Resolved'
78 # This email contains: 'Project: onlinestore' and 'Status: Resolved'
91 issue = submit_email('ticket_on_given_project.eml')
79 issue = submit_email('ticket_on_given_project.eml')
92 assert issue.is_a?(Issue)
80 assert issue.is_a?(Issue)
93 assert !issue.new_record?
81 assert !issue.new_record?
94 issue.reload
82 issue.reload
95 assert_equal Project.find(2), issue.project
83 assert_equal Project.find(2), issue.project
96 assert_equal IssueStatus.find_by_name("Resolved"), issue.status
84 assert_equal IssueStatus.find_by_name("Resolved"), issue.status
97 end
85 end
98
86
99 def test_add_issue_with_attributes_override
87 def test_add_issue_with_attributes_override
100 issue = submit_email('ticket_with_attributes.eml', :allow_override => 'tracker,category,priority')
88 issue = submit_email('ticket_with_attributes.eml', :allow_override => 'tracker,category,priority')
101 assert issue.is_a?(Issue)
89 assert issue.is_a?(Issue)
102 assert !issue.new_record?
90 assert !issue.new_record?
103 issue.reload
91 issue.reload
104 assert_equal 'New ticket on a given project', issue.subject
92 assert_equal 'New ticket on a given project', issue.subject
105 assert_equal User.find_by_login('jsmith'), issue.author
93 assert_equal User.find_by_login('jsmith'), issue.author
106 assert_equal Project.find(2), issue.project
94 assert_equal Project.find(2), issue.project
107 assert_equal 'Feature request', issue.tracker.to_s
95 assert_equal 'Feature request', issue.tracker.to_s
108 assert_equal 'Stock management', issue.category.to_s
96 assert_equal 'Stock management', issue.category.to_s
109 assert_equal 'Urgent', issue.priority.to_s
97 assert_equal 'Urgent', issue.priority.to_s
110 assert issue.description.include?('Lorem ipsum dolor sit amet, consectetuer adipiscing elit.')
98 assert issue.description.include?('Lorem ipsum dolor sit amet, consectetuer adipiscing elit.')
111 end
99 end
112
100
113 def test_add_issue_with_group_assignment
101 def test_add_issue_with_group_assignment
114 with_settings :issue_group_assignment => '1' do
102 with_settings :issue_group_assignment => '1' do
115 issue = submit_email('ticket_on_given_project.eml') do |email|
103 issue = submit_email('ticket_on_given_project.eml') do |email|
116 email.gsub!('Assigned to: John Smith', 'Assigned to: B Team')
104 email.gsub!('Assigned to: John Smith', 'Assigned to: B Team')
117 end
105 end
118 assert issue.is_a?(Issue)
106 assert issue.is_a?(Issue)
119 assert !issue.new_record?
107 assert !issue.new_record?
120 issue.reload
108 issue.reload
121 assert_equal Group.find(11), issue.assigned_to
109 assert_equal Group.find(11), issue.assigned_to
122 end
110 end
123 end
111 end
124
112
125 def test_add_issue_with_partial_attributes_override
113 def test_add_issue_with_partial_attributes_override
126 issue = submit_email('ticket_with_attributes.eml', :issue => {:priority => 'High'}, :allow_override => ['tracker'])
114 issue = submit_email('ticket_with_attributes.eml', :issue => {:priority => 'High'}, :allow_override => ['tracker'])
127 assert issue.is_a?(Issue)
115 assert issue.is_a?(Issue)
128 assert !issue.new_record?
116 assert !issue.new_record?
129 issue.reload
117 issue.reload
130 assert_equal 'New ticket on a given project', issue.subject
118 assert_equal 'New ticket on a given project', issue.subject
131 assert_equal User.find_by_login('jsmith'), issue.author
119 assert_equal User.find_by_login('jsmith'), issue.author
132 assert_equal Project.find(2), issue.project
120 assert_equal Project.find(2), issue.project
133 assert_equal 'Feature request', issue.tracker.to_s
121 assert_equal 'Feature request', issue.tracker.to_s
134 assert_nil issue.category
122 assert_nil issue.category
135 assert_equal 'High', issue.priority.to_s
123 assert_equal 'High', issue.priority.to_s
136 assert issue.description.include?('Lorem ipsum dolor sit amet, consectetuer adipiscing elit.')
124 assert issue.description.include?('Lorem ipsum dolor sit amet, consectetuer adipiscing elit.')
137 end
125 end
138
126
139 def test_add_issue_with_spaces_between_attribute_and_separator
127 def test_add_issue_with_spaces_between_attribute_and_separator
140 issue = submit_email('ticket_with_spaces_between_attribute_and_separator.eml', :allow_override => 'tracker,category,priority')
128 issue = submit_email('ticket_with_spaces_between_attribute_and_separator.eml', :allow_override => 'tracker,category,priority')
141 assert issue.is_a?(Issue)
129 assert issue.is_a?(Issue)
142 assert !issue.new_record?
130 assert !issue.new_record?
143 issue.reload
131 issue.reload
144 assert_equal 'New ticket on a given project', issue.subject
132 assert_equal 'New ticket on a given project', issue.subject
145 assert_equal User.find_by_login('jsmith'), issue.author
133 assert_equal User.find_by_login('jsmith'), issue.author
146 assert_equal Project.find(2), issue.project
134 assert_equal Project.find(2), issue.project
147 assert_equal 'Feature request', issue.tracker.to_s
135 assert_equal 'Feature request', issue.tracker.to_s
148 assert_equal 'Stock management', issue.category.to_s
136 assert_equal 'Stock management', issue.category.to_s
149 assert_equal 'Urgent', issue.priority.to_s
137 assert_equal 'Urgent', issue.priority.to_s
150 assert issue.description.include?('Lorem ipsum dolor sit amet, consectetuer adipiscing elit.')
138 assert issue.description.include?('Lorem ipsum dolor sit amet, consectetuer adipiscing elit.')
151 end
139 end
152
140
153 def test_add_issue_with_attachment_to_specific_project
141 def test_add_issue_with_attachment_to_specific_project
154 issue = submit_email('ticket_with_attachment.eml', :issue => {:project => 'onlinestore'})
142 issue = submit_email('ticket_with_attachment.eml', :issue => {:project => 'onlinestore'})
155 assert issue.is_a?(Issue)
143 assert issue.is_a?(Issue)
156 assert !issue.new_record?
144 assert !issue.new_record?
157 issue.reload
145 issue.reload
158 assert_equal 'Ticket created by email with attachment', issue.subject
146 assert_equal 'Ticket created by email with attachment', issue.subject
159 assert_equal User.find_by_login('jsmith'), issue.author
147 assert_equal User.find_by_login('jsmith'), issue.author
160 assert_equal Project.find(2), issue.project
148 assert_equal Project.find(2), issue.project
161 assert_equal 'This is a new ticket with attachments', issue.description
149 assert_equal 'This is a new ticket with attachments', issue.description
162 # Attachment properties
150 # Attachment properties
163 assert_equal 1, issue.attachments.size
151 assert_equal 1, issue.attachments.size
164 assert_equal 'Paella.jpg', issue.attachments.first.filename
152 assert_equal 'Paella.jpg', issue.attachments.first.filename
165 assert_equal 'image/jpeg', issue.attachments.first.content_type
153 assert_equal 'image/jpeg', issue.attachments.first.content_type
166 assert_equal 10790, issue.attachments.first.filesize
154 assert_equal 10790, issue.attachments.first.filesize
167 end
155 end
168
156
169 def test_add_issue_with_custom_fields
157 def test_add_issue_with_custom_fields
170 issue = submit_email('ticket_with_custom_fields.eml', :issue => {:project => 'onlinestore'})
158 issue = submit_email('ticket_with_custom_fields.eml', :issue => {:project => 'onlinestore'})
171 assert issue.is_a?(Issue)
159 assert issue.is_a?(Issue)
172 assert !issue.new_record?
160 assert !issue.new_record?
173 issue.reload
161 issue.reload
174 assert_equal 'New ticket with custom field values', issue.subject
162 assert_equal 'New ticket with custom field values', issue.subject
175 assert_equal 'Value for a custom field', issue.custom_value_for(CustomField.find_by_name('Searchable field')).value
163 assert_equal 'Value for a custom field', issue.custom_value_for(CustomField.find_by_name('Searchable field')).value
176 assert !issue.description.match(/^searchable field:/i)
164 assert !issue.description.match(/^searchable field:/i)
177 end
165 end
178
166
179 def test_add_issue_with_cc
167 def test_add_issue_with_cc
180 issue = submit_email('ticket_with_cc.eml', :issue => {:project => 'ecookbook'})
168 issue = submit_email('ticket_with_cc.eml', :issue => {:project => 'ecookbook'})
181 assert issue.is_a?(Issue)
169 assert issue.is_a?(Issue)
182 assert !issue.new_record?
170 assert !issue.new_record?
183 issue.reload
171 issue.reload
184 assert issue.watched_by?(User.find_by_mail('dlopper@somenet.foo'))
172 assert issue.watched_by?(User.find_by_mail('dlopper@somenet.foo'))
185 assert_equal 1, issue.watcher_user_ids.size
173 assert_equal 1, issue.watcher_user_ids.size
186 end
174 end
187
175
188 def test_add_issue_by_unknown_user
176 def test_add_issue_by_unknown_user
189 assert_no_difference 'User.count' do
177 assert_no_difference 'User.count' do
190 assert_equal false, submit_email('ticket_by_unknown_user.eml', :issue => {:project => 'ecookbook'})
178 assert_equal false, submit_email('ticket_by_unknown_user.eml', :issue => {:project => 'ecookbook'})
191 end
179 end
192 end
180 end
193
181
194 def test_add_issue_by_anonymous_user
182 def test_add_issue_by_anonymous_user
195 Role.anonymous.add_permission!(:add_issues)
183 Role.anonymous.add_permission!(:add_issues)
196 assert_no_difference 'User.count' do
184 assert_no_difference 'User.count' do
197 issue = submit_email('ticket_by_unknown_user.eml', :issue => {:project => 'ecookbook'}, :unknown_user => 'accept')
185 issue = submit_email('ticket_by_unknown_user.eml', :issue => {:project => 'ecookbook'}, :unknown_user => 'accept')
198 assert issue.is_a?(Issue)
186 assert issue.is_a?(Issue)
199 assert issue.author.anonymous?
187 assert issue.author.anonymous?
200 end
188 end
201 end
189 end
202
190
203 def test_add_issue_by_anonymous_user_with_no_from_address
191 def test_add_issue_by_anonymous_user_with_no_from_address
204 Role.anonymous.add_permission!(:add_issues)
192 Role.anonymous.add_permission!(:add_issues)
205 assert_no_difference 'User.count' do
193 assert_no_difference 'User.count' do
206 issue = submit_email('ticket_by_empty_user.eml', :issue => {:project => 'ecookbook'}, :unknown_user => 'accept')
194 issue = submit_email('ticket_by_empty_user.eml', :issue => {:project => 'ecookbook'}, :unknown_user => 'accept')
207 assert issue.is_a?(Issue)
195 assert issue.is_a?(Issue)
208 assert issue.author.anonymous?
196 assert issue.author.anonymous?
209 end
197 end
210 end
198 end
211
199
212 def test_add_issue_by_anonymous_user_on_private_project
200 def test_add_issue_by_anonymous_user_on_private_project
213 Role.anonymous.add_permission!(:add_issues)
201 Role.anonymous.add_permission!(:add_issues)
214 assert_no_difference 'User.count' do
202 assert_no_difference 'User.count' do
215 assert_no_difference 'Issue.count' do
203 assert_no_difference 'Issue.count' do
216 assert_equal false, submit_email('ticket_by_unknown_user.eml', :issue => {:project => 'onlinestore'}, :unknown_user => 'accept')
204 assert_equal false, submit_email('ticket_by_unknown_user.eml', :issue => {:project => 'onlinestore'}, :unknown_user => 'accept')
217 end
205 end
218 end
206 end
219 end
207 end
220
208
221 def test_add_issue_by_anonymous_user_on_private_project_without_permission_check
209 def test_add_issue_by_anonymous_user_on_private_project_without_permission_check
222 assert_no_difference 'User.count' do
210 assert_no_difference 'User.count' do
223 assert_difference 'Issue.count' do
211 assert_difference 'Issue.count' do
224 issue = submit_email('ticket_by_unknown_user.eml', :issue => {:project => 'onlinestore'}, :no_permission_check => '1', :unknown_user => 'accept')
212 issue = submit_email('ticket_by_unknown_user.eml', :issue => {:project => 'onlinestore'}, :no_permission_check => '1', :unknown_user => 'accept')
225 assert issue.is_a?(Issue)
213 assert issue.is_a?(Issue)
226 assert issue.author.anonymous?
214 assert issue.author.anonymous?
227 assert !issue.project.is_public?
215 assert !issue.project.is_public?
228 assert_equal [issue.id, 1, 2], [issue.root_id, issue.lft, issue.rgt]
216 assert_equal [issue.id, 1, 2], [issue.root_id, issue.lft, issue.rgt]
229 end
217 end
230 end
218 end
231 end
219 end
232
220
233 def test_add_issue_by_created_user
221 def test_add_issue_by_created_user
234 Setting.default_language = 'en'
222 Setting.default_language = 'en'
235 assert_difference 'User.count' do
223 assert_difference 'User.count' do
236 issue = submit_email('ticket_by_unknown_user.eml', :issue => {:project => 'ecookbook'}, :unknown_user => 'create')
224 issue = submit_email('ticket_by_unknown_user.eml', :issue => {:project => 'ecookbook'}, :unknown_user => 'create')
237 assert issue.is_a?(Issue)
225 assert issue.is_a?(Issue)
238 assert issue.author.active?
226 assert issue.author.active?
239 assert_equal 'john.doe@somenet.foo', issue.author.mail
227 assert_equal 'john.doe@somenet.foo', issue.author.mail
240 assert_equal 'John', issue.author.firstname
228 assert_equal 'John', issue.author.firstname
241 assert_equal 'Doe', issue.author.lastname
229 assert_equal 'Doe', issue.author.lastname
242
230
243 # account information
231 # account information
244 email = ActionMailer::Base.deliveries.first
232 email = ActionMailer::Base.deliveries.first
245 assert_not_nil email
233 assert_not_nil email
246 assert email.subject.include?('account activation')
234 assert email.subject.include?('account activation')
247 login = email.body.match(/\* Login: (.*)$/)[1]
235 login = email.body.match(/\* Login: (.*)$/)[1]
248 password = email.body.match(/\* Password: (.*)$/)[1]
236 password = email.body.match(/\* Password: (.*)$/)[1]
249 assert_equal issue.author, User.try_to_login(login, password)
237 assert_equal issue.author, User.try_to_login(login, password)
250 end
238 end
251 end
239 end
252
240
253 def test_add_issue_without_from_header
241 def test_add_issue_without_from_header
254 Role.anonymous.add_permission!(:add_issues)
242 Role.anonymous.add_permission!(:add_issues)
255 assert_equal false, submit_email('ticket_without_from_header.eml')
243 assert_equal false, submit_email('ticket_without_from_header.eml')
256 end
244 end
257
245
258 def test_add_issue_with_invalid_attributes
246 def test_add_issue_with_invalid_attributes
259 issue = submit_email('ticket_with_invalid_attributes.eml', :allow_override => 'tracker,category,priority')
247 issue = submit_email('ticket_with_invalid_attributes.eml', :allow_override => 'tracker,category,priority')
260 assert issue.is_a?(Issue)
248 assert issue.is_a?(Issue)
261 assert !issue.new_record?
249 assert !issue.new_record?
262 issue.reload
250 issue.reload
263 assert_nil issue.assigned_to
251 assert_nil issue.assigned_to
264 assert_nil issue.start_date
252 assert_nil issue.start_date
265 assert_nil issue.due_date
253 assert_nil issue.due_date
266 assert_equal 0, issue.done_ratio
254 assert_equal 0, issue.done_ratio
267 assert_equal 'Normal', issue.priority.to_s
255 assert_equal 'Normal', issue.priority.to_s
268 assert issue.description.include?('Lorem ipsum dolor sit amet, consectetuer adipiscing elit.')
256 assert issue.description.include?('Lorem ipsum dolor sit amet, consectetuer adipiscing elit.')
269 end
257 end
270
258
271 def test_add_issue_with_localized_attributes
259 def test_add_issue_with_localized_attributes
272 User.find_by_mail('jsmith@somenet.foo').update_attribute 'language', 'fr'
260 User.find_by_mail('jsmith@somenet.foo').update_attribute 'language', 'fr'
273 issue = submit_email('ticket_with_localized_attributes.eml', :allow_override => 'tracker,category,priority')
261 issue = submit_email('ticket_with_localized_attributes.eml', :allow_override => 'tracker,category,priority')
274 assert issue.is_a?(Issue)
262 assert issue.is_a?(Issue)
275 assert !issue.new_record?
263 assert !issue.new_record?
276 issue.reload
264 issue.reload
277 assert_equal 'New ticket on a given project', issue.subject
265 assert_equal 'New ticket on a given project', issue.subject
278 assert_equal User.find_by_login('jsmith'), issue.author
266 assert_equal User.find_by_login('jsmith'), issue.author
279 assert_equal Project.find(2), issue.project
267 assert_equal Project.find(2), issue.project
280 assert_equal 'Feature request', issue.tracker.to_s
268 assert_equal 'Feature request', issue.tracker.to_s
281 assert_equal 'Stock management', issue.category.to_s
269 assert_equal 'Stock management', issue.category.to_s
282 assert_equal 'Urgent', issue.priority.to_s
270 assert_equal 'Urgent', issue.priority.to_s
283 assert issue.description.include?('Lorem ipsum dolor sit amet, consectetuer adipiscing elit.')
271 assert issue.description.include?('Lorem ipsum dolor sit amet, consectetuer adipiscing elit.')
284 end
272 end
285
273
286 def test_add_issue_with_japanese_keywords
274 def test_add_issue_with_japanese_keywords
287 ja_dev = "\xe9\x96\x8b\xe7\x99\xba"
275 ja_dev = "\xe9\x96\x8b\xe7\x99\xba"
288 ja_dev.force_encoding('UTF-8') if ja_dev.respond_to?(:force_encoding)
276 ja_dev.force_encoding('UTF-8') if ja_dev.respond_to?(:force_encoding)
289 tracker = Tracker.create!(:name => ja_dev)
277 tracker = Tracker.create!(:name => ja_dev)
290 Project.find(1).trackers << tracker
278 Project.find(1).trackers << tracker
291 issue = submit_email('japanese_keywords_iso_2022_jp.eml', :issue => {:project => 'ecookbook'}, :allow_override => 'tracker')
279 issue = submit_email('japanese_keywords_iso_2022_jp.eml', :issue => {:project => 'ecookbook'}, :allow_override => 'tracker')
292 assert_kind_of Issue, issue
280 assert_kind_of Issue, issue
293 assert_equal tracker, issue.tracker
281 assert_equal tracker, issue.tracker
294 end
282 end
295
283
296 def test_add_issue_from_apple_mail
284 def test_add_issue_from_apple_mail
297 issue = submit_email('apple_mail_with_attachment.eml', :issue => {:project => 'ecookbook'})
285 issue = submit_email('apple_mail_with_attachment.eml', :issue => {:project => 'ecookbook'})
298 assert_kind_of Issue, issue
286 assert_kind_of Issue, issue
299 assert_equal 1, issue.attachments.size
287 assert_equal 1, issue.attachments.size
300
288
301 attachment = issue.attachments.first
289 attachment = issue.attachments.first
302 assert_equal 'paella.jpg', attachment.filename
290 assert_equal 'paella.jpg', attachment.filename
303 assert_equal 10790, attachment.filesize
291 assert_equal 10790, attachment.filesize
304 assert File.exist?(attachment.diskfile)
292 assert File.exist?(attachment.diskfile)
305 assert_equal 10790, File.size(attachment.diskfile)
293 assert_equal 10790, File.size(attachment.diskfile)
306 assert_equal 'caaf384198bcbc9563ab5c058acd73cd', attachment.digest
294 assert_equal 'caaf384198bcbc9563ab5c058acd73cd', attachment.digest
307 end
295 end
308
296
309 def test_should_ignore_emails_from_emission_address
297 def test_should_ignore_emails_from_emission_address
310 Role.anonymous.add_permission!(:add_issues)
298 Role.anonymous.add_permission!(:add_issues)
311 assert_no_difference 'User.count' do
299 assert_no_difference 'User.count' do
312 assert_equal false, submit_email('ticket_from_emission_address.eml', :issue => {:project => 'ecookbook'}, :unknown_user => 'create')
300 assert_equal false, submit_email('ticket_from_emission_address.eml', :issue => {:project => 'ecookbook'}, :unknown_user => 'create')
313 end
301 end
314 end
302 end
315
303
316 def test_add_issue_should_send_email_notification
304 def test_add_issue_should_send_email_notification
317 Setting.notified_events = ['issue_added']
305 Setting.notified_events = ['issue_added']
318 ActionMailer::Base.deliveries.clear
306 ActionMailer::Base.deliveries.clear
319 # This email contains: 'Project: onlinestore'
307 # This email contains: 'Project: onlinestore'
320 issue = submit_email('ticket_on_given_project.eml')
308 issue = submit_email('ticket_on_given_project.eml')
321 assert issue.is_a?(Issue)
309 assert issue.is_a?(Issue)
322 assert_equal 1, ActionMailer::Base.deliveries.size
310 assert_equal 1, ActionMailer::Base.deliveries.size
323 end
311 end
324
312
325 def test_update_issue
313 def test_update_issue
326 journal = submit_email('ticket_reply.eml')
314 journal = submit_email('ticket_reply.eml')
327 assert journal.is_a?(Journal)
315 assert journal.is_a?(Journal)
328 assert_equal User.find_by_login('jsmith'), journal.user
316 assert_equal User.find_by_login('jsmith'), journal.user
329 assert_equal Issue.find(2), journal.journalized
317 assert_equal Issue.find(2), journal.journalized
330 assert_match /This is reply/, journal.notes
318 assert_match /This is reply/, journal.notes
331 assert_equal 'Feature request', journal.issue.tracker.name
319 assert_equal 'Feature request', journal.issue.tracker.name
332 end
320 end
333
321
334 def test_update_issue_with_attribute_changes
322 def test_update_issue_with_attribute_changes
335 # This email contains: 'Status: Resolved'
323 # This email contains: 'Status: Resolved'
336 journal = submit_email('ticket_reply_with_status.eml')
324 journal = submit_email('ticket_reply_with_status.eml')
337 assert journal.is_a?(Journal)
325 assert journal.is_a?(Journal)
338 issue = Issue.find(journal.issue.id)
326 issue = Issue.find(journal.issue.id)
339 assert_equal User.find_by_login('jsmith'), journal.user
327 assert_equal User.find_by_login('jsmith'), journal.user
340 assert_equal Issue.find(2), journal.journalized
328 assert_equal Issue.find(2), journal.journalized
341 assert_match /This is reply/, journal.notes
329 assert_match /This is reply/, journal.notes
342 assert_equal 'Feature request', journal.issue.tracker.name
330 assert_equal 'Feature request', journal.issue.tracker.name
343 assert_equal IssueStatus.find_by_name("Resolved"), issue.status
331 assert_equal IssueStatus.find_by_name("Resolved"), issue.status
344 assert_equal '2010-01-01', issue.start_date.to_s
332 assert_equal '2010-01-01', issue.start_date.to_s
345 assert_equal '2010-12-31', issue.due_date.to_s
333 assert_equal '2010-12-31', issue.due_date.to_s
346 assert_equal User.find_by_login('jsmith'), issue.assigned_to
334 assert_equal User.find_by_login('jsmith'), issue.assigned_to
347 assert_equal "52.6", issue.custom_value_for(CustomField.find_by_name('Float field')).value
335 assert_equal "52.6", issue.custom_value_for(CustomField.find_by_name('Float field')).value
348 # keywords should be removed from the email body
336 # keywords should be removed from the email body
349 assert !journal.notes.match(/^Status:/i)
337 assert !journal.notes.match(/^Status:/i)
350 assert !journal.notes.match(/^Start Date:/i)
338 assert !journal.notes.match(/^Start Date:/i)
351 end
339 end
352
340
353 def test_update_issue_with_attachment
341 def test_update_issue_with_attachment
354 assert_difference 'Journal.count' do
342 assert_difference 'Journal.count' do
355 assert_difference 'JournalDetail.count' do
343 assert_difference 'JournalDetail.count' do
356 assert_difference 'Attachment.count' do
344 assert_difference 'Attachment.count' do
357 assert_no_difference 'Issue.count' do
345 assert_no_difference 'Issue.count' do
358 journal = submit_email('ticket_with_attachment.eml') do |raw|
346 journal = submit_email('ticket_with_attachment.eml') do |raw|
359 raw.gsub! /^Subject: .*$/, 'Subject: Re: [Cookbook - Feature #2] (New) Add ingredients categories'
347 raw.gsub! /^Subject: .*$/, 'Subject: Re: [Cookbook - Feature #2] (New) Add ingredients categories'
360 end
348 end
361 end
349 end
362 end
350 end
363 end
351 end
364 end
352 end
365 journal = Journal.first(:order => 'id DESC')
353 journal = Journal.first(:order => 'id DESC')
366 assert_equal Issue.find(2), journal.journalized
354 assert_equal Issue.find(2), journal.journalized
367 assert_equal 1, journal.details.size
355 assert_equal 1, journal.details.size
368
356
369 detail = journal.details.first
357 detail = journal.details.first
370 assert_equal 'attachment', detail.property
358 assert_equal 'attachment', detail.property
371 assert_equal 'Paella.jpg', detail.value
359 assert_equal 'Paella.jpg', detail.value
372 end
360 end
373
361
374 def test_update_issue_should_send_email_notification
362 def test_update_issue_should_send_email_notification
375 ActionMailer::Base.deliveries.clear
363 ActionMailer::Base.deliveries.clear
376 journal = submit_email('ticket_reply.eml')
364 journal = submit_email('ticket_reply.eml')
377 assert journal.is_a?(Journal)
365 assert journal.is_a?(Journal)
378 assert_equal 1, ActionMailer::Base.deliveries.size
366 assert_equal 1, ActionMailer::Base.deliveries.size
379 end
367 end
380
368
381 def test_update_issue_should_not_set_defaults
369 def test_update_issue_should_not_set_defaults
382 journal = submit_email('ticket_reply.eml', :issue => {:tracker => 'Support request', :priority => 'High'})
370 journal = submit_email('ticket_reply.eml', :issue => {:tracker => 'Support request', :priority => 'High'})
383 assert journal.is_a?(Journal)
371 assert journal.is_a?(Journal)
384 assert_match /This is reply/, journal.notes
372 assert_match /This is reply/, journal.notes
385 assert_equal 'Feature request', journal.issue.tracker.name
373 assert_equal 'Feature request', journal.issue.tracker.name
386 assert_equal 'Normal', journal.issue.priority.name
374 assert_equal 'Normal', journal.issue.priority.name
387 end
375 end
388
376
389 def test_reply_to_a_message
377 def test_reply_to_a_message
390 m = submit_email('message_reply.eml')
378 m = submit_email('message_reply.eml')
391 assert m.is_a?(Message)
379 assert m.is_a?(Message)
392 assert !m.new_record?
380 assert !m.new_record?
393 m.reload
381 m.reload
394 assert_equal 'Reply via email', m.subject
382 assert_equal 'Reply via email', m.subject
395 # The email replies to message #2 which is part of the thread of message #1
383 # The email replies to message #2 which is part of the thread of message #1
396 assert_equal Message.find(1), m.parent
384 assert_equal Message.find(1), m.parent
397 end
385 end
398
386
399 def test_reply_to_a_message_by_subject
387 def test_reply_to_a_message_by_subject
400 m = submit_email('message_reply_by_subject.eml')
388 m = submit_email('message_reply_by_subject.eml')
401 assert m.is_a?(Message)
389 assert m.is_a?(Message)
402 assert !m.new_record?
390 assert !m.new_record?
403 m.reload
391 m.reload
404 assert_equal 'Reply to the first post', m.subject
392 assert_equal 'Reply to the first post', m.subject
405 assert_equal Message.find(1), m.parent
393 assert_equal Message.find(1), m.parent
406 end
394 end
407
395
408 def test_should_strip_tags_of_html_only_emails
396 def test_should_strip_tags_of_html_only_emails
409 issue = submit_email('ticket_html_only.eml', :issue => {:project => 'ecookbook'})
397 issue = submit_email('ticket_html_only.eml', :issue => {:project => 'ecookbook'})
410 assert issue.is_a?(Issue)
398 assert issue.is_a?(Issue)
411 assert !issue.new_record?
399 assert !issue.new_record?
412 issue.reload
400 issue.reload
413 assert_equal 'HTML email', issue.subject
401 assert_equal 'HTML email', issue.subject
414 assert_equal 'This is a html-only email.', issue.description
402 assert_equal 'This is a html-only email.', issue.description
415 end
403 end
416
404
417 context "truncate emails based on the Setting" do
405 context "truncate emails based on the Setting" do
418 context "with no setting" do
406 context "with no setting" do
419 setup do
407 setup do
420 Setting.mail_handler_body_delimiters = ''
408 Setting.mail_handler_body_delimiters = ''
421 end
409 end
422
410
423 should "add the entire email into the issue" do
411 should "add the entire email into the issue" do
424 issue = submit_email('ticket_on_given_project.eml')
412 issue = submit_email('ticket_on_given_project.eml')
425 assert_issue_created(issue)
413 assert_issue_created(issue)
426 assert issue.description.include?('---')
414 assert issue.description.include?('---')
427 assert issue.description.include?('This paragraph is after the delimiter')
415 assert issue.description.include?('This paragraph is after the delimiter')
428 end
416 end
429 end
417 end
430
418
431 context "with a single string" do
419 context "with a single string" do
432 setup do
420 setup do
433 Setting.mail_handler_body_delimiters = '---'
421 Setting.mail_handler_body_delimiters = '---'
434 end
422 end
435 should "truncate the email at the delimiter for the issue" do
423 should "truncate the email at the delimiter for the issue" do
436 issue = submit_email('ticket_on_given_project.eml')
424 issue = submit_email('ticket_on_given_project.eml')
437 assert_issue_created(issue)
425 assert_issue_created(issue)
438 assert issue.description.include?('This paragraph is before delimiters')
426 assert issue.description.include?('This paragraph is before delimiters')
439 assert issue.description.include?('--- This line starts with a delimiter')
427 assert issue.description.include?('--- This line starts with a delimiter')
440 assert !issue.description.match(/^---$/)
428 assert !issue.description.match(/^---$/)
441 assert !issue.description.include?('This paragraph is after the delimiter')
429 assert !issue.description.include?('This paragraph is after the delimiter')
442 end
430 end
443 end
431 end
444
432
445 context "with a single quoted reply (e.g. reply to a Redmine email notification)" do
433 context "with a single quoted reply (e.g. reply to a Redmine email notification)" do
446 setup do
434 setup do
447 Setting.mail_handler_body_delimiters = '--- Reply above. Do not remove this line. ---'
435 Setting.mail_handler_body_delimiters = '--- Reply above. Do not remove this line. ---'
448 end
436 end
449 should "truncate the email at the delimiter with the quoted reply symbols (>)" do
437 should "truncate the email at the delimiter with the quoted reply symbols (>)" do
450 journal = submit_email('issue_update_with_quoted_reply_above.eml')
438 journal = submit_email('issue_update_with_quoted_reply_above.eml')
451 assert journal.is_a?(Journal)
439 assert journal.is_a?(Journal)
452 assert journal.notes.include?('An update to the issue by the sender.')
440 assert journal.notes.include?('An update to the issue by the sender.')
453 assert !journal.notes.match(Regexp.escape("--- Reply above. Do not remove this line. ---"))
441 assert !journal.notes.match(Regexp.escape("--- Reply above. Do not remove this line. ---"))
454 assert !journal.notes.include?('Looks like the JSON api for projects was missed.')
442 assert !journal.notes.include?('Looks like the JSON api for projects was missed.')
455 end
443 end
456 end
444 end
457
445
458 context "with multiple quoted replies (e.g. reply to a reply of a Redmine email notification)" do
446 context "with multiple quoted replies (e.g. reply to a reply of a Redmine email notification)" do
459 setup do
447 setup do
460 Setting.mail_handler_body_delimiters = '--- Reply above. Do not remove this line. ---'
448 Setting.mail_handler_body_delimiters = '--- Reply above. Do not remove this line. ---'
461 end
449 end
462 should "truncate the email at the delimiter with the quoted reply symbols (>)" do
450 should "truncate the email at the delimiter with the quoted reply symbols (>)" do
463 journal = submit_email('issue_update_with_multiple_quoted_reply_above.eml')
451 journal = submit_email('issue_update_with_multiple_quoted_reply_above.eml')
464 assert journal.is_a?(Journal)
452 assert journal.is_a?(Journal)
465 assert journal.notes.include?('An update to the issue by the sender.')
453 assert journal.notes.include?('An update to the issue by the sender.')
466 assert !journal.notes.match(Regexp.escape("--- Reply above. Do not remove this line. ---"))
454 assert !journal.notes.match(Regexp.escape("--- Reply above. Do not remove this line. ---"))
467 assert !journal.notes.include?('Looks like the JSON api for projects was missed.')
455 assert !journal.notes.include?('Looks like the JSON api for projects was missed.')
468 end
456 end
469 end
457 end
470
458
471 context "with multiple strings" do
459 context "with multiple strings" do
472 setup do
460 setup do
473 Setting.mail_handler_body_delimiters = "---\nBREAK"
461 Setting.mail_handler_body_delimiters = "---\nBREAK"
474 end
462 end
475 should "truncate the email at the first delimiter found (BREAK)" do
463 should "truncate the email at the first delimiter found (BREAK)" do
476 issue = submit_email('ticket_on_given_project.eml')
464 issue = submit_email('ticket_on_given_project.eml')
477 assert_issue_created(issue)
465 assert_issue_created(issue)
478 assert issue.description.include?('This paragraph is before delimiters')
466 assert issue.description.include?('This paragraph is before delimiters')
479 assert !issue.description.include?('BREAK')
467 assert !issue.description.include?('BREAK')
480 assert !issue.description.include?('This paragraph is between delimiters')
468 assert !issue.description.include?('This paragraph is between delimiters')
481 assert !issue.description.match(/^---$/)
469 assert !issue.description.match(/^---$/)
482 assert !issue.description.include?('This paragraph is after the delimiter')
470 assert !issue.description.include?('This paragraph is after the delimiter')
483 end
471 end
484 end
472 end
485 end
473 end
486
474
487 def test_email_with_long_subject_line
475 def test_email_with_long_subject_line
488 issue = submit_email('ticket_with_long_subject.eml')
476 issue = submit_email('ticket_with_long_subject.eml')
489 assert issue.is_a?(Issue)
477 assert issue.is_a?(Issue)
490 assert_equal issue.subject, 'New ticket on a given project with a very long subject line which exceeds 255 chars and should not be ignored but chopped off. And if the subject line is still not long enough, we just add more text. And more text. Wow, this is really annoying. Especially, if you have nothing to say...'[0,255]
478 assert_equal issue.subject, 'New ticket on a given project with a very long subject line which exceeds 255 chars and should not be ignored but chopped off. And if the subject line is still not long enough, we just add more text. And more text. Wow, this is really annoying. Especially, if you have nothing to say...'[0,255]
491 end
479 end
492
480
493 def test_new_user_from_attributes_should_return_valid_user
481 def test_new_user_from_attributes_should_return_valid_user
494 to_test = {
482 to_test = {
495 # [address, name] => [login, firstname, lastname]
483 # [address, name] => [login, firstname, lastname]
496 ['jsmith@example.net', nil] => ['jsmith@example.net', 'jsmith', '-'],
484 ['jsmith@example.net', nil] => ['jsmith@example.net', 'jsmith', '-'],
497 ['jsmith@example.net', 'John'] => ['jsmith@example.net', 'John', '-'],
485 ['jsmith@example.net', 'John'] => ['jsmith@example.net', 'John', '-'],
498 ['jsmith@example.net', 'John Smith'] => ['jsmith@example.net', 'John', 'Smith'],
486 ['jsmith@example.net', 'John Smith'] => ['jsmith@example.net', 'John', 'Smith'],
499 ['jsmith@example.net', 'John Paul Smith'] => ['jsmith@example.net', 'John', 'Paul Smith'],
487 ['jsmith@example.net', 'John Paul Smith'] => ['jsmith@example.net', 'John', 'Paul Smith'],
500 ['jsmith@example.net', 'AVeryLongFirstnameThatExceedsTheMaximumLength Smith'] => ['jsmith@example.net', 'AVeryLongFirstnameThatExceedsT', 'Smith'],
488 ['jsmith@example.net', 'AVeryLongFirstnameThatExceedsTheMaximumLength Smith'] => ['jsmith@example.net', 'AVeryLongFirstnameThatExceedsT', 'Smith'],
501 ['jsmith@example.net', 'John AVeryLongLastnameThatExceedsTheMaximumLength'] => ['jsmith@example.net', 'John', 'AVeryLongLastnameThatExceedsTh'],
489 ['jsmith@example.net', 'John AVeryLongLastnameThatExceedsTheMaximumLength'] => ['jsmith@example.net', 'John', 'AVeryLongLastnameThatExceedsTh'],
502 ['alongemailaddressthatexceedsloginlength@example.net', 'John Smith'] => ['alongemailaddressthatexceedslo', 'John', 'Smith']
490 ['alongemailaddressthatexceedsloginlength@example.net', 'John Smith'] => ['alongemailaddressthatexceedslo', 'John', 'Smith']
503 }
491 }
504
492
505 to_test.each do |attrs, expected|
493 to_test.each do |attrs, expected|
506 user = MailHandler.new_user_from_attributes(attrs.first, attrs.last)
494 user = MailHandler.new_user_from_attributes(attrs.first, attrs.last)
507
495
508 assert user.valid?
496 assert user.valid?
509 assert_equal attrs.first, user.mail
497 assert_equal attrs.first, user.mail
510 assert_equal expected[0], user.login
498 assert_equal expected[0], user.login
511 assert_equal expected[1], user.firstname
499 assert_equal expected[1], user.firstname
512 assert_equal expected[2], user.lastname
500 assert_equal expected[2], user.lastname
513 end
501 end
514 end
502 end
515
503
516 def test_new_user_from_attributes_should_respect_minimum_password_length
504 def test_new_user_from_attributes_should_respect_minimum_password_length
517 with_settings :password_min_length => 15 do
505 with_settings :password_min_length => 15 do
518 user = MailHandler.new_user_from_attributes('jsmith@example.net')
506 user = MailHandler.new_user_from_attributes('jsmith@example.net')
519 assert user.valid?
507 assert user.valid?
520 assert user.password.length >= 15
508 assert user.password.length >= 15
521 end
509 end
522 end
510 end
523
511
524 def test_new_user_from_attributes_should_use_default_login_if_invalid
512 def test_new_user_from_attributes_should_use_default_login_if_invalid
525 MailHandler.new_user_from_attributes('alongemailaddressthatexceedsloginlength-1@example.net').save!
513 MailHandler.new_user_from_attributes('alongemailaddressthatexceedsloginlength-1@example.net').save!
526
514
527 # another long address that would result in duplicate login
515 # another long address that would result in duplicate login
528 user = MailHandler.new_user_from_attributes('alongemailaddressthatexceedsloginlength-2@example.net')
516 user = MailHandler.new_user_from_attributes('alongemailaddressthatexceedsloginlength-2@example.net')
529 assert user.valid?
517 assert user.valid?
530 assert user.login =~ /^user[a-f0-9]+$/
518 assert user.login =~ /^user[a-f0-9]+$/
531 end
519 end
532
520
533 private
521 private
534
522
535 def submit_email(filename, options={})
523 def submit_email(filename, options={})
536 raw = IO.read(File.join(FIXTURES_PATH, filename))
524 raw = IO.read(File.join(FIXTURES_PATH, filename))
537 yield raw if block_given?
525 yield raw if block_given?
538 MailHandler.receive(raw, options)
526 MailHandler.receive(raw, options)
539 end
527 end
540
528
541 def assert_issue_created(issue)
529 def assert_issue_created(issue)
542 assert issue.is_a?(Issue)
530 assert issue.is_a?(Issue)
543 assert !issue.new_record?
531 assert !issue.new_record?
544 issue.reload
532 issue.reload
545 end
533 end
546 end
534 end
General Comments 0
You need to be logged in to leave comments. Login now