Added tests for email retry to deliver or add a note it delivery was not possible.

This commit is contained in:
Martin Edenhofer 2016-06-25 08:54:25 +02:00
parent 6a43eabeb4
commit 3b9f7b28df
5 changed files with 355 additions and 18 deletions

View file

@ -72,6 +72,17 @@ test:integration:email_helper:
- ruby -I test/ test/integration/email_helper_test.rb
- rake db:drop
test:integration:email_deliver:
stage: test
tags:
- core
script:
- export RAILS_ENV=test
- rake db:create
- rake db:migrate
- ruby -I test/ test/integration/email_deliver_test.rb
- rake db:drop
test:integration:twitter:
stage: test
tags:

View file

@ -244,6 +244,7 @@ send via account
self.status_out = 'error'
self.last_log_out = error
save
raise error
end
result
end

View file

@ -15,11 +15,17 @@ class Observer::Ticket::Article::CommunicateEmail::BackgroundJob
ticket.subject_build(record.subject)
end
# set retry count
if !record.preferences['delivery_retry']
record.preferences['delivery_retry'] = 0
end
record.preferences['delivery_retry'] += 1
# send email
if !ticket.group.email_address_id
raise "Can't send email, no email address definde for group id '#{ticket.group.id}'"
log_error(record, "Unable to send email, no email address definde for group id '#{ticket.group.id}'")
elsif !ticket.group.email_address.channel_id
raise "Can't send email, no channel definde for email_address id '#{ticket.group.email_address_id}'"
log_error(record, "Unable to send email, no channel definde for email_address id '#{ticket.group.email_address_id}'")
end
channel = ticket.group.email_address.channel
@ -31,21 +37,36 @@ class Observer::Ticket::Article::CommunicateEmail::BackgroundJob
end
# get linked channel and send
message = channel.deliver(
{
message_id: record.message_id,
in_reply_to: record.in_reply_to,
references: ticket.get_references([record.message_id]),
from: record.from,
to: record.to,
cc: record.cc,
subject: subject,
content_type: record.content_type,
body: record.body,
attachments: record.attachments
},
notification
)
begin
message = channel.deliver(
{
message_id: record.message_id,
in_reply_to: record.in_reply_to,
references: ticket.get_references([record.message_id]),
from: record.from,
to: record.to,
cc: record.cc,
subject: subject,
content_type: record.content_type,
body: record.body,
attachments: record.attachments
},
notification
)
rescue => e
log_error(record, e.message)
return
end
if !message
log_error(record, 'Unable to send email')
return
end
# set delivery status
record.preferences['delivery_status_message'] = nil
record.preferences['delivery_status'] = 'success'
record.preferences['delivery_status_date'] = Time.zone.now
record.save
# store mail plain
Store.add(
@ -83,4 +104,39 @@ class Observer::Ticket::Article::CommunicateEmail::BackgroundJob
created_by_id: record.created_by_id,
)
end
def log_error(local_record, message)
local_record.preferences['delivery_status'] = 'fail'
local_record.preferences['delivery_status_message'] = message
local_record.preferences['delivery_status_date'] = Time.zone.now
local_record.save
Rails.logger.error message
if local_record.preferences['delivery_retry'] > 3
Ticket::Article.create(
ticket_id: local_record.ticket_id,
content_type: 'text/plain',
body: "Unable to send email: #{message}",
internal: true,
sender: Ticket::Article::Sender.find_by(name: 'System'),
type: Ticket::Article::Type.find_by(name: 'note'),
updated_by_id: 1,
created_by_id: 1,
)
return
end
raise message
end
def max_attempts
4
end
def reschedule_at(current_time, attempts)
if Rails.env.production?
return current_time + attempts * 20.seconds
end
current_time + 5.seconds
end
end

View file

@ -3,7 +3,6 @@ require 'browser_test_helper'
class AaaGettingStartedTest < TestCase
def test_a_getting_started
#return # TODO: temp disable
if !ENV['MAILBOX_INIT']
#raise "Need MAILBOX_INIT as ENV variable like export MAILBOX_INIT='unittest01@znuny.com:somepass'"
puts "NOTICE: Need MAILBOX_INIT as ENV variable like export MAILBOX_INIT='unittest01@znuny.com:somepass'"

