Fixed issue #2327 - Websocket messages are not working correctly via Ajax long polling (e. g. multiple browser tabs can get opened with one session).
This commit is contained in:
parent
764d262cff
commit
75230c3db3
15 changed files with 303 additions and 51 deletions
|
@ -35,6 +35,11 @@ class App.WebSocket
|
||||||
_instance ?= new _webSocketSingleton
|
_instance ?= new _webSocketSingleton
|
||||||
_instance.support()
|
_instance.support()
|
||||||
|
|
||||||
|
@queue: ->
|
||||||
|
if _instance == undefined
|
||||||
|
_instance ?= new _webSocketSingleton
|
||||||
|
_instance.queue
|
||||||
|
|
||||||
# The actual Singleton class
|
# The actual Singleton class
|
||||||
class _webSocketSingleton extends App.Controller
|
class _webSocketSingleton extends App.Controller
|
||||||
@include App.LogInclude
|
@include App.LogInclude
|
||||||
|
@ -355,10 +360,10 @@ class _webSocketSingleton extends App.Controller
|
||||||
success: (data) =>
|
success: (data) =>
|
||||||
if data && data.error
|
if data && data.error
|
||||||
@client_id = undefined
|
@client_id = undefined
|
||||||
@_ajaxInit( force: true )
|
@_ajaxInit(force: true)
|
||||||
error: =>
|
error: =>
|
||||||
@client_id = undefined
|
@client_id = undefined
|
||||||
@_ajaxInit( force: true )
|
@_ajaxInit(force: true)
|
||||||
)
|
)
|
||||||
|
|
||||||
_ajaxReceive: =>
|
_ajaxReceive: =>
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
|
|
||||||
class LongPollingController < ApplicationController
|
class LongPollingController < ApplicationController
|
||||||
skip_before_action :session_update # prevent race conditions
|
skip_before_action :session_update # prevent race conditions
|
||||||
|
prepend_before_action :authentication_check_only
|
||||||
|
|
||||||
# GET /api/v1/message_send
|
# GET /api/v1/message_send
|
||||||
def message_send
|
def message_send
|
||||||
|
@ -14,24 +15,22 @@ class LongPollingController < ApplicationController
|
||||||
client_id = client_id_gen
|
client_id = client_id_gen
|
||||||
log 'new client connection', client_id
|
log 'new client connection', client_id
|
||||||
end
|
end
|
||||||
if !params['data']
|
data = params['data'].permit!.to_h
|
||||||
params['data'] = {}
|
|
||||||
end
|
|
||||||
session_data = {}
|
session_data = {}
|
||||||
if current_user&.id
|
if current_user&.id
|
||||||
session_data = { 'id' => current_user.id }
|
session_data = { 'id' => current_user.id }
|
||||||
end
|
end
|
||||||
|
|
||||||
# spool messages for new connects
|
# spool messages for new connects
|
||||||
if params['data']['spool']
|
if data['spool']
|
||||||
Sessions.spool_create(params['data'])
|
Sessions.spool_create(data)
|
||||||
end
|
end
|
||||||
if params['data']['event'] == 'login'
|
if data['event'] == 'login'
|
||||||
Sessions.create(client_id, session_data, { type: 'ajax' })
|
Sessions.create(client_id, session_data, { type: 'ajax' })
|
||||||
elsif params['data']['event']
|
elsif data['event']
|
||||||
message = Sessions::Event.run(
|
message = Sessions::Event.run(
|
||||||
event: params['data']['event'],
|
event: data['event'],
|
||||||
payload: params['data'],
|
payload: data,
|
||||||
session: session_data,
|
session: session_data,
|
||||||
client_id: client_id,
|
client_id: client_id,
|
||||||
clients: {},
|
clients: {},
|
||||||
|
@ -41,15 +40,15 @@ class LongPollingController < ApplicationController
|
||||||
Sessions.send(client_id, message)
|
Sessions.send(client_id, message)
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
log "unknown message '#{params['data'].inspect}'", client_id
|
log "unknown message '#{data.inspect}'", client_id
|
||||||
end
|
end
|
||||||
|
|
||||||
if new_connection
|
if new_connection
|
||||||
result = { client_id: client_id }
|
result = { client_id: client_id }
|
||||||
render json: result
|
render json: result
|
||||||
else
|
return
|
||||||
render json: {}
|
|
||||||
end
|
end
|
||||||
|
render json: {}
|
||||||
end
|
end
|
||||||
|
|
||||||
# GET /api/v1/message_receive
|
# GET /api/v1/message_receive
|
||||||
|
@ -110,7 +109,7 @@ class LongPollingController < ApplicationController
|
||||||
params[:client_id].to_s
|
params[:client_id].to_s
|
||||||
end
|
end
|
||||||
|
|
||||||
def log( data, client_id = '-' )
|
def log(data, client_id = '-')
|
||||||
logger.info "client(#{client_id}) #{data}"
|
logger.info "client(#{client_id}) #{data}"
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -334,6 +334,15 @@ send message to recipient client
|
||||||
|
|
||||||
Sessions.send_to(user_id, data)
|
Sessions.send_to(user_id, data)
|
||||||
|
|
||||||
|
e. g.
|
||||||
|
|
||||||
|
Sessions.send_to(user_id, {
|
||||||
|
event: 'session:takeover',
|
||||||
|
data: {
|
||||||
|
taskbar_id: 12312
|
||||||
|
},
|
||||||
|
})
|
||||||
|
|
||||||
returns
|
returns
|
||||||
|
|
||||||
true|false
|
true|false
|
||||||
|
@ -476,6 +485,14 @@ remove all session and spool messages
|
||||||
true
|
true
|
||||||
end
|
end
|
||||||
|
|
||||||
|
=begin
|
||||||
|
|
||||||
|
create spool messages
|
||||||
|
|
||||||
|
Sessions.spool_create(some: 'data')
|
||||||
|
|
||||||
|
=end
|
||||||
|
|
||||||
def self.spool_create(data)
|
def self.spool_create(data)
|
||||||
msg = JSON.generate(data)
|
msg = JSON.generate(data)
|
||||||
path = "#{@path}/spool/"
|
path = "#{@path}/spool/"
|
||||||
|
@ -492,6 +509,14 @@ remove all session and spool messages
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
=begin
|
||||||
|
|
||||||
|
get spool messages
|
||||||
|
|
||||||
|
Sessions.spool_list(junger_then, for_user_id)
|
||||||
|
|
||||||
|
=end
|
||||||
|
|
||||||
def self.spool_list(timestamp, current_user_id)
|
def self.spool_list(timestamp, current_user_id)
|
||||||
path = "#{@path}/spool/"
|
path = "#{@path}/spool/"
|
||||||
FileUtils.mkpath path
|
FileUtils.mkpath path
|
||||||
|
@ -512,6 +537,7 @@ remove all session and spool messages
|
||||||
file.flock(File::LOCK_SH)
|
file.flock(File::LOCK_SH)
|
||||||
message = file.read
|
message = file.read
|
||||||
file.flock(File::LOCK_UN)
|
file.flock(File::LOCK_UN)
|
||||||
|
message_parsed = {}
|
||||||
begin
|
begin
|
||||||
spool = JSON.parse(message)
|
spool = JSON.parse(message)
|
||||||
message_parsed = JSON.parse(spool['msg'])
|
message_parsed = JSON.parse(spool['msg'])
|
||||||
|
@ -530,7 +556,7 @@ remove all session and spool messages
|
||||||
# add spool attribute to push spool info to clients
|
# add spool attribute to push spool info to clients
|
||||||
message_parsed['spool'] = true
|
message_parsed['spool'] = true
|
||||||
|
|
||||||
# only send not already now messages
|
# only send not already older messages
|
||||||
if !timestamp || timestamp < spool['timestamp']
|
if !timestamp || timestamp < spool['timestamp']
|
||||||
|
|
||||||
# spool to recipient list
|
# spool to recipient list
|
||||||
|
@ -573,6 +599,19 @@ remove all session and spool messages
|
||||||
data
|
data
|
||||||
end
|
end
|
||||||
|
|
||||||
|
=begin
|
||||||
|
|
||||||
|
delete spool messages
|
||||||
|
|
||||||
|
Sessions.spool_delete
|
||||||
|
|
||||||
|
=end
|
||||||
|
|
||||||
|
def self.spool_delete
|
||||||
|
path = "#{@path}/spool/"
|
||||||
|
FileUtils.rm_rf path
|
||||||
|
end
|
||||||
|
|
||||||
def self.jobs(node_id = nil)
|
def self.jobs(node_id = nil)
|
||||||
|
|
||||||
# just make sure that spool path exists
|
# just make sure that spool path exists
|
||||||
|
|
|
@ -7,7 +7,7 @@ class Sessions::Event
|
||||||
begin
|
begin
|
||||||
backend = load_adapter(adapter)
|
backend = load_adapter(adapter)
|
||||||
rescue => e
|
rescue => e
|
||||||
return { event: 'error', data: { error: "No such event #{params[:event]}", payload: params[:payload] } }
|
return { event: 'error', data: { error: "No such event #{params[:event]}: #{e.inspect}", payload: params[:payload] } }
|
||||||
end
|
end
|
||||||
|
|
||||||
begin
|
begin
|
||||||
|
|
|
@ -9,6 +9,10 @@ class Sessions::Event::Base
|
||||||
return if !@clients[@client_id]
|
return if !@clients[@client_id]
|
||||||
|
|
||||||
@is_web_socket = true
|
@is_web_socket = true
|
||||||
|
|
||||||
|
return if !self.class.instance_variable_get(:@database_connection)
|
||||||
|
|
||||||
|
ActiveRecord::Base.establish_connection
|
||||||
end
|
end
|
||||||
|
|
||||||
def websocket_send(recipient_client_id, data)
|
def websocket_send(recipient_client_id, data)
|
||||||
|
@ -120,8 +124,18 @@ class Sessions::Event::Base
|
||||||
puts "#{Time.now.utc.iso8601}:client(#{client_id}) #{data}"
|
puts "#{Time.now.utc.iso8601}:client(#{client_id}) #{data}"
|
||||||
#puts "#{Time.now.utc.iso8601}:#{ level }:client(#{ client_id }) #{ data }"
|
#puts "#{Time.now.utc.iso8601}:#{ level }:client(#{ client_id }) #{ data }"
|
||||||
# rubocop:enable Rails/Output
|
# rubocop:enable Rails/Output
|
||||||
|
#Rails.logger.info "#{Time.now.utc.iso8601}:client(#{client_id}) #{data}"
|
||||||
end
|
end
|
||||||
|
|
||||||
def destroy; end
|
def self.database_connection_required
|
||||||
|
@database_connection = true
|
||||||
|
end
|
||||||
|
|
||||||
|
def destroy
|
||||||
|
return if !@is_web_socket
|
||||||
|
return if !self.class.instance_variable_get(:@database_connection)
|
||||||
|
|
||||||
|
ActiveRecord::Base.remove_connection
|
||||||
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,5 +1,15 @@
|
||||||
class Sessions::Event::Broadcast < Sessions::Event::Base
|
class Sessions::Event::Broadcast < Sessions::Event::Base
|
||||||
|
|
||||||
|
=begin
|
||||||
|
|
||||||
|
Event module to broadcast messages to all client connections.
|
||||||
|
|
||||||
|
To execute this manually, just paste the following into the browser console
|
||||||
|
|
||||||
|
App.WebSocket.send({event:'broadcast', recipient: { user_id: [1,2,3]}, data: {some: 'key'}})
|
||||||
|
|
||||||
|
=end
|
||||||
|
|
||||||
def run
|
def run
|
||||||
|
|
||||||
# list all current clients
|
# list all current clients
|
||||||
|
|
|
@ -1,17 +1,5 @@
|
||||||
class Sessions::Event::ChatBase < Sessions::Event::Base
|
class Sessions::Event::ChatBase < Sessions::Event::Base
|
||||||
|
database_connection_required
|
||||||
def initialize(params)
|
|
||||||
super(params)
|
|
||||||
return if !@is_web_socket
|
|
||||||
|
|
||||||
ActiveRecord::Base.establish_connection
|
|
||||||
end
|
|
||||||
|
|
||||||
def destroy
|
|
||||||
return if !@is_web_socket
|
|
||||||
|
|
||||||
ActiveRecord::Base.remove_connection
|
|
||||||
end
|
|
||||||
|
|
||||||
def run
|
def run
|
||||||
|
|
||||||
|
|
|
@ -1,12 +1,20 @@
|
||||||
class Sessions::Event::Login < Sessions::Event::Base
|
class Sessions::Event::Login < Sessions::Event::Base
|
||||||
|
database_connection_required
|
||||||
|
|
||||||
|
=begin
|
||||||
|
|
||||||
|
Event module to start websocket session for new client connections.
|
||||||
|
|
||||||
|
To execute this manually, just paste the following into the browser console
|
||||||
|
|
||||||
|
App.WebSocket.send({event:'login', session_id: '123'})
|
||||||
|
|
||||||
|
=end
|
||||||
|
|
||||||
def run
|
def run
|
||||||
|
|
||||||
# get user_id
|
# get user_id
|
||||||
session = nil
|
session = nil
|
||||||
if @is_web_socket
|
|
||||||
ActiveRecord::Base.establish_connection
|
|
||||||
end
|
|
||||||
|
|
||||||
app_version = AppVersion.event_data
|
app_version = AppVersion.event_data
|
||||||
|
|
||||||
|
@ -14,12 +22,7 @@ class Sessions::Event::Login < Sessions::Event::Base
|
||||||
session = ActiveRecord::SessionStore::Session.find_by(session_id: @payload['session_id'])
|
session = ActiveRecord::SessionStore::Session.find_by(session_id: @payload['session_id'])
|
||||||
end
|
end
|
||||||
|
|
||||||
if @is_web_socket
|
|
||||||
ActiveRecord::Base.remove_connection
|
|
||||||
end
|
|
||||||
|
|
||||||
new_session_data = {}
|
new_session_data = {}
|
||||||
|
|
||||||
if session&.data && session.data['user_id']
|
if session&.data && session.data['user_id']
|
||||||
new_session_data = {
|
new_session_data = {
|
||||||
'id' => session.data['user_id'],
|
'id' => session.data['user_id'],
|
||||||
|
|
|
@ -1,17 +1,15 @@
|
||||||
class Sessions::Event::Maintenance < Sessions::Event::Base
|
class Sessions::Event::Maintenance < Sessions::Event::Base
|
||||||
|
database_connection_required
|
||||||
|
|
||||||
def initialize(params)
|
=begin
|
||||||
super(params)
|
|
||||||
return if !@is_web_socket
|
|
||||||
|
|
||||||
ActiveRecord::Base.establish_connection
|
Event module to broadcast maintenance messages to all client connections.
|
||||||
end
|
|
||||||
|
|
||||||
def destroy
|
To execute this manually, just paste the following into the browser console
|
||||||
return if !@is_web_socket
|
|
||||||
|
|
||||||
ActiveRecord::Base.remove_connection
|
App.WebSocket.send({event:'maintenance', data: {some: 'key'}})
|
||||||
end
|
|
||||||
|
=end
|
||||||
|
|
||||||
def run
|
def run
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,15 @@
|
||||||
class Sessions::Event::Ping < Sessions::Event::Base
|
class Sessions::Event::Ping < Sessions::Event::Base
|
||||||
|
|
||||||
|
=begin
|
||||||
|
|
||||||
|
Event module to send pong to client connection.
|
||||||
|
|
||||||
|
To execute this manually, just paste the following into the browser console
|
||||||
|
|
||||||
|
App.WebSocket.send({event:'ping'})
|
||||||
|
|
||||||
|
=end
|
||||||
|
|
||||||
def run
|
def run
|
||||||
{
|
{
|
||||||
event: 'pong',
|
event: 'pong',
|
||||||
|
|
|
@ -1,6 +1,15 @@
|
||||||
class Sessions::Event::Spool < Sessions::Event::Base
|
class Sessions::Event::Spool < Sessions::Event::Base
|
||||||
|
|
||||||
# get spool messages and send them to new client connection
|
=begin
|
||||||
|
|
||||||
|
Event module to serve spool messages and send them to new client connection.
|
||||||
|
|
||||||
|
To execute this manually, just paste the following into the browser console
|
||||||
|
|
||||||
|
App.WebSocket.send({event:'spool'})
|
||||||
|
|
||||||
|
=end
|
||||||
|
|
||||||
def run
|
def run
|
||||||
|
|
||||||
# error handling
|
# error handling
|
||||||
|
@ -11,8 +20,13 @@ class Sessions::Event::Spool < Sessions::Event::Base
|
||||||
end
|
end
|
||||||
|
|
||||||
if !@session || !@session['id']
|
if !@session || !@session['id']
|
||||||
log 'error', "can't send spool, session not authenticated"
|
log 'error', "Can't send spool, session not authenticated"
|
||||||
return
|
return {
|
||||||
|
event: 'error',
|
||||||
|
data: {
|
||||||
|
error: 'Can\'t send spool, session not authenticated',
|
||||||
|
},
|
||||||
|
}
|
||||||
end
|
end
|
||||||
|
|
||||||
spool = Sessions.spool_list(@payload['timestamp'], @session['id'])
|
spool = Sessions.spool_list(@payload['timestamp'], @session['id'])
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
class Sessions::Event::TicketOverviewIndex < Sessions::Event::Base
|
class Sessions::Event::TicketOverviewIndex < Sessions::Event::Base
|
||||||
|
database_connection_required
|
||||||
|
|
||||||
def run
|
def run
|
||||||
return if !valid_session?
|
return if !valid_session?
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
class Sessions::Event::TicketOverviewList < Sessions::Event::Base
|
class Sessions::Event::TicketOverviewList < Sessions::Event::Base
|
||||||
|
database_connection_required
|
||||||
|
|
||||||
def run
|
def run
|
||||||
return if !valid_session?
|
return if !valid_session?
|
||||||
|
|
46
lib/sessions/event/who_am_i.rb
Normal file
46
lib/sessions/event/who_am_i.rb
Normal file
|
@ -0,0 +1,46 @@
|
||||||
|
class Sessions::Event::WhoAmI < Sessions::Event::Base
|
||||||
|
database_connection_required
|
||||||
|
|
||||||
|
=begin
|
||||||
|
|
||||||
|
Event module to send `who am i` to client connection.
|
||||||
|
|
||||||
|
To execute this manually, just paste the following into the browser console
|
||||||
|
|
||||||
|
App.WebSocket.send({event:'who_am_i'})
|
||||||
|
|
||||||
|
=end
|
||||||
|
|
||||||
|
def run
|
||||||
|
|
||||||
|
if !@session || !@session['id']
|
||||||
|
return {
|
||||||
|
event: 'who_am_i',
|
||||||
|
data: {
|
||||||
|
message: 'session not authenticated',
|
||||||
|
},
|
||||||
|
}
|
||||||
|
end
|
||||||
|
|
||||||
|
user = User.find_by(id: @session['id'])
|
||||||
|
|
||||||
|
if !user
|
||||||
|
return {
|
||||||
|
event: 'who_am_i',
|
||||||
|
data: {
|
||||||
|
message: "No such user with id #{@session['id']}",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
end
|
||||||
|
attributes = user.attributes
|
||||||
|
attributes.delete('password')
|
||||||
|
{
|
||||||
|
event: 'who_am_i',
|
||||||
|
data: {
|
||||||
|
message: 'session authenticated',
|
||||||
|
user: attributes,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
124
spec/requests/long_polling_spec.rb
Normal file
124
spec/requests/long_polling_spec.rb
Normal file
|
@ -0,0 +1,124 @@
|
||||||
|
require 'rails_helper'
|
||||||
|
|
||||||
|
RSpec.describe 'LongPolling', type: :request do
|
||||||
|
|
||||||
|
let(:agent_user) do
|
||||||
|
create(:agent_user)
|
||||||
|
end
|
||||||
|
|
||||||
|
before(:each) do
|
||||||
|
Sessions.sessions.each do |client_id|
|
||||||
|
Sessions.destroy(client_id)
|
||||||
|
end
|
||||||
|
Sessions.spool_delete
|
||||||
|
end
|
||||||
|
|
||||||
|
describe 'request handling' do
|
||||||
|
|
||||||
|
it 'receive without client_id - no user login' do
|
||||||
|
get '/api/v1/message_receive', params: { data: {} }, as: :json
|
||||||
|
expect(response).to have_http_status(422)
|
||||||
|
expect(json_response).to be_a_kind_of(Hash)
|
||||||
|
expect(json_response['error']).to eq('Invalid client_id receive!')
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'send without client_id - no user login' do
|
||||||
|
get '/api/v1/message_send', params: { data: {} }, as: :json
|
||||||
|
expect(response).to have_http_status(200)
|
||||||
|
expect(json_response).to be_a_kind_of(Hash)
|
||||||
|
expect(json_response['client_id'].to_i).to be_between(1, 9_999_999_999)
|
||||||
|
|
||||||
|
client_id = json_response['client_id']
|
||||||
|
get '/api/v1/message_send', params: { client_id: client_id, data: { event: 'spool' } }, as: :json
|
||||||
|
expect(response).to have_http_status(200)
|
||||||
|
expect(json_response).to be_a_kind_of(Hash)
|
||||||
|
expect(json_response['client_id'].to_i).to be_between(1, 9_999_999_999)
|
||||||
|
|
||||||
|
get '/api/v1/message_receive', params: { client_id: client_id, data: {} }, as: :json
|
||||||
|
expect(response).to have_http_status(422)
|
||||||
|
expect(json_response).to be_a_kind_of(Hash)
|
||||||
|
expect(json_response['error']).to eq('Invalid client_id receive!')
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'receive without client_id' do
|
||||||
|
authenticated_as(agent_user)
|
||||||
|
get '/api/v1/message_receive', params: { data: {} }, as: :json
|
||||||
|
expect(response).to have_http_status(422)
|
||||||
|
expect(json_response).to be_a_kind_of(Hash)
|
||||||
|
expect(json_response['error']).to eq('Invalid client_id receive!')
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'receive without wrong client_id' do
|
||||||
|
authenticated_as(agent_user)
|
||||||
|
get '/api/v1/message_receive', params: { client_id: 'not existing', data: {} }, as: :json
|
||||||
|
expect(response).to have_http_status(422)
|
||||||
|
expect(json_response).to be_a_kind_of(Hash)
|
||||||
|
expect(json_response['error']).to eq('Invalid client_id receive!')
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'send without client_id' do
|
||||||
|
authenticated_as(agent_user)
|
||||||
|
get '/api/v1/message_send', params: { data: {} }, as: :json
|
||||||
|
expect(response).to have_http_status(200)
|
||||||
|
expect(json_response).to be_a_kind_of(Hash)
|
||||||
|
expect(json_response['client_id'].to_i).to be_between(1, 9_999_999_999)
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'send with client_id' do
|
||||||
|
Sessions.create('123456', {}, { type: 'ajax' })
|
||||||
|
authenticated_as(agent_user)
|
||||||
|
get '/api/v1/message_send', params: { client_id: '123456', data: {} }, as: :json
|
||||||
|
expect(response).to have_http_status(200)
|
||||||
|
expect(json_response).to be_a_kind_of(Hash)
|
||||||
|
expect(json_response).to eq({})
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'send event spool and receive data' do
|
||||||
|
|
||||||
|
authenticated_as(agent_user)
|
||||||
|
get '/api/v1/message_send', params: { data: { event: 'login' } }, as: :json
|
||||||
|
expect(response).to have_http_status(200)
|
||||||
|
expect(json_response['client_id'].to_i).to be_between(1, 9_999_999_999)
|
||||||
|
client_id = json_response['client_id']
|
||||||
|
|
||||||
|
get '/api/v1/message_receive', params: { client_id: client_id, data: {} }, as: :json
|
||||||
|
expect(response).to have_http_status(200)
|
||||||
|
expect(json_response).to be_a_kind_of(Array)
|
||||||
|
expect(json_response).to eq([{ 'data' => { 'success' => true }, 'event' => 'ws:login' }])
|
||||||
|
|
||||||
|
get '/api/v1/message_send', params: { client_id: client_id, data: { event: 'spool' } }, as: :json
|
||||||
|
expect(response).to have_http_status(200)
|
||||||
|
expect(json_response).to be_a_kind_of(Hash)
|
||||||
|
expect(json_response).to eq({})
|
||||||
|
|
||||||
|
get '/api/v1/message_receive', params: { client_id: client_id, data: {} }, as: :json
|
||||||
|
expect(response).to have_http_status(200)
|
||||||
|
expect(json_response).to be_a_kind_of(Array)
|
||||||
|
expect(json_response[0]['event']).to eq('spool:sent')
|
||||||
|
expect(json_response[0]['event']).to eq('spool:sent')
|
||||||
|
expect(json_response.count).to eq(1)
|
||||||
|
|
||||||
|
spool_list = Sessions.spool_list(Time.now.utc.to_i, agent_user.id)
|
||||||
|
expect(spool_list).to eq([])
|
||||||
|
|
||||||
|
get '/api/v1/message_send', params: { client_id: client_id, data: { event: 'broadcast', spool: true, recipient: { user_id: [agent_user.id] }, data: { taskbar_id: 9_391_633 } } }, as: :json
|
||||||
|
expect(response).to have_http_status(200)
|
||||||
|
expect(json_response).to be_a_kind_of(Hash)
|
||||||
|
expect(json_response).to eq({})
|
||||||
|
|
||||||
|
get '/api/v1/message_receive', params: { client_id: client_id, data: {} }, as: :json
|
||||||
|
expect(response).to have_http_status(200)
|
||||||
|
expect(json_response).to be_a_kind_of(Hash)
|
||||||
|
expect(json_response).to eq({ 'event' => 'pong' })
|
||||||
|
|
||||||
|
travel 2.seconds
|
||||||
|
|
||||||
|
spool_list = Sessions.spool_list(Time.now.utc.to_i, agent_user.id)
|
||||||
|
expect(spool_list).to eq([])
|
||||||
|
|
||||||
|
spool_list = Sessions.spool_list(nil, agent_user.id)
|
||||||
|
expect(spool_list).to eq([{ message: { 'taskbar_id' => 9_391_633 }, type: 'direct' }])
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
|
end
|
Loading…
Reference in a new issue