# rubocop:disable all require 'test_helper' class EmailPostmasterTest < ActiveSupport::TestCase test 'valid/invalid postmaster filter' do PostmasterFilter.create!( name: 'not used', match: { from: { operator: 'contains', value: 'nobody@example.com', }, }, perform: { 'X-Zammad-Ticket-priority' => { value: '3 high', }, }, channel: 'email', active: true, created_by_id: 1, updated_by_id: 1, ) assert_raises(Exceptions::UnprocessableEntity) { PostmasterFilter.create!( name: 'empty filter should not work', match: {}, perform: { 'X-Zammad-Ticket-priority' => { value: '3 high', }, }, channel: 'email', active: true, created_by_id: 1, updated_by_id: 1, ) } assert_raises(Exceptions::UnprocessableEntity) { PostmasterFilter.create!( name: 'empty filter should not work', match: { from: { operator: 'contains', value: '', }, }, perform: { 'X-Zammad-Ticket-priority' => { value: '3 high', }, }, channel: 'email', active: true, created_by_id: 1, updated_by_id: 1, ) } assert_raises(Exceptions::UnprocessableEntity) { PostmasterFilter.create!( name: 'invalid regex', match: { from: { operator: 'contains', value: 'regex:[]', }, }, perform: { 'X-Zammad-Ticket-priority' => { value: '3 high', }, }, channel: 'email', active: true, created_by_id: 1, updated_by_id: 1, ) } assert_raises(Exceptions::UnprocessableEntity) { PostmasterFilter.create!( name: 'invalid regex', match: { from: { operator: 'contains', value: 'regex:??', }, }, perform: { 'X-Zammad-Ticket-priority' => { value: '3 high', }, }, channel: 'email', active: true, created_by_id: 1, updated_by_id: 1, ) } assert_raises(Exceptions::UnprocessableEntity) { PostmasterFilter.create!( name: 'invalid regex', match: { from: { operator: 'contains', value: 'regex:*', }, }, perform: { 'X-Zammad-Ticket-priority' => { value: '3 high', }, }, channel: 'email', active: true, created_by_id: 1, updated_by_id: 1, ) } PostmasterFilter.create!( name: 'use .*', match: { from: { operator: 'contains', value: '*', }, }, perform: { 'X-Zammad-Ticket-priority' => { value: '3 high', }, }, channel: 'email', active: true, created_by_id: 1, updated_by_id: 1, ) end test 'process with postmaster filter with regex' do group_default = Group.lookup(name: 'Users') group1 = Group.create_if_not_exists( name: 'Test Group1', created_by_id: 1, updated_by_id: 1, ) group2 = Group.create_if_not_exists( name: 'Test Group2', created_by_id: 1, updated_by_id: 1, ) PostmasterFilter.destroy_all PostmasterFilter.create!( name: 'used - empty selector', match: { from: { operator: 'contains', value: 'regex:.*', }, }, perform: { 'X-Zammad-Ticket-group_id' => { value: group2.id, }, 'X-Zammad-Ticket-priority_id' => { value: '1', }, 'x-Zammad-Article-Internal' => { value: true, }, }, channel: 'email', active: true, created_by_id: 1, updated_by_id: 1, ) data = 'From: Some Body To: Bob Cc: any@example.com Subject: some subject - no selector Some Text' parser = Channel::EmailParser.new ticket, article, user = parser.process({ group_id: group_default.id, trusted: false }, data) assert_equal('Test Group2', ticket.group.name) assert_equal('1 low', ticket.priority.name) assert_equal('some subject - no selector', ticket.title) assert_equal('Customer', article.sender.name) assert_equal('email', article.type.name) assert_equal(true, article.internal) PostmasterFilter.destroy_all PostmasterFilter.create!( name: 'used - empty selector', match: { from: { operator: 'contains', value: '*', }, }, perform: { 'X-Zammad-Ticket-group_id' => { value: group2.id, }, 'X-Zammad-Ticket-priority_id' => { value: '1', }, 'x-Zammad-Article-Internal' => { value: true, }, }, channel: 'email', active: true, created_by_id: 1, updated_by_id: 1, ) data = 'From: Some Body To: Bob Cc: any@example.com Subject: some subject - no selector Some Text' parser = Channel::EmailParser.new ticket, article, user = parser.process({ group_id: group_default.id, trusted: false }, data) assert_equal('Test Group2', ticket.group.name) assert_equal('1 low', ticket.priority.name) assert_equal('some subject - no selector', ticket.title) assert_equal('Customer', article.sender.name) assert_equal('email', article.type.name) assert_equal(true, article.internal) PostmasterFilter.destroy_all PostmasterFilter.create!( name: 'used - empty selector', match: { subject: { operator: 'contains', value: '*me*', }, }, perform: { 'X-Zammad-Ticket-group_id' => { value: group2.id, }, 'X-Zammad-Ticket-priority_id' => { value: '1', }, 'x-Zammad-Article-Internal' => { value: true, }, }, channel: 'email', active: true, created_by_id: 1, updated_by_id: 1, ) data = 'From: Some Body To: Bob Cc: any@example.com Subject: *me* Some Text' parser = Channel::EmailParser.new ticket, article, user = parser.process({ group_id: group_default.id, trusted: false }, data) assert_equal('Test Group2', ticket.group.name) assert_equal('1 low', ticket.priority.name) assert_equal('*me*', ticket.title) assert_equal('Customer', article.sender.name) assert_equal('email', article.type.name) assert_equal(true, article.internal) PostmasterFilter.destroy_all PostmasterFilter.create!( name: 'used - empty selector', match: { subject: { operator: 'contains not', value: '*me*', }, }, perform: { 'X-Zammad-Ticket-group_id' => { value: group2.id, }, 'X-Zammad-Ticket-priority_id' => { value: '1', }, 'x-Zammad-Article-Internal' => { value: true, }, }, channel: 'email', active: true, created_by_id: 1, updated_by_id: 1, ) data = 'From: Some Body To: Bob Cc: any@example.com Subject: *mo* Some Text' parser = Channel::EmailParser.new ticket, article, user = parser.process({ group_id: group_default.id, trusted: false }, data) assert_equal('Test Group2', ticket.group.name) assert_equal('1 low', ticket.priority.name) assert_equal('*mo*', ticket.title) assert_equal('Customer', article.sender.name) assert_equal('email', article.type.name) assert_equal(true, article.internal) PostmasterFilter.destroy_all PostmasterFilter.create!( name: 'used - empty selector', match: { subject: { operator: 'contains not', value: '*me*', }, }, perform: { 'X-Zammad-Ticket-group_id' => { value: group2.id, }, 'X-Zammad-Ticket-priority_id' => { value: '1', }, 'x-Zammad-Article-Internal' => { value: true, }, }, channel: 'email', active: true, created_by_id: 1, updated_by_id: 1, ) data = 'From: Some Body To: Bob Cc: any@example.com Subject: *me* Some Text' parser = Channel::EmailParser.new ticket, article, user = parser.process({ group_id: group_default.id, trusted: false }, data) assert_equal('Users', ticket.group.name) assert_equal('2 normal', ticket.priority.name) assert_equal('*me*', ticket.title) assert_equal('Customer', article.sender.name) assert_equal('email', article.type.name) assert_equal(false, article.internal) PostmasterFilter.destroy_all end test 'process with postmaster filter' do group_default = Group.lookup(name: 'Users') group1 = Group.create_if_not_exists( name: 'Test Group1', created_by_id: 1, updated_by_id: 1, ) group2 = Group.create_if_not_exists( name: 'Test Group2', created_by_id: 1, updated_by_id: 1, ) PostmasterFilter.destroy_all PostmasterFilter.create!( name: 'not used', match: { from: { operator: 'contains', value: 'nobody@example.com', }, }, perform: { 'X-Zammad-Ticket-priority' => { value: '3 high', }, }, channel: 'email', active: true, created_by_id: 1, updated_by_id: 1, ) PostmasterFilter.create!( name: 'used', match: { from: { operator: 'contains', value: 'me@example.com', }, }, perform: { 'X-Zammad-Ticket-group_id' => { value: group1.id, }, 'x-Zammad-Article-Internal' => { value: true, }, }, channel: 'email', active: true, created_by_id: 1, updated_by_id: 1, ) PostmasterFilter.create!( name: 'used x-any-recipient', match: { 'x-any-recipient' => { operator: 'contains', value: 'any@example.com', }, }, perform: { 'X-Zammad-Ticket-group_id' => { value: group2.id, }, 'x-Zammad-Article-Internal' => { value: true, }, }, channel: 'email', active: true, created_by_id: 1, updated_by_id: 1, ) data = 'From: me@example.com To: customer@example.com Subject: some subject Some Text' parser = Channel::EmailParser.new ticket, article, user = parser.process({ group_id: group_default.id, trusted: false }, data) assert_equal('Test Group1', ticket.group.name) assert_equal('2 normal', ticket.priority.name) assert_equal('some subject', ticket.title) assert_equal('Customer', article.sender.name) assert_equal('email', article.type.name) assert_equal(true, article.internal) data = 'From: Some Body To: Bob Cc: any@example.com Subject: some subject Some Text' parser = Channel::EmailParser.new ticket, article, user = parser.process({ group_id: group_default.id, trusted: false }, data) assert_equal('Test Group2', ticket.group.name) assert_equal('2 normal', ticket.priority.name) assert_equal('some subject', ticket.title) assert_equal('Customer', article.sender.name) assert_equal('email', article.type.name) assert_equal(true, article.internal) PostmasterFilter.create!( name: 'used x-any-recipient 2', match: { 'x-any-recipient' => { operator: 'contains not', value: 'any_not@example.com', }, }, perform: { 'X-Zammad-Ticket-group_id' => { value: group2.id, }, 'X-Zammad-Ticket-priority_id' => { value: '1', }, 'x-Zammad-Article-Internal' => { value: 'false', }, }, channel: 'email', active: true, created_by_id: 1, updated_by_id: 1, ) data = 'From: Some Body To: Bob Cc: any@example.com Subject: some subject2 Some Text' parser = Channel::EmailParser.new ticket, article, user = parser.process({ group_id: group_default.id, trusted: false }, data) assert_equal('Test Group2', ticket.group.name) assert_equal('1 low', ticket.priority.name) assert_equal('some subject2', ticket.title) assert_equal('Customer', article.sender.name) assert_equal('email', article.type.name) assert_equal(false, article.internal) PostmasterFilter.destroy_all # follow up with create post master filter test PostmasterFilter.create!( name: 'used - empty selector', match: { from: { operator: 'contains', value: 'example.com', }, }, perform: { 'X-Zammad-Ticket-group_id' => { value: group2.id, }, }, channel: 'email', active: true, created_by_id: 1, updated_by_id: 1, ) data = 'From: Some Body To: Bob Cc: any@example.com Subject: follow up with create post master filter test Some Text' parser = Channel::EmailParser.new ticket, article, user = parser.process({ group_id: group_default.id, trusted: false }, data) assert_equal(group2.name, ticket.group.name) assert_equal('2 normal', ticket.priority.name) assert_equal('follow up with create post master filter test', ticket.title) assert_equal('Customer', article.sender.name) assert_equal('email', article.type.name) assert_equal(false, article.internal) # move ticket ticket.group = group1 ticket.save Observer::Transaction.commit data = "From: me@example.com To: customer@example.com Subject: #{ticket.subject_build('some new subject')} Some Text" article_count = ticket.articles.count parser = Channel::EmailParser.new ticket_followup, article, user = parser.process({ group_id: group_default.id, trusted: false }, data) # check if group is still the old one assert_equal(ticket.id, ticket_followup.id) assert_equal(group1.name, ticket_followup.group.name) assert_equal(group1.name, ticket_followup.group.name) assert_equal('2 normal', ticket_followup.priority.name) assert_equal('follow up with create post master filter test', ticket_followup.title) assert_equal('Customer', article.sender.name) assert_equal('email', article.type.name) assert_equal(false, article.internal) assert_equal(article_count+1, ticket_followup.articles.count) PostmasterFilter.destroy_all PostmasterFilter.create!( name: 'used', match: { from: { operator: 'contains', value: 'me@example.com', }, }, perform: { 'X-Zammad-Ticket-group_id' => { value: group1.id, }, 'x-Zammad-Article-Internal' => { value: true, }, 'x-Zammad-Ticket-customer_id' => { value: '', value_completion: '', }, }, channel: 'email', active: true, created_by_id: 1, updated_by_id: 1, ) data = 'From: ME Bob To: customer@example.com Subject: some subject Some Text' parser = Channel::EmailParser.new ticket, article, user = parser.process({ group_id: group_default.id, trusted: false }, data) assert_equal(group1.name, ticket.group.name) assert_equal('2 normal', ticket.priority.name) assert_equal('some subject', ticket.title) assert_equal('me@example.com', ticket.customer.email) PostmasterFilter.destroy_all PostmasterFilter.create!( name: 'used', match: { from: { operator: 'contains', value: 'me@example.com', }, }, perform: { 'X-Zammad-Ticket-group_id' => { value: group1.id, }, 'x-Zammad-Article-Internal' => { value: true, }, 'x-Zammad-Ticket-customer_id' => { value: 999_999, value_completion: 'xxx', }, }, channel: 'email', active: true, created_by_id: 1, updated_by_id: 1, ) data = 'From: ME Bob To: customer@example.com Subject: some subject Some Text' parser = Channel::EmailParser.new ticket, article, user = parser.process({ group_id: group_default.id, trusted: false }, data) assert_equal(group1.name, ticket.group.name) assert_equal('2 normal', ticket.priority.name) assert_equal('some subject', ticket.title) assert_equal('me@example.com', ticket.customer.email) PostmasterFilter.destroy_all PostmasterFilter.create!( name: 'used', match: { from: { operator: 'contains', value: 'me@example.com', }, }, perform: { 'X-Zammad-Ticket-group_id' => { value: group1.id, }, 'X-Zammad-Ticket-priority_id' => { value: 888_888, }, 'x-Zammad-Article-Internal' => { value: true, }, 'x-Zammad-Ticket-customer_id' => { value: 999_999, value_completion: 'xxx', }, }, channel: 'email', active: true, created_by_id: 1, updated_by_id: 1, ) data = 'From: ME Bob To: customer@example.com Subject: some subject Some Text' parser = Channel::EmailParser.new ticket, article, user = parser.process({ group_id: group_default.id, trusted: false }, data) assert_equal(group1.name, ticket.group.name) assert_equal('2 normal', ticket.priority.name) assert_equal('some subject', ticket.title) assert_equal('me@example.com', ticket.customer.email) assert_equal('2 normal', ticket.priority.name) PostmasterFilter.destroy_all PostmasterFilter.create!( name: 'Autoresponder', match: { 'auto-submitted' => { 'operator' => 'contains not', 'value' => 'auto-generated', }, 'from' => { 'operator' => 'contains', 'value' => '@example.com', } }, perform: { 'x-zammad-article-internal' => { 'value' => 'true', }, 'x-zammad-article-type_id' => { 'value' => Ticket::Article::Type.find_by(name: 'note').id.to_s, }, 'x-zammad-ignore' => { 'value' => 'false', }, }, channel: 'email', active: true, created_by_id: 1, updated_by_id: 1, ) data = 'From: ME Bob To: customer@example.com Subject: some subject Some Text' parser = Channel::EmailParser.new ticket, article, user = parser.process({ group_id: group_default.id, trusted: false }, data) assert_equal('Users', ticket.group.name) assert_equal('2 normal', ticket.priority.name) assert_equal('some subject', ticket.title) assert_equal('me@example.com', ticket.customer.email) assert_equal('2 normal', ticket.priority.name) assert_equal('Customer', article.sender.name) assert_equal('note', article.type.name) assert_equal(true, article.internal) PostmasterFilter.destroy_all PostmasterFilter.create!( name: 'Autoresponder', match: { 'auto-submitted' => { 'operator' => 'contains', 'value' => 'auto-generated', }, 'from' => { 'operator' => 'contains', 'value' => '@example.com', } }, perform: { 'x-zammad-article-internal' => { 'value' => 'true', }, 'x-zammad-article-type_id' => { 'value' => Ticket::Article::Type.find_by(name: 'note').id.to_s, }, 'x-zammad-ignore' => { 'value' => 'false', }, }, channel: 'email', active: true, created_by_id: 1, updated_by_id: 1, ) data = 'From: ME Bob To: customer@example.com Subject: some subject Some Text' parser = Channel::EmailParser.new ticket, article, user = parser.process({ group_id: group_default.id, trusted: false }, data) assert_equal('Users', ticket.group.name) assert_equal('2 normal', ticket.priority.name) assert_equal('some subject', ticket.title) assert_equal('me@example.com', ticket.customer.email) assert_equal('2 normal', ticket.priority.name) assert_equal('Customer', article.sender.name) assert_equal('email', article.type.name) assert_equal(false, article.internal) PostmasterFilter.destroy_all PostmasterFilter.create!( name: 'Autoresponder', match: { 'auto-submitted' => { 'operator' => 'contains not', 'value' => 'auto-generated', }, 'to' => { 'operator' => 'contains', 'value' => 'customer@example.com', }, 'from' => { 'operator' => 'contains', 'value' => '@example.com', } }, perform: { 'x-zammad-article-internal' => { 'value' => 'true', }, 'x-zammad-article-type_id' => { 'value' => Ticket::Article::Type.find_by(name: 'note').id.to_s, }, 'x-zammad-ignore' => { 'value' => 'false', }, }, channel: 'email', active: true, created_by_id: 1, updated_by_id: 1, ) data = 'From: ME Bob To: customer@example.com Subject: some subject Some Text' parser = Channel::EmailParser.new ticket, article, user = parser.process({ group_id: group_default.id, trusted: false }, data) assert_equal('Users', ticket.group.name) assert_equal('2 normal', ticket.priority.name) assert_equal('some subject', ticket.title) assert_equal('me@example.com', ticket.customer.email) assert_equal('2 normal', ticket.priority.name) assert_equal('Customer', article.sender.name) assert_equal('note', article.type.name) assert_equal(true, article.internal) PostmasterFilter.destroy_all PostmasterFilter.create!( name: 'Autoresponder', match: { 'auto-submitted' => { 'operator' => 'contains', 'value' => 'auto-generated', }, 'to' => { 'operator' => 'contains', 'value' => 'customer1@example.com', }, 'from' => { 'operator' => 'contains', 'value' => '@example.com', } }, perform: { 'x-zammad-article-internal' => { 'value' => 'true', }, 'x-zammad-article-type_id' => { 'value' => Ticket::Article::Type.find_by(name: 'note').id.to_s, }, 'x-zammad-ignore' => { 'value' => 'false', }, }, channel: 'email', active: true, created_by_id: 1, updated_by_id: 1, ) data = 'From: ME Bob To: customer@example.com Subject: some subject Some Text' parser = Channel::EmailParser.new ticket, article, user = parser.process({ group_id: group_default.id, trusted: false }, data) assert_equal('Users', ticket.group.name) assert_equal('2 normal', ticket.priority.name) assert_equal('some subject', ticket.title) assert_equal('me@example.com', ticket.customer.email) assert_equal('2 normal', ticket.priority.name) assert_equal('Customer', article.sender.name) assert_equal('email', article.type.name) assert_equal(false, article.internal) end end