diff --git a/Gemfile b/Gemfile index 2f180d344..d316c914b 100644 --- a/Gemfile +++ b/Gemfile @@ -85,6 +85,7 @@ gem 'net-ldap' gem 'writeexcel' gem 'icalendar' gem 'browser' +gem 'phony' # integrations gem 'slack-notifier' diff --git a/Gemfile.lock b/Gemfile.lock index d4644fc4c..6e7bfe07c 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -135,7 +135,7 @@ GEM addressable faraday multi_json - libv8 (3.16.14.13) + libv8 (3.16.14.15) listen (3.1.1) rb-fsevent (>= 0.9.3) rb-inotify (>= 0.9.7) @@ -150,7 +150,7 @@ GEM mime-types (2.99.1) mini_portile2 (2.0.0) minitest (5.8.4) - multi_json (1.11.2) + multi_json (1.11.3) multi_xml (0.5.5) multipart-post (2.0.0) mysql2 (0.3.20) @@ -191,8 +191,9 @@ GEM omniauth-twitter (1.2.1) json (~> 1.3) omniauth-oauth (~> 1.1) - parser (2.3.0.7) + parser (2.3.1.0) ast (~> 2.2) + phony (2.15.21) pluginator (1.3.0) power_assert (0.2.7) powerpack (0.1.1) @@ -246,7 +247,7 @@ GEM rainbow (>= 1.99.1, < 3.0) ruby-progressbar (~> 1.7) unicode-display_width (~> 1.0, >= 1.0.1) - ruby-progressbar (1.7.5) + ruby-progressbar (1.8.0) rubyzip (1.2.0) sass (3.4.22) sass-rails (5.0.4) @@ -354,6 +355,7 @@ DEPENDENCIES omniauth-google-oauth2 omniauth-linkedin omniauth-twitter + phony pre-commit puma rack-livereload diff --git a/app/assets/javascripts/app/controllers/cti.coffee b/app/assets/javascripts/app/controllers/cti.coffee index df46d35d0..267b7773a 100644 --- a/app/assets/javascripts/app/controllers/cti.coffee +++ b/app/assets/javascripts/app/controllers/cti.coffee @@ -75,7 +75,6 @@ class App.CTI extends App.Controller url: '#cti' title: title ) - App.OnlineNotification.play() featureActive: => return true diff --git a/app/controllers/integration/sipgate_controller.rb b/app/controllers/integration/sipgate_controller.rb index 6e2e9d51e..60e07f697 100644 --- a/app/controllers/integration/sipgate_controller.rb +++ b/app/controllers/integration/sipgate_controller.rb @@ -8,7 +8,7 @@ class Integration::SipgateController < ApplicationController def index return if !authentication_check return if deny_if_not_role('CTI') - list = Cti::Log.order('created_at DESC').limit(60) + list = Cti::Log.order('created_at DESC, id DESC').limit(60) render json: list end @@ -130,8 +130,10 @@ class Integration::SipgateController < ApplicationController to_comment = nil if params['direction'] == 'in' to_comment = user + from_comment = update_log_item('from') else from_comment = user + to_comment = update_log_item('to') end comment = nil if params['cause'] @@ -178,6 +180,37 @@ class Integration::SipgateController < ApplicationController end + def update_log_item(direction) + from_comment_known = '' + from_comment_maybe = '' + caller_ids = Cti::CallerId.lookup(params[direction]) + caller_ids.each {|record| + comment = '' + if record.user_id + user = User.lookup(id: record.user_id) + if user + comment += user.fullname + end + elsif !record.comment.empty? + comment += record.comment + end + if record.level == 'known' + if !from_comment_known.empty? + from_comment_known += ',' + end + from_comment_known += comment + else + if !from_comment_maybe.empty? + from_comment_maybe += ',' + end + from_comment_maybe += comment + end + } + return from_comment_known if !from_comment_known.empty? + return "maybe #{from_comment_maybe}" if !from_comment_maybe.empty? + nil + end + def xml_error(error) xml = Builder::XmlMarkup.new(indent: 2) xml.instruct! diff --git a/app/models/cti/caller_id.rb b/app/models/cti/caller_id.rb new file mode 100644 index 000000000..45c7a3afe --- /dev/null +++ b/app/models/cti/caller_id.rb @@ -0,0 +1,217 @@ +module Cti + class CallerId < ApplicationModel + self.table_name = 'cti_caller_ids' + +=begin + + Cti::CallerId.maybe_add( + caller_id: '49123456789', + comment: 'Hairdresser Bob Smith, San Francisco', #optional + level: 'maybe', # known|maybe + user_id: 1, # optional + object: 'Ticket', + o_id: 123, + ) + +=end + + def self.maybe_add(data) + records = Cti::CallerId.where( + caller_id: data[:caller_id], + level: data[:level], + object: data[:object], + o_id: data[:o_id], + user_id: data[:user_id], + ) + return if records[0] + Cti::CallerId.create( + caller_id: data[:caller_id], + comment: data[:comment], + level: data[:level], + object: data[:object], + o_id: data[:o_id], + user_id: data[:user_id], + ) + end + +=begin + + caller_id_records = Cti::CallerId.lookup('49123456789') + +returns + + [record1, record2, ...] + +=end + + def self.lookup(caller_id) + Cti::CallerId.where( + caller_id: caller_id, + ).order('id DESC') + end + +=begin + + Cti::CallerId.build(ticket) + +=end + + def self.build(record) + map = config + level = nil + model = nil + map.each {|item| + next if item[:model] != record.class + level = item[:level] + model = item[:model] + } + return if !level || !model + build_item(record, model, level) + end + +=begin + + Cti::CallerId.build_item(record, model, level) + +=end + + def self.build_item(record, model, level) + + # use first customer article + if model == Ticket + article = record.articles.first + return if !article + return if article.sender.name != 'Customer' + record = article + end + + # set user id + user_id = record[:created_by_id] + if model == User + user_id = record.id + end + return if !user_id + + # get caller ids + caller_ids = [] + attributes = record.attributes + attributes.each {|_attribute, value| + next if value.class != String + next if value.empty? + local_caller_ids = Cti::CallerId.parse_text(value) + next if local_caller_ids.empty? + caller_ids = caller_ids.concat(local_caller_ids) + } + + # store caller ids + Cti::CallerId.where(object: model.to_s, o_id: record.id).destroy_all + caller_ids.each {|caller_id| + Cti::CallerId.maybe_add( + caller_id: caller_id, + level: level, + object: model.to_s, + o_id: record.id, + user_id: user_id, + ) + } + true + end + +=begin + + Cti::CallerId.rebuild + +=end + + def self.rebuild + map = config + map.each {|item| + level = item[:level] + model = item[:model] + item[:model].find_each(batch_size: 500) do |record| + build_item(record, model, level) + end + } + end + +=begin + + Cti::CallerId.config + +returns + + [ + { + model: User, + level: 'known', + }, + { + model: Ticket, + level: 'maybe', + }, + ] + +=end + + def self.config + [ + { + model: User, + level: 'known', + }, + { + model: Ticket, + level: 'maybe', + }, + ] + end + +=begin + + caller_ids = Cti::CallerId.parse_text('...') + +returns + + ['49123456789', '49987654321'] + +=end + + def self.parse_text(text) + caller_ids = [] + + # 022 1234567 + # 021 123 2345 + # 0271233211 + # 021-233-9123 + # 09 123 32112 + # 021 2331231 or 021 321123123 + # 622 32281 + # 5754321 + # 092213212 + # (09)1234321 + # +41 30 53 00 00 000 + # +42 160 0000000 + # +43 (0) 30 60 00 00 00-0 + # 0043 (0) 30 60 00 00 00-0 + + default_country_id = '49' + text.gsub!(/([\d|\s|\-|\(|\)]{6,26})/) { + number = $1.strip + number.sub!(/^00/, '') + number.sub!(/\(0\)/, '') + number.gsub!(/(\s|\-|\(|\))/, '') + if !Phony.plausible?(number) + if number =~ /^0/ + number.gsub!(/^0/, default_country_id) + else + number = "#{default_country_id}#{number}" + end + next if !Phony.plausible?(number) + end + caller_ids.push number + } + caller_ids + end + + end +end diff --git a/db/migrate/20160428000001_create_cti_caller_id.rb b/db/migrate/20160428000001_create_cti_caller_id.rb new file mode 100644 index 000000000..bcd699e76 --- /dev/null +++ b/db/migrate/20160428000001_create_cti_caller_id.rb @@ -0,0 +1,19 @@ +class CreateCtiCallerId < ActiveRecord::Migration + def up + + create_table :cti_caller_ids do |t| + t.string :caller_id, limit: 100, null: false + t.string :comment, limit: 500, null: true + t.string :level, limit: 100, null: false + t.string :object, limit: 100, null: false + t.integer :o_id, null: false + t.integer :user_id, null: true + t.timestamps null: false + end + add_index :cti_caller_ids, [:caller_id] + add_index :cti_caller_ids, [:caller_id, :level] + add_index :cti_caller_ids, [:caller_id, :user_id] + add_index :cti_caller_ids, [:object, :o_id] + + end +end diff --git a/test/integration/sipgate_controller_test.rb b/test/integration/sipgate_controller_test.rb index a48fdeb0f..51774dfc7 100644 --- a/test/integration/sipgate_controller_test.rb +++ b/test/integration/sipgate_controller_test.rb @@ -82,6 +82,44 @@ class SipgateControllerTest < ActionDispatch::IntegrationTest created_by_id: 1, ) + customer1 = User.create_or_update( + login: 'ticket-caller_id_sipgate-customer1@example.com', + firstname: 'CallerId', + lastname: 'Customer1', + email: 'ticket-caller_id_sipgate-customer1@example.com', + password: 'customerpw', + active: true, + phone: '+49 99999 222222', + fax: '+49 99999 222223', + mobile: '+4912347114711', + note: 'Phone at home: +49 99999 222224', + updated_by_id: 1, + created_by_id: 1, + ) + customer2 = User.create_or_update( + login: 'ticket-caller_id_sipgate-customer2@example.com', + firstname: 'CallerId', + lastname: 'Customer2', + email: 'ticket-caller_id_sipgate-customer2@example.com', + password: 'customerpw', + active: true, + phone: '+49 99999 222222 2', + updated_by_id: 1, + created_by_id: 1, + ) + customer3 = User.create_or_update( + login: 'ticket-caller_id_sipgate-customer3@example.com', + firstname: 'CallerId', + lastname: 'Customer3', + email: 'ticket-caller_id_sipgate-customer3@example.com', + password: 'customerpw', + active: true, + phone: '+49 99999 222222 2', + updated_by_id: 1, + created_by_id: 1, + ) + Cti::CallerId.rebuild + end test 'basic call' do @@ -223,6 +261,7 @@ class SipgateControllerTest < ActionDispatch::IntegrationTest assert_equal('4912347114711', log.to) assert_equal('out', log.direction) assert_equal('user 1', log.from_comment) + assert_equal('CallerId Customer1', log.to_comment) assert_equal(nil, log.comment) assert_equal('newCall', log.state) assert_equal(true, log.done) @@ -237,6 +276,7 @@ class SipgateControllerTest < ActionDispatch::IntegrationTest assert_equal('4912347114711', log.to) assert_equal('out', log.direction) assert_equal('user 1', log.from_comment) + assert_equal('CallerId Customer1', log.to_comment) assert_equal('cancel', log.comment) assert_equal('hangup', log.state) assert_equal(true, log.done) @@ -251,6 +291,7 @@ class SipgateControllerTest < ActionDispatch::IntegrationTest assert_equal('4912347114711', log.to) assert_equal('out', log.direction) assert_equal('user 1', log.from_comment) + assert_equal('CallerId Customer1', log.to_comment) assert_equal(nil, log.comment) assert_equal('newCall', log.state) assert_equal(true, log.done) @@ -265,6 +306,7 @@ class SipgateControllerTest < ActionDispatch::IntegrationTest assert_equal('4912347114711', log.to) assert_equal('out', log.direction) assert_equal('user 1', log.from_comment) + assert_equal('CallerId Customer1', log.to_comment) assert_equal(nil, log.comment) assert_equal('answer', log.state) assert_equal(true, log.done) @@ -279,6 +321,7 @@ class SipgateControllerTest < ActionDispatch::IntegrationTest assert_equal('4912347114711', log.to) assert_equal('out', log.direction) assert_equal('user 1', log.from_comment) + assert_equal('CallerId Customer1', log.to_comment) assert_equal('normalClearing', log.comment) assert_equal('hangup', log.state) assert_equal(true, log.done) @@ -293,6 +336,7 @@ class SipgateControllerTest < ActionDispatch::IntegrationTest assert_equal('4912347114711', log.from) assert_equal('in', log.direction) assert_equal('user 1', log.to_comment) + assert_equal('CallerId Customer1', log.from_comment) assert_equal(nil, log.comment) assert_equal('newCall', log.state) assert_equal(true, log.done) @@ -307,6 +351,7 @@ class SipgateControllerTest < ActionDispatch::IntegrationTest assert_equal('4912347114711', log.from) assert_equal('in', log.direction) assert_equal('user 1', log.to_comment) + assert_equal('CallerId Customer1', log.from_comment) assert_equal(nil, log.comment) assert_equal('answer', log.state) assert_equal(true, log.done) @@ -321,6 +366,7 @@ class SipgateControllerTest < ActionDispatch::IntegrationTest assert_equal('4912347114711', log.from) assert_equal('in', log.direction) assert_equal('user 1', log.to_comment) + assert_equal('CallerId Customer1', log.from_comment) assert_equal('normalClearing', log.comment) assert_equal('hangup', log.state) assert_equal(true, log.done) @@ -335,6 +381,7 @@ class SipgateControllerTest < ActionDispatch::IntegrationTest assert_equal('4912347114711', log.from) assert_equal('in', log.direction) assert_equal('user 1,user 2', log.to_comment) + assert_equal('CallerId Customer1', log.from_comment) assert_equal(nil, log.comment) assert_equal('newCall', log.state) assert_equal(true, log.done) @@ -349,6 +396,7 @@ class SipgateControllerTest < ActionDispatch::IntegrationTest assert_equal('4912347114711', log.from) assert_equal('in', log.direction) assert_equal('voicemail', log.to_comment) + assert_equal('CallerId Customer1', log.from_comment) assert_equal(nil, log.comment) assert_equal('answer', log.state) assert_equal(true, log.done) @@ -363,6 +411,7 @@ class SipgateControllerTest < ActionDispatch::IntegrationTest assert_equal('4912347114711', log.from) assert_equal('in', log.direction) assert_equal('voicemail', log.to_comment) + assert_equal('CallerId Customer1', log.from_comment) assert_equal('normalClearing', log.comment) assert_equal('hangup', log.state) assert_equal(false, log.done) @@ -377,6 +426,7 @@ class SipgateControllerTest < ActionDispatch::IntegrationTest assert_equal('4912347114711', log.from) assert_equal('in', log.direction) assert_equal('user 1,user 2', log.to_comment) + assert_equal('CallerId Customer1', log.from_comment) assert_equal(nil, log.comment) assert_equal('newCall', log.state) assert_equal(true, log.done) @@ -391,10 +441,26 @@ class SipgateControllerTest < ActionDispatch::IntegrationTest assert_equal('4912347114711', log.from) assert_equal('in', log.direction) assert_equal('user 1,user 2', log.to_comment) + assert_equal('CallerId Customer1', log.from_comment) assert_equal('normalClearing', log.comment) assert_equal('hangup', log.state) assert_equal(false, log.done) + # inbound - IV - new call + params = 'event=newCall&direction=in&to=4930600000000&from=49999992222222&callId=1234567890-6&user%5B%5D=user+1,user+2' + post '/api/v1/sipgate/in', params + assert_response(200) + log = Cti::Log.find_by(call_id: '1234567890-6') + assert(log) + assert_equal('4930600000000', log.to) + assert_equal('49999992222222', log.from) + assert_equal('in', log.direction) + assert_equal('user 1,user 2', log.to_comment) + assert_equal('CallerId Customer3,CallerId Customer2', log.from_comment) + assert_equal(nil, log.comment) + assert_equal('newCall', log.state) + assert_equal(true, log.done) + # get caller list get '/api/v1/cti/log' assert_response(401) @@ -405,15 +471,20 @@ class SipgateControllerTest < ActionDispatch::IntegrationTest assert_response(200) result = JSON.parse(@response.body) assert_equal(result.class, Array) - assert_equal(5, result.count) - assert_equal('hangup', result[1]['state']) - assert_equal('4930777000000', result[1]['from']) - assert_equal('user 1', result[1]['from_comment']) - assert_equal('4912347114711', result[1]['to']) - assert_equal(nil, result[1]['to_comment']) - assert_equal('1234567890-2', result[1]['call_id']) - assert_equal('normalClearing', result[1]['comment']) - assert_equal('hangup', result[1]['state']) + assert_equal(6, result.count) + assert_equal('1234567890-6', result[0]['call_id']) + assert_equal('1234567890-5', result[1]['call_id']) + assert_equal('1234567890-4', result[2]['call_id']) + assert_equal('1234567890-3', result[3]['call_id']) + assert_equal('1234567890-2', result[4]['call_id']) + assert_equal('hangup', result[4]['state']) + assert_equal('4930777000000', result[4]['from']) + assert_equal('user 1', result[4]['from_comment']) + assert_equal('4912347114711', result[4]['to']) + assert_equal('CallerId Customer1', result[4]['to_comment']) + assert_equal('normalClearing', result[4]['comment']) + assert_equal('hangup', result[4]['state']) + assert_equal('1234567890-1', result[5]['call_id']) end diff --git a/test/unit/cti_caller_id_test.rb b/test/unit/cti_caller_id_test.rb new file mode 100644 index 000000000..5122a8ca7 --- /dev/null +++ b/test/unit/cti_caller_id_test.rb @@ -0,0 +1,249 @@ +# encoding: utf-8 +require 'test_helper' + +class CtiCallerIdTest < ActiveSupport::TestCase + + test '1 parse possible phone numbers in text' do + text = "some text\ntest 123" + result = [] + assert_equal(result, Cti::CallerId.parse_text(text)) + + text = '0049 1234 123456789' + result = ['491234123456789'] + assert_equal(result, Cti::CallerId.parse_text(text)) + + text = '022 1234567' + result = ['49221234567'] + assert_equal(result, Cti::CallerId.parse_text(text)) + + text = '0271233211' + result = ['49271233211'] + assert_equal(result, Cti::CallerId.parse_text(text)) + + text = '021-233-9123' + result = ['49212339123'] + assert_equal(result, Cti::CallerId.parse_text(text)) + + text = '09 123 32112' + result = ['49912332112'] + assert_equal(result, Cti::CallerId.parse_text(text)) + + text = '021 2331231' + result = ['49212331231'] + assert_equal(result, Cti::CallerId.parse_text(text)) + + text = '021 321123123' + result = ['4921321123123'] + assert_equal(result, Cti::CallerId.parse_text(text)) + + text = '622 32281' + result = ['4962232281'] + assert_equal(result, Cti::CallerId.parse_text(text)) + + text = '5754321' + result = ['495754321'] + assert_equal(result, Cti::CallerId.parse_text(text)) + + text = '092213212' + result = ['4992213212'] + assert_equal(result, Cti::CallerId.parse_text(text)) + + text = '(09)1234321' + result = ['4991234321'] + assert_equal(result, Cti::CallerId.parse_text(text)) + + text = '+49 30 53 00 00 000' + result = ['4930530000000'] + assert_equal(result, Cti::CallerId.parse_text(text)) + + text = '+49 160 0000000' + result = ['491600000000'] + assert_equal(result, Cti::CallerId.parse_text(text)) + + text = '+49 (0) 30 60 00 00 00-0' + result = ['4930600000000'] + assert_equal(result, Cti::CallerId.parse_text(text)) + + text = '0043 (0) 30 60 00 00 00-0' + result = ['4330600000000'] + assert_equal(result, Cti::CallerId.parse_text(text)) + + text = '0043 30 60 00 00 00-0' + result = ['4330600000000'] + assert_equal(result, Cti::CallerId.parse_text(text)) + + text = '1-888-407-4747' + result = ['18884074747'] + assert_equal(result, Cti::CallerId.parse_text(text)) + + text = '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.' + result = ['4930600000000'] + assert_equal(result, Cti::CallerId.parse_text(text)) + + text = "GS Oberalteich\nTelefon 09422 1000 Telefax 09422 805000\nE-Mail: " + result = %w(4994221000 499422805000) + assert_equal(result, Cti::CallerId.parse_text(text)) + + text = 'Tel +41 81 288 63 93 / +41 76 346 72 14 ...' + result = %w(41812886393 41763467214) + assert_equal(result, Cti::CallerId.parse_text(text)) + + text = "P: +1 (949) 431 0000\nF: +1 (949) 431 0001\nW: http://znuny" + result = %w(19494310000 19494310001) + assert_equal(result, Cti::CallerId.parse_text(text)) + + end + + test '2 lookups' do + + Ticket.destroy_all + Cti::CallerId.destroy_all + + agent1 = User.create_or_update( + login: 'ticket-caller_id-agent1@example.com', + firstname: 'CallerId', + lastname: 'Agent1', + email: 'ticket-caller_id-agent1@example.com', + password: 'agentpw', + active: true, + phone: '+49 1111 222222', + fax: '+49 1111 222223', + mobile: '+49 1111 222223', + note: 'Phone at home: +49 1111 222224', + updated_by_id: 1, + created_by_id: 1, + ) + agent2 = User.create_or_update( + login: 'ticket-caller_id-agent2@example.com', + firstname: 'CallerId', + lastname: 'Agent2', + email: 'ticket-caller_id-agent2@example.com', + password: 'agentpw', + phone: '+49 2222 222222', + note: 'Phone at home: +49 2222 222224', + active: true, + updated_by_id: 1, + created_by_id: 1, + ) + agent3 = User.create_or_update( + login: 'ticket-caller_id-agent3@example.com', + firstname: 'CallerId', + lastname: 'Agent3', + email: 'ticket-caller_id-agent3@example.com', + password: 'agentpw', + phone: '+49 2222 222222', + active: true, + updated_by_id: 1, + created_by_id: 1, + ) + + customer1 = User.create_or_update( + login: 'ticket-caller_id-customer1@example.com', + firstname: 'CallerId', + lastname: 'Customer1', + email: 'ticket-caller_id-customer1@example.com', + password: 'customerpw', + active: true, + updated_by_id: 1, + created_by_id: 1, + ) + + Cti::CallerId.rebuild + + caller_ids = Cti::CallerId.lookup('491111222277') + assert_equal(0, caller_ids.count) + + caller_ids = Cti::CallerId.lookup('491111222223') + assert_equal(1, caller_ids.count) + assert_equal(agent1.id, caller_ids[0].user_id) + assert_equal('known', caller_ids[0].level) + + caller_ids = Cti::CallerId.lookup('492222222222') + assert_equal(2, caller_ids.count) + assert_equal(agent3.id, caller_ids[0].user_id) + assert_equal('known', caller_ids[0].level) + assert_equal(agent2.id, caller_ids[1].user_id) + assert_equal('known', caller_ids[1].level) + + # create ticket in group + ticket1 = Ticket.create( + title: 'some caller id test 1', + group: Group.lookup(name: 'Users'), + customer: customer1, + state: Ticket::State.lookup(name: 'new'), + priority: Ticket::Priority.lookup(name: '2 normal'), + updated_by_id: agent1.id, + created_by_id: agent1.id, + ) + article1 = 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\nFon (GEL): +49 111 366-1111 Mi-Fr +Fon (LIN): +49 222 6112222 Mo-Di +Mob: +49 333 8362222", + internal: false, + sender: Ticket::Article::Sender.where(name: 'Customer').first, + type: Ticket::Article::Type.where(name: 'email').first, + updated_by_id: customer1.id, + created_by_id: customer1.id, + ) + assert(ticket1) + + # create ticket in group + ticket2 = Ticket.create( + title: 'some caller id test 2', + group: Group.lookup(name: 'Users'), + customer: customer1, + state: Ticket::State.lookup(name: 'new'), + priority: Ticket::Priority.lookup(name: '2 normal'), + updated_by_id: agent1.id, + created_by_id: agent1.id, + ) + article2 = Ticket::Article.create( + ticket_id: ticket2.id, + from: 'some_sender@example.com', + to: 'some_recipient@example.com', + subject: 'some subject', + message_id: 'some@id', + body: "some message\nFon (GEL): +49 111 111-1111 Mi-Fr +Fon (LIN): +49 222 1112222 Mo-Di +Mob: +49 333 1112222", + internal: false, + sender: Ticket::Article::Sender.where(name: 'Agent').first, + type: Ticket::Article::Type.where(name: 'email').first, + updated_by_id: agent1.id, + created_by_id: agent1.id, + ) + assert(ticket2) + + Cti::CallerId.rebuild + + caller_ids = Cti::CallerId.lookup('491111222277') + assert_equal(0, caller_ids.count) + + caller_ids = Cti::CallerId.lookup('491111222223') + assert_equal(1, caller_ids.count) + assert_equal(agent1.id, caller_ids[0].user_id) + assert_equal('known', caller_ids[0].level) + + caller_ids = Cti::CallerId.lookup('492222222222') + assert_equal(2, caller_ids.count) + assert_equal(agent3.id, caller_ids[0].user_id) + assert_equal('known', caller_ids[0].level) + assert_equal(agent2.id, caller_ids[1].user_id) + assert_equal('known', caller_ids[1].level) + + caller_ids = Cti::CallerId.lookup('492226112222') + assert_equal(1, caller_ids.count) + assert_equal(customer1.id, caller_ids[0].user_id) + assert_equal('maybe', caller_ids[0].level) + + caller_ids = Cti::CallerId.lookup('492221112222') + assert_equal(0, caller_ids.count) + + end + +end