Implemented issue #539 - Add email address without importing historical emails.

This commit is contained in:
Martin Edenhofer 2017-07-20 14:01:14 +02:00
parent efad1f9fb1
commit d8ad2b1b2f
8 changed files with 340 additions and 52 deletions

View file

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

View file

@ -560,21 +560,24 @@ class App.ChannelEmailAccountWizard extends App.WizardModal
# inbound # inbound
configureAttributesInbound = [ configureAttributesInbound = [
{ name: 'adapter', display: 'Type', tag: 'select', multiple: false, null: false, options: @channelDriver.email.inbound }, { name: 'adapter', display: 'Type', tag: 'select', multiple: false, null: false, options: @channelDriver.email.inbound },
{ name: 'options::host', display: 'Host', tag: 'input', type: 'text', limit: 120, null: false, autocapitalize: false }, { name: 'options::host', display: 'Host', tag: 'input', type: 'text', limit: 120, null: false, autocapitalize: false },
{ name: 'options::user', display: 'User', tag: 'input', type: 'text', limit: 120, null: false, autocapitalize: false, autocomplete: 'off', }, { name: 'options::user', display: 'User', tag: 'input', type: 'text', limit: 120, null: false, autocapitalize: false, autocomplete: 'off' },
{ name: 'options::password', display: 'Password', tag: 'input', type: 'password', limit: 120, null: false, autocapitalize: false, autocomplete: 'new-password', single: true }, { name: 'options::password', display: 'Password', tag: 'input', type: 'password', limit: 120, null: false, autocapitalize: false, autocomplete: 'new-password', single: true },
{ name: 'options::ssl', display: 'SSL', tag: 'boolean', null: true, options: { true: 'yes', false: 'no' }, default: true, translate: true, item_class: 'formGroup--halfSize' }, { name: 'options::ssl', display: 'SSL', tag: 'boolean', null: true, options: { true: 'yes', false: 'no' }, default: true, translate: true, item_class: 'formGroup--halfSize' },
{ name: 'options::port', display: 'Port', tag: 'input', type: 'text', limit: 6, null: true, autocapitalize: false, default: '993', item_class: 'formGroup--halfSize' }, { name: 'options::port', display: 'Port', tag: 'input', type: 'text', limit: 6, null: true, autocapitalize: false, default: '993', item_class: 'formGroup--halfSize' },
{ name: 'options::folder', display: 'Folder', tag: 'input', type: 'text', limit: 120, null: true, autocapitalize: false }, { name: 'options::folder', display: 'Folder', tag: 'input', type: 'text', limit: 120, null: true, autocapitalize: false, item_class: 'formGroup--halfSize' },
{ name: 'options::keep_on_server', display: 'Keep messages on server', tag: 'boolean', null: true, options: { true: 'yes', false: 'no' }, translate: true, default: false, item_class: 'formGroup--halfSize' },
] ]
showHideFolder = (params, attribute, attributes, classname, form, ui) -> showHideFolder = (params, attribute, attributes, classname, form, ui) ->
return if !params return if !params
if params.adapter is 'imap' if params.adapter is 'imap'
ui.show('options::folder') ui.show('options::folder')
ui.show('options::keep_on_server')
return return
ui.hide('options::folder') ui.hide('options::folder')
ui.hide('options::keep_on_server')
handlePort = (params, attribute, attributes, classname, form, ui) -> handlePort = (params, attribute, attributes, classname, form, ui) ->
return if !params return if !params
@ -606,9 +609,10 @@ class App.ChannelEmailAccountWizard extends App.WizardModal
# fill user / password based on intro info # fill user / password based on intro info
channel_used = { options: {} } channel_used = { options: {} }
if @account['meta'] if @account['meta']
channel_used['options']['user'] = @account['meta']['email'] channel_used['options']['user'] = @account['meta']['email']
channel_used['options']['password'] = @account['meta']['password'] channel_used['options']['password'] = @account['meta']['password']
channel_used['options']['folder'] = @account['meta']['folder'] channel_used['options']['folder'] = @account['meta']['folder']
channel_used['options']['keep_on_server'] = @account['meta']['keep_on_server']
# show used backend # show used backend
@$('.base-outbound-settings').html('') @$('.base-outbound-settings').html('')
@ -670,7 +674,7 @@ class App.ChannelEmailAccountWizard extends App.WizardModal
for key, value of data.setting for key, value of data.setting
@account[key] = value @account[key] = value
if data.content_messages && data.content_messages > 0 if data.content_messages && data.content_messages > 0 && (!@account['inbound']['options'] || @account['inbound']['options']['keep_on_server'] isnt true)
message = App.i18n.translateContent('We have already found %s email(s) in your mailbox. Zammad will move it all from your mailbox into Zammad.', data.content_messages) message = App.i18n.translateContent('We have already found %s email(s) in your mailbox. Zammad will move it all from your mailbox into Zammad.', data.content_messages)
@$('.js-inbound-acknowledge .js-message').html(message) @$('.js-inbound-acknowledge .js-message').html(message)
@$('.js-inbound-acknowledge .js-back').attr('data-slide', 'js-intro') @$('.js-inbound-acknowledge .js-back').attr('data-slide', 'js-intro')
@ -724,7 +728,7 @@ class App.ChannelEmailAccountWizard extends App.WizardModal
# remember account settings # remember account settings
@account.inbound = params @account.inbound = params
if data.content_messages && data.content_messages > 0 if data.content_messages && data.content_messages > 0 && (!@account['inbound']['options'] || @account['inbound']['options']['keep_on_server'] isnt true)
message = App.i18n.translateContent('We have already found %s email(s) in your mailbox. Zammad will move it all from your mailbox into Zammad.', data.content_messages) message = App.i18n.translateContent('We have already found %s email(s) in your mailbox. Zammad will move it all from your mailbox into Zammad.', data.content_messages)
@$('.js-inbound-acknowledge .js-message').html(message) @$('.js-inbound-acknowledge .js-message').html(message)
@$('.js-inbound-acknowledge .js-back').attr('data-slide', 'js-inbound') @$('.js-inbound-acknowledge .js-back').attr('data-slide', 'js-inbound')

