Fixed some taskbar issues. Moved to events for auth:login/auth:logout.

This commit is contained in:
Martin Edenhofer 2013-06-09 00:35:18 +02:00
parent d6081c7b5c
commit bd9bd8a8ae
11 changed files with 200 additions and 122 deletions

View file

@ -6,14 +6,22 @@ class App.TaskWidget extends App.Controller
super
@render()
# rerender view
App.Event.bind 'ui:rerender', (data) =>
# render on generic ui call
App.Event.bind 'ui:rerender', =>
@render()
# rebuild taskbar widget
App.Event.bind 'auth', (user) =>
App.TaskManager.reset()
# render view
App.Event.bind 'task:render', (data) =>
@render()
# render on login
App.Event.bind 'auth:login', (user) =>
@render()
# reset current tasks on logout
App.Event.bind 'auth:logout', =>
@el.html('')
App.TaskManager.reset()
# only do take over check after spool messages are finised
App.Event.bind 'spool:sent', (data) =>

View file

@ -9,9 +9,6 @@ class App.Auth
data: JSON.stringify(params.data),
success: (data, status, xhr) =>
# clear store
App.Store.clear('all')
# set login (config, session, ...)
@_login(data)
@ -67,11 +64,9 @@ class App.Auth
# empty session
App.Session.init()
# update websocked auth info
App.WebSocket.auth()
# rebuild navbar with new navbar items
App.Event.trigger( 'auth' )
App.Event.trigger( 'auth:logout' )
App.Event.trigger( 'ui:rerender' )
return false;
@ -88,6 +83,8 @@ class App.Auth
for key, value of data.session
App.Session.set( key, value )
App.Event.trigger( 'auth', data.session )
# init of i18n
preferences = App.Session.get( 'preferences' )
if preferences && preferences.locale
@ -100,11 +97,7 @@ class App.Auth
for key, value of data.default_collections
App[key].refresh( value, options: { clear: true } )
# update websocked auth info
App.WebSocket.auth()
# rebuild navbar with user data
App.Event.trigger( 'auth', data.session )
App.Event.trigger( 'auth:login', data.session )
App.Event.trigger( 'ui:rerender' )
@ -114,14 +107,8 @@ class App.Auth
# empty session
App.Session.init()
# update websocket auth info
App.WebSocket.auth()
# clear store
App.Store.clear('all')
# rebuild navbar
App.Event.trigger( 'auth' )
App.Event.trigger( 'auth:logout' )
App.Event.trigger( 'ui:rerender' )
@_loginError: (xhr, statusText, error) ->
@ -130,12 +117,7 @@ class App.Auth
# empty session
App.Session.init()
# update websocked auth info
App.WebSocket.auth()
# clear store
App.Store.clear('all')
# rebuild navbar
App.Event.trigger( 'auth' )
App.Event.trigger( 'auth:logout' )
App.Event.trigger( 'ui:rerender' )

View file

@ -3,6 +3,8 @@ class App.Run extends App.Controller
super
@el = $('#app')
@trigger('app:ready')
# init collections
App.Collection.init()
@ -13,11 +15,13 @@ class App.Run extends App.Controller
App.Auth.loginCheck()
# start widgets
@trigger('widget:init')
widgets = App.Config.get( 'Widgets' )
if widgets
for key, widget of widgets
@el.append('<div id="' + key + '"></div>')
new widget( el: @el.find("##{key}") )
@trigger('widget:ready')
# bind to fill selected text into
App.ClipBoard.bind( @el )

View file

@ -37,6 +37,11 @@ class _Singleton
@support = false
# @support = false
# clear store on every login/logout
if @support
App.Event.bind 'auth', =>
@clear('all')
# write to local storage
write: (key, value) ->
@store[key] = value
@ -82,4 +87,4 @@ class _Singleton
# list.push key
for key of window.localStorage
list.push key
list
list

View file

