Initial support of recursive triggers for tickets - issue #2035.

This commit is contained in:
Martin Edenhofer 2018-05-29 17:42:14 +02:00
parent 53fb7e6b0b
commit b403432c76
12 changed files with 6739 additions and 147 deletions

View file

@ -202,6 +202,7 @@ Lint/InterpolationCheck:
- "test/unit/notification_factory_renderer_test.rb" - "test/unit/notification_factory_renderer_test.rb"
- "test/unit/notification_factory_template_test.rb" - "test/unit/notification_factory_template_test.rb"
- "test/unit/ticket_trigger_test.rb" - "test/unit/ticket_trigger_test.rb"
- "test/unit/ticket_trigger_recursive_disabled_test.rb"
# RSpec tests # RSpec tests
Style/NumericPredicate: Style/NumericPredicate:

View file

@ -677,6 +677,10 @@ returns
end end
end end
ticket.reload
article.reload
session_user.reload
# run postmaster post filter # run postmaster post filter
filters = {} filters = {}
Setting.where(area: 'Postmaster::PostFilter').order(:name).each do |setting| Setting.where(area: 'Postmaster::PostFilter').order(:name).each do |setting|

View file

@ -1046,11 +1046,11 @@ perform changes on ticket
tags = value['value'].split(/,/) tags = value['value'].split(/,/)
if value['operator'] == 'add' if value['operator'] == 'add'
tags.each do |tag| tags.each do |tag|
tag_add(tag) tag_add(tag, current_user_id || 1)
end end
elsif value['operator'] == 'remove' elsif value['operator'] == 'remove'
tags.each do |tag| tags.each do |tag|
tag_remove(tag) tag_remove(tag, current_user_id || 1)
end end
else else
logger.error "Unknown #{attribute} operator #{value['operator']}" logger.error "Unknown #{attribute} operator #{value['operator']}"
@ -1085,6 +1085,183 @@ perform changes on ticket
end end
return if !changed return if !changed
save save
true
end
=begin
perform active triggers on ticket
Ticket.perform_triggers(ticket, article, item, options)
=end
def self.perform_triggers(ticket, article, item, options = {})
recursive = Setting.get('ticket_trigger_recursive')
type = options[:type] || item[:type]
local_options = options.clone
local_options[:type] = type
local_options[:reset_user_id] = true
local_options[:disable] = ['Transaction::Notification']
local_options[:trigger_ids] ||= {}
local_options[:trigger_ids][ticket.id] ||= []
local_options[:loop_count] ||= 0
local_options[:loop_count] += 1
ticket_trigger_recursive_max_loop = Setting.get('ticket_trigger_recursive_max_loop')&.to_i || 10
if local_options[:loop_count] > ticket_trigger_recursive_max_loop
message = "Stopped perform_triggers for this object (Ticket/#{ticket.id}), because loop count was #{local_options[:loop_count]}!"
logger.info { message }
return [false, message]
end
triggers = if Rails.configuration.db_case_sensitive
::Trigger.where(active: true).order('LOWER(name)')
else
::Trigger.where(active: true).order(:name)
end
return [true, 'No triggers active'] if triggers.blank?
# check if notification should be send because of customer emails
send_notification = true
if local_options[:send_notification] == false
send_notification = false
elsif item[:article_id]
article = Ticket::Article.lookup(id: item[:article_id])
if article&.preferences && article.preferences['send-auto-response'] == false
send_notification = false
end
end
Transaction.execute(local_options) do
triggers.each do |trigger|
condition = trigger.condition
# check if one article attribute is used
one_has_changed_done = false
article_selector = false
trigger.condition.each_key do |key|
(object_name, attribute) = key.split('.', 2)
next if object_name != 'article'
next if attribute == 'id'
article_selector = true
end
if article && article_selector
one_has_changed_done = true
end
if article && type == 'update'
one_has_changed_done = true
end
# check ticket "has changed" options
has_changed_done = true
condition.each do |key, value|
next if value.blank?
next if value['operator'].blank?
next if !value['operator']['has changed']
# remove condition item, because it has changed
(object_name, attribute) = key.split('.', 2)
next if object_name != 'ticket'
next if item[:changes].blank?
next if !item[:changes].key?(attribute)
condition.delete(key)
one_has_changed_done = true
end
# check if we have not matching "has changed" attributes
condition.each_value do |value|
next if value.blank?
next if value['operator'].blank?
next if !value['operator']['has changed']
has_changed_done = false
break
end
# check ticket action
if condition['ticket.action']
next if condition['ticket.action']['operator'] == 'is' && condition['ticket.action']['value'] != type
next if condition['ticket.action']['operator'] != 'is' && condition['ticket.action']['value'] == type
condition.delete('ticket.action')
end
next if !has_changed_done
# check in min one attribute of condition has changed on update
one_has_changed_condition = false
if type == 'update'
# verify if ticket condition exists
condition.each_key do |key|
(object_name, attribute) = key.split('.', 2)
next if object_name != 'ticket'
one_has_changed_condition = true
next if item[:changes].blank?
next if !item[:changes].key?(attribute)
one_has_changed_done = true
break
end
next if one_has_changed_condition && !one_has_changed_done
end
# check if ticket selector is matching
condition['ticket.id'] = {
operator: 'is',
value: ticket.id,
}
next if article_selector && !article
# check if article selector is matching
if article_selector
condition['article.id'] = {
operator: 'is',
value: article.id,
}
end
# verify is condition is matching
ticket_count, tickets = Ticket.selectors(condition, 1)
next if ticket_count.blank?
next if ticket_count.zero?
next if tickets.first.id != ticket.id
user_id = ticket.updated_by_id
if article
user_id = article.updated_by_id
end
if recursive == false && local_options[:loop_count] > 1
message = "Do not execute recursive triggers per default until Zammad 3.0. With Zammad 3.0 and higher the following trigger is executed '#{trigger.name}' on Ticket:#{ticket.id}. Please review your current triggers and change them if needed."
logger.info { message }
return [true, message]
end
local_send_notification = true
if article && send_notification == false && trigger.perform['notification.email'] && trigger.perform['notification.email']['recipient']
recipient = trigger.perform['notification.email']['recipient']
local_send_notification = false
local_options[:send_notification] = false
if recipient.include?('ticket_customer') || recipient.include?('article_last_sender')
logger.info { "Skip trigger (#{trigger.name}/#{trigger.id}) because sender do not want to get auto responder for object (Ticket/#{ticket.id}/Article/#{article.id})" }
next
end
end
if local_options[:trigger_ids][ticket.id].include?(trigger.id)
logger.info { "Skip trigger (#{trigger.name}/#{trigger.id}) because was already executed for this object (Ticket:#{ticket.id}/Loop:#{local_options[:loop_count]})" }
next
end
local_options[:trigger_ids][ticket.id].push trigger.id
logger.info { "Execute trigger (#{trigger.name}/#{trigger.id}) for this object (Ticket:#{ticket.id}/Loop:#{local_options[:loop_count]})" }
ticket.perform_changes(trigger.perform, 'trigger', item, user_id)
if recursive == true
Observer::Transaction.commit(local_options)
end
end
end
[true, ticket, local_options]
end end
=begin =begin

View file

@ -13,10 +13,7 @@ class Transaction
if options[:interface_handle] if options[:interface_handle]
ApplicationHandleInfo.current = original_interface_handle ApplicationHandleInfo.current = original_interface_handle
end end
Observer::Transaction.commit( Observer::Transaction.commit(options)
disable_notification: options[:disable_notification],
disable: options[:disable],
)
PushMessages.finish PushMessages.finish
end end
end end

View file

@ -29,13 +29,6 @@ class Transaction::Trigger
return if @item[:object] != 'Ticket' return if @item[:object] != 'Ticket'
triggers = if Rails.configuration.db_case_sensitive
::Trigger.where(active: true).order('LOWER(name)')
else
::Trigger.where(active: true).order(:name)
end
return if triggers.blank?
ticket = Ticket.lookup(id: @item[:object_id]) ticket = Ticket.lookup(id: @item[:object_id])
return if !ticket return if !ticket
if @item[:article_id] if @item[:article_id]
@ -44,103 +37,8 @@ class Transaction::Trigger
original_user_id = UserInfo.current_user_id original_user_id = UserInfo.current_user_id
Transaction.execute(reset_user_id: true, disable: ['Transaction::Trigger', 'Transaction::Notification']) do Ticket.perform_triggers(ticket, article, @item, @params)
triggers.each do |trigger|
condition = trigger.condition
# check if one article attribute is used
one_has_changed_done = false
article_selector = false
trigger.condition.each_key do |key|
(object_name, attribute) = key.split('.', 2)
next if object_name != 'article'
next if attribute == 'id'
article_selector = true
end
if article && article_selector
one_has_changed_done = true
end
if article && @item[:type] == 'update'
one_has_changed_done = true
end
# check ticket "has changed" options
has_changed_done = true
condition.each do |key, value|
next if value.blank?
next if value['operator'].blank?
next if !value['operator']['has changed']
# remove condition item, because it has changed
(object_name, attribute) = key.split('.', 2)
next if object_name != 'ticket'
next if @item[:changes].blank?
next if !@item[:changes].key?(attribute)
condition.delete(key)
one_has_changed_done = true
end
# check if we have not matching "has changed" attributes
condition.each_value do |value|
next if value.blank?
next if value['operator'].blank?
next if !value['operator']['has changed']
has_changed_done = false
break
end
# check ticket action
if condition['ticket.action']
next if condition['ticket.action']['operator'] == 'is' && condition['ticket.action']['value'] != @item[:type]
next if condition['ticket.action']['operator'] != 'is' && condition['ticket.action']['value'] == @item[:type]
condition.delete('ticket.action')
end
next if !has_changed_done
# check in min one attribute of condition has changed on update
one_has_changed_condition = false
if @item[:type] == 'update'
# verify if ticket condition exists
condition.each_key do |key|
(object_name, attribute) = key.split('.', 2)
next if object_name != 'ticket'
one_has_changed_condition = true
next if @item[:changes].blank?
next if !@item[:changes].key?(attribute)
one_has_changed_done = true
break
end
next if one_has_changed_condition && !one_has_changed_done
end
# check if ticket selector is matching
condition['ticket.id'] = {
operator: 'is',
value: ticket.id,
}
next if article_selector && !article
# check if article selector is matching
if article_selector
condition['article.id'] = {
operator: 'is',
value: article.id,
}
end
# verify is condition is matching
ticket_count, tickets = Ticket.selectors(condition, 1)
next if ticket_count.blank?
next if ticket_count.zero?
next if tickets.first.id != ticket.id
user_id = ticket.updated_by_id
if article
user_id = article.updated_by_id
end
ticket.perform_changes(trigger.perform, 'trigger', @item, user_id)
end
end
UserInfo.current_user_id = original_user_id UserInfo.current_user_id = original_user_id
end end

View file

