annotate test/unit/mail_handler_test.rb @ 36:de76cd3e8c8e cc-branches

* Probably abortive experiments in extracting the branch from Hg
author Chris Cannam <chris.cannam@soundsoftware.ac.uk>
date Wed, 20 Oct 2010 10:07:29 +0100
parents 513646585e45
children 94944d00e43c
rev   line source
Chris@0 1 # encoding: utf-8
Chris@0 2 #
Chris@0 3 # Redmine - project management software
Chris@0 4 # Copyright (C) 2006-2009 Jean-Philippe Lang
Chris@0 5 #
Chris@0 6 # This program is free software; you can redistribute it and/or
Chris@0 7 # modify it under the terms of the GNU General Public License
Chris@0 8 # as published by the Free Software Foundation; either version 2
Chris@0 9 # of the License, or (at your option) any later version.
Chris@0 10 #
Chris@0 11 # This program is distributed in the hope that it will be useful,
Chris@0 12 # but WITHOUT ANY WARRANTY; without even the implied warranty of
Chris@0 13 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
Chris@0 14 # GNU General Public License for more details.
Chris@0 15 #
Chris@0 16 # You should have received a copy of the GNU General Public License
Chris@0 17 # along with this program; if not, write to the Free Software
Chris@0 18 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
Chris@0 19
Chris@0 20 require File.dirname(__FILE__) + '/../test_helper'
Chris@0 21
Chris@0 22 class MailHandlerTest < ActiveSupport::TestCase
Chris@0 23 fixtures :users, :projects,
Chris@0 24 :enabled_modules,
Chris@0 25 :roles,
Chris@0 26 :members,
Chris@0 27 :member_roles,
Chris@0 28 :issues,
Chris@0 29 :issue_statuses,
Chris@0 30 :workflows,
Chris@0 31 :trackers,
Chris@0 32 :projects_trackers,
Chris@0 33 :enumerations,
Chris@0 34 :issue_categories,
Chris@0 35 :custom_fields,
Chris@0 36 :custom_fields_trackers,
Chris@0 37 :boards,
Chris@0 38 :messages
Chris@0 39
Chris@0 40 FIXTURES_PATH = File.dirname(__FILE__) + '/../fixtures/mail_handler'
Chris@0 41
Chris@0 42 def setup
Chris@0 43 ActionMailer::Base.deliveries.clear
Chris@0 44 end
Chris@0 45
Chris@0 46 def test_add_issue
Chris@0 47 ActionMailer::Base.deliveries.clear
Chris@0 48 # This email contains: 'Project: onlinestore'
Chris@0 49 issue = submit_email('ticket_on_given_project.eml')
Chris@0 50 assert issue.is_a?(Issue)
Chris@0 51 assert !issue.new_record?
Chris@0 52 issue.reload
Chris@0 53 assert_equal 'New ticket on a given project', issue.subject
Chris@0 54 assert_equal User.find_by_login('jsmith'), issue.author
Chris@0 55 assert_equal Project.find(2), issue.project
Chris@0 56 assert_equal IssueStatus.find_by_name('Resolved'), issue.status
Chris@0 57 assert issue.description.include?('Lorem ipsum dolor sit amet, consectetuer adipiscing elit.')
Chris@0 58 assert_equal '2010-01-01', issue.start_date.to_s
Chris@0 59 assert_equal '2010-12-31', issue.due_date.to_s
Chris@0 60 assert_equal User.find_by_login('jsmith'), issue.assigned_to
Chris@0 61 # keywords should be removed from the email body
Chris@0 62 assert !issue.description.match(/^Project:/i)
Chris@0 63 assert !issue.description.match(/^Status:/i)
Chris@0 64 # Email notification should be sent
Chris@0 65 mail = ActionMailer::Base.deliveries.last
Chris@0 66 assert_not_nil mail
Chris@0 67 assert mail.subject.include?('New ticket on a given project')
Chris@0 68 end
Chris@0 69
Chris@0 70 def test_add_issue_with_status
Chris@0 71 # This email contains: 'Project: onlinestore' and 'Status: Resolved'
Chris@0 72 issue = submit_email('ticket_on_given_project.eml')
Chris@0 73 assert issue.is_a?(Issue)
Chris@0 74 assert !issue.new_record?
Chris@0 75 issue.reload
Chris@0 76 assert_equal Project.find(2), issue.project
Chris@0 77 assert_equal IssueStatus.find_by_name("Resolved"), issue.status
Chris@0 78 end
Chris@0 79
Chris@0 80 def test_add_issue_with_attributes_override
Chris@0 81 issue = submit_email('ticket_with_attributes.eml', :allow_override => 'tracker,category,priority')
Chris@0 82 assert issue.is_a?(Issue)
Chris@0 83 assert !issue.new_record?
Chris@0 84 issue.reload
Chris@0 85 assert_equal 'New ticket on a given project', issue.subject
Chris@0 86 assert_equal User.find_by_login('jsmith'), issue.author
Chris@0 87 assert_equal Project.find(2), issue.project
Chris@0 88 assert_equal 'Feature request', issue.tracker.to_s
Chris@0 89 assert_equal 'Stock management', issue.category.to_s
Chris@0 90 assert_equal 'Urgent', issue.priority.to_s
Chris@0 91 assert issue.description.include?('Lorem ipsum dolor sit amet, consectetuer adipiscing elit.')
Chris@0 92 end
Chris@0 93
Chris@0 94 def test_add_issue_with_partial_attributes_override
Chris@0 95 issue = submit_email('ticket_with_attributes.eml', :issue => {:priority => 'High'}, :allow_override => ['tracker'])
Chris@0 96 assert issue.is_a?(Issue)
Chris@0 97 assert !issue.new_record?
Chris@0 98 issue.reload
Chris@0 99 assert_equal 'New ticket on a given project', issue.subject
Chris@0 100 assert_equal User.find_by_login('jsmith'), issue.author
Chris@0 101 assert_equal Project.find(2), issue.project
Chris@0 102 assert_equal 'Feature request', issue.tracker.to_s
Chris@0 103 assert_nil issue.category
Chris@0 104 assert_equal 'High', issue.priority.to_s
Chris@0 105 assert issue.description.include?('Lorem ipsum dolor sit amet, consectetuer adipiscing elit.')
Chris@0 106 end
Chris@0 107
Chris@0 108 def test_add_issue_with_spaces_between_attribute_and_separator
Chris@0 109 issue = submit_email('ticket_with_spaces_between_attribute_and_separator.eml', :allow_override => 'tracker,category,priority')
Chris@0 110 assert issue.is_a?(Issue)
Chris@0 111 assert !issue.new_record?
Chris@0 112 issue.reload
Chris@0 113 assert_equal 'New ticket on a given project', issue.subject
Chris@0 114 assert_equal User.find_by_login('jsmith'), issue.author
Chris@0 115 assert_equal Project.find(2), issue.project
Chris@0 116 assert_equal 'Feature request', issue.tracker.to_s
Chris@0 117 assert_equal 'Stock management', issue.category.to_s
Chris@0 118 assert_equal 'Urgent', issue.priority.to_s
Chris@0 119 assert issue.description.include?('Lorem ipsum dolor sit amet, consectetuer adipiscing elit.')
Chris@0 120 end
Chris@0 121
Chris@0 122
Chris@0 123 def test_add_issue_with_attachment_to_specific_project
Chris@0 124 issue = submit_email('ticket_with_attachment.eml', :issue => {:project => 'onlinestore'})
Chris@0 125 assert issue.is_a?(Issue)
Chris@0 126 assert !issue.new_record?
Chris@0 127 issue.reload
Chris@0 128 assert_equal 'Ticket created by email with attachment', issue.subject
Chris@0 129 assert_equal User.find_by_login('jsmith'), issue.author
Chris@0 130 assert_equal Project.find(2), issue.project
Chris@0 131 assert_equal 'This is a new ticket with attachments', issue.description
Chris@0 132 # Attachment properties
Chris@0 133 assert_equal 1, issue.attachments.size
Chris@0 134 assert_equal 'Paella.jpg', issue.attachments.first.filename
Chris@0 135 assert_equal 'image/jpeg', issue.attachments.first.content_type
Chris@0 136 assert_equal 10790, issue.attachments.first.filesize
Chris@0 137 end
Chris@0 138
Chris@0 139 def test_add_issue_with_custom_fields
Chris@0 140 issue = submit_email('ticket_with_custom_fields.eml', :issue => {:project => 'onlinestore'})
Chris@0 141 assert issue.is_a?(Issue)
Chris@0 142 assert !issue.new_record?
Chris@0 143 issue.reload
Chris@0 144 assert_equal 'New ticket with custom field values', issue.subject
Chris@0 145 assert_equal 'Value for a custom field', issue.custom_value_for(CustomField.find_by_name('Searchable field')).value
Chris@0 146 assert !issue.description.match(/^searchable field:/i)
Chris@0 147 end
Chris@0 148
Chris@0 149 def test_add_issue_with_cc
Chris@0 150 issue = submit_email('ticket_with_cc.eml', :issue => {:project => 'ecookbook'})
Chris@0 151 assert issue.is_a?(Issue)
Chris@0 152 assert !issue.new_record?
Chris@0 153 issue.reload
Chris@0 154 assert issue.watched_by?(User.find_by_mail('dlopper@somenet.foo'))
Chris@0 155 assert_equal 1, issue.watchers.size
Chris@0 156 end
Chris@0 157
Chris@0 158 def test_add_issue_by_unknown_user
Chris@0 159 assert_no_difference 'User.count' do
Chris@0 160 assert_equal false, submit_email('ticket_by_unknown_user.eml', :issue => {:project => 'ecookbook'})
Chris@0 161 end
Chris@0 162 end
Chris@0 163
Chris@0 164 def test_add_issue_by_anonymous_user
Chris@0 165 Role.anonymous.add_permission!(:add_issues)
Chris@0 166 assert_no_difference 'User.count' do
Chris@0 167 issue = submit_email('ticket_by_unknown_user.eml', :issue => {:project => 'ecookbook'}, :unknown_user => 'accept')
Chris@0 168 assert issue.is_a?(Issue)
Chris@0 169 assert issue.author.anonymous?
Chris@0 170 end
Chris@0 171 end
Chris@0 172
Chris@0 173 def test_add_issue_by_anonymous_user_with_no_from_address
Chris@0 174 Role.anonymous.add_permission!(:add_issues)
Chris@0 175 assert_no_difference 'User.count' do
Chris@0 176 issue = submit_email('ticket_by_empty_user.eml', :issue => {:project => 'ecookbook'}, :unknown_user => 'accept')
Chris@0 177 assert issue.is_a?(Issue)
Chris@0 178 assert issue.author.anonymous?
Chris@0 179 end
Chris@0 180 end
Chris@0 181
Chris@0 182 def test_add_issue_by_anonymous_user_on_private_project
Chris@0 183 Role.anonymous.add_permission!(:add_issues)
Chris@0 184 assert_no_difference 'User.count' do
Chris@0 185 assert_no_difference 'Issue.count' do
Chris@0 186 assert_equal false, submit_email('ticket_by_unknown_user.eml', :issue => {:project => 'onlinestore'}, :unknown_user => 'accept')
Chris@0 187 end
Chris@0 188 end
Chris@0 189 end
Chris@0 190
Chris@0 191 def test_add_issue_by_anonymous_user_on_private_project_without_permission_check
Chris@0 192 assert_no_difference 'User.count' do
Chris@0 193 assert_difference 'Issue.count' do
Chris@0 194 issue = submit_email('ticket_by_unknown_user.eml', :issue => {:project => 'onlinestore'}, :no_permission_check => '1', :unknown_user => 'accept')
Chris@0 195 assert issue.is_a?(Issue)
Chris@0 196 assert issue.author.anonymous?
Chris@0 197 assert !issue.project.is_public?
Chris@0 198 end
Chris@0 199 end
Chris@0 200 end
Chris@0 201
Chris@0 202 def test_add_issue_by_created_user
Chris@0 203 Setting.default_language = 'en'
Chris@0 204 assert_difference 'User.count' do
Chris@0 205 issue = submit_email('ticket_by_unknown_user.eml', :issue => {:project => 'ecookbook'}, :unknown_user => 'create')
Chris@0 206 assert issue.is_a?(Issue)
Chris@0 207 assert issue.author.active?
Chris@0 208 assert_equal 'john.doe@somenet.foo', issue.author.mail
Chris@0 209 assert_equal 'John', issue.author.firstname
Chris@0 210 assert_equal 'Doe', issue.author.lastname
Chris@0 211
Chris@0 212 # account information
Chris@0 213 email = ActionMailer::Base.deliveries.first
Chris@0 214 assert_not_nil email
Chris@0 215 assert email.subject.include?('account activation')
Chris@0 216 login = email.body.match(/\* Login: (.*)$/)[1]
Chris@0 217 password = email.body.match(/\* Password: (.*)$/)[1]
Chris@0 218 assert_equal issue.author, User.try_to_login(login, password)
Chris@0 219 end
Chris@0 220 end
Chris@0 221
Chris@0 222 def test_add_issue_without_from_header
Chris@0 223 Role.anonymous.add_permission!(:add_issues)
Chris@0 224 assert_equal false, submit_email('ticket_without_from_header.eml')
Chris@0 225 end
Chris@0 226
Chris@0 227 def test_add_issue_with_japanese_keywords
Chris@0 228 tracker = Tracker.create!(:name => '開発')
Chris@0 229 Project.find(1).trackers << tracker
Chris@0 230 issue = submit_email('japanese_keywords_iso_2022_jp.eml', :issue => {:project => 'ecookbook'}, :allow_override => 'tracker')
Chris@0 231 assert_kind_of Issue, issue
Chris@0 232 assert_equal tracker, issue.tracker
Chris@0 233 end
Chris@0 234
Chris@0 235 def test_should_ignore_emails_from_emission_address
Chris@0 236 Role.anonymous.add_permission!(:add_issues)
Chris@0 237 assert_no_difference 'User.count' do
Chris@0 238 assert_equal false, submit_email('ticket_from_emission_address.eml', :issue => {:project => 'ecookbook'}, :unknown_user => 'create')
Chris@0 239 end
Chris@0 240 end
Chris@0 241
Chris@0 242 def test_add_issue_should_send_email_notification
Chris@0 243 ActionMailer::Base.deliveries.clear
Chris@0 244 # This email contains: 'Project: onlinestore'
Chris@0 245 issue = submit_email('ticket_on_given_project.eml')
Chris@0 246 assert issue.is_a?(Issue)
Chris@0 247 assert_equal 1, ActionMailer::Base.deliveries.size
Chris@0 248 end
Chris@0 249
Chris@0 250 def test_add_issue_note
Chris@0 251 journal = submit_email('ticket_reply.eml')
Chris@0 252 assert journal.is_a?(Journal)
Chris@0 253 assert_equal User.find_by_login('jsmith'), journal.user
Chris@0 254 assert_equal Issue.find(2), journal.journalized
Chris@0 255 assert_match /This is reply/, journal.notes
Chris@0 256 end
Chris@0 257
Chris@0 258 def test_add_issue_note_with_attribute_changes
Chris@0 259 # This email contains: 'Status: Resolved'
Chris@0 260 journal = submit_email('ticket_reply_with_status.eml')
Chris@0 261 assert journal.is_a?(Journal)
Chris@0 262 issue = Issue.find(journal.issue.id)
Chris@0 263 assert_equal User.find_by_login('jsmith'), journal.user
Chris@0 264 assert_equal Issue.find(2), journal.journalized
Chris@0 265 assert_match /This is reply/, journal.notes
Chris@0 266 assert_equal IssueStatus.find_by_name("Resolved"), issue.status
Chris@0 267 assert_equal '2010-01-01', issue.start_date.to_s
Chris@0 268 assert_equal '2010-12-31', issue.due_date.to_s
Chris@0 269 assert_equal User.find_by_login('jsmith'), issue.assigned_to
Chris@0 270 end
Chris@0 271
Chris@0 272 def test_add_issue_note_should_send_email_notification
Chris@0 273 ActionMailer::Base.deliveries.clear
Chris@0 274 journal = submit_email('ticket_reply.eml')
Chris@0 275 assert journal.is_a?(Journal)
Chris@0 276 assert_equal 1, ActionMailer::Base.deliveries.size
Chris@0 277 end
Chris@0 278
Chris@0 279 def test_reply_to_a_message
Chris@0 280 m = submit_email('message_reply.eml')
Chris@0 281 assert m.is_a?(Message)
Chris@0 282 assert !m.new_record?
Chris@0 283 m.reload
Chris@0 284 assert_equal 'Reply via email', m.subject
Chris@0 285 # The email replies to message #2 which is part of the thread of message #1
Chris@0 286 assert_equal Message.find(1), m.parent
Chris@0 287 end
Chris@0 288
Chris@0 289 def test_reply_to_a_message_by_subject
Chris@0 290 m = submit_email('message_reply_by_subject.eml')
Chris@0 291 assert m.is_a?(Message)
Chris@0 292 assert !m.new_record?
Chris@0 293 m.reload
Chris@0 294 assert_equal 'Reply to the first post', m.subject
Chris@0 295 assert_equal Message.find(1), m.parent
Chris@0 296 end
Chris@0 297
Chris@0 298 def test_should_strip_tags_of_html_only_emails
Chris@0 299 issue = submit_email('ticket_html_only.eml', :issue => {:project => 'ecookbook'})
Chris@0 300 assert issue.is_a?(Issue)
Chris@0 301 assert !issue.new_record?
Chris@0 302 issue.reload
Chris@0 303 assert_equal 'HTML email', issue.subject
Chris@0 304 assert_equal 'This is a html-only email.', issue.description
Chris@0 305 end
Chris@0 306
Chris@0 307 context "truncate emails based on the Setting" do
Chris@0 308 context "with no setting" do
Chris@0 309 setup do
Chris@0 310 Setting.mail_handler_body_delimiters = ''
Chris@0 311 end
Chris@0 312
Chris@0 313 should "add the entire email into the issue" do
Chris@0 314 issue = submit_email('ticket_on_given_project.eml')
Chris@0 315 assert_issue_created(issue)
Chris@0 316 assert issue.description.include?('---')
Chris@0 317 assert issue.description.include?('This paragraph is after the delimiter')
Chris@0 318 end
Chris@0 319 end
Chris@0 320
Chris@0 321 context "with a single string" do
Chris@0 322 setup do
Chris@0 323 Setting.mail_handler_body_delimiters = '---'
Chris@0 324 end
Chris@0 325
Chris@0 326 should "truncate the email at the delimiter for the issue" do
Chris@0 327 issue = submit_email('ticket_on_given_project.eml')
Chris@0 328 assert_issue_created(issue)
Chris@0 329 assert issue.description.include?('This paragraph is before delimiters')
Chris@0 330 assert issue.description.include?('--- This line starts with a delimiter')
Chris@0 331 assert !issue.description.match(/^---$/)
Chris@0 332 assert !issue.description.include?('This paragraph is after the delimiter')
Chris@0 333 end
Chris@0 334 end
Chris@0 335
Chris@0 336 context "with multiple strings" do
Chris@0 337 setup do
Chris@0 338 Setting.mail_handler_body_delimiters = "---\nBREAK"
Chris@0 339 end
Chris@0 340
Chris@0 341 should "truncate the email at the first delimiter found (BREAK)" do
Chris@0 342 issue = submit_email('ticket_on_given_project.eml')
Chris@0 343 assert_issue_created(issue)
Chris@0 344 assert issue.description.include?('This paragraph is before delimiters')
Chris@0 345 assert !issue.description.include?('BREAK')
Chris@0 346 assert !issue.description.include?('This paragraph is between delimiters')
Chris@0 347 assert !issue.description.match(/^---$/)
Chris@0 348 assert !issue.description.include?('This paragraph is after the delimiter')
Chris@0 349 end
Chris@0 350 end
Chris@0 351 end
Chris@0 352
Chris@0 353 def test_email_with_long_subject_line
Chris@0 354 issue = submit_email('ticket_with_long_subject.eml')
Chris@0 355 assert issue.is_a?(Issue)
Chris@0 356 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@0 357 end
Chris@0 358
Chris@0 359 private
Chris@0 360
Chris@0 361 def submit_email(filename, options={})
Chris@0 362 raw = IO.read(File.join(FIXTURES_PATH, filename))
Chris@0 363 MailHandler.receive(raw, options)
Chris@0 364 end
Chris@0 365
Chris@0 366 def assert_issue_created(issue)
Chris@0 367 assert issue.is_a?(Issue)
Chris@0 368 assert !issue.new_record?
Chris@0 369 issue.reload
Chris@0 370 end
Chris@0 371 end