@ -153,8 +153,7 @@ class _Singleton extends App.Controller
# start worker for task if not exists
@startController(key, callback, params, state, to_not_show)
App.Event.trigger 'ui:rerender'
App.Event.trigger 'ui:rerender:content'
App.Event.trigger 'task:render'
return key
startController: (key, callback, params, state, to_not_show) =>
@ -218,7 +217,7 @@ class _Singleton extends App.Controller
worker.release()
@workersStarted[ key ] = false
task.destroy()
App.Event.trigger 'ui:rerender'
App.Event.trigger 'task:render'
notify: ( key ) =>
task = @get( key )
@ -226,7 +225,7 @@ class _Singleton extends App.Controller
throw "No such task with '#{key}' to notify"
task.notify = true
task.save()
App.Event.trigger 'ui:rerender'
App.Event.trigger 'task:render'
reorder: ( order ) =>
prio = 0
@ -241,15 +240,17 @@ class _Singleton extends App.Controller
reset: =>
App.Taskbar.deleteAll()
App.Event.trigger 'ui:rerender'
App.Event.trigger 'task:render'
clientId: =>
if !@clientIdInt
@clientIdInt = Math.floor( Math.random() * 99999999 )
@clientIdInt = Math.floor( Math.random() * 99999999 )
@clientIdInt
tasksInitial: =>
# reopen tasks
App.Event.trigger 'taskbar:init'
# App.Taskbar.fetch()
tasks = @all()
return if !tasks
@ -277,3 +278,5 @@ class _Singleton extends App.Controller
task_count * 500
)
App.Event.trigger 'taskbar:ready'

View file

@ -47,6 +47,10 @@ class _Singleton extends App.Controller
constructor: (@args) ->
super
# on auth, send new auth data to server
App.Event.bind 'auth', =>
@auth()
# bind to send messages
App.Event.bind 'ws:send', (data) =>
@send(data)

33
doc/app_events.txt Normal file
View file

@ -0,0 +1,33 @@
1) App Boot
1.1) app:ready
1.2) collection:init
1.2.1) collection:ready
1.3) websocket:init
1.3.1) spool:sent
1.3.2) session:takenover
1.3.3) websocket:ready
1.4) auth
1.4.1) auth:login
1.4.2) auth:logout
1.5) widget:init
1.5.1) widget:ready
2) Task
2.1) taskbar:init
2.2) taskbar:ready
2.2)
trigger
remove -> task:render
notify -> task:render
reset -> task:render
3) generic events
ui:rerender -> rebuild all views
ui:rerender:content -> rebuild obly content view

View file

