annotate test/unit/mail_handler_test.rb @ 1458:b1f4c9a2af24 bug_794

Makes the default radio button checked by default -- this should fix bug #794.
author luisf <luis.figueira@eecs.qmul.ac.uk>
date Mon, 11 Nov 2013 18:25:22 +0000
parents 433d4f72a19b
children 622f24f53b42 261b3d9a4903
rev   line source
Chris@0 1 # encoding: utf-8
Chris@0 2 #
Chris@0 3 # Redmine - project management software
Chris@1115 4 # Copyright (C) 2006-2012 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@441 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@441 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@119 20 require File.expand_path('../../test_helper', __FILE__)
Chris@0 21
Chris@0 22 class MailHandlerTest < ActiveSupport::TestCase
Chris@1115 23 fixtures :users, :projects, :enabled_modules, :roles,
Chris@1115 24 :members, :member_roles, :users,
Chris@1115 25 :issues, :issue_statuses,
Chris@1115 26 :workflows, :trackers, :projects_trackers,
Chris@1115 27 :versions, :enumerations, :issue_categories,
Chris@1115 28 :custom_fields, :custom_fields_trackers, :custom_fields_projects,
Chris@1115 29 :boards, :messages
Chris@441 30
Chris@0 31 FIXTURES_PATH = File.dirname(__FILE__) + '/../fixtures/mail_handler'
Chris@441 32
Chris@0 33 def setup
Chris@0 34 ActionMailer::Base.deliveries.clear
chris@37 35 Setting.notified_events = Redmine::Notifiable.all.collect(&:name)
Chris@0 36 end
Chris@441 37
Chris@1115 38 def teardown
Chris@1115 39 Setting.clear_cache
Chris@1115 40 end
Chris@1115 41
Chris@0 42 def test_add_issue
Chris@0 43 ActionMailer::Base.deliveries.clear
Chris@0 44 # This email contains: 'Project: onlinestore'
Chris@0 45 issue = submit_email('ticket_on_given_project.eml')
Chris@0 46 assert issue.is_a?(Issue)
Chris@0 47 assert !issue.new_record?
Chris@0 48 issue.reload
Chris@119 49 assert_equal Project.find(2), issue.project
Chris@119 50 assert_equal issue.project.trackers.first, issue.tracker
Chris@0 51 assert_equal 'New ticket on a given project', issue.subject
Chris@0 52 assert_equal User.find_by_login('jsmith'), issue.author
Chris@0 53 assert_equal IssueStatus.find_by_name('Resolved'), issue.status
Chris@0 54 assert issue.description.include?('Lorem ipsum dolor sit amet, consectetuer adipiscing elit.')
Chris@0 55 assert_equal '2010-01-01', issue.start_date.to_s
Chris@0 56 assert_equal '2010-12-31', issue.due_date.to_s
Chris@0 57 assert_equal User.find_by_login('jsmith'), issue.assigned_to
Chris@507 58 assert_equal Version.find_by_name('Alpha'), issue.fixed_version
chris@37 59 assert_equal 2.5, issue.estimated_hours
chris@37 60 assert_equal 30, issue.done_ratio
Chris@119 61 assert_equal [issue.id, 1, 2], [issue.root_id, issue.lft, issue.rgt]
Chris@0 62 # keywords should be removed from the email body
Chris@0 63 assert !issue.description.match(/^Project:/i)
Chris@0 64 assert !issue.description.match(/^Status:/i)
Chris@441 65 assert !issue.description.match(/^Start Date:/i)
Chris@0 66 # Email notification should be sent
Chris@0 67 mail = ActionMailer::Base.deliveries.last
Chris@0 68 assert_not_nil mail
Chris@0 69 assert mail.subject.include?('New ticket on a given project')
Chris@0 70 end
Chris@441 71
Chris@119 72 def test_add_issue_with_default_tracker
Chris@119 73 # This email contains: 'Project: onlinestore'
Chris@1115 74 issue = submit_email(
Chris@1115 75 'ticket_on_given_project.eml',
Chris@1115 76 :issue => {:tracker => 'Support request'}
Chris@1115 77 )
Chris@119 78 assert issue.is_a?(Issue)
Chris@119 79 assert !issue.new_record?
Chris@119 80 issue.reload
Chris@119 81 assert_equal 'Support request', issue.tracker.name
Chris@119 82 end
Chris@0 83
Chris@0 84 def test_add_issue_with_status
Chris@0 85 # This email contains: 'Project: onlinestore' and 'Status: Resolved'
Chris@0 86 issue = submit_email('ticket_on_given_project.eml')
Chris@0 87 assert issue.is_a?(Issue)
Chris@0 88 assert !issue.new_record?
Chris@0 89 issue.reload
Chris@0 90 assert_equal Project.find(2), issue.project
Chris@0 91 assert_equal IssueStatus.find_by_name("Resolved"), issue.status
Chris@0 92 end
Chris@441 93
Chris@0 94 def test_add_issue_with_attributes_override
Chris@1115 95 issue = submit_email(
Chris@1115 96 'ticket_with_attributes.eml',
Chris@1115 97 :allow_override => 'tracker,category,priority'
Chris@1115 98 )
Chris@0 99 assert issue.is_a?(Issue)
Chris@0 100 assert !issue.new_record?
Chris@0 101 issue.reload
Chris@0 102 assert_equal 'New ticket on a given project', issue.subject
Chris@0 103 assert_equal User.find_by_login('jsmith'), issue.author
Chris@0 104 assert_equal Project.find(2), issue.project
Chris@0 105 assert_equal 'Feature request', issue.tracker.to_s
Chris@0 106 assert_equal 'Stock management', issue.category.to_s
Chris@0 107 assert_equal 'Urgent', issue.priority.to_s
Chris@0 108 assert issue.description.include?('Lorem ipsum dolor sit amet, consectetuer adipiscing elit.')
Chris@0 109 end
Chris@441 110
Chris@909 111 def test_add_issue_with_group_assignment
Chris@909 112 with_settings :issue_group_assignment => '1' do
Chris@909 113 issue = submit_email('ticket_on_given_project.eml') do |email|
Chris@909 114 email.gsub!('Assigned to: John Smith', 'Assigned to: B Team')
Chris@909 115 end
Chris@909 116 assert issue.is_a?(Issue)
Chris@909 117 assert !issue.new_record?
Chris@909 118 issue.reload
Chris@909 119 assert_equal Group.find(11), issue.assigned_to
Chris@909 120 end
Chris@909 121 end
Chris@909 122
Chris@0 123 def test_add_issue_with_partial_attributes_override
Chris@1115 124 issue = submit_email(
Chris@1115 125 'ticket_with_attributes.eml',
Chris@1115 126 :issue => {:priority => 'High'},
Chris@1115 127 :allow_override => ['tracker']
Chris@1115 128 )
Chris@0 129 assert issue.is_a?(Issue)
Chris@0 130 assert !issue.new_record?
Chris@0 131 issue.reload
Chris@0 132 assert_equal 'New ticket on a given project', issue.subject
Chris@0 133 assert_equal User.find_by_login('jsmith'), issue.author
Chris@0 134 assert_equal Project.find(2), issue.project
Chris@0 135 assert_equal 'Feature request', issue.tracker.to_s
Chris@0 136 assert_nil issue.category
Chris@0 137 assert_equal 'High', issue.priority.to_s
Chris@0 138 assert issue.description.include?('Lorem ipsum dolor sit amet, consectetuer adipiscing elit.')
Chris@0 139 end
Chris@441 140
Chris@0 141 def test_add_issue_with_spaces_between_attribute_and_separator
Chris@1115 142 issue = submit_email(
Chris@1115 143 'ticket_with_spaces_between_attribute_and_separator.eml',
Chris@1115 144 :allow_override => 'tracker,category,priority'
Chris@1115 145 )
Chris@0 146 assert issue.is_a?(Issue)
Chris@0 147 assert !issue.new_record?
Chris@0 148 issue.reload
Chris@0 149 assert_equal 'New ticket on a given project', issue.subject
Chris@0 150 assert_equal User.find_by_login('jsmith'), issue.author
Chris@0 151 assert_equal Project.find(2), issue.project
Chris@0 152 assert_equal 'Feature request', issue.tracker.to_s
Chris@0 153 assert_equal 'Stock management', issue.category.to_s
Chris@0 154 assert_equal 'Urgent', issue.priority.to_s
Chris@0 155 assert issue.description.include?('Lorem ipsum dolor sit amet, consectetuer adipiscing elit.')
Chris@0 156 end
Chris@0 157
Chris@0 158 def test_add_issue_with_attachment_to_specific_project
Chris@0 159 issue = submit_email('ticket_with_attachment.eml', :issue => {:project => 'onlinestore'})
Chris@0 160 assert issue.is_a?(Issue)
Chris@0 161 assert !issue.new_record?
Chris@0 162 issue.reload
Chris@0 163 assert_equal 'Ticket created by email with attachment', issue.subject
Chris@0 164 assert_equal User.find_by_login('jsmith'), issue.author
Chris@0 165 assert_equal Project.find(2), issue.project
Chris@0 166 assert_equal 'This is a new ticket with attachments', issue.description
Chris@0 167 # Attachment properties
Chris@0 168 assert_equal 1, issue.attachments.size
Chris@0 169 assert_equal 'Paella.jpg', issue.attachments.first.filename
Chris@0 170 assert_equal 'image/jpeg', issue.attachments.first.content_type
Chris@0 171 assert_equal 10790, issue.attachments.first.filesize
Chris@0 172 end
Chris@441 173
Chris@0 174 def test_add_issue_with_custom_fields
Chris@0 175 issue = submit_email('ticket_with_custom_fields.eml', :issue => {:project => 'onlinestore'})
Chris@0 176 assert issue.is_a?(Issue)
Chris@0 177 assert !issue.new_record?
Chris@0 178 issue.reload
Chris@0 179 assert_equal 'New ticket with custom field values', issue.subject
Chris@1115 180 assert_equal 'PostgreSQL', issue.custom_field_value(1)
Chris@1115 181 assert_equal 'Value for a custom field', issue.custom_field_value(2)
Chris@0 182 assert !issue.description.match(/^searchable field:/i)
Chris@0 183 end
Chris@441 184
Chris@1115 185 def test_add_issue_with_version_custom_fields
Chris@1115 186 field = IssueCustomField.create!(:name => 'Affected version', :field_format => 'version', :is_for_all => true, :tracker_ids => [1,2,3])
Chris@1115 187
Chris@1115 188 issue = submit_email('ticket_with_custom_fields.eml', :issue => {:project => 'ecookbook'}) do |email|
Chris@1115 189 email << "Affected version: 1.0\n"
Chris@1115 190 end
Chris@1115 191 assert issue.is_a?(Issue)
Chris@1115 192 assert !issue.new_record?
Chris@1115 193 issue.reload
Chris@1115 194 assert_equal '2', issue.custom_field_value(field)
Chris@1115 195 end
Chris@1115 196
Chris@1115 197 def test_add_issue_should_match_assignee_on_display_name
Chris@1115 198 user = User.generate!(:firstname => 'Foo Bar', :lastname => 'Foo Baz')
Chris@1115 199 User.add_to_project(user, Project.find(2))
Chris@1115 200 issue = submit_email('ticket_on_given_project.eml') do |email|
Chris@1115 201 email.sub!(/^Assigned to.*$/, 'Assigned to: Foo Bar Foo baz')
Chris@1115 202 end
Chris@1115 203 assert issue.is_a?(Issue)
Chris@1115 204 assert_equal user, issue.assigned_to
Chris@1115 205 end
Chris@1115 206
Chris@0 207 def test_add_issue_with_cc
Chris@0 208 issue = submit_email('ticket_with_cc.eml', :issue => {:project => 'ecookbook'})
Chris@0 209 assert issue.is_a?(Issue)
Chris@0 210 assert !issue.new_record?
Chris@0 211 issue.reload
Chris@0 212 assert issue.watched_by?(User.find_by_mail('dlopper@somenet.foo'))
chris@37 213 assert_equal 1, issue.watcher_user_ids.size
Chris@0 214 end
Chris@441 215
Chris@0 216 def test_add_issue_by_unknown_user
Chris@0 217 assert_no_difference 'User.count' do
Chris@1115 218 assert_equal false,
Chris@1115 219 submit_email(
Chris@1115 220 'ticket_by_unknown_user.eml',
Chris@1115 221 :issue => {:project => 'ecookbook'}
Chris@1115 222 )
Chris@0 223 end
Chris@0 224 end
Chris@441 225
Chris@0 226 def test_add_issue_by_anonymous_user
Chris@0 227 Role.anonymous.add_permission!(:add_issues)
Chris@0 228 assert_no_difference 'User.count' do
Chris@1115 229 issue = submit_email(
Chris@1115 230 'ticket_by_unknown_user.eml',
Chris@1115 231 :issue => {:project => 'ecookbook'},
Chris@1115 232 :unknown_user => 'accept'
Chris@1115 233 )
Chris@0 234 assert issue.is_a?(Issue)
Chris@0 235 assert issue.author.anonymous?
Chris@0 236 end
Chris@0 237 end
Chris@0 238
Chris@0 239 def test_add_issue_by_anonymous_user_with_no_from_address
Chris@0 240 Role.anonymous.add_permission!(:add_issues)
Chris@0 241 assert_no_difference 'User.count' do
Chris@1115 242 issue = submit_email(
Chris@1115 243 'ticket_by_empty_user.eml',
Chris@1115 244 :issue => {:project => 'ecookbook'},
Chris@1115 245 :unknown_user => 'accept'
Chris@1115 246 )
Chris@0 247 assert issue.is_a?(Issue)
Chris@0 248 assert issue.author.anonymous?
Chris@0 249 end
Chris@0 250 end
Chris@441 251
Chris@0 252 def test_add_issue_by_anonymous_user_on_private_project
Chris@0 253 Role.anonymous.add_permission!(:add_issues)
Chris@0 254 assert_no_difference 'User.count' do
Chris@0 255 assert_no_difference 'Issue.count' do
Chris@1115 256 assert_equal false,
Chris@1115 257 submit_email(
Chris@1115 258 'ticket_by_unknown_user.eml',
Chris@1115 259 :issue => {:project => 'onlinestore'},
Chris@1115 260 :unknown_user => 'accept'
Chris@1115 261 )
Chris@0 262 end
Chris@0 263 end
Chris@0 264 end
Chris@441 265
Chris@0 266 def test_add_issue_by_anonymous_user_on_private_project_without_permission_check
Chris@0 267 assert_no_difference 'User.count' do
Chris@0 268 assert_difference 'Issue.count' do
Chris@1115 269 issue = submit_email(
Chris@1115 270 'ticket_by_unknown_user.eml',
Chris@1115 271 :issue => {:project => 'onlinestore'},
Chris@1115 272 :no_permission_check => '1',
Chris@1115 273 :unknown_user => 'accept'
Chris@1115 274 )
Chris@0 275 assert issue.is_a?(Issue)
Chris@0 276 assert issue.author.anonymous?
Chris@0 277 assert !issue.project.is_public?
Chris@119 278 assert_equal [issue.id, 1, 2], [issue.root_id, issue.lft, issue.rgt]
Chris@0 279 end
Chris@0 280 end
Chris@0 281 end
Chris@441 282
Chris@0 283 def test_add_issue_by_created_user
Chris@0 284 Setting.default_language = 'en'
Chris@0 285 assert_difference 'User.count' do
Chris@1115 286 issue = submit_email(
Chris@1115 287 'ticket_by_unknown_user.eml',
Chris@1115 288 :issue => {:project => 'ecookbook'},
Chris@1115 289 :unknown_user => 'create'
Chris@1115 290 )
Chris@0 291 assert issue.is_a?(Issue)
Chris@0 292 assert issue.author.active?
Chris@0 293 assert_equal 'john.doe@somenet.foo', issue.author.mail
Chris@0 294 assert_equal 'John', issue.author.firstname
Chris@0 295 assert_equal 'Doe', issue.author.lastname
Chris@441 296
Chris@0 297 # account information
Chris@0 298 email = ActionMailer::Base.deliveries.first
Chris@0 299 assert_not_nil email
Chris@0 300 assert email.subject.include?('account activation')
Chris@1115 301 login = mail_body(email).match(/\* Login: (.*)$/)[1].strip
Chris@1115 302 password = mail_body(email).match(/\* Password: (.*)$/)[1].strip
Chris@0 303 assert_equal issue.author, User.try_to_login(login, password)
Chris@0 304 end
Chris@0 305 end
Chris@441 306
Chris@0 307 def test_add_issue_without_from_header
Chris@0 308 Role.anonymous.add_permission!(:add_issues)
Chris@0 309 assert_equal false, submit_email('ticket_without_from_header.eml')
Chris@0 310 end
chris@37 311
chris@37 312 def test_add_issue_with_invalid_attributes
Chris@1115 313 issue = submit_email(
Chris@1115 314 'ticket_with_invalid_attributes.eml',
Chris@1115 315 :allow_override => 'tracker,category,priority'
Chris@1115 316 )
chris@37 317 assert issue.is_a?(Issue)
chris@37 318 assert !issue.new_record?
chris@37 319 issue.reload
chris@37 320 assert_nil issue.assigned_to
chris@37 321 assert_nil issue.start_date
chris@37 322 assert_nil issue.due_date
chris@37 323 assert_equal 0, issue.done_ratio
chris@37 324 assert_equal 'Normal', issue.priority.to_s
chris@37 325 assert issue.description.include?('Lorem ipsum dolor sit amet, consectetuer adipiscing elit.')
chris@37 326 end
chris@37 327
chris@37 328 def test_add_issue_with_localized_attributes
chris@37 329 User.find_by_mail('jsmith@somenet.foo').update_attribute 'language', 'fr'
Chris@1115 330 issue = submit_email(
Chris@1115 331 'ticket_with_localized_attributes.eml',
Chris@1115 332 :allow_override => 'tracker,category,priority'
Chris@1115 333 )
chris@37 334 assert issue.is_a?(Issue)
chris@37 335 assert !issue.new_record?
chris@37 336 issue.reload
chris@37 337 assert_equal 'New ticket on a given project', issue.subject
chris@37 338 assert_equal User.find_by_login('jsmith'), issue.author
chris@37 339 assert_equal Project.find(2), issue.project
chris@37 340 assert_equal 'Feature request', issue.tracker.to_s
chris@37 341 assert_equal 'Stock management', issue.category.to_s
chris@37 342 assert_equal 'Urgent', issue.priority.to_s
chris@37 343 assert issue.description.include?('Lorem ipsum dolor sit amet, consectetuer adipiscing elit.')
chris@37 344 end
Chris@441 345
Chris@0 346 def test_add_issue_with_japanese_keywords
Chris@1115 347 ja_dev = "\xe9\x96\x8b\xe7\x99\xba"
Chris@1115 348 ja_dev.force_encoding('UTF-8') if ja_dev.respond_to?(:force_encoding)
Chris@1115 349 tracker = Tracker.create!(:name => ja_dev)
Chris@0 350 Project.find(1).trackers << tracker
Chris@1115 351 issue = submit_email(
Chris@1115 352 'japanese_keywords_iso_2022_jp.eml',
Chris@1115 353 :issue => {:project => 'ecookbook'},
Chris@1115 354 :allow_override => 'tracker'
Chris@1115 355 )
Chris@0 356 assert_kind_of Issue, issue
Chris@0 357 assert_equal tracker, issue.tracker
Chris@0 358 end
Chris@0 359
Chris@909 360 def test_add_issue_from_apple_mail
Chris@1115 361 issue = submit_email(
Chris@1115 362 'apple_mail_with_attachment.eml',
Chris@1115 363 :issue => {:project => 'ecookbook'}
Chris@1115 364 )
Chris@909 365 assert_kind_of Issue, issue
Chris@909 366 assert_equal 1, issue.attachments.size
Chris@909 367
Chris@909 368 attachment = issue.attachments.first
Chris@909 369 assert_equal 'paella.jpg', attachment.filename
Chris@909 370 assert_equal 10790, attachment.filesize
Chris@1115 371 assert File.exist?(attachment.diskfile)
Chris@1115 372 assert_equal 10790, File.size(attachment.diskfile)
Chris@1115 373 assert_equal 'caaf384198bcbc9563ab5c058acd73cd', attachment.digest
Chris@1115 374 end
Chris@1115 375
Chris@1115 376 def test_thunderbird_with_attachment_ja
Chris@1115 377 issue = submit_email(
Chris@1115 378 'thunderbird_with_attachment_ja.eml',
Chris@1115 379 :issue => {:project => 'ecookbook'}
Chris@1115 380 )
Chris@1115 381 assert_kind_of Issue, issue
Chris@1115 382 assert_equal 1, issue.attachments.size
Chris@1115 383 ja = "\xe3\x83\x86\xe3\x82\xb9\xe3\x83\x88.txt"
Chris@1115 384 ja.force_encoding('UTF-8') if ja.respond_to?(:force_encoding)
Chris@1115 385 attachment = issue.attachments.first
Chris@1115 386 assert_equal ja, attachment.filename
Chris@1115 387 assert_equal 5, attachment.filesize
Chris@1115 388 assert File.exist?(attachment.diskfile)
Chris@1115 389 assert_equal 5, File.size(attachment.diskfile)
Chris@1115 390 assert_equal 'd8e8fca2dc0f896fd7cb4cb0031ba249', attachment.digest
Chris@1115 391 end
Chris@1115 392
Chris@1115 393 def test_gmail_with_attachment_ja
Chris@1115 394 issue = submit_email(
Chris@1115 395 'gmail_with_attachment_ja.eml',
Chris@1115 396 :issue => {:project => 'ecookbook'}
Chris@1115 397 )
Chris@1115 398 assert_kind_of Issue, issue
Chris@1115 399 assert_equal 1, issue.attachments.size
Chris@1115 400 ja = "\xe3\x83\x86\xe3\x82\xb9\xe3\x83\x88.txt"
Chris@1115 401 ja.force_encoding('UTF-8') if ja.respond_to?(:force_encoding)
Chris@1115 402 attachment = issue.attachments.first
Chris@1115 403 assert_equal ja, attachment.filename
Chris@1115 404 assert_equal 5, attachment.filesize
Chris@1115 405 assert File.exist?(attachment.diskfile)
Chris@1115 406 assert_equal 5, File.size(attachment.diskfile)
Chris@1115 407 assert_equal 'd8e8fca2dc0f896fd7cb4cb0031ba249', attachment.digest
Chris@1115 408 end
Chris@1115 409
Chris@1115 410 def test_thunderbird_with_attachment_latin1
Chris@1115 411 issue = submit_email(
Chris@1115 412 'thunderbird_with_attachment_iso-8859-1.eml',
Chris@1115 413 :issue => {:project => 'ecookbook'}
Chris@1115 414 )
Chris@1115 415 assert_kind_of Issue, issue
Chris@1115 416 assert_equal 1, issue.attachments.size
Chris@1115 417 u = ""
Chris@1115 418 u.force_encoding('UTF-8') if u.respond_to?(:force_encoding)
Chris@1115 419 u1 = "\xc3\x84\xc3\xa4\xc3\x96\xc3\xb6\xc3\x9c\xc3\xbc"
Chris@1115 420 u1.force_encoding('UTF-8') if u1.respond_to?(:force_encoding)
Chris@1115 421 11.times { u << u1 }
Chris@1115 422 attachment = issue.attachments.first
Chris@1115 423 assert_equal "#{u}.png", attachment.filename
Chris@1115 424 assert_equal 130, attachment.filesize
Chris@1115 425 assert File.exist?(attachment.diskfile)
Chris@1115 426 assert_equal 130, File.size(attachment.diskfile)
Chris@1115 427 assert_equal '4d80e667ac37dddfe05502530f152abb', attachment.digest
Chris@1115 428 end
Chris@1115 429
Chris@1115 430 def test_gmail_with_attachment_latin1
Chris@1115 431 issue = submit_email(
Chris@1115 432 'gmail_with_attachment_iso-8859-1.eml',
Chris@1115 433 :issue => {:project => 'ecookbook'}
Chris@1115 434 )
Chris@1115 435 assert_kind_of Issue, issue
Chris@1115 436 assert_equal 1, issue.attachments.size
Chris@1115 437 u = ""
Chris@1115 438 u.force_encoding('UTF-8') if u.respond_to?(:force_encoding)
Chris@1115 439 u1 = "\xc3\x84\xc3\xa4\xc3\x96\xc3\xb6\xc3\x9c\xc3\xbc"
Chris@1115 440 u1.force_encoding('UTF-8') if u1.respond_to?(:force_encoding)
Chris@1115 441 11.times { u << u1 }
Chris@1115 442 attachment = issue.attachments.first
Chris@1115 443 assert_equal "#{u}.txt", attachment.filename
Chris@1115 444 assert_equal 5, attachment.filesize
Chris@1115 445 assert File.exist?(attachment.diskfile)
Chris@1115 446 assert_equal 5, File.size(attachment.diskfile)
Chris@1115 447 assert_equal 'd8e8fca2dc0f896fd7cb4cb0031ba249', attachment.digest
Chris@1115 448 end
Chris@1115 449
Chris@1115 450 def test_add_issue_with_iso_8859_1_subject
Chris@1115 451 issue = submit_email(
Chris@1115 452 'subject_as_iso-8859-1.eml',
Chris@1115 453 :issue => {:project => 'ecookbook'}
Chris@1115 454 )
Chris@1115 455 str = "Testmail from Webmail: \xc3\xa4 \xc3\xb6 \xc3\xbc..."
Chris@1115 456 str.force_encoding('UTF-8') if str.respond_to?(:force_encoding)
Chris@1115 457 assert_kind_of Issue, issue
Chris@1115 458 assert_equal str, issue.subject
Chris@1115 459 end
Chris@1115 460
Chris@1115 461 def test_add_issue_with_japanese_subject
Chris@1115 462 issue = submit_email(
Chris@1115 463 'subject_japanese_1.eml',
Chris@1115 464 :issue => {:project => 'ecookbook'}
Chris@1115 465 )
Chris@1115 466 assert_kind_of Issue, issue
Chris@1115 467 ja = "\xe3\x83\x86\xe3\x82\xb9\xe3\x83\x88"
Chris@1115 468 ja.force_encoding('UTF-8') if ja.respond_to?(:force_encoding)
Chris@1115 469 assert_equal ja, issue.subject
Chris@1115 470 end
Chris@1115 471
Chris@1115 472 def test_add_issue_with_no_subject_header
Chris@1115 473 issue = submit_email(
Chris@1115 474 'no_subject_header.eml',
Chris@1115 475 :issue => {:project => 'ecookbook'}
Chris@1115 476 )
Chris@1115 477 assert_kind_of Issue, issue
Chris@1115 478 assert_equal '(no subject)', issue.subject
Chris@1115 479 end
Chris@1115 480
Chris@1115 481 def test_add_issue_with_mixed_japanese_subject
Chris@1115 482 issue = submit_email(
Chris@1115 483 'subject_japanese_2.eml',
Chris@1115 484 :issue => {:project => 'ecookbook'}
Chris@1115 485 )
Chris@1115 486 assert_kind_of Issue, issue
Chris@1115 487 ja = "Re: \xe3\x83\x86\xe3\x82\xb9\xe3\x83\x88"
Chris@1115 488 ja.force_encoding('UTF-8') if ja.respond_to?(:force_encoding)
Chris@1115 489 assert_equal ja, issue.subject
Chris@1115 490 end
Chris@1115 491
Chris@1115 492 def test_should_ignore_emails_from_locked_users
Chris@1115 493 User.find(2).lock!
Chris@1115 494
Chris@1115 495 MailHandler.any_instance.expects(:dispatch).never
Chris@1115 496 assert_no_difference 'Issue.count' do
Chris@1115 497 assert_equal false, submit_email('ticket_on_given_project.eml')
Chris@1115 498 end
Chris@909 499 end
Chris@909 500
Chris@0 501 def test_should_ignore_emails_from_emission_address
Chris@0 502 Role.anonymous.add_permission!(:add_issues)
Chris@0 503 assert_no_difference 'User.count' do
Chris@1115 504 assert_equal false,
Chris@1115 505 submit_email(
Chris@1115 506 'ticket_from_emission_address.eml',
Chris@1115 507 :issue => {:project => 'ecookbook'},
Chris@1115 508 :unknown_user => 'create'
Chris@1115 509 )
Chris@1115 510 end
Chris@1115 511 end
Chris@1115 512
Chris@1115 513 def test_should_ignore_auto_replied_emails
Chris@1115 514 MailHandler.any_instance.expects(:dispatch).never
Chris@1115 515 [
Chris@1115 516 "X-Auto-Response-Suppress: OOF",
Chris@1115 517 "Auto-Submitted: auto-replied",
Chris@1115 518 "Auto-Submitted: Auto-Replied",
Chris@1115 519 "Auto-Submitted: auto-generated"
Chris@1115 520 ].each do |header|
Chris@1115 521 raw = IO.read(File.join(FIXTURES_PATH, 'ticket_on_given_project.eml'))
Chris@1115 522 raw = header + "\n" + raw
Chris@1115 523
Chris@1115 524 assert_no_difference 'Issue.count' do
Chris@1115 525 assert_equal false, MailHandler.receive(raw), "email with #{header} header was not ignored"
Chris@1115 526 end
Chris@0 527 end
Chris@0 528 end
Chris@0 529
Chris@0 530 def test_add_issue_should_send_email_notification
chris@37 531 Setting.notified_events = ['issue_added']
Chris@0 532 ActionMailer::Base.deliveries.clear
Chris@0 533 # This email contains: 'Project: onlinestore'
Chris@0 534 issue = submit_email('ticket_on_given_project.eml')
Chris@0 535 assert issue.is_a?(Issue)
Chris@0 536 assert_equal 1, ActionMailer::Base.deliveries.size
Chris@0 537 end
Chris@441 538
Chris@909 539 def test_update_issue
Chris@0 540 journal = submit_email('ticket_reply.eml')
Chris@0 541 assert journal.is_a?(Journal)
Chris@0 542 assert_equal User.find_by_login('jsmith'), journal.user
Chris@0 543 assert_equal Issue.find(2), journal.journalized
Chris@0 544 assert_match /This is reply/, journal.notes
Chris@1115 545 assert_equal false, journal.private_notes
Chris@119 546 assert_equal 'Feature request', journal.issue.tracker.name
Chris@0 547 end
Chris@0 548
Chris@909 549 def test_update_issue_with_attribute_changes
Chris@0 550 # This email contains: 'Status: Resolved'
Chris@0 551 journal = submit_email('ticket_reply_with_status.eml')
Chris@0 552 assert journal.is_a?(Journal)
Chris@0 553 issue = Issue.find(journal.issue.id)
Chris@0 554 assert_equal User.find_by_login('jsmith'), journal.user
Chris@0 555 assert_equal Issue.find(2), journal.journalized
Chris@0 556 assert_match /This is reply/, journal.notes
Chris@119 557 assert_equal 'Feature request', journal.issue.tracker.name
Chris@0 558 assert_equal IssueStatus.find_by_name("Resolved"), issue.status
Chris@0 559 assert_equal '2010-01-01', issue.start_date.to_s
Chris@0 560 assert_equal '2010-12-31', issue.due_date.to_s
Chris@0 561 assert_equal User.find_by_login('jsmith'), issue.assigned_to
Chris@119 562 assert_equal "52.6", issue.custom_value_for(CustomField.find_by_name('Float field')).value
Chris@441 563 # keywords should be removed from the email body
Chris@441 564 assert !journal.notes.match(/^Status:/i)
Chris@441 565 assert !journal.notes.match(/^Start Date:/i)
Chris@0 566 end
Chris@0 567
Chris@909 568 def test_update_issue_with_attachment
Chris@909 569 assert_difference 'Journal.count' do
Chris@909 570 assert_difference 'JournalDetail.count' do
Chris@909 571 assert_difference 'Attachment.count' do
Chris@909 572 assert_no_difference 'Issue.count' do
Chris@909 573 journal = submit_email('ticket_with_attachment.eml') do |raw|
Chris@909 574 raw.gsub! /^Subject: .*$/, 'Subject: Re: [Cookbook - Feature #2] (New) Add ingredients categories'
Chris@909 575 end
Chris@909 576 end
Chris@909 577 end
Chris@909 578 end
Chris@909 579 end
Chris@909 580 journal = Journal.first(:order => 'id DESC')
Chris@909 581 assert_equal Issue.find(2), journal.journalized
Chris@909 582 assert_equal 1, journal.details.size
Chris@909 583
Chris@909 584 detail = journal.details.first
Chris@909 585 assert_equal 'attachment', detail.property
Chris@909 586 assert_equal 'Paella.jpg', detail.value
Chris@909 587 end
Chris@909 588
Chris@909 589 def test_update_issue_should_send_email_notification
Chris@0 590 ActionMailer::Base.deliveries.clear
Chris@0 591 journal = submit_email('ticket_reply.eml')
Chris@0 592 assert journal.is_a?(Journal)
Chris@0 593 assert_equal 1, ActionMailer::Base.deliveries.size
Chris@0 594 end
Chris@441 595
Chris@909 596 def test_update_issue_should_not_set_defaults
Chris@1115 597 journal = submit_email(
Chris@1115 598 'ticket_reply.eml',
Chris@1115 599 :issue => {:tracker => 'Support request', :priority => 'High'}
Chris@1115 600 )
Chris@119 601 assert journal.is_a?(Journal)
Chris@119 602 assert_match /This is reply/, journal.notes
Chris@119 603 assert_equal 'Feature request', journal.issue.tracker.name
Chris@119 604 assert_equal 'Normal', journal.issue.priority.name
Chris@119 605 end
Chris@441 606
Chris@1115 607 def test_replying_to_a_private_note_should_add_reply_as_private
Chris@1115 608 private_journal = Journal.create!(:notes => 'Private notes', :journalized => Issue.find(1), :private_notes => true, :user_id => 2)
Chris@1115 609
Chris@1115 610 assert_difference 'Journal.count' do
Chris@1115 611 journal = submit_email('ticket_reply.eml') do |email|
Chris@1115 612 email.sub! %r{^In-Reply-To:.*$}, "In-Reply-To: <redmine.journal-#{private_journal.id}.20060719210421@osiris>"
Chris@1115 613 end
Chris@1115 614
Chris@1115 615 assert_kind_of Journal, journal
Chris@1115 616 assert_match /This is reply/, journal.notes
Chris@1115 617 assert_equal true, journal.private_notes
Chris@1115 618 end
Chris@1115 619 end
Chris@1115 620
Chris@0 621 def test_reply_to_a_message
Chris@0 622 m = submit_email('message_reply.eml')
Chris@0 623 assert m.is_a?(Message)
Chris@0 624 assert !m.new_record?
Chris@0 625 m.reload
Chris@0 626 assert_equal 'Reply via email', m.subject
Chris@0 627 # The email replies to message #2 which is part of the thread of message #1
Chris@0 628 assert_equal Message.find(1), m.parent
Chris@0 629 end
Chris@441 630
Chris@0 631 def test_reply_to_a_message_by_subject
Chris@0 632 m = submit_email('message_reply_by_subject.eml')
Chris@0 633 assert m.is_a?(Message)
Chris@0 634 assert !m.new_record?
Chris@0 635 m.reload
Chris@0 636 assert_equal 'Reply to the first post', m.subject
Chris@0 637 assert_equal Message.find(1), m.parent
Chris@0 638 end
Chris@441 639
Chris@0 640 def test_should_strip_tags_of_html_only_emails
Chris@0 641 issue = submit_email('ticket_html_only.eml', :issue => {:project => 'ecookbook'})
Chris@0 642 assert issue.is_a?(Issue)
Chris@0 643 assert !issue.new_record?
Chris@0 644 issue.reload
Chris@0 645 assert_equal 'HTML email', issue.subject
Chris@0 646 assert_equal 'This is a html-only email.', issue.description
Chris@0 647 end
Chris@0 648
Chris@0 649 context "truncate emails based on the Setting" do
Chris@0 650 context "with no setting" do
Chris@0 651 setup do
Chris@0 652 Setting.mail_handler_body_delimiters = ''
Chris@0 653 end
Chris@0 654
Chris@0 655 should "add the entire email into the issue" do
Chris@0 656 issue = submit_email('ticket_on_given_project.eml')
Chris@0 657 assert_issue_created(issue)
Chris@0 658 assert issue.description.include?('---')
Chris@0 659 assert issue.description.include?('This paragraph is after the delimiter')
Chris@0 660 end
Chris@0 661 end
Chris@0 662
Chris@0 663 context "with a single string" do
Chris@0 664 setup do
Chris@0 665 Setting.mail_handler_body_delimiters = '---'
Chris@0 666 end
Chris@0 667 should "truncate the email at the delimiter for the issue" do
Chris@0 668 issue = submit_email('ticket_on_given_project.eml')
Chris@0 669 assert_issue_created(issue)
Chris@0 670 assert issue.description.include?('This paragraph is before delimiters')
Chris@0 671 assert issue.description.include?('--- This line starts with a delimiter')
Chris@0 672 assert !issue.description.match(/^---$/)
Chris@0 673 assert !issue.description.include?('This paragraph is after the delimiter')
Chris@0 674 end
Chris@0 675 end
Chris@0 676
chris@37 677 context "with a single quoted reply (e.g. reply to a Redmine email notification)" do
chris@37 678 setup do
chris@37 679 Setting.mail_handler_body_delimiters = '--- Reply above. Do not remove this line. ---'
chris@37 680 end
chris@37 681 should "truncate the email at the delimiter with the quoted reply symbols (>)" do
chris@37 682 journal = submit_email('issue_update_with_quoted_reply_above.eml')
chris@37 683 assert journal.is_a?(Journal)
chris@37 684 assert journal.notes.include?('An update to the issue by the sender.')
chris@37 685 assert !journal.notes.match(Regexp.escape("--- Reply above. Do not remove this line. ---"))
chris@37 686 assert !journal.notes.include?('Looks like the JSON api for projects was missed.')
Chris@441 687 end
Chris@441 688 end
chris@37 689
chris@37 690 context "with multiple quoted replies (e.g. reply to a reply of a Redmine email notification)" do
chris@37 691 setup do
chris@37 692 Setting.mail_handler_body_delimiters = '--- Reply above. Do not remove this line. ---'
chris@37 693 end
chris@37 694 should "truncate the email at the delimiter with the quoted reply symbols (>)" do
chris@37 695 journal = submit_email('issue_update_with_multiple_quoted_reply_above.eml')
chris@37 696 assert journal.is_a?(Journal)
chris@37 697 assert journal.notes.include?('An update to the issue by the sender.')
chris@37 698 assert !journal.notes.match(Regexp.escape("--- Reply above. Do not remove this line. ---"))
chris@37 699 assert !journal.notes.include?('Looks like the JSON api for projects was missed.')
chris@37 700 end
chris@37 701 end
chris@37 702
Chris@0 703 context "with multiple strings" do
Chris@0 704 setup do
Chris@0 705 Setting.mail_handler_body_delimiters = "---\nBREAK"
Chris@0 706 end
Chris@0 707 should "truncate the email at the first delimiter found (BREAK)" do
Chris@0 708 issue = submit_email('ticket_on_given_project.eml')
Chris@0 709 assert_issue_created(issue)
Chris@0 710 assert issue.description.include?('This paragraph is before delimiters')
Chris@0 711 assert !issue.description.include?('BREAK')
Chris@0 712 assert !issue.description.include?('This paragraph is between delimiters')
Chris@0 713 assert !issue.description.match(/^---$/)
Chris@0 714 assert !issue.description.include?('This paragraph is after the delimiter')
Chris@0 715 end
Chris@0 716 end
Chris@0 717 end
Chris@441 718
Chris@0 719 def test_email_with_long_subject_line
Chris@0 720 issue = submit_email('ticket_with_long_subject.eml')
Chris@0 721 assert issue.is_a?(Issue)
Chris@0 722 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 723 end
Chris@0 724
Chris@909 725 def test_new_user_from_attributes_should_return_valid_user
Chris@909 726 to_test = {
Chris@909 727 # [address, name] => [login, firstname, lastname]
Chris@909 728 ['jsmith@example.net', nil] => ['jsmith@example.net', 'jsmith', '-'],
Chris@909 729 ['jsmith@example.net', 'John'] => ['jsmith@example.net', 'John', '-'],
Chris@909 730 ['jsmith@example.net', 'John Smith'] => ['jsmith@example.net', 'John', 'Smith'],
Chris@909 731 ['jsmith@example.net', 'John Paul Smith'] => ['jsmith@example.net', 'John', 'Paul Smith'],
Chris@909 732 ['jsmith@example.net', 'AVeryLongFirstnameThatExceedsTheMaximumLength Smith'] => ['jsmith@example.net', 'AVeryLongFirstnameThatExceedsT', 'Smith'],
Chris@1115 733 ['jsmith@example.net', 'John AVeryLongLastnameThatExceedsTheMaximumLength'] => ['jsmith@example.net', 'John', 'AVeryLongLastnameThatExceedsTh']
Chris@909 734 }
Chris@909 735
Chris@909 736 to_test.each do |attrs, expected|
Chris@909 737 user = MailHandler.new_user_from_attributes(attrs.first, attrs.last)
Chris@909 738
Chris@1115 739 assert user.valid?, user.errors.full_messages.to_s
Chris@909 740 assert_equal attrs.first, user.mail
Chris@909 741 assert_equal expected[0], user.login
Chris@909 742 assert_equal expected[1], user.firstname
Chris@909 743 assert_equal expected[2], user.lastname
Chris@909 744 end
Chris@909 745 end
Chris@909 746
Chris@909 747 def test_new_user_from_attributes_should_respect_minimum_password_length
Chris@909 748 with_settings :password_min_length => 15 do
Chris@909 749 user = MailHandler.new_user_from_attributes('jsmith@example.net')
Chris@909 750 assert user.valid?
Chris@909 751 assert user.password.length >= 15
Chris@909 752 end
Chris@909 753 end
Chris@1115 754
Chris@909 755 def test_new_user_from_attributes_should_use_default_login_if_invalid
Chris@1115 756 user = MailHandler.new_user_from_attributes('foo+bar@example.net')
Chris@909 757 assert user.valid?
Chris@909 758 assert user.login =~ /^user[a-f0-9]+$/
Chris@1115 759 assert_equal 'foo+bar@example.net', user.mail
Chris@1115 760 end
Chris@1115 761
Chris@1115 762 def test_new_user_with_utf8_encoded_fullname_should_be_decoded
Chris@1115 763 assert_difference 'User.count' do
Chris@1115 764 issue = submit_email(
Chris@1115 765 'fullname_of_sender_as_utf8_encoded.eml',
Chris@1115 766 :issue => {:project => 'ecookbook'},
Chris@1115 767 :unknown_user => 'create'
Chris@1115 768 )
Chris@1115 769 end
Chris@1115 770
Chris@1115 771 user = User.first(:order => 'id DESC')
Chris@1115 772 assert_equal "foo@example.org", user.mail
Chris@1115 773 str1 = "\xc3\x84\xc3\xa4"
Chris@1115 774 str2 = "\xc3\x96\xc3\xb6"
Chris@1115 775 str1.force_encoding('UTF-8') if str1.respond_to?(:force_encoding)
Chris@1115 776 str2.force_encoding('UTF-8') if str2.respond_to?(:force_encoding)
Chris@1115 777 assert_equal str1, user.firstname
Chris@1115 778 assert_equal str2, user.lastname
Chris@909 779 end
Chris@909 780
Chris@0 781 private
Chris@441 782
Chris@0 783 def submit_email(filename, options={})
Chris@0 784 raw = IO.read(File.join(FIXTURES_PATH, filename))
Chris@909 785 yield raw if block_given?
Chris@0 786 MailHandler.receive(raw, options)
Chris@0 787 end
Chris@0 788
Chris@0 789 def assert_issue_created(issue)
Chris@0 790 assert issue.is_a?(Issue)
Chris@0 791 assert !issue.new_record?
Chris@0 792 issue.reload
Chris@0 793 end
Chris@0 794 end