2022-01-01 13:38:12 +00:00
|
|
|
# Copyright (C) 2012-2022 Zammad Foundation, https://zammad-foundation.org/
|
2021-06-01 12:20:20 +00:00
|
|
|
|
2020-05-14 21:26:15 +00:00
|
|
|
module EnsureWebsocket
|
2021-07-16 13:00:49 +00:00
|
|
|
# Ensures that websocket is connected
|
2020-05-14 21:26:15 +00:00
|
|
|
#
|
|
|
|
# @param timeout [Integer] seconds to wait
|
|
|
|
# @param check_if_pinged [Boolean] checks if was pinged to prevent stale connections
|
|
|
|
#
|
|
|
|
# @yield block to execute between disruptive action (e.g. browser refresh) and action that requires websocket
|
|
|
|
def ensure_websocket(timeout: 2.minutes, check_if_pinged: true)
|
|
|
|
timestamp = Time.zone.now if check_if_pinged
|
|
|
|
|
|
|
|
yield if block_given?
|
|
|
|
|
|
|
|
wait(timeout).until do
|
|
|
|
next if check_if_pinged && !pinged_since?(timestamp)
|
|
|
|
|
|
|
|
connection_open?
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
private
|
|
|
|
|
|
|
|
# Checks if session was active since given time
|
|
|
|
#
|
|
|
|
# @param timestamp [Time] when session was (re)activated
|
|
|
|
# @return [Boolean]
|
|
|
|
def pinged_since?(timestamp)
|
|
|
|
unix_time = timestamp.to_i
|
|
|
|
|
|
|
|
Sessions
|
|
|
|
.list
|
|
|
|
.values
|
|
|
|
.map { |elem| elem.dig(:meta, :last_ping) }
|
|
|
|
.any? { |elem| elem >= unix_time }
|
|
|
|
end
|
|
|
|
|
|
|
|
# Checks if websocket connection is active. Javascript function returns string identifier or empty string
|
|
|
|
#
|
|
|
|
# @return [Boolean]
|
|
|
|
def connection_open?
|
|
|
|
page
|
|
|
|
.evaluate_script('App.WebSocket.channel()')
|
|
|
|
.present?
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
RSpec.configure do |config|
|
|
|
|
config.include EnsureWebsocket, type: :system
|
|
|
|
end
|