2016-12-06 12:26:08 +00:00
|
|
|
|
require 'rails_helper'
|
|
|
|
|
|
|
|
|
|
RSpec.describe Cti::CallerId do
|
2019-01-14 09:30:51 +00:00
|
|
|
|
describe '.extract_numbers' do
|
|
|
|
|
context 'for strings containing arbitrary numbers (<6 digits long)' do
|
|
|
|
|
it 'returns an empty array' do
|
2019-01-17 06:57:03 +00:00
|
|
|
|
expect(described_class.extract_numbers(<<~INPUT.chomp)).to be_empty
|
|
|
|
|
some text
|
|
|
|
|
test 123
|
|
|
|
|
INPUT
|
2019-01-14 09:30:51 +00:00
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
context 'for strings containing a phone number with "(0)" after country code' do
|
|
|
|
|
it 'returns the number in an array, without the leading "(0)"' do
|
2019-01-17 06:57:03 +00:00
|
|
|
|
expect(described_class.extract_numbers(<<~INPUT.chomp)).to eq(['4930600000000'])
|
|
|
|
|
Lorem ipsum dolor sit amet, consectetuer +49 (0) 30 60 00 00 00-0
|
|
|
|
|
adipiscing elit. Aenean commodo ligula eget dolor. Aenean massa.
|
|
|
|
|
Cum sociis natoque penatibus et magnis dis parturient montes, nascetur
|
|
|
|
|
ridiculus mus. Donec quam felis, ultricies nec, pellentesque eu,
|
|
|
|
|
pretium quis, sem. Nulla consequat massa quis enim. Donec pede
|
|
|
|
|
justo, fringilla vel.
|
|
|
|
|
INPUT
|
2019-01-14 09:30:51 +00:00
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
context 'for strings containing a phone number with leading 0 (no country code)' do
|
|
|
|
|
it 'returns the number in an array, using default country code (49)' do
|
2019-01-17 06:57:03 +00:00
|
|
|
|
expect(described_class.extract_numbers(<<~INPUT.chomp)).to eq(['4994221000'])
|
|
|
|
|
GS Oberalteich
|
|
|
|
|
Telefon 09422 1000
|
|
|
|
|
E-Mail:
|
|
|
|
|
INPUT
|
2019-01-14 09:30:51 +00:00
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
context 'for strings containing multiple phone numbers' do
|
|
|
|
|
it 'returns all numbers in an array' do
|
2019-01-17 06:57:03 +00:00
|
|
|
|
expect(described_class.extract_numbers(<<~INPUT.chomp)).to eq(%w[41812886393 41763467214])
|
|
|
|
|
Tel +41 81 288 63 93 / +41 76 346 72 14 ...
|
|
|
|
|
INPUT
|
2019-01-14 09:30:51 +00:00
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
context 'for strings containing US-formatted numbers' do
|
|
|
|
|
it 'returns the numbers in an array correctly' do
|
2019-01-17 06:57:03 +00:00
|
|
|
|
expect(described_class.extract_numbers(<<~INPUT.chomp)).to eq(%w[19494310000 19494310001])
|
|
|
|
|
P: +1 (949) 431 0000
|
|
|
|
|
F: +1 (949) 431 0001
|
|
|
|
|
W: http://znuny
|
|
|
|
|
INPUT
|
2019-01-14 09:30:51 +00:00
|
|
|
|
end
|
|
|
|
|
end
|
2016-12-06 12:26:08 +00:00
|
|
|
|
end
|
2018-07-23 08:24:23 +00:00
|
|
|
|
|
2019-01-14 09:30:51 +00:00
|
|
|
|
describe '.normalize_number' do
|
|
|
|
|
it 'does not modify digit-only strings (starting with 1-9)' do
|
|
|
|
|
expect(described_class.normalize_number('5754321')).to eq('5754321')
|
|
|
|
|
end
|
2018-07-23 08:24:23 +00:00
|
|
|
|
|
2019-01-14 09:30:51 +00:00
|
|
|
|
it 'strips whitespace' do
|
|
|
|
|
expect(described_class.normalize_number('622 32281')).to eq('62232281')
|
|
|
|
|
end
|
2018-07-23 08:24:23 +00:00
|
|
|
|
|
2019-01-14 09:30:51 +00:00
|
|
|
|
it 'strips hyphens' do
|
|
|
|
|
expect(described_class.normalize_number('1-888-407-4747')).to eq('18884074747')
|
2018-07-23 08:24:23 +00:00
|
|
|
|
end
|
|
|
|
|
|
2019-01-14 09:30:51 +00:00
|
|
|
|
it 'strips leading pluses' do
|
|
|
|
|
expect(described_class.normalize_number('+49 30 53 00 00 000')).to eq('4930530000000')
|
|
|
|
|
expect(described_class.normalize_number('+49 160 0000000')).to eq('491600000000')
|
|
|
|
|
end
|
2018-07-23 08:24:23 +00:00
|
|
|
|
|
2019-01-14 09:30:51 +00:00
|
|
|
|
it 'replaces a single leading zero with the default country code (49)' do
|
|
|
|
|
expect(described_class.normalize_number('092213212')).to eq('4992213212')
|
|
|
|
|
expect(described_class.normalize_number('0271233211')).to eq('49271233211')
|
|
|
|
|
expect(described_class.normalize_number('022 1234567')).to eq('49221234567')
|
|
|
|
|
expect(described_class.normalize_number('09 123 32112')).to eq('49912332112')
|
|
|
|
|
expect(described_class.normalize_number('021 2331231')).to eq('49212331231')
|
|
|
|
|
expect(described_class.normalize_number('021 321123123')).to eq('4921321123123')
|
|
|
|
|
expect(described_class.normalize_number('0150 12345678')).to eq('4915012345678')
|
|
|
|
|
expect(described_class.normalize_number('021-233-9123')).to eq('49212339123')
|
|
|
|
|
end
|
2018-07-23 08:24:23 +00:00
|
|
|
|
|
2019-01-14 09:30:51 +00:00
|
|
|
|
it 'strips two leading zeroes' do
|
|
|
|
|
expect(described_class.normalize_number('0049 1234 123456789')).to eq('491234123456789')
|
|
|
|
|
expect(described_class.normalize_number('0043 30 60 00 00 00-0')).to eq('4330600000000')
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
it 'strips leading zero from "(0x)" at start of number or after country code' do
|
|
|
|
|
expect(described_class.normalize_number('(09)1234321')).to eq('4991234321')
|
|
|
|
|
expect(described_class.normalize_number('+49 (0) 30 60 00 00 00-0')).to eq('4930600000000')
|
|
|
|
|
expect(described_class.normalize_number('0043 (0) 30 60 00 00 00-0')).to eq('4330600000000')
|
2018-07-23 08:24:23 +00:00
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
|
2019-01-17 06:57:03 +00:00
|
|
|
|
describe '.lookup' do
|
|
|
|
|
context 'when given an unrecognized number' do
|
|
|
|
|
it 'returns an empty array' do
|
|
|
|
|
expect(Cti::CallerId.lookup('1')).to eq([])
|
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
context 'when given a recognized number' do
|
|
|
|
|
subject!(:caller_id) { create(:caller_id) }
|
|
|
|
|
|
|
|
|
|
it 'returns an array with the corresponding CallerId' do
|
|
|
|
|
expect(Cti::CallerId.lookup(caller_id.caller_id))
|
|
|
|
|
.to match_array([caller_id])
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
context 'shared by multiple CallerIds' do
|
|
|
|
|
subject!(:caller_ids) do
|
|
|
|
|
User.last(2).map { |u| create(:caller_id, caller_id: '1234567890', user: u) }
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
# NOTE: this only works if the CallerId records are for distinct Users.
|
|
|
|
|
# Not sure if that's necessary to the spec, though.
|
|
|
|
|
it 'returns all CallerId records with that number' do
|
|
|
|
|
expect(Cti::CallerId.lookup('1234567890')).to match_array(caller_ids)
|
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
describe '.rebuild' do
|
|
|
|
|
context 'when a User record contains a valid phone number' do
|
|
|
|
|
let!(:user) { create(:agent_user, phone: '+49 123 456') }
|
|
|
|
|
|
|
|
|
|
context 'and no corresponding CallerId exists' do
|
|
|
|
|
it 'generates a CallerId record (with #level "known")' do
|
|
|
|
|
Cti::CallerId.destroy_all # CallerId already generated in User callback
|
|
|
|
|
|
|
|
|
|
expect { Cti::CallerId.rebuild }
|
|
|
|
|
.to change { Cti::CallerId.exists?(user_id: user.id, caller_id: '49123456', level: 'known') }
|
|
|
|
|
.to(true)
|
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
it 'does not create duplicate CallerId records' do
|
|
|
|
|
expect { Cti::CallerId.rebuild }.not_to change { Cti::CallerId.count }
|
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
context 'when no User exists for a given CallerId record' do
|
|
|
|
|
subject!(:caller_id) { create(:caller_id) }
|
|
|
|
|
|
|
|
|
|
it 'deletes the CallerId record' do
|
|
|
|
|
expect { Cti::CallerId.rebuild }
|
|
|
|
|
.to change { Cti::CallerId.exists?(caller_id.id) }.to(false)
|
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
context 'when two User records contains the same valid phone number' do
|
|
|
|
|
let!(:users) { create_list(:agent_user, 2, phone: '+49 123 456') }
|
|
|
|
|
|
|
|
|
|
it 'generates two corresponding CallerId records (with #level "known")' do
|
|
|
|
|
Cti::CallerId.destroy_all # CallerId already generated in User callback
|
|
|
|
|
|
|
|
|
|
expect { Cti::CallerId.rebuild }
|
|
|
|
|
.to change { Cti::CallerId.exists?(user_id: users.first.id, caller_id: '49123456', level: 'known') }
|
|
|
|
|
.to(true)
|
|
|
|
|
.and change { Cti::CallerId.exists?(user_id: users.last.id, caller_id: '49123456', level: 'known') }
|
|
|
|
|
.to(true)
|
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
context 'when an Article record contains a valid phone number in its body' do
|
|
|
|
|
let!(:article) { create(:ticket_article, body: <<~BODY, sender_name: sender_name) }
|
|
|
|
|
some message
|
|
|
|
|
Fon (GEL): +49 123-456 Mi-Fr
|
|
|
|
|
BODY
|
|
|
|
|
|
|
|
|
|
context 'and comes from a customer' do
|
|
|
|
|
let(:sender_name) { 'Customer' }
|
|
|
|
|
|
|
|
|
|
it 'generates a CallerId record (with #level "maybe")' do
|
|
|
|
|
Cti::CallerId.destroy_all # CallerId already generated in Article observer job
|
|
|
|
|
|
|
|
|
|
expect { Cti::CallerId.rebuild }
|
|
|
|
|
.to change { Cti::CallerId.exists?(user_id: article.created_by_id, caller_id: '49123456', level: 'maybe') }
|
|
|
|
|
.to(true)
|
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
context 'and comes from an Agent' do
|
|
|
|
|
let(:sender_name) { 'Agent' }
|
|
|
|
|
|
|
|
|
|
it 'does not generate a CallerId record' do
|
|
|
|
|
expect { Cti::CallerId.rebuild }
|
|
|
|
|
.not_to change { Cti::CallerId.exists?(caller_id: '49123456') }
|
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
|
2019-01-14 09:30:51 +00:00
|
|
|
|
describe 'callbacks' do
|
|
|
|
|
subject!(:caller_id) { build(:cti_caller_id, caller_id: phone) }
|
|
|
|
|
let(:phone) { '1234567890' }
|
|
|
|
|
|
|
|
|
|
describe 'on creation' do
|
|
|
|
|
it 'adopts CTI Logs from same number (via UpdateCtiLogsByCallerJob)' do
|
|
|
|
|
expect(UpdateCtiLogsByCallerJob).to receive(:perform_later)
|
|
|
|
|
|
|
|
|
|
caller_id.save
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
it 'splits job into fg and bg (for more responsive UI – see #2057)' do
|
|
|
|
|
expect(UpdateCtiLogsByCallerJob).to receive(:perform_now).with(phone, limit: 20)
|
|
|
|
|
expect(UpdateCtiLogsByCallerJob).to receive(:perform_later).with(phone, limit: 40, offset: 20)
|
|
|
|
|
|
|
|
|
|
caller_id.save
|
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
describe 'on destruction' do
|
|
|
|
|
before { caller_id.save }
|
|
|
|
|
|
|
|
|
|
it 'orphans CTI Logs from same number (via UpdateCtiLogsByCallerJob)' do
|
|
|
|
|
expect(UpdateCtiLogsByCallerJob).to receive(:perform_later).with(phone)
|
2018-07-23 08:24:23 +00:00
|
|
|
|
|
2019-01-14 09:30:51 +00:00
|
|
|
|
caller_id.destroy
|
|
|
|
|
end
|
2018-07-23 08:24:23 +00:00
|
|
|
|
end
|
|
|
|
|
end
|
2016-12-06 12:26:08 +00:00
|
|
|
|
end
|