View file

@ -0,0 +1,270 @@
# encoding: utf-8
require 'test_helper'
class EmailDeliverTest < ActiveSupport::TestCase
test 'basic check' do
if !ENV['MAIL_SERVER']
raise "Need MAIL_SERVER as ENV variable like export MAIL_SERVER='mx.example.com'"
end
if !ENV['MAIL_SERVER_ACCOUNT']
raise "Need MAIL_SERVER_ACCOUNT as ENV variable like export MAIL_SERVER_ACCOUNT='user:somepass'"
end
server_login = ENV['MAIL_SERVER_ACCOUNT'].split(':')[0]
server_password = ENV['MAIL_SERVER_ACCOUNT'].split(':')[1]
email_address = EmailAddress.create(
realname: 'me Helpdesk',
email: "me#{rand(999_999_999)}@example.com",
updated_by_id: 1,
created_by_id: 1,
)
group = Group.create_or_update(
name: 'DeliverTest',
email_address_id: email_address.id,
updated_by_id: 1,
created_by_id: 1,
)
channel = Channel.create(
area: 'Email::Account',
group_id: group.id,
options: {
inbound: {
adapter: 'imap',
options: {
host: 'mx1.example.com',
user: 'example',
password: 'some_pw',
ssl: true,
}
},
outbound: {
adapter: 'sendmail'
}
},
active: true,
updated_by_id: 1,
created_by_id: 1,
)
email_address.channel_id = channel.id
email_address.save
ticket1 = Ticket.create(
title: 'some delivery test',
group: group,
customer_id: 2,
state: Ticket::State.lookup(name: 'new'),
priority: Ticket::Priority.lookup(name: '2 normal'),
updated_by_id: 1,
created_by_id: 1,
)
assert(ticket1, 'ticket created')
article1 = Ticket::Article.create(
ticket_id: ticket1.id,
to: 'some_recipient@example_not_existing_what_ever.com',
subject: 'some subject',
message_id: 'some@id',
body: 'some message delivery test',
internal: false,
sender: Ticket::Article::Sender.find_by(name: 'Agent'),
type: Ticket::Article::Type.find_by(name: 'email'),
updated_by_id: 1,
created_by_id: 1,
)
assert_equal(nil, article1.preferences['delivery_retry'])
assert_equal(nil, article1.preferences['delivery_status'])
assert_equal(nil, article1.preferences['delivery_status_date'])
assert_equal(nil, article1.preferences['delivery_status_message'])
result = Observer::Ticket::Article::CommunicateEmail::BackgroundJob.new(article1.id)
assert(result.perform)
article1_lookup = Ticket::Article.find(article1.id)
assert_equal(1, article1_lookup.preferences['delivery_retry'])
assert_equal('success', article1_lookup.preferences['delivery_status'])
assert(article1_lookup.preferences['delivery_status_date'])
assert_equal(nil, article1_lookup.preferences['delivery_status_message'])
# send with invalid smtp settings
channel.update_attributes(
options: {
inbound: {
adapter: 'imap',
options: {
host: 'mx1.example.com',
user: 'example',
password: 'some_pw',
ssl: true,
}
},
outbound: {
adapter: 'smtp',
options: {
host: 'mx1.example.com',
port: 25,
start_tls: true,
user: 'not_existing',
password: 'not_existing',
},
},
},
)
assert_raises(RuntimeError) {
result = Observer::Ticket::Article::CommunicateEmail::BackgroundJob.new(article1.id)
assert_not(result.perform)
}
article1_lookup = Ticket::Article.find(article1.id)
assert_equal(2, article1_lookup.preferences['delivery_retry'])
assert_equal('fail', article1_lookup.preferences['delivery_status'])
assert(article1_lookup.preferences['delivery_status_date'])
assert(article1_lookup.preferences['delivery_status_message'])
# send with correct smtp settings
channel.update_attributes(
options: {
inbound: {
adapter: 'imap',
options: {
host: 'mx1.example.com',
user: 'example',
password: 'some_pw',
ssl: true,
}
},
outbound: {
adapter: 'smtp',
options: {
host: ENV['MAIL_SERVER'],
port: 25,
start_tls: true,
user: server_login,
password: server_password,
},
},
},
)
result = Observer::Ticket::Article::CommunicateEmail::BackgroundJob.new(article1.id)
assert(result.perform)
article1_lookup = Ticket::Article.find(article1.id)
assert_equal(3, article1_lookup.preferences['delivery_retry'])
assert_equal('success', article1_lookup.preferences['delivery_status'])
assert(article1_lookup.preferences['delivery_status_date'])
assert_nil(article1_lookup.preferences['delivery_status_message'])
# check retry jobs
# remove background jobs
Delayed::Job.destroy_all
# send with invalid smtp settings
channel.update_attributes(
options: {
inbound: {
adapter: 'imap',
options: {
host: 'mx1.example.com',
user: 'example',
password: 'some_pw',
ssl: true,
}
},
outbound: {
adapter: 'smtp',
options: {
host: 'mx1.example.com',
port: 25,
start_tls: true,
user: 'not_existing',
password: 'not_existing',
},
},
},
)
# remove background jobs
Delayed::Job.destroy_all
article2 = Ticket::Article.create(
ticket_id: ticket1.id,
to: 'some_recipient@example_not_existing_what_ever.com',
subject: 'some subject2',
message_id: 'some@id',
body: 'some message delivery test2',
internal: false,
sender: Ticket::Article::Sender.find_by(name: 'Agent'),
type: Ticket::Article::Type.find_by(name: 'email'),
updated_by_id: 1,
created_by_id: 1,
)
assert_raises(RuntimeError) {
Scheduler.worker(true)
}
article2_lookup = Ticket::Article.find(article2.id)
assert_equal(2, ticket1.articles.count)
assert_equal(1, article2_lookup.preferences['delivery_retry'])
assert_equal('fail', article2_lookup.preferences['delivery_status'])
assert(article2_lookup.preferences['delivery_status_date'])
assert(article2_lookup.preferences['delivery_status_message'])
Scheduler.worker(true)
article2_lookup = Ticket::Article.find(article2.id)
assert_equal(2, ticket1.articles.count)
assert_equal(1, article2_lookup.preferences['delivery_retry'])
assert_equal('fail', article2_lookup.preferences['delivery_status'])
assert(article2_lookup.preferences['delivery_status_date'])
assert(article2_lookup.preferences['delivery_status_message'])
sleep 6
assert_raises(RuntimeError) {
Scheduler.worker(true)
}
article2_lookup = Ticket::Article.find(article2.id)
assert_equal(2, ticket1.articles.count)
assert_equal(2, article2_lookup.preferences['delivery_retry'])
assert_equal('fail', article2_lookup.preferences['delivery_status'])
assert(article2_lookup.preferences['delivery_status_date'])
assert(article2_lookup.preferences['delivery_status_message'])
Scheduler.worker(true)
article2_lookup = Ticket::Article.find(article2.id)
assert_equal(2, ticket1.articles.count)
assert_equal(2, article2_lookup.preferences['delivery_retry'])
assert_equal('fail', article2_lookup.preferences['delivery_status'])
assert(article2_lookup.preferences['delivery_status_date'])
assert(article2_lookup.preferences['delivery_status_message'])
sleep 11
assert_raises(RuntimeError) {
Scheduler.worker(true)
}
article2_lookup = Ticket::Article.find(article2.id)
assert_equal(2, ticket1.articles.count)
assert_equal(3, article2_lookup.preferences['delivery_retry'])
assert_equal('fail', article2_lookup.preferences['delivery_status'])
assert(article2_lookup.preferences['delivery_status_date'])
assert(article2_lookup.preferences['delivery_status_message'])
sleep 16
Scheduler.worker(true)
article2_lookup = Ticket::Article.find(article2.id)
assert_equal(3, ticket1.articles.count)
assert_equal('System', ticket1.articles.last.sender.name)
assert_equal(4, article2_lookup.preferences['delivery_retry'])
assert_equal('fail', article2_lookup.preferences['delivery_status'])
assert(article2_lookup.preferences['delivery_status_date'])
assert(article2_lookup.preferences['delivery_status_message'])
end
end