@ -147,7 +147,6 @@ EventMachine.run {
log 'error', "can't parse spool message: #{ message }, #{ e.inspect }"
next
end
# add spool attribute to push spool info to clients
message_parsed['data']['spool'] = true
msg = JSON.generate( message_parsed )
@ -156,8 +155,8 @@ EventMachine.run {
if !data['timestamp'] || data['timestamp'] < message[:timestamp]
# spool to recipient list
if message[:msg_object]['recipient'] && message[:msg_object]['recipient']['user_id']
message[:msg_object]['recipient']['user_id'].each { |user_id|
if message_parsed['data']['recipient'] && message_parsed['data']['recipient']['user_id']
message_parsed['data']['recipient']['user_id'].each { |user_id|
if @clients[client_id][:session]['id'] == user_id
log 'notice', "send spool to (user_id=#{user_id})", client_id
@clients[client_id][:websocket].send( "[#{ msg }]" )
@ -194,19 +193,18 @@ EventMachine.run {
client_list = Session.list
client_list.each {|local_client_id, local_client|
if local_client_id.to_s != client_id.to_s
# broadcast to recipient list
if data['recipient']
if data['recipient'].class != Hash
log 'error', "recipient attribute isn't a hash '#{ data['recipient'].inspect }'"
if data['data']['recipient']
if data['data']['recipient'].class != Hash
log 'error', "recipient attribute isn't a hash '#{ data['data']['recipient'].inspect }'"
else
if !data['recipient'].has_key?('user_id')
log 'error', "need recipient.user_id attribute '#{ data['recipient'].inspect }'"
if !data['data']['recipient'].has_key?('user_id')
log 'error', "need recipient.user_id attribute '#{ data['data']['recipient'].inspect }'"
else
if data['recipient']['user_id'].class != Array
log 'error', "recipient.user_id attribute isn't an array '#{ data['recipient']['user_id'].inspect }'"
if data['data']['recipient']['user_id'].class != Array
log 'error', "recipient.user_id attribute isn't an array '#{ data['data']['recipient']['user_id'].inspect }'"
else
data['recipient']['user_id'].each { |user_id|
data['data']['recipient']['user_id'].each { |user_id|
if local_client[:user][:id].to_i == user_id.to_i
log 'notice', "send broadcast to (user_id=#{user_id})", local_client_id
if local_client[:meta][:type] == 'websocket' && @clients[ local_client_id ]

View file

@ -1,7 +1,7 @@
# encoding: utf-8
require 'browser_test_helper'
class TaskbarTest < TestCase
class TaskbarSessionTest < TestCase
def test_current_session_a_same_agent
tests = [
{
@ -106,74 +106,4 @@ class TaskbarTest < TestCase
browser_double_test(tests)
end
def test_persistant_task_a
tests = [
{
:name => 'persistant task',
:action => [
{
:execute => 'click',
:css => 'a[href="#new"]',
},
{
:execute => 'click',
:css => 'a[href="#ticket_create/call_inbound"]',
},
{
:execute => 'wait',
:value => 5,
},
{
:execute => 'check',
:css => '.active .ticket_create',
:result => true,
},
{
:execute => 'set',
:css => '.active .ticket_create input[name="subject"]',
:value => 'some test AAA',
},
{
:execute => 'wait',
:value => 20,
},
],
},
]
browser_signle_test_with_login(tests, { :username => 'agent1@example.com' })
end
def test_persistant_task_b
tests = [
{
:name => 'persistant task',
:action => [
{
:execute => 'wait',
:value => 6,
},
{
:execute => 'click',
:css => '.task',
},
{
:execute => 'match',
:css => 'body',
:value => 'some test AAA',
:match_result => true,
},
{
:execute => 'click',
:css => '.taskbar [data-type="close"]',
},
{
:execute => 'match',
:css => 'body',
:value => 'some test AAA',
:match_result => false,
},
],
},
]
browser_signle_test_with_login(tests, { :username => 'agent1@example.com' })
end
end

View file

@ -0,0 +1,86 @@
# encoding: utf-8
require 'browser_test_helper'
class TaskbarTaskTest < TestCase
def test_persistant_task_a
tests = [
{
:name => 'persistant task',
:action => [
{
:execute => 'wait',
:value => 2,
},
{
:execute => 'close_all_tasks',
},
{
:execute => 'wait',
:value => 1,
},
{
:execute => 'click',
:css => 'a[href="#new"]',
},
{
:execute => 'click',
:css => 'a[href="#ticket_create/call_inbound"]',
},
{
:execute => 'wait',
:value => 3,
},
{
:execute => 'check',
:css => '.active .ticket_create',
:result => true,
},
{
:execute => 'set',
:css => '.active .ticket_create input[name="subject"]',
:value => 'some test AAA',
},
{
:execute => 'wait',
:value => 20,
},
],
},
]
browser_signle_test_with_login(tests, { :username => 'agent1@example.com' })
end
def test_persistant_task_b
tests = [
{
:name => 'persistant task',
:action => [
{
:execute => 'wait',
:value => 4,
},
{
:execute => 'click',
:css => '.task',
},
{
:execute => 'match',
:css => 'body',
:value => 'some test AAA',
:match_result => true,
},
{
:execute => 'click',
:css => '.taskbar [data-type="close"]',
},
{
:execute => 'match',
:css => 'body',
:value => 'some test AAA',
:match_result => false,
},
],
},
]
browser_signle_test_with_login(tests, { :username => 'agent1@example.com' })
end
end

View file

@ -158,11 +158,15 @@ class TestCase < Test::Unit::TestCase
end
instance.close
end
def browser_element_action(test, action, instance)
if action[:css]
begin
element = instance.find_element( { :css => action[:css] } )
if action[:range] == 'all'
element = instance.find_elements( { :css => action[:css] } )
else
element = instance.find_element( { :css => action[:css] } )
end
rescue
element = nil
end
@ -179,6 +183,20 @@ class TestCase < Test::Unit::TestCase
end
elsif action[:element] == :alert
element = instance.switch_to.alert
elsif action[:execute] == 'close_all_tasks'
while true
begin
element = instance.find_element( { :css => '.taskbar [data-type="close"]' } )
if element
element.click
sleep 0.8
else
break
end
rescue
break
end
end
else
assert( false, "(#{test[:name]}) unknow selector for '#{action[:element]}'" )
end
@ -195,7 +213,13 @@ class TestCase < Test::Unit::TestCase
dropdown = Selenium::WebDriver::Support::Select.new(element)
dropdown.select_by(:text, action[:value])
elsif action[:execute] == 'click'
element.click
if element.class == Array
element.each {|item|
item.click
}
else
element.click
end
elsif action[:execute] == 'accept'
element.accept
elsif action[:execute] == 'dismiss'
@ -263,6 +287,7 @@ class TestCase < Test::Unit::TestCase
end
end
elsif action[:execute] == 'check'
elsif action[:execute] == 'close_all_tasks'
else
assert( false, "(#{test[:name]}) unknow action '#{action[:execute]}'" )
end