# Redmine - project management software # Copyright (C) 2006-2009 Jean-Philippe Lang # # This program is free software; you can redistribute it and/or # modify it under the terms of the GNU General Public License # as published by the Free Software Foundation; either version 2 # of the License, or (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. require File.dirname(__FILE__) + '/../test_helper' class MailHandlerTest < ActiveSupport::TestCase fixtures :users, :projects, :enabled_modules, :roles, :members, :member_roles, :issues, :issue_statuses, :workflows, :trackers, :projects_trackers, :enumerations, :issue_categories, :custom_fields, :custom_fields_trackers, :boards, :messages FIXTURES_PATH = File.dirname(__FILE__) + '/../fixtures/mail_handler' def setup ActionMailer::Base.deliveries.clear end def test_add_issue # This email contains: 'Project: onlinestore' issue = submit_email('ticket_on_given_project.eml') assert issue.is_a?(Issue) assert !issue.new_record? issue.reload assert_equal 'New ticket on a given project', issue.subject assert_equal User.find_by_login('jsmith'), issue.author assert_equal Project.find(2), issue.project assert_equal IssueStatus.find_by_name('Resolved'), issue.status assert issue.description.include?('Lorem ipsum dolor sit amet, consectetuer adipiscing elit.') # keywords should be removed from the email body assert !issue.description.match(/^Project:/i) assert !issue.description.match(/^Status:/i) end def test_add_issue_with_status # This email contains: 'Project: onlinestore' and 'Status: Resolved' issue = submit_email('ticket_on_given_project.eml') assert issue.is_a?(Issue) assert !issue.new_record? issue.reload assert_equal Project.find(2), issue.project assert_equal IssueStatus.find_by_name("Resolved"), issue.status end def test_add_issue_with_attributes_override issue = submit_email('ticket_with_attributes.eml', :allow_override => 'tracker,category,priority') assert issue.is_a?(Issue) assert !issue.new_record? issue.reload assert_equal 'New ticket on a given project', issue.subject assert_equal User.find_by_login('jsmith'), issue.author assert_equal Project.find(2), issue.project assert_equal 'Feature request', issue.tracker.to_s assert_equal 'Stock management', issue.category.to_s assert_equal 'Urgent', issue.priority.to_s assert issue.description.include?('Lorem ipsum dolor sit amet, consectetuer adipiscing elit.') end def test_add_issue_with_partial_attributes_override issue = submit_email('ticket_with_attributes.eml', :issue => {:priority => 'High'}, :allow_override => ['tracker']) assert issue.is_a?(Issue) assert !issue.new_record? issue.reload assert_equal 'New ticket on a given project', issue.subject assert_equal User.find_by_login('jsmith'), issue.author assert_equal Project.find(2), issue.project assert_equal 'Feature request', issue.tracker.to_s assert_nil issue.category assert_equal 'High', issue.priority.to_s assert issue.description.include?('Lorem ipsum dolor sit amet, consectetuer adipiscing elit.') end def test_add_issue_with_spaces_between_attribute_and_separator issue = submit_email('ticket_with_spaces_between_attribute_and_separator.eml', :allow_override => 'tracker,category,priority') assert issue.is_a?(Issue) assert !issue.new_record? issue.reload assert_equal 'New ticket on a given project', issue.subject assert_equal User.find_by_login('jsmith'), issue.author assert_equal Project.find(2), issue.project assert_equal 'Feature request', issue.tracker.to_s assert_equal 'Stock management', issue.category.to_s assert_equal 'Urgent', issue.priority.to_s assert issue.description.include?('Lorem ipsum dolor sit amet, consectetuer adipiscing elit.') end def test_add_issue_with_attachment_to_specific_project issue = submit_email('ticket_with_attachment.eml', :issue => {:project => 'onlinestore'}) assert issue.is_a?(Issue) assert !issue.new_record? issue.reload assert_equal 'Ticket created by email with attachment', issue.subject assert_equal User.find_by_login('jsmith'), issue.author assert_equal Project.find(2), issue.project assert_equal 'This is a new ticket with attachments', issue.description # Attachment properties assert_equal 1, issue.attachments.size assert_equal 'Paella.jpg', issue.attachments.first.filename assert_equal 'image/jpeg', issue.attachments.first.content_type assert_equal 10790, issue.attachments.first.filesize end def test_add_issue_with_custom_fields issue = submit_email('ticket_with_custom_fields.eml', :issue => {:project => 'onlinestore'}) assert issue.is_a?(Issue) assert !issue.new_record? issue.reload assert_equal 'New ticket with custom field values', issue.subject assert_equal 'Value for a custom field', issue.custom_value_for(CustomField.find_by_name('Searchable field')).value assert !issue.description.match(/^searchable field:/i) end def test_add_issue_with_cc issue = submit_email('ticket_with_cc.eml', :issue => {:project => 'ecookbook'}) assert issue.is_a?(Issue) assert !issue.new_record? issue.reload assert issue.watched_by?(User.find_by_mail('dlopper@somenet.foo')) assert_equal 1, issue.watchers.size end def test_add_issue_by_unknown_user assert_no_difference 'User.count' do assert_equal false, submit_email('ticket_by_unknown_user.eml', :issue => {:project => 'ecookbook'}) end end def test_add_issue_by_anonymous_user Role.anonymous.add_permission!(:add_issues) assert_no_difference 'User.count' do issue = submit_email('ticket_by_unknown_user.eml', :issue => {:project => 'ecookbook'}, :unknown_user => 'accept') assert issue.is_a?(Issue) assert issue.author.anonymous? end end def test_add_issue_by_created_user Setting.default_language = 'en' assert_difference 'User.count' do issue = submit_email('ticket_by_unknown_user.eml', :issue => {:project => 'ecookbook'}, :unknown_user => 'create') assert issue.is_a?(Issue) assert issue.author.active? assert_equal 'john.doe@somenet.foo', issue.author.mail assert_equal 'John', issue.author.firstname assert_equal 'Doe', issue.author.lastname # account information email = ActionMailer::Base.deliveries.first assert_not_nil email assert email.subject.include?('account activation') login = email.body.match(/\* Login: (.*)$/)[1] password = email.body.match(/\* Password: (.*)$/)[1] assert_equal issue.author, User.try_to_login(login, password) end end def test_add_issue_without_from_header Role.anonymous.add_permission!(:add_issues) assert_equal false, submit_email('ticket_without_from_header.eml') end def test_add_issue_should_send_email_notification ActionMailer::Base.deliveries.clear # This email contains: 'Project: onlinestore' issue = submit_email('ticket_on_given_project.eml') assert issue.is_a?(Issue) assert_equal 1, ActionMailer::Base.deliveries.size end def test_add_issue_note journal = submit_email('ticket_reply.eml') assert journal.is_a?(Journal) assert_equal User.find_by_login('jsmith'), journal.user assert_equal Issue.find(2), journal.journalized assert_match /This is reply/, journal.notes end def test_add_issue_note_with_status_change # This email contains: 'Status: Resolved' journal = submit_email('ticket_reply_with_status.eml') assert journal.is_a?(Journal) issue = Issue.find(journal.issue.id) assert_equal User.find_by_login('jsmith'), journal.user assert_equal Issue.find(2), journal.journalized assert_match /This is reply/, journal.notes assert_equal IssueStatus.find_by_name("Resolved"), issue.status end def test_add_issue_note_should_send_email_notification ActionMailer::Base.deliveries.clear journal = submit_email('ticket_reply.eml') assert journal.is_a?(Journal) assert_equal 1, ActionMailer::Base.deliveries.size end def test_reply_to_a_message m = submit_email('message_reply.eml') assert m.is_a?(Message) assert !m.new_record? m.reload assert_equal 'Reply via email', m.subject # The email replies to message #2 which is part of the thread of message #1 assert_equal Message.find(1), m.parent end def test_reply_to_a_message_by_subject m = submit_email('message_reply_by_subject.eml') assert m.is_a?(Message) assert !m.new_record? m.reload assert_equal 'Reply to the first post', m.subject assert_equal Message.find(1), m.parent end def test_should_strip_tags_of_html_only_emails issue = submit_email('ticket_html_only.eml', :issue => {:project => 'ecookbook'}) assert issue.is_a?(Issue) assert !issue.new_record? issue.reload assert_equal 'HTML email', issue.subject assert_equal 'This is a html-only email.', issue.description end private def submit_email(filename, options={}) raw = IO.read(File.join(FIXTURES_PATH, filename)) MailHandler.receive(raw, options) end end