Added tests for email retry to deliver or add a note it delivery was not possible.
This commit is contained in:
parent
6a43eabeb4
commit
3b9f7b28df
5 changed files with 355 additions and 18 deletions
|
@ -72,6 +72,17 @@ test:integration:email_helper:
|
||||||
- ruby -I test/ test/integration/email_helper_test.rb
|
- ruby -I test/ test/integration/email_helper_test.rb
|
||||||
- rake db:drop
|
- 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:
|
test:integration:twitter:
|
||||||
stage: test
|
stage: test
|
||||||
tags:
|
tags:
|
||||||
|
|
|
@ -244,6 +244,7 @@ send via account
|
||||||
self.status_out = 'error'
|
self.status_out = 'error'
|
||||||
self.last_log_out = error
|
self.last_log_out = error
|
||||||
save
|
save
|
||||||
|
raise error
|
||||||
end
|
end
|
||||||
result
|
result
|
||||||
end
|
end
|
||||||
|
|
|
@ -15,11 +15,17 @@ class Observer::Ticket::Article::CommunicateEmail::BackgroundJob
|
||||||
ticket.subject_build(record.subject)
|
ticket.subject_build(record.subject)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# set retry count
|
||||||
|
if !record.preferences['delivery_retry']
|
||||||
|
record.preferences['delivery_retry'] = 0
|
||||||
|
end
|
||||||
|
record.preferences['delivery_retry'] += 1
|
||||||
|
|
||||||
# send email
|
# send email
|
||||||
if !ticket.group.email_address_id
|
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
|
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
|
end
|
||||||
|
|
||||||
channel = ticket.group.email_address.channel
|
channel = ticket.group.email_address.channel
|
||||||
|
@ -31,21 +37,36 @@ class Observer::Ticket::Article::CommunicateEmail::BackgroundJob
|
||||||
end
|
end
|
||||||
|
|
||||||
# get linked channel and send
|
# get linked channel and send
|
||||||
message = channel.deliver(
|
begin
|
||||||
{
|
message = channel.deliver(
|
||||||
message_id: record.message_id,
|
{
|
||||||
in_reply_to: record.in_reply_to,
|
message_id: record.message_id,
|
||||||
references: ticket.get_references([record.message_id]),
|
in_reply_to: record.in_reply_to,
|
||||||
from: record.from,
|
references: ticket.get_references([record.message_id]),
|
||||||
to: record.to,
|
from: record.from,
|
||||||
cc: record.cc,
|
to: record.to,
|
||||||
subject: subject,
|
cc: record.cc,
|
||||||
content_type: record.content_type,
|
subject: subject,
|
||||||
body: record.body,
|
content_type: record.content_type,
|
||||||
attachments: record.attachments
|
body: record.body,
|
||||||
},
|
attachments: record.attachments
|
||||||
notification
|
},
|
||||||
)
|
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 mail plain
|
||||||
Store.add(
|
Store.add(
|
||||||
|
@ -83,4 +104,39 @@ class Observer::Ticket::Article::CommunicateEmail::BackgroundJob
|
||||||
created_by_id: record.created_by_id,
|
created_by_id: record.created_by_id,
|
||||||
)
|
)
|
||||||
end
|
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
|
end
|
||||||
|
|
|
@ -3,7 +3,6 @@ require 'browser_test_helper'
|
||||||
|
|
||||||
class AaaGettingStartedTest < TestCase
|
class AaaGettingStartedTest < TestCase
|
||||||
def test_a_getting_started
|
def test_a_getting_started
|
||||||
#return # TODO: temp disable
|
|
||||||
if !ENV['MAILBOX_INIT']
|
if !ENV['MAILBOX_INIT']
|
||||||
#raise "Need MAILBOX_INIT as ENV variable like export MAILBOX_INIT='unittest01@znuny.com:somepass'"
|
#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'"
|
puts "NOTICE: Need MAILBOX_INIT as ENV variable like export MAILBOX_INIT='unittest01@znuny.com:somepass'"
|
||||||
|
|
270
test/integration/email_deliver_test.rb
Normal file
270
test/integration/email_deliver_test.rb
Normal 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
|
Loading…
Reference in a new issue