Added x-header support and unit tests.

This commit is contained in:
Martin Edenhofer 2012-05-06 22:48:23 +02:00
parent 00cc1ff6ce
commit 04123e3359
4 changed files with 156 additions and 19 deletions

View file

@ -78,18 +78,39 @@ class Channel::EmailParser
def process(channel, msg)
mail = parse( msg )
# check if trust x-headers
if !channel[:trusted]
mail.each {|key, value|
if key =~ /^x-zammad/i
mail.delete(key)
end
}
end
# check ignore header
return true if mail[ 'x-zammad-ignore'.to_sym ] == 'true' || mail[ 'x-zammad-ignore'.to_sym ] == true
ticket = nil
article = nil
user = nil
# use transaction
ActiveRecord::Base.transaction do
user = User.where( :email => mail[:from_email] ).first
if !user then
if mail[ 'x-zammad-customer-login'.to_sym ]
user = User.where( :login => mail[ 'x-zammad-customer-login'.to_sym ] ).first
end
if !user
user = User.where( :email => mail[ 'x-zammad-customer-email'.to_sym ] || mail[:from_email] ).first
end
if !user
puts 'create user...'
roles = Role.where( :name => 'Customer' )
user = User.create(
:login => mail[:from_email],
:firstname => mail[:from_display_name],
:lastname => '',
:email => mail[:from_email],
:login => mail[ 'x-zammad-customer-login'.to_sym ] || mail[ 'x-zammad-customer-email'.to_sym ] || mail[:from_email],
:firstname => mail[ 'x-zammad-customer-firstname'.to_sym ] || mail[:from_display_name],
:lastname => mail[ 'x-zammad-customer-lastname'.to_sym ],
:email => mail[ 'x-zammad-customer-email'.to_sym ] || mail[:from_email],
:password => '',
:active => true,
:roles => roles,
@ -114,31 +135,73 @@ class Channel::EmailParser
end
# create new ticket
if !ticket then
ticket = Ticket.create(
if !ticket
# set attributes
ticket_attributes = {
:group_id => channel[:group_id] || 1,
:customer_id => user.id,
:title => mail[:subject],
:ticket_state_id => Ticket::State.where(:name => 'new').first.id,
:ticket_priority_id => Ticket::Priority.where(:name => '2 normal').first.id,
:created_by_id => user.id
)
:ticket_state_id => Ticket::State.where( :name => 'new' ).first.id,
:ticket_priority_id => Ticket::Priority.where( :name => '2 normal' ).first.id,
:created_by_id => user.id,
}
# x-headers lookup
map = [
[ 'x-zammad-group', Group, 'group_id', 'name' ],
[ 'x-zammad-state', Ticket::State, 'ticket_state_id', 'name' ],
[ 'x-zammad-priority', Ticket::Priority, 'ticket_priority_id', 'name' ],
[ 'x-zammad-owner', User, 'owner_id', 'login' ],
]
map.each { |item|
if mail[ item[0].to_sym ]
if item[1].where( item[3].to_sym => mail[ item[0].to_sym ] ).first
ticket_attributes[ item[2].to_sym ] = item[1].where( item[3].to_sym => mail[ item[0].to_sym ] ).first.id
end
end
}
# create ticket
ticket = Ticket.create( ticket_attributes )
end
# import mail
article = Ticket::Article.create(
# set attributes
internal = false
if mail[ 'X-Zammad-Article-Visability'.to_sym ] && mail[ 'X-Zammad-Article-Visability'.to_sym ] == 'internal'
internal = true
end
article_attributes = {
:created_by_id => user.id,
:ticket_id => ticket.id,
:ticket_article_type_id => Ticket::Article::Type.where(:name => 'email').first.id,
:ticket_article_sender_id => Ticket::Article::Sender.where(:name => 'Customer').first.id,
:ticket_article_type_id => Ticket::Article::Type.where( :name => 'email' ).first.id,
:ticket_article_sender_id => Ticket::Article::Sender.where( :name => 'Customer' ).first.id,
:body => mail[:plain_part],
:from => mail[:from],
:to => mail[:to],
:cc => mail[:cc],
:subject => mail[:subject],
:message_id => mail[:message_id],
:internal => false
)
:internal => internal,
}
# x-headers lookup
map = [
[ 'x-zammad-article-type', Ticket::Article::Type, 'ticket_article_type_id', 'name' ],
[ 'x-zammad-article-sender', Ticket::Article::Sender, 'ticket_article_sender_id', 'name' ],
]
map.each { |item|
if mail[ item[0].to_sym ]
if item[1].where( item[3].to_sym => mail[ item[0].to_sym ] ).first
article_attributes[ item[2].to_sym ] = item[1].where( item[3].to_sym => mail[ item[0].to_sym ] ).first.id
end
end
}
# create article
article = Ticket::Article.create(article_attributes)
# store mail plain
Store.add(
@ -161,10 +224,12 @@ class Channel::EmailParser
)
end
end
return ticket, article, user
end
# execute ticket events
Ticket::Observer::Notification.transaction
# return new objects
return ticket, article, user
end
end

View file

@ -9,5 +9,8 @@ class ActiveSupport::TestCase
# -- they do not yet inherit this setting
fixtures :all
# load seeds
load "#{Rails.root}/db/seeds.rb"
# Add more helper methods to be used by all tests here...
end

View file

@ -45,7 +45,7 @@ class EmailParserTest < ActiveSupport::TestCase
# check body
md5 = Digest::MD5.hexdigest( data[:plain_part] )
assert_equal( file[:body_md5], md5 )
puts data[:from]
# check params
file[:params].each { |key, value|
if key.to_s == 'plain_part'

View file

@ -0,0 +1,69 @@
# encoding: utf-8
require 'test_helper'
class EmailProcessTest < ActiveSupport::TestCase
test 'process' do
files = [
{
:data => 'From: me@example.com
To: customer@example.com
Subject: some subject
Some Text',
:success => true,
},
{
:data => 'From: me@example.com
To: customer@example.com
Subject: some subject
X-Zammad-Ignore: true
Some Text',
:success => false,
},
{
:data => 'From: me@example.com
To: customer@example.com
Subject: some subject
X-Zammad-Priority: 3 high
X-Zammad-Article-Sender: system
x-Zammad-Article-Type: phone
Some Text',
:success => true,
:result => {
0 => {
:ticket_priority => '3 high',
},
1 => {
:ticket_article_sender => 'System',
:ticket_article_type => 'phone',
},
},
},
]
files.each { |file|
parser = Channel::EmailParser.new
result = parser.process( { :trusted => true }, file[:data] )
if file[:success] && result[1]
assert( true )
if file[:result]
[ 0, 1, 2 ].each { |level|
if file[:result][level]
file[:result][level].each { |key, value|
assert_equal( result[level].send(key).name, value.to_s)
}
end
}
end
elsif !file[:success] && result == true
assert( true )
elsif !file[:success] && result[1]
assert( false, 'ticket should not be created' )
else
assert( false, 'UNKNOWN!' )
end
}
end
end