View file

@ -450,8 +450,8 @@ class EmailNotification extends App.WizardFullScreen
if adapter is 'smtp' if adapter is 'smtp'
configureAttributesOutbound = [ configureAttributesOutbound = [
{ name: 'options::host', display: 'Host', tag: 'input', type: 'text', limit: 120, null: false, autocapitalize: false, autofocus: true }, { name: 'options::host', display: 'Host', tag: 'input', type: 'text', limit: 120, null: false, autocapitalize: false, autofocus: true },
{ name: 'options::user', display: 'User', tag: 'input', type: 'text', limit: 120, null: true, autocapitalize: false, autocomplete: 'new-password' }, { name: 'options::user', display: 'User', tag: 'input', type: 'text', limit: 120, null: true, autocapitalize: false, autocomplete: 'off' },
{ name: 'options::password', display: 'Password', tag: 'input', type: 'password', limit: 120, null: true, autocapitalize: false, autocomplete: 'new-password', single: true }, { name: 'options::password', display: 'Password', tag: 'input', type: 'password', limit: 120, null: true, autocapitalize: false, autocomplete: 'off', single: true },
{ name: 'options::port', display: 'Port', tag: 'input', type: 'text', limit: 6, null: true, autocapitalize: false }, { name: 'options::port', display: 'Port', tag: 'input', type: 'text', limit: 6, null: true, autocapitalize: false },
] ]
@form = new App.ControllerForm( @form = new App.ControllerForm(
@ -671,20 +671,24 @@ class ChannelEmail extends App.WizardFullScreen
# inbound # inbound
configureAttributesInbound = [ configureAttributesInbound = [
{ name: 'adapter', display: 'Type', tag: 'select', multiple: false, null: false, options: @channelDriver.email.inbound }, { name: 'adapter', display: 'Type', tag: 'select', multiple: false, null: false, options: @channelDriver.email.inbound },
{ name: 'options::host', display: 'Host', tag: 'input', type: 'text', limit: 120, null: false, autocapitalize: false }, { name: 'options::host', display: 'Host', tag: 'input', type: 'text', limit: 120, null: false, autocapitalize: false },
{ name: 'options::user', display: 'User', tag: 'input', type: 'text', limit: 120, null: false, autocapitalize: false, autocomplete: 'new-password', }, { name: 'options::user', display: 'User', tag: 'input', type: 'text', limit: 120, null: false, autocapitalize: false, autocomplete: 'off', },
{ name: 'options::password', display: 'Password', tag: 'input', type: 'password', limit: 120, null: false, autocapitalize: false, autocomplete: 'new-password', single: true }, { name: 'options::password', display: 'Password', tag: 'input', type: 'password', limit: 120, null: false, autocapitalize: false, autocomplete: 'off', single: true },
{ name: 'options::ssl', display: 'SSL', tag: 'boolean', null: true, options: { true: 'yes', false: 'no' }, default: true, translate: true, item_class: 'formGroup--halfSize' }, { name: 'options::ssl', display: 'SSL', tag: 'boolean', null: true, options: { true: 'yes', false: 'no' }, default: true, translate: true, item_class: 'formGroup--halfSize' },
{ name: 'options::port', display: 'Port', tag: 'input', type: 'text', limit: 6, null: true, autocapitalize: false, default: '993', item_class: 'formGroup--halfSize' }, { name: 'options::port', display: 'Port', tag: 'input', type: 'text', limit: 6, null: true, autocapitalize: false, default: '993', item_class: 'formGroup--halfSize' },
{ name: 'options::folder', display: 'Folder', tag: 'input', type: 'text', limit: 120, null: true, autocapitalize: false, item_class: 'formGroup--halfSize' },
{ name: 'options::keep_on_server', display: 'Keep messages on server', tag: 'boolean', null: true, options: { true: 'yes', false: 'no' }, translate: true, default: false, item_class: 'formGroup--halfSize' },
] ]
showHideFolder = (params, attribute, attributes, classname, form, ui) -> showHideFolder = (params, attribute, attributes, classname, form, ui) ->
return if !params return if !params
if params.adapter is 'imap' if params.adapter is 'imap'
ui.show('options::folder') ui.show('options::folder')
ui.show('options::keep_on_server')
return return
ui.hide('options::folder') ui.hide('options::folder')
ui.hide('options::keep_on_server')
handlePort = (params, attribute, attributes, classname, form, ui) -> handlePort = (params, attribute, attributes, classname, form, ui) ->
return if !params return if !params
@ -700,7 +704,7 @@ class ChannelEmail extends App.WizardFullScreen
return return
new App.ControllerForm( new App.ControllerForm(
el: @$('.base-inbound-settings'), el: @$('.base-inbound-settings')
model: model:
configure_attributes: configureAttributesInbound configure_attributes: configureAttributesInbound
className: '' className: ''
@ -716,8 +720,10 @@ class ChannelEmail extends App.WizardFullScreen
# fill user / password based on intro info # fill user / password based on intro info
channel_used = { options: {} } channel_used = { options: {} }
if @account['meta'] if @account['meta']
channel_used['options']['user'] = @account['meta']['email'] channel_used['options']['user'] = @account['meta']['email']
channel_used['options']['password'] = @account['meta']['password'] channel_used['options']['password'] = @account['meta']['password']
channel_used['options']['folder'] = @account['meta']['folder']
channel_used['options']['keep_on_server'] = @account['meta']['keep_on_server']
# show used backend # show used backend
@$('.base-outbound-settings').html('') @$('.base-outbound-settings').html('')
@ -725,8 +731,8 @@ class ChannelEmail extends App.WizardFullScreen
if adapter is 'smtp' if adapter is 'smtp'
configureAttributesOutbound = [ configureAttributesOutbound = [
{ name: 'options::host', display: 'Host', tag: 'input', type: 'text', limit: 120, null: false, autocapitalize: false, autofocus: true }, { name: 'options::host', display: 'Host', tag: 'input', type: 'text', limit: 120, null: false, autocapitalize: false, autofocus: true },
{ name: 'options::user', display: 'User', tag: 'input', type: 'text', limit: 120, null: true, autocapitalize: false, autocomplete: 'new-password', }, { name: 'options::user', display: 'User', tag: 'input', type: 'text', limit: 120, null: true, autocapitalize: false, autocomplete: 'off', },
{ name: 'options::password', display: 'Password', tag: 'input', type: 'password', limit: 120, null: true, autocapitalize: false, autocomplete: 'new-password', single: true }, { name: 'options::password', display: 'Password', tag: 'input', type: 'password', limit: 120, null: true, autocapitalize: false, autocomplete: 'off', single: true },
{ name: 'options::port', display: 'Port', tag: 'input', type: 'text', limit: 6, null: true, autocapitalize: false }, { name: 'options::port', display: 'Port', tag: 'input', type: 'text', limit: 6, null: true, autocapitalize: false },
] ]
@form = new App.ControllerForm( @form = new App.ControllerForm(
@ -745,7 +751,7 @@ class ChannelEmail extends App.WizardFullScreen
@account.meta = params @account.meta = params
@disable(e) @disable(e)
@$('.js-probe .js-email').text( params.email ) @$('.js-probe .js-email').text(params.email)
@showSlide('js-probe') @showSlide('js-probe')
@ajax( @ajax(
@ -760,7 +766,7 @@ class ChannelEmail extends App.WizardFullScreen
for key, value of data.setting for key, value of data.setting
@account[key] = value @account[key] = value
if data.content_messages && data.content_messages > 0 if data.content_messages && data.content_messages > 0 && (!@account['inbound']['options'] || @account['inbound']['options']['keep_on_server'] isnt true)
message = App.i18n.translateContent('We have already found %s email(s) in your mailbox. Zammad will move it all from your mailbox into Zammad.', data.content_messages) message = App.i18n.translateContent('We have already found %s email(s) in your mailbox. Zammad will move it all from your mailbox into Zammad.', data.content_messages)
@$('.js-inbound-acknowledge .js-message').html(message) @$('.js-inbound-acknowledge .js-message').html(message)
@$('.js-inbound-acknowledge .js-back').attr('data-slide', 'js-intro') @$('.js-inbound-acknowledge .js-back').attr('data-slide', 'js-intro')
@ -809,7 +815,7 @@ class ChannelEmail extends App.WizardFullScreen
# remember account settings # remember account settings
@account.inbound = params @account.inbound = params
if data.content_messages && data.content_messages > 0 if data.content_messages && data.content_messages > 0 && (!@account['inbound']['options'] || @account['inbound']['options']['keep_on_server'] isnt true)
message = App.i18n.translateContent('We have already found %s emails in your mailbox. Zammad will move it all from your mailbox into Zammad.', data.content_messages) message = App.i18n.translateContent('We have already found %s emails in your mailbox. Zammad will move it all from your mailbox into Zammad.', data.content_messages)
@$('.js-inbound-acknowledge .js-message').html(message) @$('.js-inbound-acknowledge .js-message').html(message)
@$('.js-inbound-acknowledge .js-back').attr('data-slide', 'js-inbound') @$('.js-inbound-acknowledge .js-back').attr('data-slide', 'js-inbound')

View file

@ -63,7 +63,7 @@
</form> </form>
<form class="setup wizard hide js-inbound"> <form class="setup wizard hide js-inbound">
<div class="wizard-slide"> <div class="wizard-slide wizard-slide--large">
<h2><%- @T('Email Inbound') %></h2> <h2><%- @T('Email Inbound') %></h2>
<div class="wizard-body vertical justified"> <div class="wizard-body vertical justified">
<div class="alert alert--danger hide" role="alert"></div> <div class="alert alert--danger hide" role="alert"></div>

View file

@ -6457,6 +6457,10 @@ footer {
width: 400px; width: 400px;
padding-bottom: 18px; padding-bottom: 18px;
margin-bottom: 20px; margin-bottom: 20px;
&.wizard-slide--large {
width: 460px;
}
} }
.wizard h2 { .wizard h2 {

View file

@ -52,6 +52,7 @@ example
host: 'outlook.office365.com', host: 'outlook.office365.com',
user: 'xxx@znuny.onmicrosoft.com', user: 'xxx@znuny.onmicrosoft.com',
password: 'xxx', password: 'xxx',
keep_on_server: true,
} }
channel = Channel.last channel = Channel.last
instance = Channel::Driver::Imap.new instance = Channel::Driver::Imap.new
@ -60,13 +61,18 @@ example
=end =end
def fetch (options, channel, check_type = '', verify_string = '') def fetch (options, channel, check_type = '', verify_string = '')
ssl = true ssl = true
port = 993 port = 993
keep_on_server = false
folder = 'INBOX'
if options[:keep_on_server] == true || options[:keep_on_server] == 'true'
keep_on_server = true
end
if options.key?(:ssl) && options[:ssl] == false if options.key?(:ssl) && options[:ssl] == false
ssl = false ssl = false
port = 143 port = 143
end end
if options.key?(:port) && !options[:port].empty? if options.key?(:port) && options[:port].present?
port = options[:port] port = options[:port]
# disable ssl for non ssl ports # disable ssl for non ssl ports
@ -74,8 +80,11 @@ example
ssl = false ssl = false
end end
end end
if options[:folder].present?
folder = options[:folder]
end
Rails.logger.info "fetching imap (#{options[:host]}/#{options[:user]} port=#{port},ssl=#{ssl},folder=#{options[:folder]})" Rails.logger.info "fetching imap (#{options[:host]}/#{options[:user]} port=#{port},ssl=#{ssl},folder=#{folder},keep_on_server=#{keep_on_server})"
# on check, reduce open_timeout to have faster probing # on check, reduce open_timeout to have faster probing
timeout = 45 timeout = 45
@ -90,17 +99,17 @@ example
@imap.login(options[:user], options[:password]) @imap.login(options[:user], options[:password])
# select folder # select folder
if !options[:folder] || options[:folder].empty? @imap.select(folder)
@imap.select('INBOX')
else
@imap.select(options[:folder])
end
# sort messages by date on server (if not supported), if not fetch messages via search (first in, first out) # sort messages by date on server (if not supported), if not fetch messages via search (first in, first out)
filter = ['ALL']
if keep_on_server && check_type != 'check' && check_type != 'verify'
filter = %w(NOT SEEN)
end
begin begin
message_ids = @imap.sort(['DATE'], ['ALL'], 'US-ASCII') message_ids = @imap.sort(['DATE'], filter, 'US-ASCII')
rescue rescue
message_ids = @imap.search(['ALL']) message_ids = @imap.search(filter)
end end
# check mode only # check mode only
@ -168,9 +177,8 @@ example
message_ids.each do |message_id| message_ids.each do |message_id|
count += 1 count += 1
Rails.logger.info " - message #{count}/#{count_all}" Rails.logger.info " - message #{count}/#{count_all}"
#Rails.logger.info msg.to_s
message_meta = @imap.fetch(message_id, ['RFC822.SIZE', 'FLAGS', 'INTERNALDATE'])[0] message_meta = @imap.fetch(message_id, ['RFC822.SIZE', 'ENVELOPE', 'FLAGS', 'INTERNALDATE'])[0]
# ignore to big messages # ignore to big messages
info = too_big?(message_meta, count, count_all) info = too_big?(message_meta, count, count_all)
@ -182,14 +190,23 @@ example
# ignore deleted messages # ignore deleted messages
next if deleted?(message_meta, count, count_all) next if deleted?(message_meta, count, count_all)
# ignore already imported
next if already_imported?(message_id, message_meta, count, count_all, keep_on_server)
# delete email from server after article was created # delete email from server after article was created
msg = @imap.fetch(message_id, 'RFC822')[0].attr['RFC822'] msg = @imap.fetch(message_id, 'RFC822')[0].attr['RFC822']
next if !msg next if !msg
process(channel, msg, false) process(channel, msg, false)
@imap.store(message_id, '+FLAGS', [:Deleted]) if !keep_on_server
@imap.store(message_id, '+FLAGS', [:Deleted])
else
@imap.store(message_id, '+FLAGS', [:Seen])
end
count_fetched += 1 count_fetched += 1
end end
@imap.expunge() if !keep_on_server
@imap.expunge()
end
disconnect disconnect
if count.zero? if count.zero?
Rails.logger.info ' - no message' Rails.logger.info ' - no message'
@ -209,6 +226,20 @@ example
private private
def already_imported?(message_id, message_meta, count, count_all, keep_on_server)
return false if !keep_on_server
return false if !message_meta.attr
return false if !message_meta.attr['ENVELOPE']
local_message_id = message_meta.attr['ENVELOPE'].message_id
return false if local_message_id.blank?
local_message_id_md5 = Digest::MD5.hexdigest(local_message_id)
article = Ticket::Article.where(message_id_md5: local_message_id_md5).order('created_at DESC, id DESC').limit(1).first
return false if !article
@imap.store(message_id, '+FLAGS', [:Seen])
Rails.logger.info " - ignore message #{count}/#{count_all} - because message message id already imported"
true
end
def deleted?(message_meta, count, count_all) def deleted?(message_meta, count, count_all)
return false if !message_meta.attr['FLAGS'].include?(:Deleted) return false if !message_meta.attr['FLAGS'].include?(:Deleted)
Rails.logger.info " - ignore message #{count}/#{count_all} - because message has already delete flag" Rails.logger.info " - ignore message #{count}/#{count_all} - because message has already delete flag"

View file

@ -4,16 +4,16 @@ require 'test_helper'
class EmailDeliverTest < ActiveSupport::TestCase class EmailDeliverTest < ActiveSupport::TestCase
test 'basic check' do test 'basic check' do
if !ENV['MAIL_SERVER'] if ENV['MAIL_SERVER'].blank?
raise "Need MAIL_SERVER as ENV variable like export MAIL_SERVER='mx.example.com'" raise "Need MAIL_SERVER as ENV variable like export MAIL_SERVER='mx.example.com'"
end end
if !ENV['MAIL_SERVER_ACCOUNT'] if ENV['MAIL_SERVER_ACCOUNT'].blank?
raise "Need MAIL_SERVER_ACCOUNT as ENV variable like export MAIL_SERVER_ACCOUNT='user:somepass'" raise "Need MAIL_SERVER_ACCOUNT as ENV variable like export MAIL_SERVER_ACCOUNT='user:somepass'"
end end
server_login = ENV['MAIL_SERVER_ACCOUNT'].split(':')[0] server_login = ENV['MAIL_SERVER_ACCOUNT'].split(':')[0]
server_password = ENV['MAIL_SERVER_ACCOUNT'].split(':')[1] server_password = ENV['MAIL_SERVER_ACCOUNT'].split(':')[1]
email_address = EmailAddress.create( email_address = EmailAddress.create!(
realname: 'me Helpdesk', realname: 'me Helpdesk',
email: "me#{rand(999_999_999)}@example.com", email: "me#{rand(999_999_999)}@example.com",
updated_by_id: 1, updated_by_id: 1,
@ -27,7 +27,7 @@ class EmailDeliverTest < ActiveSupport::TestCase
created_by_id: 1, created_by_id: 1,
) )
channel = Channel.create( channel = Channel.create!(
area: 'Email::Account', area: 'Email::Account',
group_id: group.id, group_id: group.id,
options: { options: {
@ -50,9 +50,9 @@ class EmailDeliverTest < ActiveSupport::TestCase
) )
email_address.channel_id = channel.id email_address.channel_id = channel.id
email_address.save email_address.save!
ticket1 = Ticket.create( ticket1 = Ticket.create!(
title: 'some delivery test', title: 'some delivery test',
group: group, group: group,
customer_id: 2, customer_id: 2,
@ -63,7 +63,7 @@ class EmailDeliverTest < ActiveSupport::TestCase
) )
assert(ticket1, 'ticket created') assert(ticket1, 'ticket created')
article1 = Ticket::Article.create( article1 = Ticket::Article.create!(
ticket_id: ticket1.id, ticket_id: ticket1.id,
to: 'some_recipient@example_not_existing_what_ever.com', to: 'some_recipient@example_not_existing_what_ever.com',
subject: 'some subject', subject: 'some subject',
@ -189,7 +189,7 @@ class EmailDeliverTest < ActiveSupport::TestCase
# remove background jobs # remove background jobs
Delayed::Job.destroy_all Delayed::Job.destroy_all
article2 = Ticket::Article.create( article2 = Ticket::Article.create!(
ticket_id: ticket1.id, ticket_id: ticket1.id,
to: 'some_recipient@example_not_existing_what_ever.com', to: 'some_recipient@example_not_existing_what_ever.com',
subject: 'some subject2', subject: 'some subject2',

View file

@ -0,0 +1,232 @@
# encoding: utf-8
require 'test_helper'
require 'net/imap'
class EmailKeepOnServerTest < ActiveSupport::TestCase
setup do
if ENV['KEEP_ON_MAIL_SERVER'].blank?
raise "Need KEEP_ON_MAIL_SERVER as ENV variable like export KEEP_ON_MAIL_SERVER='mx.example.com'"
end
if ENV['KEEP_ON_MAIL_SERVER_ACCOUNT'].blank?
raise "Need KEEP_ON_MAIL_SERVER_ACCOUNT as ENV variable like export KEEP_ON_MAIL_SERVER_ACCOUNT='user:somepass'"
end
@server_login = ENV['KEEP_ON_MAIL_SERVER_ACCOUNT'].split(':')[0]
@server_password = ENV['KEEP_ON_MAIL_SERVER_ACCOUNT'].split(':')[1]
@folder = "keep_on_mail_server_#{rand(999_999_999)}"
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: 'KeepOnServerTest',
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: ENV['KEEP_ON_MAIL_SERVER'],
user: @server_login,
password: @server_password,
ssl: true,
folder: @folder,
#keep_on_server: true,
}
},
outbound: {
adapter: 'sendmail'
}
},
active: true,
updated_by_id: 1,
created_by_id: 1,
)
email_address.channel_id = @channel.id
email_address.save!
end
test 'keep on server' do
@channel.options[:inbound][:options][:keep_on_server] = true
@channel.save!
# clean mailbox
imap = Net::IMAP.new(ENV['KEEP_ON_MAIL_SERVER'], 993, true, nil, false)
imap.login(@server_login, @server_password)
imap.create(@folder)
imap.select(@folder)
# put unseen message in it
imap.append(@folder, "Subject: hello1
From: shugo@example.com
To: shugo@example.com
Message-ID: <some1@example_keep_on_server>
hello world
".gsub(/\n/, "\r\n"), [], Time.zone.now)
# verify if message is still on server
message_ids = imap.sort(['DATE'], ['ALL'], 'US-ASCII')
assert_equal(1, message_ids.count)
message_meta = imap.fetch(1, ['FLAGS'])[0].attr
assert_not(message_meta['FLAGS'].include?(:Seen))
# fetch messages
article_count = Ticket::Article.count
@channel.fetch(true)
assert_equal(article_count + 1, Ticket::Article.count)
# verify if message is still on server
message_ids = imap.sort(['DATE'], ['ALL'], 'US-ASCII')
assert_equal(1, message_ids.count)
message_meta = imap.fetch(1, ['RFC822.HEADER', 'FLAGS'])[0].attr
assert(message_meta['FLAGS'].include?(:Seen))
# fetch messages
article_count = Ticket::Article.count
@channel.fetch(true)
assert_equal(article_count, Ticket::Article.count)
# verify if message is still on server
message_ids = imap.sort(['DATE'], ['ALL'], 'US-ASCII')
assert_equal(1, message_ids.count)
# put unseen message in it
imap.append(@folder, "Subject: hello2
From: shugo@example.com
To: shugo@example.com
Message-ID: <some2@example_keep_on_server>
hello world
".gsub(/\n/, "\r\n"), [], Time.zone.now)
message_meta = imap.fetch(1, ['FLAGS'])[0].attr
assert(message_meta['FLAGS'].include?(:Seen))
message_meta = imap.fetch(2, ['FLAGS'])[0].attr
assert_not(message_meta['FLAGS'].include?(:Seen))
# fetch messages
article_count = Ticket::Article.count
@channel.fetch(true)
assert_equal(article_count + 1, Ticket::Article.count)
# verify if message is still on server
message_ids = imap.sort(['DATE'], ['ALL'], 'US-ASCII')
assert_equal(2, message_ids.count)
message_meta = imap.fetch(1, ['FLAGS'])[0].attr
assert(message_meta['FLAGS'].include?(:Seen))
message_meta = imap.fetch(2, ['FLAGS'])[0].attr
assert(message_meta['FLAGS'].include?(:Seen))
# set messages to not seen
imap.store(1, '-FLAGS', [:Seen])
imap.store(2, '-FLAGS', [:Seen])
# fetch messages
article_count = Ticket::Article.count
@channel.fetch(true)
assert_equal(article_count, Ticket::Article.count)
imap.delete(@folder)
@channel.destroy!
end
test 'keep not on server' do
@channel.options[:inbound][:options][:keep_on_server] = false
@channel.save!
# clean mailbox
imap = Net::IMAP.new(ENV['KEEP_ON_MAIL_SERVER'], 993, true, nil, false)
imap.login(@server_login, @server_password)
imap.create(@folder)
imap.select(@folder)
# put unseen message in it
imap.append(@folder, "Subject: hello1
From: shugo@example.com
To: shugo@example.com
Message-ID: <some1@example_remove_from_server>
hello world
".gsub(/\n/, "\r\n"), [], Time.zone.now)
# verify if message is still on server
message_ids = imap.sort(['DATE'], ['ALL'], 'US-ASCII')
assert_equal(1, message_ids.count)
message_meta = imap.fetch(1, ['FLAGS'])[0].attr
assert_not(message_meta['FLAGS'].include?(:Seen))
# fetch messages
article_count = Ticket::Article.count
@channel.fetch(true)
assert_equal(article_count + 1, Ticket::Article.count)
# verify if message is still on server
message_ids = imap.sort(['DATE'], ['ALL'], 'US-ASCII')
assert_equal(1, message_ids.count)
# put unseen message in it
imap.append(@folder, "Subject: hello2
From: shugo@example.com
To: shugo@example.com
Message-ID: <some2@example_remove_from_server>
hello world
".gsub(/\n/, "\r\n"), [], Time.zone.now)
# verify if message is still on server
message_ids = imap.sort(['DATE'], ['ALL'], 'US-ASCII')
assert_equal(1, message_ids.count)
message_meta = imap.fetch(1, ['FLAGS'])[0].attr
assert_not(message_meta['FLAGS'].include?(:Seen))
# fetch messages
article_count = Ticket::Article.count
@channel.fetch(true)
assert_equal(article_count + 1, Ticket::Article.count)
# verify if message is still on server
message_ids = imap.sort(['DATE'], ['ALL'], 'US-ASCII')
assert_equal(1, message_ids.count)
# put unseen message in it
imap.append(@folder, "Subject: hello2
From: shugo@example.com
To: shugo@example.com
Message-ID: <some2@example_remove_from_server>
hello world
".gsub(/\n/, "\r\n"), [], Time.zone.now)
# verify if message is still on server
message_ids = imap.sort(['DATE'], ['ALL'], 'US-ASCII')
assert_equal(1, message_ids.count)
# fetch messages
article_count = Ticket::Article.count
@channel.fetch(true)
assert_equal(article_count + 1, Ticket::Article.count)
imap.delete(@folder)
@channel.destroy!
end
end