annotate .svn/pristine/02/02c68441083bdea630158440f0e7d9d62ff8f790.svn-base @ 1298:4f746d8966dd redmine_2.3_integration

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