Fixed issue #2255 - CTI: Limit used caller log states and prevent race conditions (if callback comes later).
This commit is contained in:
parent
cff3dba0a8
commit
ce9ebe828f
2 changed files with 233 additions and 29 deletions
|
@ -4,6 +4,8 @@ module Cti
|
|||
|
||||
store :preferences
|
||||
|
||||
validates :state, format: { with: /\A(newCall|answer|hangup)\z/, message: 'newCall|answer|hangup is allowed' }
|
||||
|
||||
after_commit :push_incoming_call, :push_caller_list_update
|
||||
|
||||
=begin
|
||||
|
@ -288,7 +290,7 @@ Cti::Log.process(
|
|||
=end
|
||||
|
||||
def self.process(params)
|
||||
comment = params['cause']
|
||||
cause = params['cause']
|
||||
event = params['event']
|
||||
user = params['user']
|
||||
call_id = params['callId'] || params['call_id']
|
||||
|
@ -308,11 +310,14 @@ Cti::Log.process(
|
|||
to_comment, preferences = CallerId.get_comment_preferences(params['to'], 'to')
|
||||
end
|
||||
|
||||
log = find_by(call_id: call_id)
|
||||
|
||||
case event
|
||||
when 'newCall'
|
||||
if params['direction'] == 'in'
|
||||
done = false
|
||||
end
|
||||
raise "call_id #{call_id} already exists!" if log
|
||||
create(
|
||||
direction: params['direction'],
|
||||
from: params['from'],
|
||||
|
@ -320,15 +325,16 @@ Cti::Log.process(
|
|||
to: params['to'],
|
||||
to_comment: to_comment,
|
||||
call_id: call_id,
|
||||
comment: comment,
|
||||
comment: cause,
|
||||
state: event,
|
||||
initialized_at: Time.zone.now,
|
||||
preferences: preferences,
|
||||
done: done,
|
||||
)
|
||||
when 'answer'
|
||||
log = find_by(call_id: call_id)
|
||||
raise "No such call_id #{call_id}" if !log
|
||||
return if log.state == 'hangup' # call is already hangup, ignore answer
|
||||
log.with_lock do
|
||||
log.state = 'answer'
|
||||
log.start_at = Time.zone.now
|
||||
log.duration_waiting_time = log.start_at.to_i - log.initialized_at.to_i
|
||||
|
@ -336,14 +342,15 @@ Cti::Log.process(
|
|||
log.to_comment = user
|
||||
end
|
||||
log.done = true
|
||||
log.comment = comment
|
||||
log.comment = cause
|
||||
log.save
|
||||
end
|
||||
when 'hangup'
|
||||
log = find_by(call_id: call_id)
|
||||
raise "No such call_id #{call_id}" if !log
|
||||
log.with_lock do
|
||||
log.done = done
|
||||
if params['direction'] == 'in'
|
||||
if log.state == 'newCall'
|
||||
if log.state == 'newCall' && cause != 'forwarded'
|
||||
log.done = false
|
||||
elsif log.to_comment == 'voicemail'
|
||||
log.done = false
|
||||
|
@ -356,8 +363,9 @@ Cti::Log.process(
|
|||
elsif !log.duration_waiting_time && log.initialized_at
|
||||
log.duration_waiting_time = log.end_at.to_i - log.initialized_at.to_i
|
||||
end
|
||||
log.comment = comment
|
||||
log.comment = cause
|
||||
log.save
|
||||
end
|
||||
else
|
||||
raise ArgumentError, "Unknown event #{event.inspect}"
|
||||
end
|
||||
|
|
|
@ -547,4 +547,200 @@ Mob: +49 333 8362222",
|
|||
assert_equal(0, Cti::CallerId.where(user_id: @agent2.id).count)
|
||||
end
|
||||
|
||||
test 'order of events' do
|
||||
Cti::Log.process(
|
||||
'cause' => '',
|
||||
'event' => 'newCall',
|
||||
'user' => 'user 1',
|
||||
'from' => '491111222222',
|
||||
'to' => '4930600000000',
|
||||
'callId' => 'touch-loop-1',
|
||||
'direction' => 'in',
|
||||
)
|
||||
|
||||
last = Cti::Log.last
|
||||
assert_equal(last.state, 'newCall')
|
||||
assert_equal(last.done, false)
|
||||
|
||||
travel 2.seconds
|
||||
Cti::Log.process(
|
||||
'cause' => '',
|
||||
'event' => 'hangup',
|
||||
'user' => 'user 1',
|
||||
'from' => '491111222222',
|
||||
'to' => '4930600000000',
|
||||
'callId' => 'touch-loop-1',
|
||||
'direction' => 'in',
|
||||
)
|
||||
last.reload
|
||||
assert_equal(last.state, 'hangup')
|
||||
assert_equal(last.done, false)
|
||||
|
||||
travel 2.seconds
|
||||
Cti::Log.process(
|
||||
'cause' => '',
|
||||
'event' => 'answer',
|
||||
'user' => 'user 1',
|
||||
'from' => '491111222222',
|
||||
'to' => '4930600000000',
|
||||
'callId' => 'touch-loop-1',
|
||||
'direction' => 'in',
|
||||
)
|
||||
last.reload
|
||||
assert_equal(last.state, 'hangup')
|
||||
assert_equal(last.done, false)
|
||||
|
||||
end
|
||||
|
||||
test 'not answered should be not marked as done' do
|
||||
|
||||
Cti::Log.process(
|
||||
'cause' => '',
|
||||
'event' => 'newCall',
|
||||
'user' => 'user 1',
|
||||
'from' => '491111222222',
|
||||
'to' => '4930600000000',
|
||||
'callId' => 'touch-loop-1',
|
||||
'direction' => 'in',
|
||||
)
|
||||
|
||||
last = Cti::Log.last
|
||||
assert_equal(last.state, 'newCall')
|
||||
assert_equal(last.done, false)
|
||||
|
||||
travel 2.seconds
|
||||
Cti::Log.process(
|
||||
'cause' => '',
|
||||
'event' => 'hangup',
|
||||
'user' => 'user 1',
|
||||
'from' => '491111222222',
|
||||
'to' => '4930600000000',
|
||||
'callId' => 'touch-loop-1',
|
||||
'direction' => 'in',
|
||||
)
|
||||
last.reload
|
||||
assert_equal(last.state, 'hangup')
|
||||
assert_equal(last.done, false)
|
||||
end
|
||||
|
||||
test 'answered should be marked as done' do
|
||||
|
||||
Cti::Log.process(
|
||||
'cause' => '',
|
||||
'event' => 'newCall',
|
||||
'user' => 'user 1',
|
||||
'from' => '491111222222',
|
||||
'to' => '4930600000000',
|
||||
'callId' => 'touch-loop-1',
|
||||
'direction' => 'in',
|
||||
)
|
||||
|
||||
last = Cti::Log.last
|
||||
assert_equal(last.state, 'newCall')
|
||||
assert_equal(last.done, false)
|
||||
|
||||
travel 2.seconds
|
||||
Cti::Log.process(
|
||||
'cause' => '',
|
||||
'event' => 'answer',
|
||||
'user' => 'user 1',
|
||||
'from' => '491111222222',
|
||||
'to' => '4930600000000',
|
||||
'callId' => 'touch-loop-1',
|
||||
'direction' => 'in',
|
||||
)
|
||||
last = Cti::Log.last
|
||||
assert_equal(last.state, 'answer')
|
||||
assert_equal(last.done, true)
|
||||
|
||||
travel 2.seconds
|
||||
Cti::Log.process(
|
||||
'cause' => '',
|
||||
'event' => 'hangup',
|
||||
'user' => 'user 1',
|
||||
'from' => '491111222222',
|
||||
'to' => '4930600000000',
|
||||
'callId' => 'touch-loop-1',
|
||||
'direction' => 'in',
|
||||
)
|
||||
last.reload
|
||||
assert_equal(last.state, 'hangup')
|
||||
assert_equal(last.done, true)
|
||||
end
|
||||
|
||||
test 'voicemail should not be marked as done' do
|
||||
|
||||
Cti::Log.process(
|
||||
'cause' => '',
|
||||
'event' => 'newCall',
|
||||
'user' => 'user 1',
|
||||
'from' => '491111222222',
|
||||
'to' => '4930600000000',
|
||||
'callId' => 'touch-loop-1',
|
||||
'direction' => 'in',
|
||||
)
|
||||
|
||||
last = Cti::Log.last
|
||||
assert_equal(last.state, 'newCall')
|
||||
assert_equal(last.done, false)
|
||||
|
||||
Cti::Log.process(
|
||||
'cause' => '',
|
||||
'event' => 'answer',
|
||||
'user' => 'voicemail',
|
||||
'from' => '491111222222',
|
||||
'to' => '4930600000000',
|
||||
'callId' => 'touch-loop-1',
|
||||
'direction' => 'in',
|
||||
)
|
||||
last = Cti::Log.last
|
||||
assert_equal(last.state, 'answer')
|
||||
assert_equal(last.done, true)
|
||||
|
||||
travel 2.seconds
|
||||
Cti::Log.process(
|
||||
'cause' => '',
|
||||
'event' => 'hangup',
|
||||
'user' => 'user 1',
|
||||
'from' => '491111222222',
|
||||
'to' => '4930600000000',
|
||||
'callId' => 'touch-loop-1',
|
||||
'direction' => 'in',
|
||||
)
|
||||
last.reload
|
||||
assert_equal(last.state, 'hangup')
|
||||
assert_equal(last.done, false)
|
||||
end
|
||||
|
||||
test 'forwarded should be marked as done' do
|
||||
|
||||
Cti::Log.process(
|
||||
'cause' => '',
|
||||
'event' => 'newCall',
|
||||
'user' => 'user 1',
|
||||
'from' => '491111222222',
|
||||
'to' => '4930600000000',
|
||||
'callId' => 'touch-loop-1',
|
||||
'direction' => 'in',
|
||||
)
|
||||
|
||||
last = Cti::Log.last
|
||||
assert_equal(last.state, 'newCall')
|
||||
assert_equal(last.done, false)
|
||||
|
||||
travel 2.seconds
|
||||
Cti::Log.process(
|
||||
'cause' => 'forwarded',
|
||||
'event' => 'hangup',
|
||||
'user' => 'user 1',
|
||||
'from' => '491111222222',
|
||||
'to' => '4930600000000',
|
||||
'callId' => 'touch-loop-1',
|
||||
'direction' => 'in',
|
||||
)
|
||||
last.reload
|
||||
assert_equal(last.state, 'hangup')
|
||||
assert_equal(last.done, true)
|
||||
end
|
||||
|
||||
end
|
||||
|
|
Loading…
Reference in a new issue