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