@ -0,0 +1,79 @@
class Issue2035RecursiveTicketTrigger < ActiveRecord::Migration[5.1]
def change
# return if it's a new setup
return if !Setting.find_by(name: 'system_init_done')
Setting.create_if_not_exists(
title: 'Recursive Ticket Triggers',
name: 'ticket_trigger_recursive',
area: 'Ticket::Core',
description: 'Activate the recursive processing of ticket triggers.',
options: {
form: [
{
display: 'Recursive Ticket Triggers',
null: true,
name: 'ticket_trigger_recursive',
tag: 'boolean',
options: {
true => 'yes',
false => 'no',
},
},
],
},
state: false,
preferences: {
permission: ['admin.ticket'],
hidden: true,
},
frontend: false
)
Setting.create_if_not_exists(
title: 'Recursive Ticket Triggers Loop Max.',
name: 'ticket_trigger_recursive_max_loop',
area: 'Ticket::Core',
description: 'Maximum number of recursively executed triggers.',
options: {
form: [
{
display: 'Recursive Ticket Triggers',
null: true,
name: 'ticket_trigger_recursive_max_loop',
tag: 'select',
options: {
1 => ' 1',
2 => ' 2',
3 => ' 3',
4 => ' 4',
5 => ' 5',
6 => ' 6',
7 => ' 7',
8 => ' 8',
9 => ' 9',
10 => '10',
11 => '11',
12 => '12',
13 => '13',
14 => '14',
15 => '15',
16 => '16',
17 => '17',
18 => '18',
19 => '19',
20 => '20',
},
},
],
},
state: 10,
preferences: {
permission: ['admin.ticket'],
hidden: true,
},
frontend: false
)
end
end

View file

