require 'rails_helper' RSpec.describe SignatureDetection do describe '.find_signature' do context 'when given an array of hashes' do let(:messages) do raw_message_files.map do |f| { content: File.read(f), content_type: content_type } end end context 'with plain text messages in their :content keys (sample input 1)' do let(:content_type) { 'text/plain' } let(:raw_message_files) do [ Rails.root.join('test', 'data', 'email_signature_detection', 'client_a_1.txt'), Rails.root.join('test', 'data', 'email_signature_detection', 'client_a_2.txt'), Rails.root.join('test', 'data', 'email_signature_detection', 'client_a_3.txt') ] end it 'returns the first 5–10-line substring they share in common' do expect(described_class.find_signature(messages)).to eq(<<~SIG.chomp) Mit freundlichen Grüßen Bob Smith Berechtigungen und dez. Department ________________________________ Musik AG Berechtigungen und dez. Department (ITPBM) Kastanien 2 SIG end end context 'with plain text messages in their :content keys (sample input 2)' do let(:content_type) { 'text/plain' } let(:raw_message_files) do [ Rails.root.join('test', 'data', 'email_signature_detection', 'client_b_1.txt'), Rails.root.join('test', 'data', 'email_signature_detection', 'client_b_2.txt'), Rails.root.join('test', 'data', 'email_signature_detection', 'client_b_3.txt') ] end it 'returns the first 5–10-line substring they share in common' do expect(described_class.find_signature(messages)).to eq(<<~SIG.chomp) Freundliche Grüße Günter Lässig Lokale Daten Music GmbH Baustraße 123, 12345 Max City Telefon 0123 5432114 Telefax 0123 5432139 SIG end end context 'with HTML messages in their :content keys' do let(:content_type) { 'text/html' } let(:raw_message_files) do [ Rails.root.join('test', 'data', 'email_signature_detection', 'client_c_1.html'), Rails.root.join('test', 'data', 'email_signature_detection', 'client_c_2.html'), Rails.root.join('test', 'data', 'email_signature_detection', 'client_c_3.html') ] end it 'converts messages (via #html2text) then returns the first 5–10-line substring they share in common' do expect(described_class.find_signature(messages)).to eq(<<~SIG.chomp) ChristianSmith Technik Tel: +49 12 34 56 78 441 Fax: +49 12 34 56 78 499 Email: Christian.Smith@example.com Web: www.example.com ABC KFZ- und Flugzeug B.V. & Co. KG Hauptverwaltung SIG end end end context 'when input messages do not share 5-line common substrings' do let(:messages) do Array.new(2) { { content: <<~RAW, content_type: 'text/plain' } } Lorem ipsum dolor sit amet, consectetur adipiscing elit. Ut ut tincidunt nunc. Sed mattis aliquam tellus sit amet lacinia. Mauris fermentum dictum aliquet. Nam ex risus, gravida et ornare ut, mollis non sapien. RAW end it 'doesn’t break' do expect { described_class.find_signature(messages) }.not_to raise_error end end end describe '.find_signature_line' do context 'when given a plain text message' do let(:content_type) { 'text/plain' } let(:content) { File.read(Rails.root.join('test', 'data', 'email_signature_detection', 'client_a_1.txt')) } context 'and a substring it contains' do let(:signature) { <<~SIG.chomp } Mit freundlichen Grüßen Bob Smith Berechtigungen und dez. Department ________________________________ Musik AG Berechtigungen und dez. Department (ITPBM) Kastanien 2 SIG it 'returns the line of the message where the signature begins' do expect(described_class.find_signature_line(signature, content, content_type)).to eq(10) end end end context 'when given an HTML message' do let(:content_type) { 'text/html' } let(:content) { File.read(Rails.root.join('test', 'data', 'email_signature_detection', 'example1.html')) } context 'and a substring it contains' do let(:signature) { <<~SIG.chomp } ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Bob Smith ABC Organisation EXAMPLE IT-Service GmbH Dorten 5 F&E 12345 Da / Germany Phone: +49 (0) 1234 567 890 / +49 (0) 1234 567 891 Fax:     +49 (0) 1234 567 892 SIG it 'converts messages (via #html2text) then returns the line of the message where the signature begins' do expect(described_class.find_signature_line(signature, content, content_type)).to eq(11) end end end end describe '.rebuild_all_articles' do context 'when a user exists with a recorded signature' do let!(:customer) { create(:customer_user, preferences: { signature_detection: "\nbar" }) } context 'and multiple articles exist for that customer' do let!(:articles) do [create(:ticket_article, created_by_id: customer.id, body: "foo\nfoo\nbar"), create(:ticket_article, created_by_id: customer.id, body: "foo\nbar")] end it 'updates the signature-line data of all articles' do expect { described_class.rebuild_all_articles } .to change { articles.first.reload.preferences[:signature_detection] }.to(3) .and change { articles.second.reload.preferences[:signature_detection] }.to(2) end end end end end