diff --git a/app/models/channel/filter/follow_up_merged.rb b/app/models/channel/filter/follow_up_merged.rb index 834598ffd..d12f7f979 100644 --- a/app/models/channel/filter/follow_up_merged.rb +++ b/app/models/channel/filter/follow_up_merged.rb @@ -5,8 +5,7 @@ module Channel::Filter::FollowUpMerged def self.run(_channel, mail) return if mail[:'x-zammad-ticket-id'].blank? - # get ticket# from subject - ticket = Ticket.find(mail[:'x-zammad-ticket-id']) + ticket = Ticket.find_by(id: mail[:'x-zammad-ticket-id']) return if ticket.blank? ticket = find_merge_follow_up_ticket(ticket) @@ -29,13 +28,12 @@ module Channel::Filter::FollowUpMerged next if link['link_type'] != 'parent' next if link['link_object'] != 'Ticket' - check_ticket = Ticket.find(link['link_object_value']) - + check_ticket = Ticket.find_by(id: link['link_object_value']) next if check_ticket.blank? + next if check_ticket.state.name == 'merged' merge_ticket = check_ticket - break end merge_ticket diff --git a/spec/factories/channel.rb b/spec/factories/channel.rb new file mode 100644 index 000000000..dbbdc33d7 --- /dev/null +++ b/spec/factories/channel.rb @@ -0,0 +1,9 @@ +FactoryBot.define do + factory :channel do + area 'Email::Dummy' + group { ::Group.find(1) } + active true + options {} + preferences {} + end +end diff --git a/spec/models/channel/filter/follow_up_merged_spec.rb b/spec/models/channel/filter/follow_up_merged_spec.rb index 3f24956fd..dad469f8f 100644 --- a/spec/models/channel/filter/follow_up_merged_spec.rb +++ b/spec/models/channel/filter/follow_up_merged_spec.rb @@ -1,65 +1,97 @@ require 'rails_helper' -RSpec.describe Channel::Filter::FollowUpMerged do +RSpec.describe Channel::Filter::FollowUpMerged, type: :channel_filter do - describe '#find_merge_follow_up_ticket' do + context 'merged' do - it 'finds the follow up ticket for merged tickets' do + it 'handles ticket merged to one ticket' do + ticket1 = create(:ticket) + ticket2 = create(:ticket) + + ticket1.merge_to( ticket_id: ticket2.id, user_id: 1 ) + + mail = { + 'x-zammad-ticket-id': ticket1.id + } + + filter(mail) + + expect(mail[:'x-zammad-ticket-id']).to eq(ticket2.id) + end + + it 'handles first merged chain' do + ticket1 = create(:ticket) + ticket2 = create(:ticket) + ticket3 = create(:ticket) + + ticket1.merge_to( ticket_id: ticket2.id, user_id: 1 ) + ticket2.merge_to( ticket_id: ticket3.id, user_id: 1 ) + + mail = { + 'x-zammad-ticket-id': ticket1.id + } + + filter(mail) + + expect(mail[:'x-zammad-ticket-id']).to eq(ticket3.id) + end + + it 'handles ticket in merged ticket chain' do ticket1 = create(:ticket) ticket2 = create(:ticket) ticket3 = create(:ticket) ticket4 = create(:ticket) - ticket5 = create(:ticket) ticket1.merge_to( ticket_id: ticket2.id, user_id: 1 ) ticket2.merge_to( ticket_id: ticket3.id, user_id: 1 ) ticket3.merge_to( ticket_id: ticket4.id, user_id: 1 ) - ticket4.merge_to( ticket_id: ticket5.id, user_id: 1 ) - ticket = Channel::Filter::FollowUpMerged.find_merge_follow_up_ticket(ticket1) - expect(ticket.id).to eq(ticket5.id) + mail = { + 'x-zammad-ticket-id': ticket2.id + } - follow_up_raw = "From: me@example.com -To: customer@example.com -Subject: #{ticket1.subject_build('some new subject')} + filter(mail) -blub follow up" - ticket_p, article_p, user_p = Channel::EmailParser.new.process({}, follow_up_raw) - expect(ticket_p.id).to eq(ticket5.id) - - follow_up_raw = "From: me@example.com -To: customer@example.com -Subject: #{ticket2.subject_build('some new subject')} - -blub follow up" - ticket_p, article_p, user_p = Channel::EmailParser.new.process({}, follow_up_raw) - expect(ticket_p.id).to eq(ticket5.id) - - follow_up_raw = "From: me@example.com -To: customer@example.com -Subject: #{ticket3.subject_build('some new subject')} - -blub follow up" - ticket_p, article_p, user_p = Channel::EmailParser.new.process({}, follow_up_raw) - expect(ticket_p.id).to eq(ticket5.id) - - follow_up_raw = "From: me@example.com -To: customer@example.com -Subject: #{ticket4.subject_build('some new subject')} - -blub follow up" - ticket_p, article_p, user_p = Channel::EmailParser.new.process({}, follow_up_raw) - expect(ticket_p.id).to eq(ticket5.id) - - follow_up_raw = "From: me@example.com -To: customer@example.com -Subject: #{ticket5.subject_build('some new subject')} - -blub follow up" - ticket_p, article_p, user_p = Channel::EmailParser.new.process({}, follow_up_raw) - expect(ticket_p.id).to eq(ticket5.id) + expect(mail[:'x-zammad-ticket-id']).to eq(ticket4.id) end - end + context 'ignored mails' do + + it 'ignores new tickets' do + mail = {} + + expect do + filter(mail) + end.to not_change { + mail + } + end + + it 'ignores unmerged tickets' do + ticket = create(:ticket) + + mail = { + 'x-zammad-ticket-id': ticket.id + } + + expect do + filter(mail) + end.to not_change { + mail + } + end + + it 'ignores not existing tickets' do + mail = { + 'x-zammad-ticket-id': 1_234_567_890 + } + + expect do + filter(mail) + end.to not_change { + mail + } + end + end end diff --git a/spec/support/channel_filter.rb b/spec/support/channel_filter.rb new file mode 100644 index 000000000..a8a149104 --- /dev/null +++ b/spec/support/channel_filter.rb @@ -0,0 +1,36 @@ +module ChannelFilterHelper + + # Provides a helper method to run the current class Channel::Filter. + # Make sure to define type: :channel_filter in your RSpec.describe call. + # + # @param [Hash] mail_hash contains the parsed mail data + # @param [Channel] channel contains the channel that processes this call which is usually not needed + # + # @example + # filter({:'x-zammad-ticket-id' => 1234, ...}) + # + # @return [nil] + def filter(mail_hash, channel: {}) + described_class.run(channel, mail_hash) + end + + # Provides a helper method to parse a mail String and run the current class Channel::Filter. + # Make sure to define type: :channel_filter in your RSpec.describe call. + # + # @param [String] mail_string contains the plain mail content + # @param [Channel] channel contains the channel that processes this call which is usually not needed + # + # @example + # filter_parsed('From: me@example.com...') + # + # @return [Hash] parsed mails Hash + def filter_parsed(mail_string, channel: {}) + Channel::EmailParser.new.parse(mail_string).tap do |mail_hash| + filter(mail_hash, channel: channel) + end + end +end + +RSpec.configure do |config| + config.include ChannelFilterHelper, type: :channel_filter +end