@ -1978,6 +1978,77 @@ Setting.create_if_not_exists(
frontend: false frontend: false
) )
Setting.create_if_not_exists(
title: 'Recursive Ticket Triggers',
name: 'ticket_trigger_recursive',
area: 'Ticket::Core',
description: 'Activate the recursive processing of ticket triggers.',
options: {
form: [
{
display: 'Recursive Ticket Triggers',
null: true,
name: 'ticket_trigger_recursive',
tag: 'boolean',
options: {
true => 'yes',
false => 'no',
},
},
],
},
state: false,
preferences: {
permission: ['admin.ticket'],
hidden: true,
},
frontend: false
)
Setting.create_if_not_exists(
title: 'Recursive Ticket Triggers Loop Max.',
name: 'ticket_trigger_recursive_max_loop',
area: 'Ticket::Core',
description: 'Maximum number of recursively executed triggers.',
options: {
form: [
{
display: 'Recursive Ticket Triggers',
null: true,
name: 'ticket_trigger_recursive_max_loop',
tag: 'select',
options: {
1 => ' 1',
2 => ' 2',
3 => ' 3',
4 => ' 4',
5 => ' 5',
6 => ' 6',
7 => ' 7',
8 => ' 8',
9 => ' 9',
10 => '10',
11 => '11',
12 => '12',
13 => '13',
14 => '14',
15 => '15',
16 => '16',
17 => '17',
18 => '18',
19 => '19',
20 => '20',
},
},
],
},
state: 10,
preferences: {
permission: ['admin.ticket'],
hidden: true,
},
frontend: false
)
Setting.create_if_not_exists( Setting.create_if_not_exists(
title: 'Enable Ticket creation', title: 'Enable Ticket creation',
name: 'customer_ticket_create', name: 'customer_ticket_create',

View file

@ -2,10 +2,10 @@ require 'test_helper'
class EmailProcessAutoResponseTest < ActiveSupport::TestCase class EmailProcessAutoResponseTest < ActiveSupport::TestCase
test 'process auto reply check' do test 'process auto reply check - 1' do
roles = Role.where(name: 'Agent') roles = Role.where(name: 'Agent')
agent1 = User.create_or_update( agent1 = User.create!(
login: 'ticket-auto-responder-agent1@example.com', login: 'ticket-auto-responder-agent1@example.com',
firstname: 'AutoReponder', firstname: 'AutoReponder',
lastname: 'Agent1', lastname: 'Agent1',
@ -18,9 +18,13 @@ class EmailProcessAutoResponseTest < ActiveSupport::TestCase
created_by_id: 1, created_by_id: 1,
) )
Trigger.create_or_update( Trigger.create!(
name: 'auto reply', name: '002 auto reply',
condition: { condition: {
'ticket.action' => {
'operator' => 'is',
'value' => 'create',
},
'ticket.state_id' => { 'ticket.state_id' => {
'operator' => 'is', 'operator' => 'is',
'value' => Ticket::State.lookup(name: 'new').id.to_s, 'value' => Ticket::State.lookup(name: 'new').id.to_s,
@ -37,7 +41,7 @@ class EmailProcessAutoResponseTest < ActiveSupport::TestCase
}, },
'ticket.tags' => { 'ticket.tags' => {
'operator' => 'add', 'operator' => 'add',
'value' => 'aa, kk', 'value' => 'aa, kk, auto-reply',
}, },
}, },
disable_notification: true, disable_notification: true,
@ -188,8 +192,8 @@ test"
assert_equal(1, article_p.ticket.articles.count) assert_equal(1, article_p.ticket.articles.count)
# add an agent notification # add an agent notification
Trigger.create_or_update( Trigger.create!(
name: 'additional agent notification', name: '001 additional agent notification',
condition: { condition: {
'ticket.state_id' => { 'ticket.state_id' => {
'operator' => 'is', 'operator' => 'is',
@ -207,7 +211,7 @@ test"
}, },
'ticket.tags' => { 'ticket.tags' => {
'operator' => 'add', 'operator' => 'add',
'value' => 'aa, kk', 'value' => 'aa, kk, agent-notification',
}, },
}, },
disable_notification: true, disable_notification: true,
@ -226,20 +230,663 @@ Some Text"
ticket_p, article_p, user_p, mail = Channel::EmailParser.new.process({}, email_raw_string) ticket_p, article_p, user_p, mail = Channel::EmailParser.new.process({}, email_raw_string)
assert_equal(false, mail['x-zammad-send-auto-response'.to_sym]) assert_equal(false, mail['x-zammad-send-auto-response'.to_sym])
Scheduler.worker(true) Scheduler.worker(true)
tags = ticket_p.tag_list
assert_equal('new', ticket_p.state.name)
assert_equal('3 high', ticket_p.priority.name)
assert(tags.include?('aa'))
assert(tags.include?('kk'))
assert(tags.include?('agent-notification'))
assert_equal(3, tags.count)
assert_equal(2, article_p.ticket.articles.count) assert_equal(2, article_p.ticket.articles.count)
article_customer = article_p.ticket.articles.first article_customer = article_p.ticket.articles.first
assert_equal('me@example.com', article_customer.from) assert_equal('me@example.com', article_customer.from)
assert_equal('customer@example.com', article_customer.to) assert_equal('customer@example.com', article_customer.to)
assert_equal('Customer', article_customer.sender.name) assert_equal('Customer', article_customer.sender.name)
assert_equal('email', article_customer.type.name) assert_equal('email', article_customer.type.name)
article_notification = article_p.ticket.articles.last article_notification = article_p.ticket.articles[1]
assert_match(/New Ticket add. info/, article_notification.subject) assert_match(/New Ticket add. info/, article_notification.subject)
assert_no_match(/me@example.com/, article_notification.to) assert_no_match(/me@example.com/, article_notification.to)
assert_match(/#{agent1.email}/, article_notification.to) assert_match(/#{agent1.email}/, article_notification.to)
assert_equal('System', article_notification.sender.name) assert_equal('System', article_notification.sender.name)
assert_equal('email', article_notification.type.name) assert_equal('email', article_notification.type.name)
Trigger.destroy_all Setting.set('ticket_trigger_recursive', true)
ticket_p, article_p, user_p, mail = Channel::EmailParser.new.process({}, email_raw_string)
assert_equal(false, mail['x-zammad-send-auto-response'.to_sym])
Scheduler.worker(true)
tags = ticket_p.tag_list
assert_equal('new', ticket_p.state.name)
assert_equal('3 high', ticket_p.priority.name)
assert(tags.include?('aa'))
assert(tags.include?('kk'))
assert(tags.include?('agent-notification'))
assert_equal(3, tags.count)
assert_equal(2, article_p.ticket.articles.count)
article_customer = article_p.ticket.articles.first
assert_equal('me@example.com', article_customer.from)
assert_equal('customer@example.com', article_customer.to)
assert_equal('Customer', article_customer.sender.name)
assert_equal('email', article_customer.type.name)
article_notification = article_p.ticket.articles[1]
assert_match(/New Ticket add. info/, article_notification.subject)
assert_no_match(/me@example.com/, article_notification.to)
assert_match(/#{agent1.email}/, article_notification.to)
assert_equal('System', article_notification.sender.name)
assert_equal('email', article_notification.type.name)
Setting.set('ticket_trigger_recursive', false)
email_raw_string = "From: me@example.com
To: customer@example.com
Subject: some new subject
Some Text"
ticket_p, article_p, user_p, mail = Channel::EmailParser.new.process({}, email_raw_string)
assert_equal(true, mail['x-zammad-send-auto-response'.to_sym])
Scheduler.worker(true)
tags = ticket_p.tag_list
assert_equal('new', ticket_p.state.name)
assert_equal('3 high', ticket_p.priority.name)
assert(tags.include?('aa'))
assert(tags.include?('kk'))
assert(tags.include?('agent-notification'))
assert(tags.include?('auto-reply'))
assert_equal(3, article_p.ticket.articles.count)
article_customer = article_p.ticket.articles[0]
assert_equal('me@example.com', article_customer.from)
assert_equal('customer@example.com', article_customer.to)
assert_equal('Customer', article_customer.sender.name)
assert_equal('email', article_customer.type.name)
article_notification = article_p.ticket.articles[1]
assert_match(/New Ticket add. info/, article_notification.subject)
assert_no_match(/me@example.com/, article_notification.to)
assert_match(/#{agent1.email}/, article_notification.to)
assert_equal('System', article_notification.sender.name)
assert_equal('email', article_notification.type.name)
article_auto_reply = article_p.ticket.articles[2]
assert_match(/Thanks for your inquiry/, article_auto_reply.subject)
assert_match(/me@example.com/, article_auto_reply.to)
assert_equal('System', article_auto_reply.sender.name)
assert_equal('email', article_auto_reply.type.name)
Setting.set('ticket_trigger_recursive', true)
ticket_p, article_p, user_p, mail = Channel::EmailParser.new.process({}, email_raw_string)
assert_equal(true, mail['x-zammad-send-auto-response'.to_sym])
Scheduler.worker(true)
tags = ticket_p.tag_list
assert_equal('new', ticket_p.state.name)
assert_equal('3 high', ticket_p.priority.name)
assert(tags.include?('aa'))
assert(tags.include?('kk'))
assert(tags.include?('agent-notification'))
assert(tags.include?('auto-reply'))
assert_equal(3, article_p.ticket.articles.count)
article_customer = article_p.ticket.articles[0]
assert_equal('me@example.com', article_customer.from)
assert_equal('customer@example.com', article_customer.to)
assert_equal('Customer', article_customer.sender.name)
assert_equal('email', article_customer.type.name)
article_notification = article_p.ticket.articles[1]
assert_match(/New Ticket add. info/, article_notification.subject)
assert_no_match(/me@example.com/, article_notification.to)
assert_match(/#{agent1.email}/, article_notification.to)
assert_equal('System', article_notification.sender.name)
assert_equal('email', article_notification.type.name)
article_auto_reply = article_p.ticket.articles[2]
assert_match(/Thanks for your inquiry/, article_auto_reply.subject)
assert_match(/me@example.com/, article_auto_reply.to)
assert_equal('System', article_auto_reply.sender.name)
assert_equal('email', article_auto_reply.type.name)
end
test 'process auto reply check - 2' do
roles = Role.where(name: 'Agent')
agent1 = User.create!(
login: 'ticket-auto-responder-agent1@example.com',
firstname: 'AutoReponder',
lastname: 'Agent1',
email: 'ticket-auto-responder-agent1@example.com',
password: 'agentpw',
active: true,
roles: roles,
groups: Group.all,
updated_by_id: 1,
created_by_id: 1,
)
Trigger.create!(
name: '001 auto reply',
condition: {
'ticket.action' => {
'operator' => 'is',
'value' => 'create',
},
'ticket.state_id' => {
'operator' => 'is',
'value' => Ticket::State.lookup(name: 'new').id.to_s,
}
},
perform: {
'notification.email' => {
'body' => 'some text<br>#{ticket.customer.lastname}<br>#{ticket.title}',
'recipient' => 'ticket_customer',
'subject' => 'Thanks for your inquiry (#{ticket.title})!',
},
'ticket.priority_id' => {
'value' => Ticket::Priority.lookup(name: '3 high').id.to_s,
},
'ticket.tags' => {
'operator' => 'add',
'value' => 'aa, kk, auto-reply',
},
},
disable_notification: true,
active: true,
created_by_id: 1,
updated_by_id: 1,
)
email_raw_string = "From: me@example.com
To: customer@example.com
Subject: some new subject
Some Text"
ticket_p, article_p, user_p, mail = Channel::EmailParser.new.process({}, email_raw_string)
assert_equal(true, mail['x-zammad-send-auto-response'.to_sym])
Scheduler.worker(true)
assert_equal(2, article_p.ticket.articles.count)
email_raw_string = "From: me@example.com
To: customer@example.com
Subject: some new subject
X-Loop: yes
Some Text"
ticket_p, article_p, user_p, mail = Channel::EmailParser.new.process({}, email_raw_string)
assert_equal(false, mail['x-zammad-send-auto-response'.to_sym])
Scheduler.worker(true)
assert_equal(1, article_p.ticket.articles.count)
email_raw_string = "From: me@example.com
To: customer@example.com
Subject: some new subject
Precedence: Bulk
Some Text"
ticket_p, article_p, user_p, mail = Channel::EmailParser.new.process({}, email_raw_string)
assert_equal(false, mail['x-zammad-send-auto-response'.to_sym])
email_raw_string = "From: me@example.com
To: customer@example.com
Subject: some new subject
Auto-Submitted: auto-generated
Some Text"
Scheduler.worker(true)
assert_equal(1, article_p.ticket.articles.count)
ticket_p, article_p, user_p, mail = Channel::EmailParser.new.process({}, email_raw_string)
assert_equal(false, mail['x-zammad-send-auto-response'.to_sym])
email_raw_string = "From: me@example.com
To: customer@example.com
Subject: some new subject
X-Auto-Response-Suppress: All
Some Text"
ticket_p, article_p, user_p, mail = Channel::EmailParser.new.process({}, email_raw_string)
assert_equal(false, mail['x-zammad-send-auto-response'.to_sym])
Scheduler.worker(true)
assert_equal(1, article_p.ticket.articles.count)
email_raw_string = "From: me@example.com
To: customer@example.com
Subject: some new subject
List-Unsubscribe: <mailto:somebody@example.com>
Some Text"
fqdn = Setting.get('fqdn')
email_raw_string = "From: me@example.com
To: customer@example.com
Subject: some new subject
Message-ID: <1234@#{fqdn}>
Some Text"
ticket_p, article_p, user_p, mail = Channel::EmailParser.new.process({}, email_raw_string)
assert_equal(false, mail['x-zammad-send-auto-response'.to_sym])
Scheduler.worker(true)
assert_equal(1, article_p.ticket.articles.count)
fqdn = Setting.get('fqdn')
email_raw_string = "From: me@example.com
To: customer@example.com
Subject: some new subject
Message-ID: <1234@not_matching.#{fqdn}>
Some Text"
ticket_p, article_p, user_p, mail = Channel::EmailParser.new.process({}, email_raw_string)
assert_equal(true, mail['x-zammad-send-auto-response'.to_sym])
Scheduler.worker(true)
assert_equal(2, article_p.ticket.articles.count)
email_raw_string = "Return-Path: <XX@XX.XX>
X-Original-To: sales@znuny.com
Received: from mail-qk0-f170.example.com (mail-qk0-f170.example.com [209.1.1.1])
by arber.znuny.com (Postfix) with ESMTPS id C3AED5FE2E
for <sales@znuny.com>; Mon, 22 Aug 2016 19:03:15 +0200 (CEST)
Received: by mail-qk0-f170.example.com with SMTP id t7so87721720qkh.1
for <sales@znuny.com>; Mon, 22 Aug 2016 10:03:15 -0700 (PDT)
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed;
d=XX.XX; s=example;
h=to:from:date:message-id:subject:mime-version:precedence
:auto-submitted:content-transfer-encoding:content-disposition;
bh=SL5tTVvGdxsKjLic38irxzlP439P3jixJH0QTG1HJ5I=;
b=CIk3PLELgjOCagyiFFbd6rlb8ZRDGYRUrg5Dntxa7e5X+PT4cgL+IE13N9TFkK8ZUJ
GohlaPLGiBymIYLTtYMKUpcf22oiX8ZgGiSu1aEMC1Gsa1ZDf+vpy4kd4+7EecRT3IWF
4RafQxeaqe67budhQpO1Z6UAel6BdJj0xguKM=
X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed;
d=1e100.net; s=20130820;
h=x-gm-message-state:to:from:date:message-id:subject:mime-version
:precedence:auto-submitted:content-transfer-encoding
:content-disposition;
bh=SL5tTVvGdxsKjLic38irxzlP439P3jixJH0QTG1HJ5I=;
b=PYULo3xigc4O/cuNZ79OathQ5HDMFWWIwUxz6CHbpXDQR5k3EPy/skJU1992hVz9Rl
xiGwScBCkMqOjlxHjQSWhFJIxNtdvMk4m0bixBZ79IEvRuQa9cEbqjf6efnV58br5ftQ
2osHrtQczoSqLE/d61/o102RfQ0avVyX8XNJik0iepg8MiCY7LTOE9hrbnuDDLxgQecH
rMEfkR7bafcUj1YEto5Vd7uV11cVZYx8UIQqVAVbfygv8dTSFeOzz3NyM0M41rRexfYH
79Yi5i7z/Wk6q2427wkJ3FIR1B7VQVQEmcq/Texbch+gAXPGBNPUHdg2WHt7NXGktrHL
d3DA==
X-Gm-Message-State: AE9vXwMCTnihGiG/tc7xNNlhFLcEK6DPp7otypJg5e4alD3xGK2R707BP29druIi/mcdNyaHg1vP5lSZ8EvrwvOF8iA0HNFhECGjBTJ40YrSJAR8E89xVwxFv/er+U3vEpqmPmt+hL4QhxK/+D2gKOcHSxku
X-Received: by 10.1.1.1 with SMTP id 17mr25015996qkf.279.1471885393931;
Mon, 22 Aug 2016 10:03:13 -0700 (PDT)
To: sales@znuny.com
From: \"XXX\" <XX@XX.XX>
Date: Mon, 22 Aug 2016 10:03:13 -0700
Message-ID: <CA+kqV8PH1DU+zcSx3M00Hrm_oJedRLjbgAUdoi9p0+sMwYsyUg@mail.gmail.com>
Subject: XX PieroXXway - vacation response RE: Callback Request: XX XX [Ticket#1118974]
MIME-Version: 1.0
Precedence: bulk
X-Autoreply: yes
Auto-Submitted: auto-replied
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
Content-Disposition: inline
test"
ticket_p, article_p, user_p, mail = Channel::EmailParser.new.process({}, email_raw_string)
assert_equal(false, mail['x-zammad-send-auto-response'.to_sym])
Scheduler.worker(true)
assert_equal(1, article_p.ticket.articles.count)
# add an agent notification
Trigger.create!(
name: '002 additional agent notification',
condition: {
'ticket.state_id' => {
'operator' => 'is',
'value' => Ticket::State.lookup(name: 'new').id.to_s,
}
},
perform: {
'notification.email' => {
'body' => 'some text<br>#{ticket.customer.lastname}<br>#{ticket.title}',
'recipient' => 'ticket_agents',
'subject' => 'New Ticket add. info (#{ticket.title})!',
},
'ticket.priority_id' => {
'value' => Ticket::Priority.lookup(name: '3 high').id.to_s,
},
'ticket.tags' => {
'operator' => 'add',
'value' => 'aa, kk, agent-notification',
},
},
disable_notification: true,
active: true,
created_by_id: 1,
updated_by_id: 1,
)
email_raw_string = "From: me@example.com
To: customer@example.com
Subject: some new subject
X-Loop: yes
Some Text"
ticket_p, article_p, user_p, mail = Channel::EmailParser.new.process({}, email_raw_string)
assert_equal(false, mail['x-zammad-send-auto-response'.to_sym])
Scheduler.worker(true)
tags = ticket_p.tag_list
assert_equal('new', ticket_p.state.name)
assert_equal('3 high', ticket_p.priority.name)
assert(tags.include?('aa'))
assert(tags.include?('kk'))
assert(tags.include?('agent-notification'))
assert_equal(3, tags.count)
assert_equal(2, article_p.ticket.articles.count)
article_customer = article_p.ticket.articles.first
assert_equal('me@example.com', article_customer.from)
assert_equal('customer@example.com', article_customer.to)
assert_equal('Customer', article_customer.sender.name)
assert_equal('email', article_customer.type.name)
article_notification = article_p.ticket.articles[1]
assert_match(/New Ticket add. info/, article_notification.subject)
assert_no_match(/me@example.com/, article_notification.to)
assert_match(/#{agent1.email}/, article_notification.to)
assert_equal('System', article_notification.sender.name)
assert_equal('email', article_notification.type.name)
Setting.set('ticket_trigger_recursive', true)
ticket_p, article_p, user_p, mail = Channel::EmailParser.new.process({}, email_raw_string)
assert_equal(false, mail['x-zammad-send-auto-response'.to_sym])
Scheduler.worker(true)
tags = ticket_p.tag_list
assert_equal('new', ticket_p.state.name)
assert_equal('3 high', ticket_p.priority.name)
assert(tags.include?('aa'))
assert(tags.include?('kk'))
assert(tags.include?('agent-notification'))
assert_equal(3, tags.count)
assert_equal(2, article_p.ticket.articles.count)
article_customer = article_p.ticket.articles.first
assert_equal('me@example.com', article_customer.from)
assert_equal('customer@example.com', article_customer.to)
assert_equal('Customer', article_customer.sender.name)
assert_equal('email', article_customer.type.name)
article_notification = article_p.ticket.articles[1]
assert_match(/New Ticket add. info/, article_notification.subject)
assert_no_match(/me@example.com/, article_notification.to)
assert_match(/#{agent1.email}/, article_notification.to)
assert_equal('System', article_notification.sender.name)
assert_equal('email', article_notification.type.name)
Setting.set('ticket_trigger_recursive', false)
email_raw_string = "From: me@example.com
To: customer@example.com
Subject: some new subject
Some Text"
ticket_p, article_p, user_p, mail = Channel::EmailParser.new.process({}, email_raw_string)
assert_equal(true, mail['x-zammad-send-auto-response'.to_sym])
Scheduler.worker(true)
tags = ticket_p.tag_list
assert_equal('new', ticket_p.state.name)
assert_equal('3 high', ticket_p.priority.name)
assert(tags.include?('aa'))
assert(tags.include?('kk'))
assert(tags.include?('agent-notification'))
assert(tags.include?('auto-reply'))
assert_equal(3, article_p.ticket.articles.count)
article_customer = article_p.ticket.articles[0]
assert_equal('me@example.com', article_customer.from)
assert_equal('customer@example.com', article_customer.to)
assert_equal('Customer', article_customer.sender.name)
assert_equal('email', article_customer.type.name)
article_auto_reply = article_p.ticket.articles[1]
assert_match(/Thanks for your inquiry/, article_auto_reply.subject)
assert_match(/me@example.com/, article_auto_reply.to)
assert_equal('System', article_auto_reply.sender.name)
assert_equal('email', article_auto_reply.type.name)
article_notification = article_p.ticket.articles[2]
assert_match(/New Ticket add. info/, article_notification.subject)
assert_no_match(/me@example.com/, article_notification.to)
assert_match(/#{agent1.email}/, article_notification.to)
assert_equal('System', article_notification.sender.name)
assert_equal('email', article_notification.type.name)
Setting.set('ticket_trigger_recursive', true)
ticket_p, article_p, user_p, mail = Channel::EmailParser.new.process({}, email_raw_string)
assert_equal(true, mail['x-zammad-send-auto-response'.to_sym])
Scheduler.worker(true)
tags = ticket_p.tag_list
assert_equal('new', ticket_p.state.name)
assert_equal('3 high', ticket_p.priority.name)
assert(tags.include?('aa'))
assert(tags.include?('kk'))
assert(tags.include?('agent-notification'))
assert(tags.include?('auto-reply'))
assert_equal(3, article_p.ticket.articles.count)
article_customer = article_p.ticket.articles[0]
assert_equal('me@example.com', article_customer.from)
assert_equal('customer@example.com', article_customer.to)
assert_equal('Customer', article_customer.sender.name)
assert_equal('email', article_customer.type.name)
article_auto_reply = article_p.ticket.articles[1]
assert_match(/Thanks for your inquiry/, article_auto_reply.subject)
assert_match(/me@example.com/, article_auto_reply.to)
assert_equal('System', article_auto_reply.sender.name)
assert_equal('email', article_auto_reply.type.name)
article_notification = article_p.ticket.articles[2]
assert_match(/New Ticket add. info/, article_notification.subject)
assert_no_match(/me@example.com/, article_notification.to)
assert_match(/#{agent1.email}/, article_notification.to)
assert_equal('System', article_notification.sender.name)
assert_equal('email', article_notification.type.name)
end
test 'process auto reply check - recursive' do
roles = Role.where(name: 'Agent')
agent1 = User.create!(
login: 'ticket-auto-responder-agent1@example.com',
firstname: 'AutoReponder',
lastname: 'Agent1',
email: 'ticket-auto-responder-agent1@example.com',
password: 'agentpw',
active: true,
roles: roles,
groups: Group.all,
updated_by_id: 1,
created_by_id: 1,
)
Trigger.create!(
name: '001 auto reply',
condition: {
'ticket.action' => {
'operator' => 'is',
'value' => 'create',
},
'ticket.state_id' => {
'operator' => 'is',
'value' => Ticket::State.lookup(name: 'open').id.to_s,
}
},
perform: {
'notification.email' => {
'body' => 'some text<br>#{ticket.customer.lastname}<br>#{ticket.title}',
'recipient' => 'ticket_customer',
'subject' => 'Thanks for your inquiry (#{ticket.title})!',
},
'ticket.priority_id' => {
'value' => Ticket::Priority.lookup(name: '3 high').id.to_s,
},
'ticket.tags' => {
'operator' => 'add',
'value' => 'aa, kk, auto-reply',
},
},
disable_notification: true,
active: true,
created_by_id: 1,
updated_by_id: 1,
)
# add an agent notification
Trigger.create!(
name: '002 additional agent notification',
condition: {
'ticket.state_id' => {
'operator' => 'is',
'value' => Ticket::State.lookup(name: 'new').id.to_s,
}
},
perform: {
'notification.email' => {
'body' => 'some text<br>#{ticket.customer.lastname}<br>#{ticket.title}',
'recipient' => 'ticket_agents',
'subject' => 'New Ticket add. info (#{ticket.title})!',
},
'ticket.priority_id' => {
'value' => Ticket::Priority.lookup(name: '3 high').id.to_s,
},
'ticket.state_id' => {
'value' => Ticket::State.lookup(name: 'open').id.to_s,
},
'ticket.tags' => {
'operator' => 'add',
'value' => 'aa, kk, agent-notification',
},
},
disable_notification: true,
active: true,
created_by_id: 1,
updated_by_id: 1,
)
email_raw_string = "From: me@example.com
To: customer@example.com
Subject: some new subject
X-Loop: yes
Some Text"
ticket_p, article_p, user_p, mail = Channel::EmailParser.new.process({}, email_raw_string)
assert_equal(false, mail['x-zammad-send-auto-response'.to_sym])
Scheduler.worker(true)
tags = ticket_p.tag_list
assert_equal('open', ticket_p.state.name)
assert_equal('3 high', ticket_p.priority.name)
assert(tags.include?('aa'))
assert(tags.include?('kk'))
assert(tags.include?('agent-notification'))
assert_equal(3, tags.count)
assert_equal(2, article_p.ticket.articles.count)
article_customer = article_p.ticket.articles.first
assert_equal('me@example.com', article_customer.from)
assert_equal('customer@example.com', article_customer.to)
assert_equal('Customer', article_customer.sender.name)
assert_equal('email', article_customer.type.name)
article_notification = article_p.ticket.articles[1]
assert_match(/New Ticket add. info/, article_notification.subject)
assert_no_match(/me@example.com/, article_notification.to)
assert_match(/#{agent1.email}/, article_notification.to)
assert_equal('System', article_notification.sender.name)
assert_equal('email', article_notification.type.name)
Setting.set('ticket_trigger_recursive', true)
ticket_p, article_p, user_p, mail = Channel::EmailParser.new.process({}, email_raw_string)
assert_equal(false, mail['x-zammad-send-auto-response'.to_sym])
Scheduler.worker(true)
tags = ticket_p.tag_list
assert_equal('open', ticket_p.state.name)
assert_equal('3 high', ticket_p.priority.name)
assert(tags.include?('aa'))
assert(tags.include?('kk'))
assert(tags.include?('agent-notification'))
assert_equal(3, tags.count)
assert_equal(2, article_p.ticket.articles.count)
article_customer = article_p.ticket.articles.first
assert_equal('me@example.com', article_customer.from)
assert_equal('customer@example.com', article_customer.to)
assert_equal('Customer', article_customer.sender.name)
assert_equal('email', article_customer.type.name)
article_notification = article_p.ticket.articles[1]
assert_match(/New Ticket add. info/, article_notification.subject)
assert_no_match(/me@example.com/, article_notification.to)
assert_match(/#{agent1.email}/, article_notification.to)
assert_equal('System', article_notification.sender.name)
assert_equal('email', article_notification.type.name)
Setting.set('ticket_trigger_recursive', false)
email_raw_string = "From: me@example.com
To: customer@example.com
Subject: some new subject
Some Text"
ticket_p, article_p, user_p, mail = Channel::EmailParser.new.process({}, email_raw_string)
assert_equal(true, mail['x-zammad-send-auto-response'.to_sym])
Scheduler.worker(true)
tags = ticket_p.tag_list
assert_equal('open', ticket_p.state.name)
assert_equal('3 high', ticket_p.priority.name)
assert(tags.include?('aa'))
assert(tags.include?('kk'))
assert(tags.include?('agent-notification'))
assert_equal(2, article_p.ticket.articles.count)
article_customer = article_p.ticket.articles[0]
assert_equal('me@example.com', article_customer.from)
assert_equal('customer@example.com', article_customer.to)
assert_equal('Customer', article_customer.sender.name)
assert_equal('email', article_customer.type.name)
article_notification = article_p.ticket.articles[1]
assert_match(/New Ticket add. info/, article_notification.subject)
assert_no_match(/me@example.com/, article_notification.to)
assert_match(/#{agent1.email}/, article_notification.to)
assert_equal('System', article_notification.sender.name)
assert_equal('email', article_notification.type.name)
Setting.set('ticket_trigger_recursive', true)
ticket_p, article_p, user_p, mail = Channel::EmailParser.new.process({}, email_raw_string)
assert_equal(true, mail['x-zammad-send-auto-response'.to_sym])
Scheduler.worker(true)
tags = ticket_p.tag_list
assert_equal('open', ticket_p.state.name)
assert_equal('3 high', ticket_p.priority.name)
assert(tags.include?('aa'))
assert(tags.include?('kk'))
assert(tags.include?('agent-notification'))
assert(tags.include?('auto-reply'))
assert_equal(3, article_p.ticket.articles.count)
article_customer = article_p.ticket.articles[0]
assert_equal('me@example.com', article_customer.from)
assert_equal('customer@example.com', article_customer.to)
assert_equal('Customer', article_customer.sender.name)
assert_equal('email', article_customer.type.name)
article_notification = article_p.ticket.articles[1]
assert_match(/New Ticket add. info/, article_notification.subject)
assert_no_match(/me@example.com/, article_notification.to)
assert_match(/#{agent1.email}/, article_notification.to)
assert_equal('System', article_notification.sender.name)
assert_equal('email', article_notification.type.name)
article_auto_reply = article_p.ticket.articles[2]
assert_match(/Thanks for your inquiry/, article_auto_reply.subject)
assert_match(/me@example.com/, article_auto_reply.to)
assert_equal('System', article_auto_reply.sender.name)
assert_equal('email', article_auto_reply.type.name)
end end

View file

@ -0,0 +1,677 @@
require 'test_helper'
class TicketTriggerExtendedRecursiveDisabledTest < ActiveSupport::TestCase
setup do
Setting.set('ticket_trigger_recursive', false)
end
test 'recursive trigger' do
trigger1 = Trigger.create!(
name: '1) set prio to 3 high',
condition: {
'ticket.action' => {
'operator' => 'is',
'value' => 'create',
},
'ticket.state_id' => {
'operator' => 'is',
'value' => Ticket::State.lookup(name: 'new').id.to_s,
},
},
perform: {
'ticket.priority_id' => {
'value' => Ticket::Priority.lookup(name: '3 high').id.to_s,
},
},
disable_notification: true,
active: true,
created_by_id: 1,
updated_by_id: 1,
)
trigger2 = Trigger.create!(
name: '2) set state to closed',
condition: {
'ticket.action' => {
'operator' => 'is',
'value' => 'create',
},
'ticket.priority_id' => {
'operator' => 'is',
'value' => Ticket::Priority.lookup(name: '3 high').id.to_s,
},
},
perform: {
'ticket.state_id' => {
'value' => Ticket::State.lookup(name: 'closed').id.to_s,
},
},
disable_notification: true,
active: true,
created_by_id: 1,
updated_by_id: 1,
)
email_raw_string = 'From: me@example.com
To: customer@example.com
Subject: some new subject
Some Text'
ticket_p, article_p, user_p, mail = Channel::EmailParser.new.process({}, email_raw_string)
assert_equal('some new subject', ticket_p.title)
assert_equal('Users', ticket_p.group.name)
assert_equal('3 high', ticket_p.priority.name)
assert_equal('closed', ticket_p.state.name)
assert_equal(1, ticket_p.articles.count, 'ticket1.articles verify')
end
test 'recursive trigger - loop test' do
trigger1 = Trigger.create!(
name: '1) set prio to 3 high',
condition: {
'ticket.priority_id' => {
'operator' => 'is',
'value' => Ticket::Priority.lookup(name: '2 normal').id.to_s,
},
},
perform: {
'ticket.priority_id' => {
'value' => Ticket::Priority.lookup(name: '3 high').id.to_s,
},
'ticket.state_id' => {
'value' => Ticket::State.lookup(name: 'closed').id.to_s,
},
},
disable_notification: true,
active: true,
created_by_id: 1,
updated_by_id: 1,
)
trigger2 = Trigger.create!(
name: '2) set prio to 1 low',
condition: {
'ticket.priority_id' => {
'operator' => 'is',
'value' => Ticket::Priority.lookup(name: '3 high').id.to_s,
},
},
perform: {
'ticket.priority_id' => {
'value' => Ticket::Priority.lookup(name: '1 low').id.to_s,
},
'ticket.state_id' => {
'value' => Ticket::State.lookup(name: 'open').id.to_s,
},
},
disable_notification: true,
active: true,
created_by_id: 1,
updated_by_id: 1,
)
trigger3 = Trigger.create!(
name: '3) set prio to 3 high',
condition: {
'ticket.priority_id' => {
'operator' => 'is',
'value' => Ticket::Priority.lookup(name: '1 low').id.to_s,
},
},
perform: {
'ticket.priority_id' => {
'value' => Ticket::Priority.lookup(name: '2 normal').id.to_s,
},
},
disable_notification: true,
active: true,
created_by_id: 1,
updated_by_id: 1,
)
email_raw_string = 'From: me@example.com
To: customer@example.com
Subject: some new subject
Some Text'
ticket_p, article_p, user_p, mail = Channel::EmailParser.new.process({}, email_raw_string)
assert_equal('some new subject', ticket_p.title)
assert_equal('Users', ticket_p.group.name)
assert_equal('2 normal', ticket_p.priority.name)
assert_equal('open', ticket_p.state.name)
assert_equal(1, ticket_p.articles.count, 'ticket1.articles verify')
end
test 'recursive trigger - 2 trigger will not trigger next trigger' do
trigger1 = Trigger.create!(
name: '1) set prio to 3 high',
condition: {
'ticket.action' => {
'operator' => 'is',
'value' => 'create',
},
'ticket.priority_id' => {
'operator' => 'is',
'value' => Ticket::Priority.lookup(name: '2 normal').id.to_s,
},
},
perform: {
'ticket.priority_id' => {
'value' => Ticket::Priority.lookup(name: '3 high').id.to_s,
},
},
disable_notification: true,
active: true,
created_by_id: 1,
updated_by_id: 1,
)
trigger2 = Trigger.create!(
name: '2) set state to open',
condition: {
'ticket.action' => {
'operator' => 'is',
'value' => 'create',
},
'ticket.priority_id' => {
'operator' => 'is',
'value' => Ticket::Priority.lookup(name: '2 normal').id.to_s,
},
},
perform: {
'ticket.state_id' => {
'value' => Ticket::State.lookup(name: 'open').id.to_s,
},
},
disable_notification: true,
active: true,
created_by_id: 1,
updated_by_id: 1,
)
trigger3 = Trigger.create!(
name: '3) set state to closed',
condition: {
'ticket.action' => {
'operator' => 'is',
'value' => 'create',
},
'ticket.priority_id' => {
'operator' => 'is',
'value' => Ticket::Priority.lookup(name: '2 normal').id.to_s,
},
'ticket.state_id' => {
'operator' => 'is',
'value' => Ticket::State.lookup(name: 'open').id.to_s,
},
},
perform: {
'ticket.state_id' => {
'value' => Ticket::State.lookup(name: 'closed').id.to_s,
},
},
disable_notification: true,
active: true,
created_by_id: 1,
updated_by_id: 1,
)
email_raw_string = 'From: me@example.com
To: customer@example.com
Subject: some new subject
Some Text'
ticket_p, article_p, user_p, mail = Channel::EmailParser.new.process({}, email_raw_string)
assert_equal('some new subject', ticket_p.title)
assert_equal('Users', ticket_p.group.name)
assert_equal('3 high', ticket_p.priority.name)
assert_equal('new', ticket_p.state.name)
assert_equal(1, ticket_p.articles.count, 'ticket1.articles verify')
end
test 'recursive trigger - 2 trigger will trigger next trigger - case 1' do
trigger1 = Trigger.create!(
name: '1) set state to closed',
condition: {
'ticket.action' => {
'operator' => 'is',
'value' => 'create',
},
'ticket.priority_id' => {
'operator' => 'is',
'value' => Ticket::Priority.lookup(name: '3 high').id.to_s,
},
'ticket.state_id' => {
'operator' => 'is',
'value' => Ticket::State.lookup(name: 'open').id.to_s,
},
},
perform: {
'ticket.state_id' => {
'value' => Ticket::State.lookup(name: 'closed').id.to_s,
},
},
disable_notification: true,
active: true,
created_by_id: 1,
updated_by_id: 1,
)
trigger2 = Trigger.create!(
name: '2) set prio to 3 high',
condition: {
'ticket.action' => {
'operator' => 'is',
'value' => 'create',
},
'ticket.priority_id' => {
'operator' => 'is',
'value' => Ticket::Priority.lookup(name: '2 normal').id.to_s,
},
},
perform: {
'ticket.priority_id' => {
'value' => Ticket::Priority.lookup(name: '3 high').id.to_s,
},
},
disable_notification: true,
active: true,
created_by_id: 1,
updated_by_id: 1,
)
trigger3 = Trigger.create!(
name: '3) set state to open',
condition: {
'ticket.action' => {
'operator' => 'is',
'value' => 'create',
},
},
perform: {
'ticket.state_id' => {
'value' => Ticket::State.lookup(name: 'open').id.to_s,
},
},
disable_notification: true,
active: true,
created_by_id: 1,
updated_by_id: 1,
)
email_raw_string = 'From: me@example.com
To: customer@example.com
Subject: some new subject
Some Text'
ticket_p, article_p, user_p, mail = Channel::EmailParser.new.process({}, email_raw_string)
assert_equal('some new subject', ticket_p.title)
assert_equal('Users', ticket_p.group.name)
assert_equal('3 high', ticket_p.priority.name)
assert_equal('open', ticket_p.state.name)
assert_equal(1, ticket_p.articles.count, 'ticket1.articles verify')
end
test 'recursive trigger - 2 trigger will trigger next trigger - case 2' do
trigger1 = Trigger.create!(
name: '1) set prio to 3 high',
condition: {
'ticket.action' => {
'operator' => 'is',
'value' => 'create',
},
'ticket.priority_id' => {
'operator' => 'is',
'value' => Ticket::Priority.lookup(name: '2 normal').id.to_s,
},
'ticket.state_id' => {
'operator' => 'is',
'value' => Ticket::State.lookup(name: 'closed').id.to_s,
},
},
perform: {
'ticket.priority_id' => {
'value' => Ticket::Priority.lookup(name: '3 high').id.to_s,
},
},
disable_notification: true,
active: true,
created_by_id: 1,
updated_by_id: 1,
)
trigger2 = Trigger.create!(
name: '2) set state to closed',
condition: {
'ticket.action' => {
'operator' => 'is',
'value' => 'create',
},
'ticket.priority_id' => {
'operator' => 'is',
'value' => Ticket::Priority.lookup(name: '2 normal').id.to_s,
},
'ticket.state_id' => {
'operator' => 'is',
'value' => Ticket::State.lookup(name: 'open').id.to_s,
},
},
perform: {
'ticket.state_id' => {
'value' => Ticket::State.lookup(name: 'closed').id.to_s,
},
},
disable_notification: true,
active: true,
created_by_id: 1,
updated_by_id: 1,
)
trigger3 = Trigger.create!(
name: '3) set state to open',
condition: {
'ticket.action' => {
'operator' => 'is',
'value' => 'create',
},
},
perform: {
'ticket.state_id' => {
'value' => Ticket::State.lookup(name: 'open').id.to_s,
},
},
disable_notification: true,
active: true,
created_by_id: 1,
updated_by_id: 1,
)
email_raw_string = 'From: me@example.com
To: customer@example.com
Subject: some new subject
Some Text'
ticket_p, article_p, user_p, mail = Channel::EmailParser.new.process({}, email_raw_string)
assert_equal('some new subject', ticket_p.title)
assert_equal('Users', ticket_p.group.name)
assert_equal('2 normal', ticket_p.priority.name)
assert_equal('open', ticket_p.state.name)
assert_equal(1, ticket_p.articles.count, 'ticket1.articles verify')
end
test 'trigger based move and verify correct agent notifications' do
group1 = Group.create!(
name: 'Group 1',
active: true,
email_address: EmailAddress.first,
created_by_id: 1,
updated_by_id: 1,
)
group2 = Group.create!(
name: 'Group 2',
active: true,
email_address: EmailAddress.first,
created_by_id: 1,
updated_by_id: 1,
)
group3 = Group.create!(
name: 'Group 3',
active: true,
email_address: EmailAddress.first,
created_by_id: 1,
updated_by_id: 1,
)
roles = Role.where(name: 'Agent')
user1 = User.create!(
login: 'trigger1@example.org',
firstname: 'trigger1',
lastname: 'trigger1',
email: 'trigger1@example.org',
password: 'some_pass',
active: true,
groups: [group1],
roles: roles,
created_by_id: 1,
updated_by_id: 1,
)
user2 = User.create!(
login: 'trigger2@example.org',
firstname: 'trigger2',
lastname: 'trigger2',
email: 'trigger2@example.org',
password: 'some_pass',
active: true,
groups: [group2],
roles: roles,
created_by_id: 1,
updated_by_id: 1,
)
# trigger, move ticket created in group1 into group3 and then into group2
trigger1 = Trigger.create_or_update(
name: '1 dispatch',
condition: {
'ticket.action' => {
'operator' => 'is',
'value' => 'create',
},
'ticket.group_id' => {
'operator' => 'is',
'value' => group3.id.to_s,
},
'ticket.state_id' => {
'operator' => 'is',
'value' => Ticket::State.lookup(name: 'new').id.to_s,
},
},
perform: {
'ticket.group_id' => {
'value' => group2.id.to_s,
},
},
disable_notification: true,
active: true,
created_by_id: 1,
updated_by_id: 1,
)
trigger2 = Trigger.create_or_update(
name: '2 dispatch',
condition: {
'ticket.action' => {
'operator' => 'is',
'value' => 'create',
},
'ticket.state_id' => {
'operator' => 'is',
'value' => Ticket::State.lookup(name: 'new').id.to_s,
},
},
perform: {
'ticket.group_id' => {
'value' => group3.id.to_s,
},
},
disable_notification: true,
active: true,
created_by_id: 1,
updated_by_id: 1,
)
ticket1 = Ticket.create!(
title: '123',
group: group1,
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)
assert_equal(ticket1.title, '123')
assert_equal(ticket1.group.name, group1.name)
assert_equal(ticket1.state.name, 'new')
article_inbound1 = Ticket::Article.create!(
ticket_id: ticket1.id,
from: 'some_sender@example.com',
to: 'some_recipient@example.com',
subject: 'some subject',
message_id: 'some@id',
body: 'some message',
internal: false,
sender: Ticket::Article::Sender.find_by(name: 'Customer'),
type: Ticket::Article::Type.find_by(name: 'email'),
updated_by_id: 1,
created_by_id: 1,
)
# verfiy if agent1 got no notifcation
assert_equal(0, NotificationFactory::Mailer.already_sent?(ticket1, user1, 'email'), ticket1.id)
# verfiy if agent2 got no notifcation
assert_equal(0, NotificationFactory::Mailer.already_sent?(ticket1, user2, 'email'), ticket1.id)
Observer::Transaction.commit
Scheduler.worker(true)
ticket1.reload
assert_equal('123', ticket1.title)
assert_equal(group3.name, ticket1.group.name)
assert_equal('new', ticket1.state.name)
assert_equal('2 normal', ticket1.priority.name)
assert_equal(1, ticket1.articles.count)
# verfiy if agent1 got no notifcation
assert_equal(0, NotificationFactory::Mailer.already_sent?(ticket1, user1, 'email'), ticket1.id)
# verfiy if agent2 got notifcation
assert_equal(0, NotificationFactory::Mailer.already_sent?(ticket1, user2, 'email'), ticket1.id)
end
test 'recursive trigger loop check' do
trigger0 = Trigger.create!(
name: '000',
condition: {
'ticket.action' => {
'operator' => 'is',
'value' => 'create',
},
'ticket.priority_id' => {
'operator' => 'is',
'value' => Ticket::Priority.lookup(name: '1 low').id.to_s,
},
},
perform: {
'ticket.state_id' => {
'value' => Ticket::State.lookup(name: 'closed').id.to_s,
},
},
disable_notification: true,
active: true,
created_by_id: 1,
updated_by_id: 1,
)
trigger1 = Trigger.create!(
name: '001',
condition: {
'ticket.action' => {
'operator' => 'is',
'value' => 'create',
},
'ticket.priority_id' => {
'operator' => 'is',
'value' => Ticket::Priority.lookup(name: '3 high').id.to_s,
},
},
perform: {
'ticket.priority_id' => {
'value' => Ticket::Priority.lookup(name: '1 low').id.to_s,
},
},
disable_notification: true,
active: true,
created_by_id: 1,
updated_by_id: 1,
)
trigger2 = Trigger.create!(
name: '002',
condition: {
'ticket.action' => {
'operator' => 'is',
'value' => 'create',
},
'ticket.priority_id' => {
'operator' => 'is',
'value' => Ticket::Priority.lookup(name: '2 normal').id.to_s,
},
},
perform: {
'ticket.priority_id' => {
'value' => Ticket::Priority.lookup(name: '3 high').id.to_s,
},
},
disable_notification: true,
active: true,
created_by_id: 1,
updated_by_id: 1,
)
group1 = Group.find_by(name: 'Users')
ticket1 = Ticket.create!(
title: '123',
group: group1,
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)
assert_equal(ticket1.title, '123')
assert_equal(ticket1.group.name, group1.name)
assert_equal(ticket1.state.name, 'new')
article_inbound1 = Ticket::Article.create!(
ticket_id: ticket1.id,
from: 'some_sender@example.com',
to: 'some_recipient@example.com',
subject: 'some subject',
message_id: 'some@id',
body: 'some message',
internal: false,
sender: Ticket::Article::Sender.find_by(name: 'Customer'),
type: Ticket::Article::Type.find_by(name: 'email'),
updated_by_id: 1,
created_by_id: 1,
)
Observer::Transaction.commit
Scheduler.worker(true)
ticket1.reload
assert_equal('123', ticket1.title)
assert_equal('new', ticket1.state.name)
assert_equal('3 high', ticket1.priority.name)
assert_equal(1, ticket1.articles.count)
end
end

View file

@ -0,0 +1,718 @@
require 'test_helper'
class TicketTriggerExtendedTest < ActiveSupport::TestCase
setup do
Setting.set('ticket_trigger_recursive', true)
end
test 'recursive trigger' do
trigger1 = Trigger.create!(
name: '1) set prio to 3 high',
condition: {
'ticket.action' => {
'operator' => 'is',
'value' => 'create',
},
'ticket.state_id' => {
'operator' => 'is',
'value' => Ticket::State.lookup(name: 'new').id.to_s,
},
},
perform: {
'ticket.priority_id' => {
'value' => Ticket::Priority.lookup(name: '3 high').id.to_s,
},
},
disable_notification: true,
active: true,
created_by_id: 1,
updated_by_id: 1,
)
trigger2 = Trigger.create!(
name: '2) set state to closed',
condition: {
'ticket.action' => {
'operator' => 'is',
'value' => 'create',
},
'ticket.priority_id' => {
'operator' => 'is',
'value' => Ticket::Priority.lookup(name: '3 high').id.to_s,
},
},
perform: {
'ticket.state_id' => {
'value' => Ticket::State.lookup(name: 'closed').id.to_s,
},
},
disable_notification: true,
active: true,
created_by_id: 1,
updated_by_id: 1,
)
email_raw_string = 'From: me@example.com
To: customer@example.com
Subject: some new subject
Some Text'
ticket_p, article_p, user_p, mail = Channel::EmailParser.new.process({}, email_raw_string)
assert_equal('some new subject', ticket_p.title)
assert_equal('Users', ticket_p.group.name)
assert_equal('3 high', ticket_p.priority.name)
assert_equal('closed', ticket_p.state.name)
assert_equal(1, ticket_p.articles.count, 'ticket1.articles verify')
end
test 'recursive trigger - loop test' do
trigger1 = Trigger.create!(
name: '1) set prio to 3 high',
condition: {
'ticket.priority_id' => {
'operator' => 'is',
'value' => Ticket::Priority.lookup(name: '2 normal').id.to_s,
},
},
perform: {
'ticket.priority_id' => {
'value' => Ticket::Priority.lookup(name: '3 high').id.to_s,
},
'ticket.state_id' => {
'value' => Ticket::State.lookup(name: 'closed').id.to_s,
},
},
disable_notification: true,
active: true,
created_by_id: 1,
updated_by_id: 1,
)
trigger2 = Trigger.create!(
name: '2) set prio to 1 low',
condition: {
'ticket.priority_id' => {
'operator' => 'is',
'value' => Ticket::Priority.lookup(name: '3 high').id.to_s,
},
},
perform: {
'ticket.priority_id' => {
'value' => Ticket::Priority.lookup(name: '1 low').id.to_s,
},
'ticket.state_id' => {
'value' => Ticket::State.lookup(name: 'open').id.to_s,
},
},
disable_notification: true,
active: true,
created_by_id: 1,
updated_by_id: 1,
)
trigger3 = Trigger.create!(
name: '3) set prio to 3 high',
condition: {
'ticket.priority_id' => {
'operator' => 'is',
'value' => Ticket::Priority.lookup(name: '1 low').id.to_s,
},
},
perform: {
'ticket.priority_id' => {
'value' => Ticket::Priority.lookup(name: '2 normal').id.to_s,
},
},
disable_notification: true,
active: true,
created_by_id: 1,
updated_by_id: 1,
)
email_raw_string = 'From: me@example.com
To: customer@example.com
Subject: some new subject
Some Text'
ticket_p, article_p, user_p, mail = Channel::EmailParser.new.process({}, email_raw_string)
assert_equal('some new subject', ticket_p.title)
assert_equal('Users', ticket_p.group.name)
assert_equal('2 normal', ticket_p.priority.name)
assert_equal('open', ticket_p.state.name)
assert_equal(1, ticket_p.articles.count, 'ticket1.articles verify')
end
test 'recursive trigger - 2 trigger will not trigger next trigger' do
trigger1 = Trigger.create!(
name: '1) set prio to 3 high',
condition: {
'ticket.action' => {
'operator' => 'is',
'value' => 'create',
},
'ticket.priority_id' => {
'operator' => 'is',
'value' => Ticket::Priority.lookup(name: '2 normal').id.to_s,
},
},
perform: {
'ticket.priority_id' => {
'value' => Ticket::Priority.lookup(name: '3 high').id.to_s,
},
},
disable_notification: true,
active: true,
created_by_id: 1,
updated_by_id: 1,
)
trigger2 = Trigger.create!(
name: '2) set state to open',
condition: {
'ticket.action' => {
'operator' => 'is',
'value' => 'create',
},
'ticket.priority_id' => {
'operator' => 'is',
'value' => Ticket::Priority.lookup(name: '2 normal').id.to_s,
},
},
perform: {
'ticket.state_id' => {
'value' => Ticket::State.lookup(name: 'open').id.to_s,
},
},
disable_notification: true,
active: true,
created_by_id: 1,
updated_by_id: 1,
)
trigger3 = Trigger.create!(
name: '3) set state to closed',
condition: {
'ticket.action' => {
'operator' => 'is',
'value' => 'create',
},
'ticket.priority_id' => {
'operator' => 'is',
'value' => Ticket::Priority.lookup(name: '2 normal').id.to_s,
},
'ticket.state_id' => {
'operator' => 'is',
'value' => Ticket::State.lookup(name: 'open').id.to_s,
},
},
perform: {
'ticket.state_id' => {
'value' => Ticket::State.lookup(name: 'closed').id.to_s,
},
},
disable_notification: true,
active: true,
created_by_id: 1,
updated_by_id: 1,
)
email_raw_string = 'From: me@example.com
To: customer@example.com
Subject: some new subject
Some Text'
ticket_p, article_p, user_p, mail = Channel::EmailParser.new.process({}, email_raw_string)
assert_equal('some new subject', ticket_p.title)
assert_equal('Users', ticket_p.group.name)
assert_equal('3 high', ticket_p.priority.name)
assert_equal('new', ticket_p.state.name)
assert_equal(1, ticket_p.articles.count, 'ticket1.articles verify')
end
test 'recursive trigger - 2 trigger will trigger next trigger - case 1' do
trigger1 = Trigger.create!(
name: '1) set state to closed',
condition: {
'ticket.action' => {
'operator' => 'is',
'value' => 'create',
},
'ticket.priority_id' => {
'operator' => 'is',
'value' => Ticket::Priority.lookup(name: '3 high').id.to_s,
},
'ticket.state_id' => {
'operator' => 'is',
'value' => Ticket::State.lookup(name: 'open').id.to_s,
},
},
perform: {
'ticket.state_id' => {
'value' => Ticket::State.lookup(name: 'closed').id.to_s,
},
},
disable_notification: true,
active: true,
created_by_id: 1,
updated_by_id: 1,
)
trigger2 = Trigger.create!(
name: '2) set prio to 3 high',
condition: {
'ticket.action' => {
'operator' => 'is',
'value' => 'create',
},
'ticket.priority_id' => {
'operator' => 'is',
'value' => Ticket::Priority.lookup(name: '2 normal').id.to_s,
},
},
perform: {
'ticket.priority_id' => {
'value' => Ticket::Priority.lookup(name: '3 high').id.to_s,
},
},
disable_notification: true,
active: true,
created_by_id: 1,
updated_by_id: 1,
)
trigger3 = Trigger.create!(
name: '3) set state to open',
condition: {
'ticket.action' => {
'operator' => 'is',
'value' => 'create',
},
},
perform: {
'ticket.state_id' => {
'value' => Ticket::State.lookup(name: 'open').id.to_s,
},
},
disable_notification: true,
active: true,
created_by_id: 1,
updated_by_id: 1,
)
email_raw_string = 'From: me@example.com
To: customer@example.com
Subject: some new subject
Some Text'
ticket_p, article_p, user_p, mail = Channel::EmailParser.new.process({}, email_raw_string)
assert_equal('some new subject', ticket_p.title)
assert_equal('Users', ticket_p.group.name)
assert_equal('3 high', ticket_p.priority.name)
assert_equal('closed', ticket_p.state.name)
assert_equal(1, ticket_p.articles.count, 'ticket1.articles verify')
end
test 'recursive trigger - 2 trigger will trigger next trigger - case 2' do
trigger1 = Trigger.create!(
name: '1) set prio to 3 high',
condition: {
'ticket.action' => {
'operator' => 'is',
'value' => 'create',
},
'ticket.priority_id' => {
'operator' => 'is',
'value' => Ticket::Priority.lookup(name: '2 normal').id.to_s,
},
'ticket.state_id' => {
'operator' => 'is',
'value' => Ticket::State.lookup(name: 'closed').id.to_s,
},
},
perform: {
'ticket.priority_id' => {
'value' => Ticket::Priority.lookup(name: '3 high').id.to_s,
},
},
disable_notification: true,
active: true,
created_by_id: 1,
updated_by_id: 1,
)
trigger2 = Trigger.create!(
name: '2) set state to closed',
condition: {
'ticket.action' => {
'operator' => 'is',
'value' => 'create',
},
'ticket.priority_id' => {
'operator' => 'is',
'value' => Ticket::Priority.lookup(name: '2 normal').id.to_s,
},
'ticket.state_id' => {
'operator' => 'is',
'value' => Ticket::State.lookup(name: 'open').id.to_s,
},
},
perform: {
'ticket.state_id' => {
'value' => Ticket::State.lookup(name: 'closed').id.to_s,
},
},
disable_notification: true,
active: true,
created_by_id: 1,
updated_by_id: 1,
)
trigger3 = Trigger.create!(
name: '3) set state to open',
condition: {
'ticket.action' => {
'operator' => 'is',
'value' => 'create',
},
},
perform: {
'ticket.state_id' => {
'value' => Ticket::State.lookup(name: 'open').id.to_s,
},
},
disable_notification: true,
active: true,
created_by_id: 1,
updated_by_id: 1,
)
email_raw_string = 'From: me@example.com
To: customer@example.com
Subject: some new subject
Some Text'
ticket_p, article_p, user_p, mail = Channel::EmailParser.new.process({}, email_raw_string)
assert_equal('some new subject', ticket_p.title)
assert_equal('Users', ticket_p.group.name)
assert_equal('3 high', ticket_p.priority.name)
assert_equal('closed', ticket_p.state.name)
assert_equal(1, ticket_p.articles.count, 'ticket1.articles verify')
end
test 'trigger based move and verify correct agent notifications' do
group1 = Group.create!(
name: 'Group 1',
active: true,
email_address: EmailAddress.first,
created_by_id: 1,
updated_by_id: 1,
)
group2 = Group.create!(
name: 'Group 2',
active: true,
email_address: EmailAddress.first,
created_by_id: 1,
updated_by_id: 1,
)
group3 = Group.create!(
name: 'Group 3',
active: true,
email_address: EmailAddress.first,
created_by_id: 1,
updated_by_id: 1,
)
roles = Role.where(name: 'Agent')
user1 = User.create!(
login: 'trigger1@example.org',
firstname: 'trigger1',
lastname: 'trigger1',
email: 'trigger1@example.org',
password: 'some_pass',
active: true,
groups: [group1],
roles: roles,
created_by_id: 1,
updated_by_id: 1,
)
user2 = User.create!(
login: 'trigger2@example.org',
firstname: 'trigger2',
lastname: 'trigger2',
email: 'trigger2@example.org',
password: 'some_pass',
active: true,
groups: [group2],
roles: roles,
created_by_id: 1,
updated_by_id: 1,
)
# trigger, move ticket created in group1 into group3 and then into group2
trigger1 = Trigger.create_or_update(
name: '1 dispatch',
condition: {
'ticket.action' => {
'operator' => 'is',
'value' => 'create',
},
'ticket.group_id' => {
'operator' => 'is',
'value' => group3.id.to_s,
},
'ticket.state_id' => {
'operator' => 'is',
'value' => Ticket::State.lookup(name: 'new').id.to_s,
},
},
perform: {
'ticket.group_id' => {
'value' => group2.id.to_s,
},
},
disable_notification: true,
active: true,
created_by_id: 1,
updated_by_id: 1,
)
trigger2 = Trigger.create_or_update(
name: '2 dispatch',
condition: {
'ticket.action' => {
'operator' => 'is',
'value' => 'create',
},
'ticket.state_id' => {
'operator' => 'is',
'value' => Ticket::State.lookup(name: 'new').id.to_s,
},
},
perform: {
'ticket.group_id' => {
'value' => group3.id.to_s,
},
},
disable_notification: true,
active: true,
created_by_id: 1,
updated_by_id: 1,
)
ticket1 = Ticket.create!(
title: '123',
group: group1,
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)
assert_equal(ticket1.title, '123')
assert_equal(ticket1.group.name, group1.name)
assert_equal(ticket1.state.name, 'new')
article_inbound1 = Ticket::Article.create!(
ticket_id: ticket1.id,
from: 'some_sender@example.com',
to: 'some_recipient@example.com',
subject: 'some subject',
message_id: 'some@id',
body: 'some message',
internal: false,
sender: Ticket::Article::Sender.find_by(name: 'Customer'),
type: Ticket::Article::Type.find_by(name: 'email'),
updated_by_id: 1,
created_by_id: 1,
)
# verfiy if agent1 got no notifcation
assert_equal(0, NotificationFactory::Mailer.already_sent?(ticket1, user1, 'email'), ticket1.id)
# verfiy if agent2 got no notifcation
assert_equal(0, NotificationFactory::Mailer.already_sent?(ticket1, user2, 'email'), ticket1.id)
Observer::Transaction.commit
Scheduler.worker(true)
ticket1.reload
assert_equal('123', ticket1.title)
assert_equal(group2.name, ticket1.group.name)
assert_equal('new', ticket1.state.name)
assert_equal('2 normal', ticket1.priority.name)
assert_equal(1, ticket1.articles.count)
# verfiy if agent1 got no notifcation
assert_equal(0, NotificationFactory::Mailer.already_sent?(ticket1, user1, 'email'), ticket1.id)
# verfiy if agent2 got notifcation
assert_equal(1, NotificationFactory::Mailer.already_sent?(ticket1, user2, 'email'), ticket1.id)
end
test 'recursive trigger loop check' do
Setting.set('ticket_trigger_recursive_max_loop', 2)
trigger0 = Trigger.create!(
name: '000',
condition: {
'ticket.action' => {
'operator' => 'is',
'value' => 'create',
},
'ticket.priority_id' => {
'operator' => 'is',
'value' => Ticket::Priority.lookup(name: '1 low').id.to_s,
},
},
perform: {
'ticket.state_id' => {
'value' => Ticket::State.lookup(name: 'closed').id.to_s,
},
},
disable_notification: true,
active: true,
created_by_id: 1,
updated_by_id: 1,
)
trigger1 = Trigger.create!(
name: '001',
condition: {
'ticket.action' => {
'operator' => 'is',
'value' => 'create',
},
'ticket.priority_id' => {
'operator' => 'is',
'value' => Ticket::Priority.lookup(name: '3 high').id.to_s,
},
},
perform: {
'ticket.priority_id' => {
'value' => Ticket::Priority.lookup(name: '1 low').id.to_s,
},
},
disable_notification: true,
active: true,
created_by_id: 1,
updated_by_id: 1,
)
trigger2 = Trigger.create!(
name: '002',
condition: {
'ticket.action' => {
'operator' => 'is',
'value' => 'create',
},
'ticket.priority_id' => {
'operator' => 'is',
'value' => Ticket::Priority.lookup(name: '2 normal').id.to_s,
},
},
perform: {
'ticket.priority_id' => {
'value' => Ticket::Priority.lookup(name: '3 high').id.to_s,
},
},
disable_notification: true,
active: true,
created_by_id: 1,
updated_by_id: 1,
)
group1 = Group.find_by(name: 'Users')
ticket1 = Ticket.create!(
title: '123',
group: group1,
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)
assert_equal(ticket1.title, '123')
assert_equal(ticket1.group.name, group1.name)
assert_equal(ticket1.state.name, 'new')
article_inbound1 = Ticket::Article.create!(
ticket_id: ticket1.id,
from: 'some_sender@example.com',
to: 'some_recipient@example.com',
subject: 'some subject',
message_id: 'some@id',
body: 'some message',
internal: false,
sender: Ticket::Article::Sender.find_by(name: 'Customer'),
type: Ticket::Article::Type.find_by(name: 'email'),
updated_by_id: 1,
created_by_id: 1,
)
Observer::Transaction.commit
Scheduler.worker(true)
ticket1.reload
assert_equal('123', ticket1.title)
assert_equal('new', ticket1.state.name)
assert_equal('1 low', ticket1.priority.name)
assert_equal(1, ticket1.articles.count)
Setting.set('ticket_trigger_recursive_max_loop', 3)
ticket1 = Ticket.create!(
title: '123',
group: group1,
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)
assert_equal(ticket1.title, '123')
assert_equal(ticket1.group.name, group1.name)
assert_equal(ticket1.state.name, 'new')
article_inbound1 = Ticket::Article.create!(
ticket_id: ticket1.id,
from: 'some_sender@example.com',
to: 'some_recipient@example.com',
subject: 'some subject',
message_id: 'some@id',
body: 'some message',
internal: false,
sender: Ticket::Article::Sender.find_by(name: 'Customer'),
type: Ticket::Article::Type.find_by(name: 'email'),
updated_by_id: 1,
created_by_id: 1,
)
Observer::Transaction.commit
Scheduler.worker(true)
ticket1.reload
assert_equal('123', ticket1.title)
assert_equal('closed', ticket1.state.name)
assert_equal('1 low', ticket1.priority.name)
assert_equal(1, ticket1.articles.count)
end
end

File diff suppressed because it is too large Load diff

View file

@ -1,6 +1,11 @@
require 'test_helper' require 'test_helper'
class TicketTriggerTest < ActiveSupport::TestCase class TicketTriggerTest < ActiveSupport::TestCase
setup do
Setting.set('ticket_trigger_recursive', true)
end
test '1 basic' do test '1 basic' do
trigger1 = Trigger.create_or_update( trigger1 = Trigger.create_or_update(
name: 'aaa loop check', name: 'aaa loop check',
@ -18,7 +23,7 @@ class TicketTriggerTest < ActiveSupport::TestCase
'notification.email' => { 'notification.email' => {
'body' => 'some lala', 'body' => 'some lala',
'recipient' => 'ticket_customer', 'recipient' => 'ticket_customer',
'subject' => 'Thanks for your inquiry - loop check (#{ticket.title})!', 'subject' => 'Thanks for your inquiry - loop check - only once (#{ticket.title})!',
}, },
}, },
disable_notification: true, disable_notification: true,
@ -186,9 +191,10 @@ class TicketTriggerTest < ActiveSupport::TestCase
assert_equal('Users', ticket1.group.name, 'ticket1.group verify') assert_equal('Users', ticket1.group.name, 'ticket1.group verify')
assert_equal('new', ticket1.state.name, 'ticket1.state verify') assert_equal('new', ticket1.state.name, 'ticket1.state verify')
assert_equal('3 high', ticket1.priority.name, 'ticket1.priority verify') assert_equal('3 high', ticket1.priority.name, 'ticket1.priority verify')
assert_equal(2, ticket1.articles.count, 'ticket1.articles verify') assert_equal(3, ticket1.articles.count, 'ticket1.articles verify')
assert_equal(%w[aa kk abc], ticket1.tag_list) assert_equal(%w[aa kk should_not_loop abc], ticket1.tag_list)
article1 = ticket1.articles.last
article1 = ticket1.articles.second
assert_match('Zammad <zammad@localhost>', article1.from) assert_match('Zammad <zammad@localhost>', article1.from)
assert_match('nicole.braun@zammad.org', article1.to) assert_match('nicole.braun@zammad.org', article1.to)
assert_match('Thanks for your inquiry (some <b>title</b> äöüß)!', article1.subject) assert_match('Thanks for your inquiry (some <b>title</b> äöüß)!', article1.subject)
@ -196,6 +202,13 @@ class TicketTriggerTest < ActiveSupport::TestCase
assert_match('&gt; some message &lt;b&gt;note&lt;/b&gt;<br>&gt; new line', article1.body) assert_match('&gt; some message &lt;b&gt;note&lt;/b&gt;<br>&gt; new line', article1.body)
assert_equal('text/html', article1.content_type) assert_equal('text/html', article1.content_type)
article1 = ticket1.articles.last
assert_match('Zammad <zammad@localhost>', article1.from)
assert_match('nicole.braun@zammad.org', article1.to)
assert_match('Thanks for your inquiry - loop check - only once (some <b>title</b> äöüß)!', article1.subject)
assert_match('some lala', article1.body)
assert_equal('text/html', article1.content_type)
ticket1.priority = Ticket::Priority.lookup(name: '2 normal') ticket1.priority = Ticket::Priority.lookup(name: '2 normal')
ticket1.save! ticket1.save!
Observer::Transaction.commit Observer::Transaction.commit
@ -205,8 +218,8 @@ class TicketTriggerTest < ActiveSupport::TestCase
assert_equal('Users', ticket1.group.name, 'ticket1.group verify') assert_equal('Users', ticket1.group.name, 'ticket1.group verify')
assert_equal('new', ticket1.state.name, 'ticket1.state verify') assert_equal('new', ticket1.state.name, 'ticket1.state verify')
assert_equal('2 normal', ticket1.priority.name, 'ticket1.priority verify') assert_equal('2 normal', ticket1.priority.name, 'ticket1.priority verify')
assert_equal(2, ticket1.articles.count, 'ticket1.articles verify') assert_equal(3, ticket1.articles.count, 'ticket1.articles verify')
assert_equal(%w[aa kk abc], ticket1.tag_list) assert_equal(%w[aa kk should_not_loop abc], ticket1.tag_list)
ticket1.state = Ticket::State.lookup(name: 'open') ticket1.state = Ticket::State.lookup(name: 'open')
ticket1.save! ticket1.save!
@ -218,8 +231,8 @@ class TicketTriggerTest < ActiveSupport::TestCase
assert_equal('Users', ticket1.group.name, 'ticket1.group verify') assert_equal('Users', ticket1.group.name, 'ticket1.group verify')
assert_equal('open', ticket1.state.name, 'ticket1.state verify') assert_equal('open', ticket1.state.name, 'ticket1.state verify')
assert_equal('2 normal', ticket1.priority.name, 'ticket1.priority verify') assert_equal('2 normal', ticket1.priority.name, 'ticket1.priority verify')
assert_equal(2, ticket1.articles.count, 'ticket1.articles verify') assert_equal(3, ticket1.articles.count, 'ticket1.articles verify')
assert_equal(%w[aa kk abc], ticket1.tag_list) assert_equal(%w[aa kk should_not_loop abc], ticket1.tag_list)
ticket1.state = Ticket::State.lookup(name: 'new') ticket1.state = Ticket::State.lookup(name: 'new')
ticket1.save! ticket1.save!
@ -231,8 +244,8 @@ class TicketTriggerTest < ActiveSupport::TestCase
assert_equal('Users', ticket1.group.name, 'ticket1.group verify') assert_equal('Users', ticket1.group.name, 'ticket1.group verify')
assert_equal('new', ticket1.state.name, 'ticket1.state verify') assert_equal('new', ticket1.state.name, 'ticket1.state verify')
assert_equal('3 high', ticket1.priority.name, 'ticket1.priority verify') assert_equal('3 high', ticket1.priority.name, 'ticket1.priority verify')
assert_equal(2, ticket1.articles.count, 'ticket1.articles verify') assert_equal(3, ticket1.articles.count, 'ticket1.articles verify')
assert_equal(%w[aa abc], ticket1.tag_list) assert_equal(%w[aa should_not_loop abc], ticket1.tag_list)
ticket2 = Ticket.create!( ticket2 = Ticket.create!(
title: "some title\n äöüß", title: "some title\n äöüß",
@ -299,8 +312,8 @@ class TicketTriggerTest < ActiveSupport::TestCase
assert_equal('Users', ticket3.group.name, 'ticket3.group verify') assert_equal('Users', ticket3.group.name, 'ticket3.group verify')
assert_equal('new', ticket3.state.name, 'ticket3.state verify') assert_equal('new', ticket3.state.name, 'ticket3.state verify')
assert_equal('3 high', ticket3.priority.name, 'ticket3.priority verify') assert_equal('3 high', ticket3.priority.name, 'ticket3.priority verify')
assert_equal(3, ticket3.articles.count, 'ticket3.articles verify') assert_equal(4, ticket3.articles.count, 'ticket3.articles verify')
assert_equal(%w[aa kk abc article_create_trigger], ticket3.tag_list) assert_equal(%w[aa kk should_not_loop abc article_create_trigger], ticket3.tag_list)
article3 = ticket3.articles[1] article3 = ticket3.articles[1]
assert_match('Zammad <zammad@localhost>', article3.from) assert_match('Zammad <zammad@localhost>', article3.from)
assert_match('nicole.braun@zammad.org', article3.to) assert_match('nicole.braun@zammad.org', article3.to)
@ -312,8 +325,14 @@ class TicketTriggerTest < ActiveSupport::TestCase
article3 = ticket3.articles[2] article3 = ticket3.articles[2]
assert_match('Zammad <zammad@localhost>', article3.from) assert_match('Zammad <zammad@localhost>', article3.from)
assert_match('nicole.braun@zammad.org', article3.to) assert_match('nicole.braun@zammad.org', article3.to)
assert_match('Thanks for your inquiry - 1234 check (some <b>title</b> äöüß3)!', article3.subject) assert_match('Thanks for your inquiry - loop check - only once (some <b>title</b>', article3.subject)
assert_match('some lala', article3.body)
assert_equal('text/html', article3.content_type) assert_equal('text/html', article3.content_type)
article4 = ticket3.articles[3]
assert_match('Zammad <zammad@localhost>', article4.from)
assert_match('nicole.braun@zammad.org', article4.to)
assert_match('Thanks for your inquiry - 1234 check (some <b>title</b> äöüß3)!', article4.subject)
assert_equal('text/html', article4.content_type)
Ticket::Article.create!( Ticket::Article.create!(
ticket_id: ticket3.id, ticket_id: ticket3.id,
@ -337,8 +356,8 @@ class TicketTriggerTest < ActiveSupport::TestCase
assert_equal('Users', ticket3.group.name, 'ticket3.group verify') assert_equal('Users', ticket3.group.name, 'ticket3.group verify')
assert_equal('new', ticket3.state.name, 'ticket3.state verify') assert_equal('new', ticket3.state.name, 'ticket3.state verify')
assert_equal('3 high', ticket3.priority.name, 'ticket3.priority verify') assert_equal('3 high', ticket3.priority.name, 'ticket3.priority verify')
assert_equal(4, ticket3.articles.count, 'ticket3.articles verify') assert_equal(5, ticket3.articles.count, 'ticket3.articles verify')
assert_equal(%w[aa abc article_create_trigger], ticket3.tag_list) assert_equal(%w[aa should_not_loop abc article_create_trigger], ticket3.tag_list)
Ticket::Article.create!( Ticket::Article.create!(
ticket_id: ticket3.id, ticket_id: ticket3.id,
@ -362,8 +381,8 @@ class TicketTriggerTest < ActiveSupport::TestCase
assert_equal('Users', ticket3.group.name, 'ticket3.group verify') assert_equal('Users', ticket3.group.name, 'ticket3.group verify')
assert_equal('new', ticket3.state.name, 'ticket3.state verify') assert_equal('new', ticket3.state.name, 'ticket3.state verify')
assert_equal('3 high', ticket3.priority.name, 'ticket3.priority verify') assert_equal('3 high', ticket3.priority.name, 'ticket3.priority verify')
assert_equal(5, ticket3.articles.count, 'ticket3.articles verify') assert_equal(6, ticket3.articles.count, 'ticket3.articles verify')
assert_equal(%w[aa abc article_create_trigger], ticket3.tag_list) assert_equal(%w[aa should_not_loop abc article_create_trigger], ticket3.tag_list)
Ticket::Article.create!( Ticket::Article.create!(
ticket_id: ticket3.id, ticket_id: ticket3.id,
@ -387,8 +406,8 @@ class TicketTriggerTest < ActiveSupport::TestCase
assert_equal('Users', ticket3.group.name, 'ticket3.group verify') assert_equal('Users', ticket3.group.name, 'ticket3.group verify')
assert_equal('new', ticket3.state.name, 'ticket3.state verify') assert_equal('new', ticket3.state.name, 'ticket3.state verify')
assert_equal('3 high', ticket3.priority.name, 'ticket3.priority verify') assert_equal('3 high', ticket3.priority.name, 'ticket3.priority verify')
assert_equal(7, ticket3.articles.count, 'ticket3.articles verify') assert_equal(9, ticket3.articles.count, 'ticket3.articles verify')
assert_equal(%w[aa abc article_create_trigger], ticket3.tag_list) assert_equal(%w[aa should_not_loop abc article_create_trigger], ticket3.tag_list)
end end
test '2 actions - create' do test '2 actions - create' do
@ -829,24 +848,35 @@ class TicketTriggerTest < ActiveSupport::TestCase
# process mail without Precedence header # process mail without Precedence header
content = IO.binread('test/fixtures/ticket_trigger/mail1.box') content = IO.binread('test/fixtures/ticket_trigger/mail1.box')
ticket_p, article_p, user_p, mail = Channel::EmailParser.new.process({}, content) ticket_p1, article_p1, user_p1, mail = Channel::EmailParser.new.process({}, content)
assert_equal('new', ticket_p.state.name) assert_not_equal(ticket_p.id, ticket_p1.id)
assert_equal(2, ticket_p.articles.count) assert_equal('new', ticket_p1.state.name)
assert_equal(2, ticket_p1.articles.count)
# process mail with Precedence header (no auto response) # process mail with Precedence header (no auto response)
content = IO.binread('test/fixtures/ticket_trigger/mail2.box') content = IO.binread('test/fixtures/ticket_trigger/mail2.box')
ticket_p, article_p, user_p, mail = Channel::EmailParser.new.process({}, content) ticket_p2, article_p2, user_p2, mail = Channel::EmailParser.new.process({}, content)
assert_equal('new', ticket_p.state.name) assert_not_equal(ticket_p.id, ticket_p1.id)
assert_equal(1, ticket_p.articles.count) assert_not_equal(ticket_p.id, ticket_p2.id)
assert_not_equal(ticket_p1.id, ticket_p2.id)
assert_equal('new', ticket_p2.state.name)
assert_equal(1, ticket_p2.articles.count)
# process mail with abuse@ (no auto response) # process mail with abuse@ (no auto response)
content = IO.binread('test/fixtures/ticket_trigger/mail3.box') content = IO.binread('test/fixtures/ticket_trigger/mail3.box')
ticket_p, article_p, user_p, mail = Channel::EmailParser.new.process({}, content) ticket_p3, article_p3, user_p3, mail = Channel::EmailParser.new.process({}, content)
assert_equal('new', ticket_p.state.name) assert_not_equal(ticket_p.id, ticket_p1.id)
assert_equal(1, ticket_p.articles.count) assert_not_equal(ticket_p.id, ticket_p2.id)
assert_not_equal(ticket_p.id, ticket_p3.id)
assert_not_equal(ticket_p1.id, ticket_p2.id)
assert_not_equal(ticket_p1.id, ticket_p3.id)
assert_not_equal(ticket_p2.id, ticket_p1.id)
assert_not_equal(ticket_p2.id, ticket_p3.id)
assert_equal('new', ticket_p3.state.name)
assert_equal(1, ticket_p3.articles.count)
end end
test '4 has changed' do test '4 has changed' do