Refactoring: Migrate email-process unit sub-tests to RSpec.
This commit is contained in:
parent
92d7ee95e0
commit
b19ac485bf
8 changed files with 311 additions and 613 deletions
|
@ -1,10 +1,15 @@
|
|||
FactoryBot.define do
|
||||
factory :ticket do
|
||||
transient do
|
||||
state_name 'new'
|
||||
priority_name '2 normal'
|
||||
end
|
||||
|
||||
title { 'Test Ticket' }
|
||||
group
|
||||
customer
|
||||
state { Ticket::State.lookup(name: 'new') }
|
||||
priority { Ticket::Priority.lookup(name: '2 normal') }
|
||||
state { Ticket::State.lookup(name: state_name) }
|
||||
priority { Ticket::Priority.lookup(name: priority_name) }
|
||||
updated_by_id { 1 }
|
||||
created_by_id { 1 }
|
||||
|
||||
|
|
18
spec/lib/mail/encodings_spec.rb
Normal file
18
spec/lib/mail/encodings_spec.rb
Normal file
|
@ -0,0 +1,18 @@
|
|||
require 'rails_helper'
|
||||
|
||||
RSpec.describe Mail::Encodings do
|
||||
# Regression test for https://github.com/zammad/zammad/issues/2456
|
||||
# (Mail lib was originally broken, so we patched it.
|
||||
# Then, upstream was fixed, whereas our patch broke.)
|
||||
describe '.value_decode' do
|
||||
it 'decodes us-ascii encoded strings' do
|
||||
expect(Mail::Encodings.value_decode('=?us-ascii?Q?Test?='))
|
||||
.to eql('Test')
|
||||
end
|
||||
|
||||
it 'decodes utf-8 encoded strings' do
|
||||
expect(Mail::Encodings.value_decode('=?UTF-8?Q? Personal=C3=A4nderung?='))
|
||||
.to eql(' Personaländerung')
|
||||
end
|
||||
end
|
||||
end
|
|
@ -1,50 +1,68 @@
|
|||
require 'rails_helper'
|
||||
|
||||
RSpec.describe Channel::EmailParser, type: :model do
|
||||
let(:subject) { described_class.new }
|
||||
let(:mail_file) { Rails.root.join('test', 'data', 'mail', 'mail001.box') }
|
||||
let(:raw_mail) { File.read(mail_file) }
|
||||
describe '#parse' do
|
||||
# regression test for issue 2390 - Add a postmaster filter to not show emails with potential issue
|
||||
describe 'handling HTML links in message content' do
|
||||
context 'with under 5,000 links' do
|
||||
it 'parses message content as normal' do
|
||||
expect(described_class.new.parse(<<~RAW)[:body]).to start_with('<a href="https://zammad.com/"')
|
||||
From: nicole.braun@zammad.com
|
||||
Content-Type: text/html
|
||||
|
||||
<html><body>
|
||||
#{Array.new(10) { '<a href="https://zammad.com/">Dummy Link</a>' }.join(' ')}
|
||||
</body></html>
|
||||
RAW
|
||||
end
|
||||
end
|
||||
|
||||
context 'with 5,000+ links' do
|
||||
it 'replaces message content with error message' do
|
||||
expect(described_class.new.parse(<<~RAW)).to include('body' => Channel::EmailParser::EXCESSIVE_LINKS_MSG)
|
||||
From: nicole.braun@zammad.com
|
||||
Content-Type: text/html
|
||||
|
||||
<html><body>
|
||||
#{Array.new(5001) { '<a href="https://zammad.com/">Dummy Link</a>' }.join(' ')}
|
||||
</body></html>
|
||||
RAW
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe '#process' do
|
||||
let(:raw_mail) { File.read(mail_file).sub(/(?<=^Subject: ).*$/, test_string) }
|
||||
let(:test_string) { Setting.get('ticket_hook') + Setting.get('ticket_hook_divider') + ticket.number }
|
||||
let(:raw_mail) { File.read(mail_file) }
|
||||
|
||||
describe 'auto-creating new users' do
|
||||
context 'with one unrecognized email address' do
|
||||
it 'creates one new user' do
|
||||
expect { Channel::EmailParser.new.process({}, <<~RAW) }.to change { User.count }.by(1)
|
||||
From: #{Faker::Internet.unique.email}
|
||||
RAW
|
||||
end
|
||||
end
|
||||
|
||||
context 'with a large number of unrecognized recipient addresses' do
|
||||
it 'never creates more than 40 users' do
|
||||
expect { Channel::EmailParser.new.process({}, <<~RAW) }.to change { User.count }.by(40)
|
||||
From: nicole.braun@zammad.org
|
||||
To: #{Array.new(20) { Faker::Internet.unique.email }.join(', ')}
|
||||
Cc: #{Array.new(21) { Faker::Internet.unique.email }.join(', ')}
|
||||
RAW
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe 'associating emails to tickets' do
|
||||
let(:mail_file) { Rails.root.join('test', 'data', 'mail', 'mail001.box') }
|
||||
let(:ticket_ref) { Setting.get('ticket_hook') + Setting.get('ticket_hook_divider') + ticket.number }
|
||||
let(:ticket) { create(:ticket) }
|
||||
|
||||
context 'for creating new users' do
|
||||
context 'with one unrecognized email address' do
|
||||
let(:raw_mail) { <<~RAW }
|
||||
From: #{Faker::Internet.unique.email}
|
||||
To: #{User.pluck(:email).reject(&:blank?).sample}
|
||||
Subject: Foo bar
|
||||
|
||||
Lorem ipsum dolor
|
||||
RAW
|
||||
|
||||
it 'creates one new user' do
|
||||
expect { Channel::EmailParser.new.process({}, raw_mail) }
|
||||
.to change { User.count }.by(1)
|
||||
end
|
||||
end
|
||||
|
||||
context 'with a large number (42+) of unrecognized email addresses' do
|
||||
let(:raw_mail) { <<~RAW }
|
||||
From: #{Faker::Internet.unique.email}
|
||||
To: #{Array.new(22) { Faker::Internet.unique.email }.join(', ')}
|
||||
Cc: #{Array.new(22) { Faker::Internet.unique.email }.join(', ')}
|
||||
Subject: test max sender identify
|
||||
|
||||
Some Text
|
||||
RAW
|
||||
|
||||
it 'never creates more than 41 users per email' do
|
||||
expect { Channel::EmailParser.new.process({}, raw_mail) }
|
||||
.to change { User.count }.by(41)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
context 'for associating emails to tickets' do
|
||||
context 'when email subject contains ticket reference' do
|
||||
let(:raw_mail) { File.read(mail_file).sub(/(?<=^Subject: ).*$/, ticket_ref) }
|
||||
|
||||
it 'adds message to ticket' do
|
||||
expect { described_class.new.process({}, raw_mail) }
|
||||
.to change { ticket.articles.length }
|
||||
|
@ -56,7 +74,7 @@ RSpec.describe Channel::EmailParser, type: :model do
|
|||
|
||||
context 'when body contains ticket reference' do
|
||||
context 'in visible text' do
|
||||
let(:raw_mail) { File.read(mail_file).sub(/Hallo =\nMartin,(?=<o:p>)/, test_string) }
|
||||
let(:raw_mail) { File.read(mail_file).sub(/Hallo =\nMartin,(?=<o:p>)/, ticket_ref) }
|
||||
|
||||
it 'adds message to ticket' do
|
||||
expect { described_class.new.process({}, raw_mail) }
|
||||
|
@ -65,7 +83,7 @@ RSpec.describe Channel::EmailParser, type: :model do
|
|||
end
|
||||
|
||||
context 'as part of a larger word' do
|
||||
let(:raw_mail) { File.read(mail_file).sub(/(?<=Hallo) =\n(?=Martin,<o:p>)/, test_string) }
|
||||
let(:raw_mail) { File.read(mail_file).sub(/(?<=Hallo) =\n(?=Martin,<o:p>)/, ticket_ref) }
|
||||
|
||||
it 'creates a separate ticket' do
|
||||
expect { described_class.new.process({}, raw_mail) }
|
||||
|
@ -74,7 +92,7 @@ RSpec.describe Channel::EmailParser, type: :model do
|
|||
end
|
||||
|
||||
context 'in html attributes' do
|
||||
let(:raw_mail) { File.read(mail_file).sub(%r{<a href.*?/a>}m, %(<table bgcolor="#{test_string}"> </table>)) }
|
||||
let(:raw_mail) { File.read(mail_file).sub(%r{<a href.*?/a>}m, %(<table bgcolor="#{ticket_ref}"> </table>)) }
|
||||
|
||||
it 'creates a separate ticket' do
|
||||
expect { described_class.new.process({}, raw_mail) }
|
||||
|
@ -85,7 +103,7 @@ RSpec.describe Channel::EmailParser, type: :model do
|
|||
end
|
||||
end
|
||||
|
||||
context 'for sender/recipient address formatting' do
|
||||
describe 'sender/recipient address formatting' do
|
||||
# see https://github.com/zammad/zammad/issues/2198
|
||||
context 'when sender address contains spaces (#2198)' do
|
||||
let(:mail_file) { Rails.root.join('test', 'data', 'mail', 'mail071.box') }
|
||||
|
@ -93,7 +111,7 @@ RSpec.describe Channel::EmailParser, type: :model do
|
|||
|
||||
it 'removes them before creating a new user' do
|
||||
expect { described_class.new.process({}, raw_mail) }
|
||||
.to change { User.where(email: sender_email).count }.to(1)
|
||||
.to change { User.exists?(email: sender_email) }
|
||||
end
|
||||
|
||||
it 'marks new user email as invalid' do
|
||||
|
@ -113,7 +131,7 @@ RSpec.describe Channel::EmailParser, type: :model do
|
|||
|
||||
it 'removes them before creating a new user' do
|
||||
expect { described_class.new.process({}, raw_mail) }
|
||||
.to change { User.where(email: sender_email).count }.to(1)
|
||||
.to change { User.exists?(email: sender_email) }
|
||||
end
|
||||
|
||||
it 'marks new user email as invalid' do
|
||||
|
@ -127,7 +145,7 @@ RSpec.describe Channel::EmailParser, type: :model do
|
|||
end
|
||||
end
|
||||
|
||||
context 'for charset handling' do
|
||||
describe 'charset handling' do
|
||||
# see https://github.com/zammad/zammad/issues/2224
|
||||
context 'when header specifies Windows-1258 charset (#2224)' do
|
||||
let(:mail_file) { Rails.root.join('test', 'data', 'mail', 'mail072.box') }
|
||||
|
@ -139,46 +157,10 @@ RSpec.describe Channel::EmailParser, type: :model do
|
|||
end
|
||||
end
|
||||
|
||||
context 'mail with links' do
|
||||
|
||||
def mock_mail(number_of_links)
|
||||
link = '<a href="https://zammad.com/">Dummy Link</a> '
|
||||
|
||||
mail = Mail.new
|
||||
mail.html_part = "<html><body>#{link * number_of_links}</body></html>"
|
||||
mail
|
||||
end
|
||||
|
||||
let(:mail_10) { mock_mail(10).to_s }
|
||||
let(:mail_5k) { mock_mail(5001).to_s }
|
||||
|
||||
# regression test for issue 2390 - Add a postmaster filter to not show emails with potential issue
|
||||
it '(>5k links) are replaced by a warning message' do
|
||||
expect( described_class.new.parse(mail_5k)[:body] )
|
||||
.to eql( Channel::EmailParser::EXCESSIVE_LINKS_MSG )
|
||||
end
|
||||
|
||||
it '(10 links) are not touched' do
|
||||
expect( described_class.new.parse(mail_10)[:body] )
|
||||
.to start_with( '<a href="https://zammad.com/"' )
|
||||
end
|
||||
end
|
||||
|
||||
context 'Mail::Encodings.value_decode' do
|
||||
it 'decode us-ascii encoded strings' do
|
||||
expect( Mail::Encodings.value_decode('=?us-ascii?Q?Test?=') ).to eql( 'Test' )
|
||||
end
|
||||
|
||||
it 'decode utf-8 encoded strings' do
|
||||
expect( Mail::Encodings.value_decode('=?UTF-8?Q? Personal=C3=A4nderung?=') ).to eql( ' Personaländerung' )
|
||||
end
|
||||
end
|
||||
|
||||
context 'when handling Content-Transfer-Encoding of attachments' do
|
||||
|
||||
context 'with x-uuencode' do
|
||||
|
||||
describe 'attachment handling' do
|
||||
context 'with header "Content-Transfer-Encoding: x-uuencode"' do
|
||||
let(:mail_file) { Rails.root.join('test', 'data', 'mail', 'mail078-content_transfer_encoding_x_uuencode.box') }
|
||||
let(:article) { described_class.new.process({}, raw_mail).second }
|
||||
|
||||
it 'does not raise RuntimeError' do
|
||||
expect { described_class.new.process({}, raw_mail) }
|
||||
|
@ -186,26 +168,115 @@ RSpec.describe Channel::EmailParser, type: :model do
|
|||
end
|
||||
|
||||
it 'parses the content correctly' do
|
||||
_ticket, article, _user, _mail = described_class.new.process({}, raw_mail)
|
||||
expect(article.attachments.first.filename).to eq('PGP_Cmts_on_12-14-01_Pkg.txt')
|
||||
expect(article.attachments.first.content).to eq('Hello Zammad')
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
context 'when mail contains image(s)' do
|
||||
describe 'inline image handling' do
|
||||
# see https://github.com/zammad/zammad/issues/2486
|
||||
context 'when image is large but not resizable' do
|
||||
let(:mail_file) { Rails.root.join('test', 'data', 'mail', 'mail079.box') }
|
||||
let(:attachment) { article.attachments.last }
|
||||
let(:article) { described_class.new.process({}, raw_mail).second }
|
||||
|
||||
it "doesn't set resizable preference" do
|
||||
_ticket, article = described_class.new.process({}, raw_mail)
|
||||
attachment = article.attachments.last
|
||||
|
||||
expect(attachment.filename).to eq('a.jpg')
|
||||
expect(attachment.preferences).not_to include('resizable' => true)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
context 'for “delivery failed” notifications (a.k.a. bounce messages)' do
|
||||
let(:ticket) { article.ticket }
|
||||
let(:article) { create(:ticket_article, sender_name: 'Agent', message_id: message_id) }
|
||||
let(:message_id) { raw_mail[/(?<=^(References|Message-ID): )\S*/] }
|
||||
|
||||
context 'with future retries (delayed)' do
|
||||
let(:mail_file) { Rails.root.join('test', 'data', 'mail', 'mail078.box') }
|
||||
|
||||
context 'on a closed ticket' do
|
||||
before { ticket.update(state: Ticket::State.find_by(name: 'closed')) }
|
||||
|
||||
it 'sets #preferences on resulting ticket to { "send-auto-responses" => false, "is-auto-reponse" => true }' do
|
||||
article = Channel::EmailParser.new.process({}, raw_mail).second
|
||||
expect(article.preferences)
|
||||
.to include('send-auto-response' => false, 'is-auto-response' => true)
|
||||
end
|
||||
|
||||
it 'returns a Mail object with an x-zammad-out-of-office header' do
|
||||
output_mail = Channel::EmailParser.new.process({}, raw_mail).last
|
||||
expect(output_mail).to include('x-zammad-out-of-office': true)
|
||||
end
|
||||
|
||||
it 'finds the article referenced in the bounce message headers, then adds the bounce message to its ticket' do
|
||||
expect { Channel::EmailParser.new.process({}, raw_mail) }
|
||||
.to change { ticket.articles.count }.by(1)
|
||||
end
|
||||
|
||||
it 'does not re-open the ticket' do
|
||||
expect { Channel::EmailParser.new.process({}, raw_mail) }
|
||||
.not_to change { ticket.reload.state.name }.from('closed')
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
context 'with no future retries (undeliverable): sample input 1' do
|
||||
let(:mail_file) { Rails.root.join('test', 'data', 'mail', 'mail033-undelivered-mail-returned-to-sender.box') }
|
||||
|
||||
context 'for original message sent by Agent' do
|
||||
it 'sets #preferences on resulting ticket to { "send-auto-responses" => false, "is-auto-reponse" => true }' do
|
||||
article = Channel::EmailParser.new.process({}, raw_mail).second
|
||||
expect(article.preferences)
|
||||
.to include('send-auto-response' => false, 'is-auto-response' => true)
|
||||
end
|
||||
|
||||
it 'finds the article referenced in the bounce message headers, then adds the bounce message to its ticket' do
|
||||
expect { Channel::EmailParser.new.process({}, raw_mail) }
|
||||
.to change { ticket.articles.count }.by(1)
|
||||
end
|
||||
|
||||
it 'does not alter the ticket state' do
|
||||
expect { Channel::EmailParser.new.process({}, raw_mail) }
|
||||
.not_to change { ticket.reload.state.name }.from('open')
|
||||
end
|
||||
end
|
||||
|
||||
context 'for original message sent by Customer' do
|
||||
let(:article) { create(:ticket_article, sender_name: 'Customer', message_id: message_id) }
|
||||
|
||||
it 'sets #preferences on resulting ticket to { "send-auto-responses" => false, "is-auto-reponse" => true }' do
|
||||
article = Channel::EmailParser.new.process({}, raw_mail).second
|
||||
expect(article.preferences)
|
||||
.to include('send-auto-response' => false, 'is-auto-response' => true)
|
||||
end
|
||||
|
||||
it 'finds the article referenced in the bounce message headers, then adds the bounce message to its ticket' do
|
||||
expect { Channel::EmailParser.new.process({}, raw_mail) }
|
||||
.to change { ticket.articles.count }.by(1)
|
||||
end
|
||||
|
||||
it 'does not alter the ticket state' do
|
||||
expect { Channel::EmailParser.new.process({}, raw_mail) }
|
||||
.not_to change { ticket.reload.state.name }.from('new')
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
context 'with no future retries (undeliverable): sample input 2' do
|
||||
let(:mail_file) { Rails.root.join('test', 'data', 'mail', 'mail055.box') }
|
||||
|
||||
it 'finds the article referenced in the bounce message headers, then adds the bounce message to its ticket' do
|
||||
expect { Channel::EmailParser.new.process({}, raw_mail) }
|
||||
.to change { ticket.articles.count }.by(1)
|
||||
end
|
||||
|
||||
it 'does not alter the ticket state' do
|
||||
expect { Channel::EmailParser.new.process({}, raw_mail) }
|
||||
.not_to change { ticket.reload.state.name }.from('open')
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -256,6 +256,18 @@ RSpec.describe Ticket, type: :model do
|
|||
end
|
||||
|
||||
describe 'Attributes:' do
|
||||
describe '#state' do
|
||||
context 'for brand new tickets' do
|
||||
context 'when a non-customer article is added' do
|
||||
let(:article) { create(:ticket_article, ticket: ticket, sender_name: 'Agent') }
|
||||
|
||||
it 'switches to "open"' do
|
||||
expect { article }.to change { ticket.state.name }.from('new').to('open')
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe '#pending_time' do
|
||||
subject(:ticket) { create(:ticket, pending_time: Time.zone.now + 2.days) }
|
||||
|
||||
|
|
|
@ -4,10 +4,10 @@ require 'models/application_model_examples'
|
|||
RSpec.describe Trigger, type: :model do
|
||||
it_behaves_like 'ApplicationModel', can_assets: { selectors: %i[condition perform] }
|
||||
|
||||
subject(:trigger) { create(:trigger) }
|
||||
before { Trigger.destroy_all } # Default DB state includes three sample triggers
|
||||
subject!(:trigger) { create(:trigger, condition: condition, perform: perform) }
|
||||
|
||||
describe '#assets (for supplying model data to front-end framework)' do
|
||||
subject(:trigger) { create(:trigger, condition: condition, perform: perform) }
|
||||
let(:condition) { { 'ticket.state_id' => { operator: 'is', value: 1 } } }
|
||||
let(:perform) { { 'ticket.priority_id' => { value: 1 } } }
|
||||
|
||||
|
@ -17,4 +17,113 @@ RSpec.describe Trigger, type: :model do
|
|||
.and include(Ticket::Priority.first.assets({}))
|
||||
end
|
||||
end
|
||||
|
||||
describe 'Send-email triggers' do
|
||||
let(:perform) do
|
||||
{
|
||||
'notification.email' => {
|
||||
'recipient' => 'ticket_customer',
|
||||
'subject' => 'foo',
|
||||
'body' => 'bar'
|
||||
}
|
||||
}
|
||||
end
|
||||
|
||||
context 'for condition "ticket created"' do
|
||||
let(:condition) do
|
||||
{ 'ticket.action' => { 'operator' => 'is', 'value' => 'create' } }
|
||||
end
|
||||
|
||||
context 'when ticket is created directly' do
|
||||
let!(:ticket) { create(:ticket) }
|
||||
|
||||
it 'fires (without altering ticket state)' do
|
||||
expect { Observer::Transaction.commit }
|
||||
.to change { Ticket::Article.count }.by(1)
|
||||
.and not_change { ticket.reload.state.name }.from('new')
|
||||
end
|
||||
end
|
||||
|
||||
context 'when ticket is created via Channel::EmailParser.process' do
|
||||
before { create(:email_address, groups: [Group.first]) }
|
||||
let(:raw_email) { File.read(Rails.root.join('test', 'data', 'mail', 'mail001.box')) }
|
||||
|
||||
it 'fires (without altering ticket state)' do
|
||||
expect { Channel::EmailParser.new.process({}, raw_email) }
|
||||
.to change { Ticket.count }.by(1)
|
||||
.and change { Ticket::Article.count }.by(2)
|
||||
|
||||
expect(Ticket.last.state.name).to eq('new')
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
context 'for condition "ticket updated"' do
|
||||
let(:condition) do
|
||||
{ 'ticket.action' => { 'operator' => 'is', 'value' => 'update' } }
|
||||
end
|
||||
|
||||
let!(:ticket) { create(:ticket).tap { Observer::Transaction.commit } }
|
||||
|
||||
context 'when new article is created directly' do
|
||||
context 'with empty #preferences hash' do
|
||||
let!(:article) { create(:ticket_article, ticket: ticket) }
|
||||
|
||||
it 'fires (without altering ticket state)' do
|
||||
expect { Observer::Transaction.commit }
|
||||
.to change { ticket.reload.articles.count }.by(1)
|
||||
.and not_change { ticket.reload.state.name }.from('new')
|
||||
end
|
||||
end
|
||||
|
||||
context 'with #preferences { "send-auto-response" => false }' do
|
||||
let!(:article) do
|
||||
create(:ticket_article,
|
||||
ticket: ticket,
|
||||
preferences: { 'send-auto-response' => false })
|
||||
end
|
||||
|
||||
it 'does not fire' do
|
||||
expect { Observer::Transaction.commit }
|
||||
.not_to change { ticket.reload.articles.count }
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
context 'when new article is created via Channel::EmailParser.process' do
|
||||
context 'with a regular message' do
|
||||
let!(:article) do
|
||||
create(:ticket_article,
|
||||
ticket: ticket,
|
||||
message_id: raw_email[/(?<=^References: )\S*/],
|
||||
subject: raw_email[/(?<=^Subject: Re: ).*$/])
|
||||
end
|
||||
|
||||
let(:raw_email) { File.read(Rails.root.join('test', 'data', 'mail', 'mail005.box')) }
|
||||
|
||||
it 'fires (without altering ticket state)' do
|
||||
expect { Channel::EmailParser.new.process({}, raw_email) }
|
||||
.to not_change { Ticket.count }
|
||||
.and change { ticket.reload.articles.count }.by(2)
|
||||
.and not_change { ticket.reload.state.name }.from('new')
|
||||
end
|
||||
end
|
||||
|
||||
context 'with delivery-failed "bounce message"' do
|
||||
let!(:article) do
|
||||
create(:ticket_article,
|
||||
ticket: ticket,
|
||||
message_id: raw_email[/(?<=^Message-ID: )\S*/])
|
||||
end
|
||||
|
||||
let(:raw_email) { File.read(Rails.root.join('test', 'data', 'mail', 'mail055.box')) }
|
||||
|
||||
it 'does not fire' do
|
||||
expect { Channel::EmailParser.new.process({}, raw_email) }
|
||||
.to change { ticket.reload.articles.count }.by(1)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -1,52 +1,21 @@
|
|||
require 'test_helper'
|
||||
|
||||
class EmailProcessBounceDeliveryTemporaryFailed < ActiveSupport::TestCase
|
||||
|
||||
test 'process with temp faild bounce email' do
|
||||
|
||||
ticket = Ticket.create!(
|
||||
title: 'temp failed check - ms',
|
||||
group: Group.lookup(name: 'Users'),
|
||||
customer_id: 2,
|
||||
state: Ticket::State.lookup(name: 'closed'),
|
||||
priority: Ticket::Priority.lookup(name: '2 normal'),
|
||||
updated_by_id: 1,
|
||||
created_by_id: 1,
|
||||
)
|
||||
article = Ticket::Article.create!(
|
||||
ticket_id: ticket.id,
|
||||
from: 'some_sender@example.com',
|
||||
to: 'some_recipient@example.com',
|
||||
subject: 'temp failed check',
|
||||
message_id: '<20150830145601.30.608881@edenhofer.zammad.com>',
|
||||
body: 'some message bounce check',
|
||||
internal: false,
|
||||
sender: Ticket::Article::Sender.lookup(name: 'Agent'),
|
||||
type: Ticket::Article::Type.lookup(name: 'email'),
|
||||
updated_by_id: 1,
|
||||
created_by_id: 1,
|
||||
)
|
||||
travel 1.second
|
||||
|
||||
# temp faild bounce email
|
||||
email_raw_string = "Content-Type: multipart/report; boundary=\"000000000000ca4a1a057417a375\"; report-type=delivery-status
|
||||
Content-Type: multipart/report; boundary="000000000000ca4a1a057417a375"; report-type=delivery-status
|
||||
From: Mail Delivery Subsystem <mailer-daemon@example.com>
|
||||
To: service@example.de
|
||||
Auto-Submitted: auto-replied
|
||||
Subject: Delivery Status Notification (Delay)
|
||||
References: #{article.message_id}
|
||||
In-Reply-To: #{article.message_id}
|
||||
References: <20150830145601.30.608881@example.com>
|
||||
In-Reply-To: <20150830145601.30.608881@example.com>
|
||||
Message-ID: <5b7e8af4.1c69fb81.3ac1b.e296.GMRIR@mx.example.com>
|
||||
Date: Thu, 23 Aug 2018 03:22:44 -0700 (PDT)
|
||||
|
||||
--000000000000ca4a1a057417a375
|
||||
Content-Type: multipart/related; boundary=\"000000000000ca53d4057417a37c\"
|
||||
Content-Type: multipart/related; boundary="000000000000ca53d4057417a37c"
|
||||
|
||||
--000000000000ca53d4057417a37c
|
||||
Content-Type: multipart/alternative; boundary=\"000000000000ca53de057417a37d\"
|
||||
Content-Type: multipart/alternative; boundary="000000000000ca53de057417a37d"
|
||||
|
||||
--000000000000ca53de057417a37d
|
||||
Content-Type: text/plain; charset=\"UTF-8\"
|
||||
Content-Type: text/plain; charset="UTF-8"
|
||||
Content-Transfer-Encoding: quoted-printable
|
||||
|
||||
|
||||
|
@ -72,7 +41,7 @@ Content-Type: message/delivery-status
|
|||
Reporting-MTA: dns; example.com
|
||||
Received-From-MTA: dns; service@example.de
|
||||
Arrival-Date: Wed, 22 Aug 2018 02:00:03 -0700 (PDT)
|
||||
X-Original-Message-ID: #{article.message_id}
|
||||
X-Original-Message-ID: <20150830145601.30.608881@example.com>
|
||||
|
||||
Final-Recipient: rfc822; bob.smith@example.de
|
||||
Action: delayed
|
||||
|
@ -89,21 +58,10 @@ Content-Type: message/rfc822
|
|||
Date: Wed, 22 Aug 2018 11:00:03 +0200
|
||||
From: example Helpdesk <service@example.de>
|
||||
To: bob.smith@example.de
|
||||
Message-ID: #{article.message_id}
|
||||
Message-ID: <20150830145601.30.608881@example.com>
|
||||
Subject: Ihre Anfrage () [Ticket#638810]
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
|
||||
ABC
|
||||
|
||||
--000000000000ca4a1a057417a375--
|
||||
"
|
||||
|
||||
ticket_p, article_p, user_p, mail = Channel::EmailParser.new.process({}, email_raw_string)
|
||||
assert_equal(true, mail['x-zammad-out-of-office'.to_sym])
|
||||
ticket = Ticket.find(ticket.id)
|
||||
assert_equal(ticket.id, ticket_p.id)
|
||||
assert_equal('closed', ticket.state.name)
|
||||
|
||||
end
|
||||
|
||||
end
|
|
@ -1,219 +0,0 @@
|
|||
require 'test_helper'
|
||||
|
||||
class EmailProcessBounceDeliveryPermanentFailedTest < ActiveSupport::TestCase
|
||||
|
||||
test 'process with bounce trigger email loop check - article based blocker' do
|
||||
roles = Role.where(name: %w[Customer])
|
||||
customer1 = User.create_or_update(
|
||||
login: 'ticket-bounce-trigger1@example.com',
|
||||
firstname: 'Notification',
|
||||
lastname: 'Customer1',
|
||||
email: 'ticket-bounce-trigger1@example.com',
|
||||
active: true,
|
||||
roles: roles,
|
||||
preferences: {},
|
||||
updated_by_id: 1,
|
||||
created_by_id: 1,
|
||||
)
|
||||
|
||||
Trigger.create_or_update(
|
||||
name: 'auto reply new ticket',
|
||||
condition: {
|
||||
'ticket.action' => {
|
||||
'operator' => 'is',
|
||||
'value' => 'create',
|
||||
},
|
||||
},
|
||||
perform: {
|
||||
'notification.email' => {
|
||||
'body' => 'some text<br>#{ticket.customer.lastname}<br>#{ticket.title}<br>#{article.body}',
|
||||
'recipient' => 'ticket_customer',
|
||||
'subject' => 'Thanks for your inquiry (#{ticket.title})!',
|
||||
},
|
||||
},
|
||||
disable_notification: true,
|
||||
active: true,
|
||||
created_by_id: 1,
|
||||
updated_by_id: 1,
|
||||
)
|
||||
Trigger.create_or_update(
|
||||
name: 'auto reply followup',
|
||||
condition: {
|
||||
'ticket.action' => {
|
||||
'operator' => 'is',
|
||||
'value' => 'update',
|
||||
},
|
||||
},
|
||||
perform: {
|
||||
'notification.email' => {
|
||||
'body' => 'some text<br>#{ticket.customer.lastname}<br>#{ticket.title}<br>#{article.body}',
|
||||
'recipient' => 'ticket_customer',
|
||||
'subject' => 'Thanks for your follow up (#{ticket.title})!',
|
||||
},
|
||||
},
|
||||
disable_notification: true,
|
||||
active: true,
|
||||
created_by_id: 1,
|
||||
updated_by_id: 1,
|
||||
)
|
||||
|
||||
ticket = Ticket.create!(
|
||||
title: 'bounce check',
|
||||
group: Group.lookup(name: 'Users'),
|
||||
customer: customer1,
|
||||
state: Ticket::State.lookup(name: 'new'),
|
||||
priority: Ticket::Priority.lookup(name: '2 normal'),
|
||||
updated_by_id: 1,
|
||||
created_by_id: 1,
|
||||
)
|
||||
article = Ticket::Article.create!(
|
||||
ticket_id: ticket.id,
|
||||
from: 'some_sender@example.com',
|
||||
to: 'some_recipient@example.com',
|
||||
subject: 'bounce check',
|
||||
message_id: '<20150830145601.30.6088xx@edenhofer.zammad.com>',
|
||||
body: 'some message bounce check',
|
||||
internal: false,
|
||||
sender: Ticket::Article::Sender.where(name: 'Agent').first,
|
||||
type: Ticket::Article::Type.where(name: 'email').first,
|
||||
updated_by_id: 1,
|
||||
created_by_id: 1,
|
||||
)
|
||||
Observer::Transaction.commit
|
||||
assert_equal('new', ticket.state.name)
|
||||
assert_equal(2, ticket.articles.count)
|
||||
|
||||
article = Ticket::Article.create!(
|
||||
ticket_id: ticket.id,
|
||||
from: 'some_sender@example.com',
|
||||
to: customer1.email,
|
||||
subject: 'bounce check 2',
|
||||
message_id: '<20150830145601.30.608881@edenhofer.zammad.com>',
|
||||
body: 'some message bounce check 2',
|
||||
internal: false,
|
||||
sender: Ticket::Article::Sender.where(name: 'Agent').first,
|
||||
type: Ticket::Article::Type.where(name: 'email').first,
|
||||
updated_by_id: 1,
|
||||
created_by_id: 1,
|
||||
)
|
||||
Observer::Transaction.commit
|
||||
assert_equal(4, ticket.articles.count)
|
||||
|
||||
travel 1.second
|
||||
email_raw_string = File.read(Rails.root.join('test', 'data', 'mail', 'mail033-undelivered-mail-returned-to-sender.box'))
|
||||
ticket_p, article_p, user_p = Channel::EmailParser.new.process({}, email_raw_string)
|
||||
assert_equal(ticket.id, ticket_p.id)
|
||||
assert_equal('open', ticket_p.state.name)
|
||||
assert_equal(5, ticket_p.articles.count)
|
||||
travel_back
|
||||
ticket.destroy
|
||||
end
|
||||
|
||||
test 'process with bounce trigger email loop check - bounce based blocker' do
|
||||
roles = Role.where(name: %w[Customer])
|
||||
customer2 = User.create_or_update(
|
||||
login: 'ticket-bounce-trigger2@example.com',
|
||||
firstname: 'Notification',
|
||||
lastname: 'Customer2',
|
||||
email: 'ticket-bounce-trigger2@example.com',
|
||||
active: true,
|
||||
roles: roles,
|
||||
preferences: {},
|
||||
updated_by_id: 1,
|
||||
created_by_id: 1,
|
||||
)
|
||||
|
||||
Trigger.create_or_update(
|
||||
name: 'auto reply new ticket',
|
||||
condition: {
|
||||
'ticket.action' => {
|
||||
'operator' => 'is',
|
||||
'value' => 'create',
|
||||
},
|
||||
},
|
||||
perform: {
|
||||
'notification.email' => {
|
||||
'body' => 'some text<br>#{ticket.customer.lastname}<br>#{ticket.title}<br>#{article.body}',
|
||||
'recipient' => 'ticket_customer',
|
||||
'subject' => 'Thanks for your inquiry (#{ticket.title})!',
|
||||
},
|
||||
},
|
||||
disable_notification: true,
|
||||
active: true,
|
||||
created_by_id: 1,
|
||||
updated_by_id: 1,
|
||||
)
|
||||
Trigger.create_or_update(
|
||||
name: 'auto reply followup',
|
||||
condition: {
|
||||
'ticket.action' => {
|
||||
'operator' => 'is',
|
||||
'value' => 'update',
|
||||
},
|
||||
},
|
||||
perform: {
|
||||
'notification.email' => {
|
||||
'body' => 'some text<br>#{ticket.customer.lastname}<br>#{ticket.title}<br>#{article.body}',
|
||||
'recipient' => 'ticket_customer',
|
||||
'subject' => 'Thanks for your follow up (#{ticket.title})!',
|
||||
},
|
||||
},
|
||||
disable_notification: true,
|
||||
active: true,
|
||||
created_by_id: 1,
|
||||
updated_by_id: 1,
|
||||
)
|
||||
|
||||
ticket = Ticket.create!(
|
||||
title: 'bounce check',
|
||||
group: Group.lookup(name: 'Users'),
|
||||
customer: customer2,
|
||||
state: Ticket::State.lookup(name: 'new'),
|
||||
priority: Ticket::Priority.lookup(name: '2 normal'),
|
||||
updated_by_id: 1,
|
||||
created_by_id: 1,
|
||||
)
|
||||
article = Ticket::Article.create!(
|
||||
ticket_id: ticket.id,
|
||||
from: 'some_sender@example.com',
|
||||
to: 'some_recipient@example.com',
|
||||
subject: 'bounce check',
|
||||
message_id: '<20150830145601.30.6088xx@edenhofer.zammad.com>',
|
||||
body: 'some message bounce check',
|
||||
internal: false,
|
||||
sender: Ticket::Article::Sender.where(name: 'Agent').first,
|
||||
type: Ticket::Article::Type.where(name: 'email').first,
|
||||
updated_by_id: 1,
|
||||
created_by_id: 1,
|
||||
)
|
||||
Observer::Transaction.commit
|
||||
assert_equal('new', ticket.state.name)
|
||||
assert_equal(2, ticket.articles.count)
|
||||
|
||||
article = Ticket::Article.create!(
|
||||
ticket_id: ticket.id,
|
||||
from: 'some_sender@example.com',
|
||||
to: 'some_recipient@example.com',
|
||||
subject: 'bounce check 2',
|
||||
message_id: '<20170526150141.232.13312@example.zammad.loc>',
|
||||
body: 'some message bounce check 2',
|
||||
internal: false,
|
||||
sender: Ticket::Article::Sender.where(name: 'Agent').first,
|
||||
type: Ticket::Article::Type.where(name: 'email').first,
|
||||
updated_by_id: 1,
|
||||
created_by_id: 1,
|
||||
)
|
||||
Observer::Transaction.commit
|
||||
assert_equal(4, ticket.articles.count)
|
||||
|
||||
travel 1.second
|
||||
email_raw_string = File.read(Rails.root.join('test', 'data', 'mail', 'mail055.box'))
|
||||
ticket_p, article_p, user_p = Channel::EmailParser.new.process({}, email_raw_string)
|
||||
assert_equal(ticket.id, ticket_p.id)
|
||||
assert_equal('open', ticket_p.state.name)
|
||||
assert_equal(5, ticket_p.articles.count)
|
||||
travel_back
|
||||
ticket.destroy
|
||||
end
|
||||
|
||||
end
|
|
@ -1,256 +0,0 @@
|
|||
require 'test_helper'
|
||||
|
||||
class EmailProcessBounceFollowUpTest < ActiveSupport::TestCase
|
||||
|
||||
test 'process with bounce follow up check' do
|
||||
|
||||
ticket = Ticket.create(
|
||||
title: 'bounce check',
|
||||
group: Group.lookup(name: 'Users'),
|
||||
customer_id: 2,
|
||||
state: Ticket::State.lookup(name: 'new'),
|
||||
priority: Ticket::Priority.lookup(name: '2 normal'),
|
||||
updated_by_id: 1,
|
||||
created_by_id: 1,
|
||||
)
|
||||
article = Ticket::Article.create(
|
||||
ticket_id: ticket.id,
|
||||
from: 'some_sender@example.com',
|
||||
to: 'some_recipient@example.com',
|
||||
subject: 'bounce check',
|
||||
message_id: '<20150830145601.30.608881@edenhofer.zammad.com>',
|
||||
body: 'some message bounce check',
|
||||
internal: false,
|
||||
sender: Ticket::Article::Sender.where(name: 'Customer').first,
|
||||
type: Ticket::Article::Type.where(name: 'email').first,
|
||||
updated_by_id: 1,
|
||||
created_by_id: 1,
|
||||
)
|
||||
travel 1.second
|
||||
email_file_path = Rails.root.join('test', 'data', 'mail', 'mail033-undelivered-mail-returned-to-sender.box')
|
||||
email_raw_string = File.read(email_file_path)
|
||||
ticket_p, article_p, user_p = Channel::EmailParser.new.process({}, email_raw_string)
|
||||
assert_equal(ticket.id, ticket_p.id)
|
||||
assert_equal('new', ticket_p.state.name)
|
||||
travel_back
|
||||
ticket.destroy
|
||||
|
||||
end
|
||||
|
||||
test 'process with bounce trigger email loop check - article based blocker' do
|
||||
roles = Role.where(name: %w[Customer])
|
||||
customer1 = User.create_or_update(
|
||||
login: 'ticket-bounce-trigger1@example.com',
|
||||
firstname: 'Notification',
|
||||
lastname: 'Customer1',
|
||||
email: 'ticket-bounce-trigger1@example.com',
|
||||
active: true,
|
||||
roles: roles,
|
||||
preferences: {},
|
||||
updated_by_id: 1,
|
||||
created_by_id: 1,
|
||||
)
|
||||
|
||||
Trigger.create_or_update(
|
||||
name: 'auto reply new ticket',
|
||||
condition: {
|
||||
'ticket.action' => {
|
||||
'operator' => 'is',
|
||||
'value' => 'create',
|
||||
},
|
||||
},
|
||||
perform: {
|
||||
'notification.email' => {
|
||||
'body' => 'some text<br>#{ticket.customer.lastname}<br>#{ticket.title}<br>#{article.body}',
|
||||
'recipient' => 'ticket_customer',
|
||||
'subject' => 'Thanks for your inquiry (#{ticket.title})!',
|
||||
},
|
||||
},
|
||||
disable_notification: true,
|
||||
active: true,
|
||||
created_by_id: 1,
|
||||
updated_by_id: 1,
|
||||
)
|
||||
Trigger.create_or_update(
|
||||
name: 'auto reply followup',
|
||||
condition: {
|
||||
'ticket.action' => {
|
||||
'operator' => 'is',
|
||||
'value' => 'update',
|
||||
},
|
||||
},
|
||||
perform: {
|
||||
'notification.email' => {
|
||||
'body' => 'some text<br>#{ticket.customer.lastname}<br>#{ticket.title}<br>#{article.body}',
|
||||
'recipient' => 'ticket_customer',
|
||||
'subject' => 'Thanks for your follow up (#{ticket.title})!',
|
||||
},
|
||||
},
|
||||
disable_notification: true,
|
||||
active: true,
|
||||
created_by_id: 1,
|
||||
updated_by_id: 1,
|
||||
)
|
||||
|
||||
ticket = Ticket.create(
|
||||
title: 'bounce check',
|
||||
group: Group.lookup(name: 'Users'),
|
||||
customer: customer1,
|
||||
state: Ticket::State.lookup(name: 'new'),
|
||||
priority: Ticket::Priority.lookup(name: '2 normal'),
|
||||
updated_by_id: 1,
|
||||
created_by_id: 1,
|
||||
)
|
||||
article = Ticket::Article.create(
|
||||
ticket_id: ticket.id,
|
||||
from: 'some_sender@example.com',
|
||||
to: 'some_recipient@example.com',
|
||||
subject: 'bounce check',
|
||||
message_id: '<20150830145601.30.6088xx@edenhofer.zammad.com>',
|
||||
body: 'some message bounce check',
|
||||
internal: false,
|
||||
sender: Ticket::Article::Sender.where(name: 'Agent').first,
|
||||
type: Ticket::Article::Type.where(name: 'email').first,
|
||||
updated_by_id: 1,
|
||||
created_by_id: 1,
|
||||
)
|
||||
Observer::Transaction.commit
|
||||
assert_equal('new', ticket.state.name)
|
||||
assert_equal(2, ticket.articles.count)
|
||||
|
||||
article = Ticket::Article.create(
|
||||
ticket_id: ticket.id,
|
||||
from: 'some_sender@example.com',
|
||||
to: customer1.email,
|
||||
subject: 'bounce check 2',
|
||||
message_id: '<20150830145601.30.608881@edenhofer.zammad.com>',
|
||||
body: 'some message bounce check 2',
|
||||
internal: false,
|
||||
sender: Ticket::Article::Sender.where(name: 'Agent').first,
|
||||
type: Ticket::Article::Type.where(name: 'email').first,
|
||||
updated_by_id: 1,
|
||||
created_by_id: 1,
|
||||
)
|
||||
Observer::Transaction.commit
|
||||
assert_equal(4, ticket.articles.count)
|
||||
|
||||
travel 1.second
|
||||
email_file_path = Rails.root.join('test', 'data', 'mail', 'mail033-undelivered-mail-returned-to-sender.box')
|
||||
email_raw_string = File.read(email_file_path)
|
||||
ticket_p, article_p, user_p = Channel::EmailParser.new.process({}, email_raw_string)
|
||||
assert_equal(ticket.id, ticket_p.id)
|
||||
assert_equal('open', ticket_p.state.name)
|
||||
assert_equal(5, ticket_p.articles.count)
|
||||
travel_back
|
||||
ticket.destroy
|
||||
end
|
||||
|
||||
test 'process with bounce trigger email loop check - bounce based blocker' do
|
||||
roles = Role.where(name: %w[Customer])
|
||||
customer2 = User.create_or_update(
|
||||
login: 'ticket-bounce-trigger2@example.com',
|
||||
firstname: 'Notification',
|
||||
lastname: 'Customer2',
|
||||
email: 'ticket-bounce-trigger2@example.com',
|
||||
active: true,
|
||||
roles: roles,
|
||||
preferences: {},
|
||||
updated_by_id: 1,
|
||||
created_by_id: 1,
|
||||
)
|
||||
|
||||
Trigger.create_or_update(
|
||||
name: 'auto reply new ticket',
|
||||
condition: {
|
||||
'ticket.action' => {
|
||||
'operator' => 'is',
|
||||
'value' => 'create',
|
||||
},
|
||||
},
|
||||
perform: {
|
||||
'notification.email' => {
|
||||
'body' => 'some text<br>#{ticket.customer.lastname}<br>#{ticket.title}<br>#{article.body}',
|
||||
'recipient' => 'ticket_customer',
|
||||
'subject' => 'Thanks for your inquiry (#{ticket.title})!',
|
||||
},
|
||||
},
|
||||
disable_notification: true,
|
||||
active: true,
|
||||
created_by_id: 1,
|
||||
updated_by_id: 1,
|
||||
)
|
||||
Trigger.create_or_update(
|
||||
name: 'auto reply followup',
|
||||
condition: {
|
||||
'ticket.action' => {
|
||||
'operator' => 'is',
|
||||
'value' => 'update',
|
||||
},
|
||||
},
|
||||
perform: {
|
||||
'notification.email' => {
|
||||
'body' => 'some text<br>#{ticket.customer.lastname}<br>#{ticket.title}<br>#{article.body}',
|
||||
'recipient' => 'ticket_customer',
|
||||
'subject' => 'Thanks for your follow up (#{ticket.title})!',
|
||||
},
|
||||
},
|
||||
disable_notification: true,
|
||||
active: true,
|
||||
created_by_id: 1,
|
||||
updated_by_id: 1,
|
||||
)
|
||||
|
||||
ticket = Ticket.create(
|
||||
title: 'bounce check',
|
||||
group: Group.lookup(name: 'Users'),
|
||||
customer: customer2,
|
||||
state: Ticket::State.lookup(name: 'new'),
|
||||
priority: Ticket::Priority.lookup(name: '2 normal'),
|
||||
updated_by_id: 1,
|
||||
created_by_id: 1,
|
||||
)
|
||||
article = Ticket::Article.create(
|
||||
ticket_id: ticket.id,
|
||||
from: 'some_sender@example.com',
|
||||
to: 'some_recipient@example.com',
|
||||
subject: 'bounce check',
|
||||
message_id: '<20150830145601.30.6088xx@edenhofer.zammad.com>',
|
||||
body: 'some message bounce check',
|
||||
internal: false,
|
||||
sender: Ticket::Article::Sender.where(name: 'Agent').first,
|
||||
type: Ticket::Article::Type.where(name: 'email').first,
|
||||
updated_by_id: 1,
|
||||
created_by_id: 1,
|
||||
)
|
||||
Observer::Transaction.commit
|
||||
assert_equal('new', ticket.state.name)
|
||||
assert_equal(2, ticket.articles.count)
|
||||
|
||||
article = Ticket::Article.create(
|
||||
ticket_id: ticket.id,
|
||||
from: 'some_sender@example.com',
|
||||
to: 'some_recipient@example.com',
|
||||
subject: 'bounce check 2',
|
||||
message_id: '<20170526150141.232.13312@example.zammad.loc>',
|
||||
body: 'some message bounce check 2',
|
||||
internal: false,
|
||||
sender: Ticket::Article::Sender.where(name: 'Agent').first,
|
||||
type: Ticket::Article::Type.where(name: 'email').first,
|
||||
updated_by_id: 1,
|
||||
created_by_id: 1,
|
||||
)
|
||||
Observer::Transaction.commit
|
||||
assert_equal(4, ticket.articles.count)
|
||||
|
||||
travel 1.second
|
||||
email_file_path = Rails.root.join('test', 'data', 'mail', 'mail055.box')
|
||||
email_raw_string = File.read(email_file_path)
|
||||
ticket_p, article_p, user_p = Channel::EmailParser.new.process({}, email_raw_string)
|
||||
assert_equal(ticket.id, ticket_p.id)
|
||||
assert_equal('open', ticket_p.state.name)
|
||||
assert_equal(5, ticket_p.articles.count)
|
||||
travel_back
|
||||
ticket.destroy
|
||||
end
|
||||
|
||||
end
|
Loading…
Reference in a new issue