Update queue position also if customer closed chat. Get new chat state from server after client closed chat. Added more indexes.
This commit is contained in:
parent
543c27a0bc
commit
646c11406c
10 changed files with 527 additions and 51 deletions
|
@ -26,7 +26,7 @@ class Chat < ApplicationModel
|
||||||
}
|
}
|
||||||
|
|
||||||
# get queue postion if needed
|
# get queue postion if needed
|
||||||
session = Chat.session_state(session_id)
|
session = Chat::Session.messages_by_session_id(session_id)
|
||||||
if session
|
if session
|
||||||
return {
|
return {
|
||||||
state: 'reconnect',
|
state: 'reconnect',
|
||||||
|
@ -51,10 +51,10 @@ class Chat < ApplicationModel
|
||||||
end
|
end
|
||||||
|
|
||||||
# if all seads are used
|
# if all seads are used
|
||||||
if active_chat_count >= max_queue
|
if Chat.active_chat_count >= max_queue
|
||||||
return {
|
return {
|
||||||
state: 'no_seats_available',
|
state: 'no_seats_available',
|
||||||
queue: seads_available,
|
queue: Chat.seads_available,
|
||||||
}
|
}
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -62,32 +62,14 @@ class Chat < ApplicationModel
|
||||||
{ state: 'online' }
|
{ state: 'online' }
|
||||||
end
|
end
|
||||||
|
|
||||||
def self.session_state(session_id)
|
|
||||||
session_attributes = []
|
|
||||||
chat_session = Chat::Session.find_by(session_id: session_id)
|
|
||||||
return if !chat_session
|
|
||||||
Chat::Message.where(chat_session_id: chat_session.id).each { |message|
|
|
||||||
session_attributes.push message.attributes
|
|
||||||
}
|
|
||||||
session_attributes
|
|
||||||
end
|
|
||||||
|
|
||||||
def self.agent_state(user_id)
|
def self.agent_state(user_id)
|
||||||
return { state: 'chat_disabled' } if !Setting.get('chat')
|
return { state: 'chat_disabled' } if !Setting.get('chat')
|
||||||
actice_sessions = []
|
|
||||||
Chat::Session.where(state: 'running', user_id: user_id).order('created_at ASC').each {|session|
|
|
||||||
session_attributes = session.attributes
|
|
||||||
session_attributes['messages'] = []
|
|
||||||
Chat::Message.where(chat_session_id: session.id).each { |message|
|
|
||||||
session_attributes['messages'].push message.attributes
|
|
||||||
}
|
|
||||||
actice_sessions.push session_attributes
|
|
||||||
}
|
|
||||||
{
|
{
|
||||||
waiting_chat_count: waiting_chat_count,
|
waiting_chat_count: waiting_chat_count,
|
||||||
running_chat_count: running_chat_count,
|
running_chat_count: running_chat_count,
|
||||||
#available_agents: available_agents,
|
active_sessions: Chat::Session.active_chats_by_user_id(user_id),
|
||||||
active_sessions: actice_sessions,
|
seads_available: seads_available,
|
||||||
|
seads_total: seads_total,
|
||||||
active: Chat::Agent.state(user_id)
|
active: Chat::Agent.state(user_id)
|
||||||
}
|
}
|
||||||
end
|
end
|
||||||
|
@ -100,11 +82,11 @@ class Chat < ApplicationModel
|
||||||
Chat::Session.where(state: ['running']).count
|
Chat::Session.where(state: ['running']).count
|
||||||
end
|
end
|
||||||
|
|
||||||
def active_chat_count
|
def self.active_chat_count
|
||||||
Chat::Session.where(state: %w(waiting running)).count
|
Chat::Session.where(state: %w(waiting running)).count
|
||||||
end
|
end
|
||||||
|
|
||||||
def available_agents(diff = 2.minutes)
|
def self.available_agents(diff = 2.minutes)
|
||||||
agents = {}
|
agents = {}
|
||||||
Chat::Agent.where(active: true).where('updated_at > ?', Time.zone.now - diff).each {|record|
|
Chat::Agent.where(active: true).where('updated_at > ?', Time.zone.now - diff).each {|record|
|
||||||
agents[record.updated_by_id] = record.concurrent
|
agents[record.updated_by_id] = record.concurrent
|
||||||
|
@ -112,15 +94,15 @@ class Chat < ApplicationModel
|
||||||
agents
|
agents
|
||||||
end
|
end
|
||||||
|
|
||||||
def seads_total(diff = 2.minutes)
|
def self.seads_total(diff = 2.minutes)
|
||||||
total = 0
|
total = 0
|
||||||
available_agents(diff).each {|_record, concurrent|
|
available_agents(diff).each {|_user_id, concurrent|
|
||||||
total += concurrent
|
total += concurrent
|
||||||
}
|
}
|
||||||
total
|
total
|
||||||
end
|
end
|
||||||
|
|
||||||
def seads_available(diff = 2.minutes)
|
def self.seads_available(diff = 2.minutes)
|
||||||
seads_total(diff) - active_chat_count
|
seads_total(diff) - active_chat_count
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -35,4 +35,27 @@ class Chat::Session < ApplicationModel
|
||||||
}
|
}
|
||||||
position
|
position
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def self.messages_by_session_id(session_id)
|
||||||
|
chat_session = Chat::Session.find_by(session_id: session_id)
|
||||||
|
return if !chat_session
|
||||||
|
session_attributes = []
|
||||||
|
Chat::Message.where(chat_session_id: chat_session.id).each { |message|
|
||||||
|
session_attributes.push message.attributes
|
||||||
|
}
|
||||||
|
session_attributes
|
||||||
|
end
|
||||||
|
|
||||||
|
def self.active_chats_by_user_id(user_id)
|
||||||
|
actice_sessions = []
|
||||||
|
Chat::Session.where(state: 'running', user_id: user_id).order('created_at ASC').each {|session|
|
||||||
|
session_attributes = session.attributes
|
||||||
|
session_attributes['messages'] = []
|
||||||
|
Chat::Message.where(chat_session_id: session.id).each { |message|
|
||||||
|
session_attributes['messages'].push message.attributes
|
||||||
|
}
|
||||||
|
actice_sessions.push session_attributes
|
||||||
|
}
|
||||||
|
actice_sessions
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
9
db/migrate/20151113000001_update_chat.rb
Normal file
9
db/migrate/20151113000001_update_chat.rb
Normal file
|
@ -0,0 +1,9 @@
|
||||||
|
class UpdateChat < ActiveRecord::Migration
|
||||||
|
def up
|
||||||
|
add_index :chat_sessions, [:session_id]
|
||||||
|
add_index :chat_sessions, [:chat_id]
|
||||||
|
add_index :chat_messages, [:chat_session_id]
|
||||||
|
add_index :chat_agents, [:active]
|
||||||
|
add_index :chat_agents, [:updated_by_id], unique: true
|
||||||
|
end
|
||||||
|
end
|
|
@ -4,7 +4,6 @@ class Sessions::Event::ChatBase
|
||||||
@data = data
|
@data = data
|
||||||
@session = session
|
@session = session
|
||||||
@client_id = client_id
|
@client_id = client_id
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
def pre
|
def pre
|
||||||
|
@ -35,4 +34,22 @@ class Sessions::Event::ChatBase
|
||||||
}
|
}
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def broadcast_customer_state_update
|
||||||
|
|
||||||
|
# send position update to other waiting sessions
|
||||||
|
position = 0
|
||||||
|
Chat::Session.where(state: 'waiting').order('created_at ASC').each {|local_chat_session|
|
||||||
|
position += 1
|
||||||
|
data = {
|
||||||
|
event: 'chat_session_queue',
|
||||||
|
data: {
|
||||||
|
state: 'queue',
|
||||||
|
position: position,
|
||||||
|
session_id: local_chat_session.session_id,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
local_chat_session.send_to_recipients(data)
|
||||||
|
}
|
||||||
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
|
@ -49,6 +49,9 @@ class Sessions::Event::ChatSessionClose < Sessions::Event::ChatBase
|
||||||
# set state update to all agents
|
# set state update to all agents
|
||||||
broadcast_agent_state_update
|
broadcast_agent_state_update
|
||||||
|
|
||||||
|
# send position update to other waiting sessions
|
||||||
|
broadcast_customer_state_update
|
||||||
|
|
||||||
# notify about "leaving"
|
# notify about "leaving"
|
||||||
else
|
else
|
||||||
message = {
|
message = {
|
||||||
|
|
|
@ -39,20 +39,9 @@ class Sessions::Event::ChatSessionStart < Sessions::Event::ChatBase
|
||||||
chat_session.send_to_recipients(data)
|
chat_session.send_to_recipients(data)
|
||||||
|
|
||||||
# send position update to other waiting sessions
|
# send position update to other waiting sessions
|
||||||
position = 0
|
broadcast_customer_state_update
|
||||||
Chat::Session.where(state: 'waiting').order('created_at ASC').each {|local_chat_session|
|
|
||||||
position += 1
|
|
||||||
data = {
|
|
||||||
event: 'chat_session_queue',
|
|
||||||
data: {
|
|
||||||
state: 'queue',
|
|
||||||
position: position,
|
|
||||||
session_id: local_chat_session.session_id,
|
|
||||||
},
|
|
||||||
}
|
|
||||||
local_chat_session.send_to_recipients(data)
|
|
||||||
}
|
|
||||||
|
|
||||||
|
# send state update to agents
|
||||||
broadcast_agent_state_update
|
broadcast_agent_state_update
|
||||||
|
|
||||||
nil
|
nil
|
||||||
|
|
|
@ -132,12 +132,15 @@ do($ = window.jQuery, window) ->
|
||||||
@log 'debug', 'Zammad Chat: ready'
|
@log 'debug', 'Zammad Chat: ready'
|
||||||
when 'offline'
|
when 'offline'
|
||||||
@onError 'Zammad Chat: No agent online'
|
@onError 'Zammad Chat: No agent online'
|
||||||
|
@hide()
|
||||||
@wsClose()
|
@wsClose()
|
||||||
when 'chat_disabled'
|
when 'chat_disabled'
|
||||||
@onError 'Zammad Chat: Chat is disabled'
|
@onError 'Zammad Chat: Chat is disabled'
|
||||||
|
@hide()
|
||||||
@wsClose()
|
@wsClose()
|
||||||
when 'no_seats_available'
|
when 'no_seats_available'
|
||||||
@onError 'Zammad Chat: Too many clients in queue. Clients in queue: ', pipe.data.queue
|
@onError 'Zammad Chat: Too many clients in queue. Clients in queue: ', pipe.data.queue
|
||||||
|
@hide()
|
||||||
@wsClose()
|
@wsClose()
|
||||||
when 'reconnect'
|
when 'reconnect'
|
||||||
@log 'debug', 'old messages', pipe.data.session
|
@log 'debug', 'old messages', pipe.data.session
|
||||||
|
@ -291,9 +294,6 @@ do($ = window.jQuery, window) ->
|
||||||
if @onInitialQueueDelayId
|
if @onInitialQueueDelayId
|
||||||
clearTimeout(@onInitialQueueDelayId)
|
clearTimeout(@onInitialQueueDelayId)
|
||||||
|
|
||||||
sessionStorage.removeItem 'sessionId'
|
|
||||||
sessionStorage.removeItem 'unfinished_message'
|
|
||||||
|
|
||||||
@closeWindow()
|
@closeWindow()
|
||||||
|
|
||||||
closeWindow: =>
|
closeWindow: =>
|
||||||
|
@ -309,6 +309,10 @@ do($ = window.jQuery, window) ->
|
||||||
session_id: @sessionId
|
session_id: @sessionId
|
||||||
|
|
||||||
@setSessionId undefined
|
@setSessionId undefined
|
||||||
|
sessionStorage.removeItem 'unfinished_message'
|
||||||
|
|
||||||
|
# restart connection
|
||||||
|
@onWebSocketOpen()
|
||||||
|
|
||||||
hide: ->
|
hide: ->
|
||||||
@el.removeClass('zammad-chat-is-visible')
|
@el.removeClass('zammad-chat-is-visible')
|
||||||
|
|
|
@ -2,7 +2,6 @@
|
||||||
<meta charset="utf-8">
|
<meta charset="utf-8">
|
||||||
<title>Zammad Chat</title>
|
<title>Zammad Chat</title>
|
||||||
<link rel="stylesheet" href="chat.css">
|
<link rel="stylesheet" href="chat.css">
|
||||||
<link rel="stylesheet" href="znuny.css">
|
|
||||||
<meta name="viewport" content="width=device-width">
|
<meta name="viewport" content="width=device-width">
|
||||||
<script>document.write('<script src="http://' + (location.host || 'localhost').split(':')[0] + ':35738/livereload.js?snipver=1"></' + 'script>')</script>
|
<script>document.write('<script src="http://' + (location.host || 'localhost').split(':')[0] + ':35738/livereload.js?snipver=1"></' + 'script>')</script>
|
||||||
<style>
|
<style>
|
||||||
|
@ -66,7 +65,7 @@
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
||||||
<img class="mockup" width="100%" src="znuny.png">
|
<img class="mockup" width="100%" src="website.png">
|
||||||
|
|
||||||
<div class="settings">
|
<div class="settings">
|
||||||
<table>
|
<table>
|
||||||
|
@ -142,9 +141,6 @@
|
||||||
host: 'ws://localhost',
|
host: 'ws://localhost',
|
||||||
port: 6042,
|
port: 6042,
|
||||||
debug: true,
|
debug: true,
|
||||||
background: '#494d52',
|
|
||||||
flat: true,
|
|
||||||
show: false
|
|
||||||
});
|
});
|
||||||
|
|
||||||
$('.settings :input').on({
|
$('.settings :input').on({
|
||||||
|
|
147
public/assets/chat/znuny.html
Normal file
147
public/assets/chat/znuny.html
Normal file
|
@ -0,0 +1,147 @@
|
||||||
|
<!doctype html>
|
||||||
|
<meta charset="utf-8">
|
||||||
|
<title>Zammad Chat</title>
|
||||||
|
<link rel="stylesheet" href="chat.css">
|
||||||
|
<link rel="stylesheet" href="znuny.css">
|
||||||
|
<meta name="viewport" content="width=device-width">
|
||||||
|
<script>document.write('<script src="http://' + (location.host || 'localhost').split(':')[0] + ':35738/livereload.js?snipver=1"></' + 'script>')</script>
|
||||||
|
<style>
|
||||||
|
body {
|
||||||
|
margin: 0;
|
||||||
|
font-family: sans-serif;
|
||||||
|
}
|
||||||
|
|
||||||
|
.mockup {
|
||||||
|
vertical-align: bottom;
|
||||||
|
}
|
||||||
|
|
||||||
|
.settings {
|
||||||
|
position: fixed;
|
||||||
|
left: 20px;
|
||||||
|
top: 20px;
|
||||||
|
background: white;
|
||||||
|
font-size: 14px;
|
||||||
|
padding: 10px;
|
||||||
|
border-radius: 5px;
|
||||||
|
box-shadow: 0 3px 10px rgba(0,0,0,.3);
|
||||||
|
}
|
||||||
|
|
||||||
|
.settings input {
|
||||||
|
vertical-align: middle;
|
||||||
|
}
|
||||||
|
.settings input + input {
|
||||||
|
margin-right: 3px;
|
||||||
|
}
|
||||||
|
|
||||||
|
table td:first-child {
|
||||||
|
text-align: right;
|
||||||
|
padding-right: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
td {
|
||||||
|
padding: 5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
h2 {
|
||||||
|
font-size: 1em;
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
@media only screen and (max-width: 768px) {
|
||||||
|
.settings {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.Box {
|
||||||
|
background: hsl(0,0%,91%);
|
||||||
|
width: 26px;
|
||||||
|
height: 24px;
|
||||||
|
color: hsl(0,0%,47%);
|
||||||
|
float: left;
|
||||||
|
}
|
||||||
|
.Box.Active {
|
||||||
|
background: hsl(0,0%,36%);
|
||||||
|
color: white;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
||||||
|
<img class="mockup" width="100%" src="znuny.png">
|
||||||
|
|
||||||
|
<div class="settings">
|
||||||
|
<table>
|
||||||
|
<tr>
|
||||||
|
<td>
|
||||||
|
<td><h2>Settings</h2>
|
||||||
|
<tr>
|
||||||
|
<td>
|
||||||
|
<input id="flat" type="checkbox" data-option="flat">
|
||||||
|
<td>
|
||||||
|
<label for="flat">Flat Design</label>
|
||||||
|
<tr>
|
||||||
|
<td>
|
||||||
|
<input type="color" id="color" value="#AE99D6" data-option="color">
|
||||||
|
<td>
|
||||||
|
<label for="color">Color</label>
|
||||||
|
<tr>
|
||||||
|
<td>
|
||||||
|
<input type="range" id="borderRadius" value="5" min="0" max="20" data-option="borderRadius">
|
||||||
|
<input type="number" value="5" min="5" max="20" data-option="borderRadius">px
|
||||||
|
<td>
|
||||||
|
<label for="borderRadius">Border Radius</label>
|
||||||
|
<tr>
|
||||||
|
<td>
|
||||||
|
<input type="range" id="fontSize" value="12" min="11" max="18" data-option="fontSize">
|
||||||
|
<input type="number" value="12" min="11" max="18" data-option="fontSize">px
|
||||||
|
<td>
|
||||||
|
<label for="fontSize">Font Size</label>
|
||||||
|
<tr>
|
||||||
|
<td>
|
||||||
|
<td><button class="open-zammad-chat">Open Chat</button>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<script src="jquery-2.1.4.min.js"></script>
|
||||||
|
<script src="chat.js"></script>
|
||||||
|
<script>
|
||||||
|
var chat = new ZammadChat({
|
||||||
|
host: 'ws://localhost',
|
||||||
|
port: 6042,
|
||||||
|
debug: true,
|
||||||
|
background: '#494d52',
|
||||||
|
flat: true,
|
||||||
|
shown: false
|
||||||
|
});
|
||||||
|
|
||||||
|
$('.settings :input').on({
|
||||||
|
change: function(){
|
||||||
|
switch($(this).attr('data-option')){
|
||||||
|
case "flat":
|
||||||
|
$('.zammad-chat').toggleClass('zammad-chat--flat', this.checked);
|
||||||
|
break;
|
||||||
|
case "color":
|
||||||
|
setScssVariable('themeColor', this.value);
|
||||||
|
updateStyle();
|
||||||
|
break;
|
||||||
|
case "borderRadius":
|
||||||
|
setScssVariable('borderRadius', this.value + "px");
|
||||||
|
updateStyle();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
input: function(){
|
||||||
|
switch($(this).attr('data-option')){
|
||||||
|
case "borderRadius":
|
||||||
|
$('[data-option="borderRadius"]').val(this.value);
|
||||||
|
setScssVariable('borderRadius', this.value + "px");
|
||||||
|
updateStyle();
|
||||||
|
break;
|
||||||
|
case "fontSize":
|
||||||
|
$('[data-option="fontSize"]').val(this.value);
|
||||||
|
setScssVariable('fontSize', this.value + "px");
|
||||||
|
updateStyle();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
</script>
|
306
test/unit/chat_test.rb
Normal file
306
test/unit/chat_test.rb
Normal file
|
@ -0,0 +1,306 @@
|
||||||
|
# encoding: utf-8
|
||||||
|
require 'test_helper'
|
||||||
|
|
||||||
|
class ChatTest < ActiveSupport::TestCase
|
||||||
|
|
||||||
|
# create base
|
||||||
|
groups = Group.all
|
||||||
|
roles = Role.where( name: %w(Agent Chat) )
|
||||||
|
agent1 = User.create_or_update(
|
||||||
|
login: 'ticket-chat-agent1@example.com',
|
||||||
|
firstname: 'Notification',
|
||||||
|
lastname: 'Agent1',
|
||||||
|
email: 'ticket-chat-agent1@example.com',
|
||||||
|
password: 'agentpw',
|
||||||
|
active: true,
|
||||||
|
roles: roles,
|
||||||
|
groups: groups,
|
||||||
|
updated_at: '2015-02-05 16:37:00',
|
||||||
|
updated_by_id: 1,
|
||||||
|
created_by_id: 1,
|
||||||
|
)
|
||||||
|
agent2 = User.create_or_update(
|
||||||
|
login: 'ticket-chat-agent2@example.com',
|
||||||
|
firstname: 'Notification',
|
||||||
|
lastname: 'Agent2',
|
||||||
|
email: 'ticket-chat-agent2@example.com',
|
||||||
|
password: 'agentpw',
|
||||||
|
active: true,
|
||||||
|
roles: roles,
|
||||||
|
groups: groups,
|
||||||
|
updated_at: '2015-02-05 16:38:00',
|
||||||
|
updated_by_id: 1,
|
||||||
|
created_by_id: 1,
|
||||||
|
)
|
||||||
|
|
||||||
|
test 'default test' do
|
||||||
|
|
||||||
|
Chat.delete_all
|
||||||
|
Chat::Topic.delete_all
|
||||||
|
Chat::Session.delete_all
|
||||||
|
Chat::Message.delete_all
|
||||||
|
Chat::Agent.delete_all
|
||||||
|
Setting.set('chat', false)
|
||||||
|
chat = Chat.create(
|
||||||
|
name: 'default',
|
||||||
|
max_queue: 5,
|
||||||
|
note: '',
|
||||||
|
active: true,
|
||||||
|
updated_by_id: 1,
|
||||||
|
created_by_id: 1,
|
||||||
|
)
|
||||||
|
chat_topic = Chat::Topic.create(
|
||||||
|
chat_id: chat.id,
|
||||||
|
name: 'default',
|
||||||
|
updated_by_id: 1,
|
||||||
|
created_by_id: 1,
|
||||||
|
)
|
||||||
|
|
||||||
|
# check if feature is disabled
|
||||||
|
assert_equal('chat_disabled', chat.customer_state[:state])
|
||||||
|
assert_equal('chat_disabled', Chat.agent_state(agent1.id)[:state])
|
||||||
|
Setting.set('chat', true)
|
||||||
|
|
||||||
|
# check customer state
|
||||||
|
assert_equal('offline', chat.customer_state[:state])
|
||||||
|
|
||||||
|
# check agent state
|
||||||
|
agent_state = Chat.agent_state(agent1.id)
|
||||||
|
assert_equal(0, agent_state[:waiting_chat_count])
|
||||||
|
assert_equal(0, agent_state[:running_chat_count])
|
||||||
|
assert_equal([], agent_state[:active_sessions])
|
||||||
|
assert_equal(0, agent_state[:seads_available])
|
||||||
|
assert_equal(0, agent_state[:seads_total])
|
||||||
|
assert_equal(false, agent_state[:active])
|
||||||
|
|
||||||
|
# set agent 1 to active
|
||||||
|
chat_agent1 = Chat::Agent.create_or_update(
|
||||||
|
active: true,
|
||||||
|
concurrent: 4,
|
||||||
|
updated_by_id: agent1.id,
|
||||||
|
created_by_id: agent1.id,
|
||||||
|
)
|
||||||
|
|
||||||
|
# check customer state
|
||||||
|
assert_equal('online', chat.customer_state[:state])
|
||||||
|
|
||||||
|
# check agent state
|
||||||
|
agent_state = Chat.agent_state(agent1.id)
|
||||||
|
assert_equal(0, agent_state[:waiting_chat_count])
|
||||||
|
assert_equal(0, agent_state[:running_chat_count])
|
||||||
|
assert_equal([], agent_state[:active_sessions])
|
||||||
|
assert_equal(4, agent_state[:seads_available])
|
||||||
|
assert_equal(4, agent_state[:seads_total])
|
||||||
|
assert_equal(true, agent_state[:active])
|
||||||
|
|
||||||
|
# start session
|
||||||
|
chat_session1 = Chat::Session.create(
|
||||||
|
chat_id: chat.id,
|
||||||
|
user_id: agent1.id,
|
||||||
|
)
|
||||||
|
assert(chat_session1.session_id)
|
||||||
|
|
||||||
|
# check customer state
|
||||||
|
assert_equal('online', chat.customer_state[:state])
|
||||||
|
|
||||||
|
# check agent state
|
||||||
|
agent_state = Chat.agent_state(agent1.id)
|
||||||
|
assert_equal(1, agent_state[:waiting_chat_count])
|
||||||
|
assert_equal(0, agent_state[:running_chat_count])
|
||||||
|
assert_equal([], agent_state[:active_sessions])
|
||||||
|
assert_equal(3, agent_state[:seads_available])
|
||||||
|
assert_equal(4, agent_state[:seads_total])
|
||||||
|
assert_equal(true, agent_state[:active])
|
||||||
|
|
||||||
|
# activate second agent
|
||||||
|
chat_agent2 = Chat::Agent.create_or_update(
|
||||||
|
active: true,
|
||||||
|
concurrent: 2,
|
||||||
|
updated_by_id: agent2.id,
|
||||||
|
created_by_id: agent2.id,
|
||||||
|
)
|
||||||
|
|
||||||
|
# check customer state
|
||||||
|
assert_equal('online', chat.customer_state[:state])
|
||||||
|
|
||||||
|
# check agent1 state
|
||||||
|
agent_state = Chat.agent_state(agent1.id)
|
||||||
|
assert_equal(1, agent_state[:waiting_chat_count])
|
||||||
|
assert_equal(0, agent_state[:running_chat_count])
|
||||||
|
assert_equal([], agent_state[:active_sessions])
|
||||||
|
assert_equal(5, agent_state[:seads_available])
|
||||||
|
assert_equal(6, agent_state[:seads_total])
|
||||||
|
assert_equal(true, agent_state[:active])
|
||||||
|
|
||||||
|
# check agent2 state
|
||||||
|
agent_state = Chat.agent_state(agent2.id)
|
||||||
|
assert_equal(1, agent_state[:waiting_chat_count])
|
||||||
|
assert_equal(0, agent_state[:running_chat_count])
|
||||||
|
assert_equal([], agent_state[:active_sessions])
|
||||||
|
assert_equal(5, agent_state[:seads_available])
|
||||||
|
assert_equal(6, agent_state[:seads_total])
|
||||||
|
assert_equal(true, agent_state[:active])
|
||||||
|
|
||||||
|
# start next chat
|
||||||
|
chat_session2 = Chat::Session.create(
|
||||||
|
chat_id: chat.id,
|
||||||
|
)
|
||||||
|
|
||||||
|
# check customer state
|
||||||
|
assert_equal('online', chat.customer_state[:state])
|
||||||
|
|
||||||
|
# check agent1 state
|
||||||
|
agent_state = Chat.agent_state(agent1.id)
|
||||||
|
assert_equal(2, agent_state[:waiting_chat_count])
|
||||||
|
assert_equal(0, agent_state[:running_chat_count])
|
||||||
|
assert_equal([], agent_state[:active_sessions])
|
||||||
|
assert_equal(4, agent_state[:seads_available])
|
||||||
|
assert_equal(6, agent_state[:seads_total])
|
||||||
|
assert_equal(true, agent_state[:active])
|
||||||
|
|
||||||
|
# check agent2 state
|
||||||
|
agent_state = Chat.agent_state(agent2.id)
|
||||||
|
assert_equal(2, agent_state[:waiting_chat_count])
|
||||||
|
assert_equal(0, agent_state[:running_chat_count])
|
||||||
|
assert_equal([], agent_state[:active_sessions])
|
||||||
|
assert_equal(4, agent_state[:seads_available])
|
||||||
|
assert_equal(6, agent_state[:seads_total])
|
||||||
|
assert_equal(true, agent_state[:active])
|
||||||
|
|
||||||
|
# start new chats
|
||||||
|
chat_session3 = Chat::Session.create(
|
||||||
|
chat_id: chat.id,
|
||||||
|
)
|
||||||
|
chat_session4 = Chat::Session.create(
|
||||||
|
chat_id: chat.id,
|
||||||
|
)
|
||||||
|
chat_session5 = Chat::Session.create(
|
||||||
|
chat_id: chat.id,
|
||||||
|
)
|
||||||
|
chat_session6 = Chat::Session.create(
|
||||||
|
chat_id: chat.id,
|
||||||
|
)
|
||||||
|
|
||||||
|
# check customer state
|
||||||
|
assert_equal('no_seats_available', chat.customer_state[:state])
|
||||||
|
|
||||||
|
# check agent1 state
|
||||||
|
agent_state = Chat.agent_state(agent1.id)
|
||||||
|
assert_equal(6, agent_state[:waiting_chat_count])
|
||||||
|
assert_equal(0, agent_state[:running_chat_count])
|
||||||
|
assert_equal([], agent_state[:active_sessions])
|
||||||
|
assert_equal(0, agent_state[:seads_available])
|
||||||
|
assert_equal(6, agent_state[:seads_total])
|
||||||
|
assert_equal(true, agent_state[:active])
|
||||||
|
|
||||||
|
# check agent2 state
|
||||||
|
agent_state = Chat.agent_state(agent2.id)
|
||||||
|
assert_equal(6, agent_state[:waiting_chat_count])
|
||||||
|
assert_equal(0, agent_state[:running_chat_count])
|
||||||
|
assert_equal([], agent_state[:active_sessions])
|
||||||
|
assert_equal(0, agent_state[:seads_available])
|
||||||
|
assert_equal(6, agent_state[:seads_total])
|
||||||
|
assert_equal(true, agent_state[:active])
|
||||||
|
|
||||||
|
chat_session6.state = 'running'
|
||||||
|
chat_session6.save
|
||||||
|
|
||||||
|
# check customer state
|
||||||
|
assert_equal('no_seats_available', chat.customer_state[:state])
|
||||||
|
assert_equal(0, chat.customer_state[:queue])
|
||||||
|
|
||||||
|
# check agent1 state
|
||||||
|
agent_state = Chat.agent_state(agent1.id)
|
||||||
|
assert_equal(5, agent_state[:waiting_chat_count])
|
||||||
|
assert_equal(1, agent_state[:running_chat_count])
|
||||||
|
assert_equal([], agent_state[:active_sessions])
|
||||||
|
assert_equal(0, agent_state[:seads_available])
|
||||||
|
assert_equal(6, agent_state[:seads_total])
|
||||||
|
assert_equal(true, agent_state[:active])
|
||||||
|
|
||||||
|
# check agent2 state
|
||||||
|
agent_state = Chat.agent_state(agent2.id)
|
||||||
|
assert_equal(5, agent_state[:waiting_chat_count])
|
||||||
|
assert_equal(1, agent_state[:running_chat_count])
|
||||||
|
assert_equal([], agent_state[:active_sessions])
|
||||||
|
assert_equal(0, agent_state[:seads_available])
|
||||||
|
assert_equal(6, agent_state[:seads_total])
|
||||||
|
assert_equal(true, agent_state[:active])
|
||||||
|
|
||||||
|
chat_agent2.active = false
|
||||||
|
chat_agent2.save
|
||||||
|
|
||||||
|
# check customer state
|
||||||
|
assert_equal('no_seats_available', chat.customer_state[:state])
|
||||||
|
assert_equal(-2, chat.customer_state[:queue])
|
||||||
|
|
||||||
|
# check agent1 state
|
||||||
|
agent_state = Chat.agent_state(agent1.id)
|
||||||
|
assert_equal(5, agent_state[:waiting_chat_count])
|
||||||
|
assert_equal(1, agent_state[:running_chat_count])
|
||||||
|
assert_equal([], agent_state[:active_sessions])
|
||||||
|
assert_equal(-2, agent_state[:seads_available])
|
||||||
|
assert_equal(4, agent_state[:seads_total])
|
||||||
|
assert_equal(true, agent_state[:active])
|
||||||
|
|
||||||
|
# check agent2 state
|
||||||
|
agent_state = Chat.agent_state(agent2.id)
|
||||||
|
assert_equal(5, agent_state[:waiting_chat_count])
|
||||||
|
assert_equal(1, agent_state[:running_chat_count])
|
||||||
|
assert_equal([], agent_state[:active_sessions])
|
||||||
|
assert_equal(-2, agent_state[:seads_available])
|
||||||
|
assert_equal(4, agent_state[:seads_total])
|
||||||
|
assert_equal(false, agent_state[:active])
|
||||||
|
|
||||||
|
chat_session6.state = 'closed'
|
||||||
|
chat_session6.save
|
||||||
|
|
||||||
|
# check customer state
|
||||||
|
assert_equal('no_seats_available', chat.customer_state[:state])
|
||||||
|
assert_equal(-1, chat.customer_state[:queue])
|
||||||
|
|
||||||
|
# check agent1 state
|
||||||
|
agent_state = Chat.agent_state(agent1.id)
|
||||||
|
assert_equal(5, agent_state[:waiting_chat_count])
|
||||||
|
assert_equal(0, agent_state[:running_chat_count])
|
||||||
|
assert_equal([], agent_state[:active_sessions])
|
||||||
|
assert_equal(-1, agent_state[:seads_available])
|
||||||
|
assert_equal(4, agent_state[:seads_total])
|
||||||
|
assert_equal(true, agent_state[:active])
|
||||||
|
|
||||||
|
# check agent2 state
|
||||||
|
agent_state = Chat.agent_state(agent2.id)
|
||||||
|
assert_equal(5, agent_state[:waiting_chat_count])
|
||||||
|
assert_equal(0, agent_state[:running_chat_count])
|
||||||
|
assert_equal([], agent_state[:active_sessions])
|
||||||
|
assert_equal(-1, agent_state[:seads_available])
|
||||||
|
assert_equal(4, agent_state[:seads_total])
|
||||||
|
assert_equal(false, agent_state[:active])
|
||||||
|
|
||||||
|
chat_session5.destroy
|
||||||
|
chat_session4.destroy
|
||||||
|
|
||||||
|
# check customer state
|
||||||
|
assert_equal('online', chat.customer_state[:state])
|
||||||
|
|
||||||
|
# check agent1 state
|
||||||
|
agent_state = Chat.agent_state(agent1.id)
|
||||||
|
assert_equal(3, agent_state[:waiting_chat_count])
|
||||||
|
assert_equal(0, agent_state[:running_chat_count])
|
||||||
|
assert_equal([], agent_state[:active_sessions])
|
||||||
|
assert_equal(1, agent_state[:seads_available])
|
||||||
|
assert_equal(4, agent_state[:seads_total])
|
||||||
|
assert_equal(true, agent_state[:active])
|
||||||
|
|
||||||
|
# check agent2 state
|
||||||
|
agent_state = Chat.agent_state(agent2.id)
|
||||||
|
assert_equal(3, agent_state[:waiting_chat_count])
|
||||||
|
assert_equal(0, agent_state[:running_chat_count])
|
||||||
|
assert_equal([], agent_state[:active_sessions])
|
||||||
|
assert_equal(1, agent_state[:seads_available])
|
||||||
|
assert_equal(4, agent_state[:seads_total])
|
||||||
|
assert_equal(false, agent_state[:active])
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
Loading…
Reference in a new issue