Merge branch 'develop' into feature/ui2

Conflicts:
	app/assets/javascripts/app/controllers/session.js.coffee
	test/browser/prefereces_test.rb
This commit is contained in:
Martin Edenhofer 2013-08-14 02:15:50 +02:00
commit e4da295984
44 changed files with 233 additions and 185 deletions

View file

@ -92,5 +92,4 @@ group :development, :test do
# gem 'em-websocket-client' # gem 'em-websocket-client'
end end
gem 'business_time'
gem 'thin' gem 'thin'

View file

@ -23,6 +23,12 @@ class App.Controller extends Spine.Controller
# create common accessors # create common accessors
@apiPath = @Config.get('api_path') @apiPath = @Config.get('api_path')
# remember ajax calls to abort them on dom release
@ajaxCalls = []
@ajax = (data) =>
ajaxId = App.Ajax.request(data)
@ajaxCalls.push ajaxId
bind: (event, callback) => bind: (event, callback) =>
App.Event.bind( App.Event.bind(
event event
@ -53,6 +59,9 @@ class App.Controller extends Spine.Controller
App.Event.unbindLevel(@controllerId) App.Event.unbindLevel(@controllerId)
App.Delay.clearLevel(@controllerId) App.Delay.clearLevel(@controllerId)
App.Interval.clearLevel(@controllerId) App.Interval.clearLevel(@controllerId)
if @ajaxCalls
for callId in @ajaxCalls
App.Ajax.abort(callId)
release: => release: =>
# release custom bindings after it got removed from dom # release custom bindings after it got removed from dom
@ -74,7 +83,6 @@ class App.Controller extends Spine.Controller
App.Interval.reset() App.Interval.reset()
App.WebSocket.close( force: true ) App.WebSocket.close( force: true )
# add @notify methode to create notification # add @notify methode to create notification
notify: (data) -> notify: (data) ->
App.Event.trigger 'notify', data App.Event.trigger 'notify', data
@ -376,7 +384,7 @@ class App.Controller extends Spine.Controller
# get data # get data
tickets = {} tickets = {}
App.Com.ajax( App.Ajax.request(
type: 'GET', type: 'GET',
url: @Config.get('api_path') + '/ticket_customer', url: @Config.get('api_path') + '/ticket_customer',
data: { data: {

View file

@ -20,7 +20,7 @@ class App.DashboardActivityStream extends App.Controller
# init fetch via ajax, all other updates on time via websockets # init fetch via ajax, all other updates on time via websockets
else else
App.Com.ajax( @ajax(
id: 'dashoard_activity_stream' id: 'dashoard_activity_stream'
type: 'GET' type: 'GET'
url: @apiPath + '/activity_stream' url: @apiPath + '/activity_stream'

View file

@ -8,7 +8,7 @@ class App.DashboardRecentViewed extends App.Controller
@items = [] @items = []
# get data # get data
App.Com.ajax( @ajax(
id: 'dashboard_recent_viewed', id: 'dashboard_recent_viewed',
type: 'GET', type: 'GET',
url: @apiPath + '/recent_viewed', url: @apiPath + '/recent_viewed',

View file

@ -18,7 +18,7 @@ class App.DashboardRss extends App.Controller
# init fetch via ajax, all other updates on time via websockets # init fetch via ajax, all other updates on time via websockets
else else
App.Com.ajax( @ajax(
id: 'dashboard_rss' id: 'dashboard_rss'
type: 'GET' type: 'GET'
url: @apiPath + '/rss_fetch' url: @apiPath + '/rss_fetch'

View file

@ -27,7 +27,7 @@ class App.DashboardTicket extends App.Controller
# init fetch via ajax, all other updates on time via websockets # init fetch via ajax, all other updates on time via websockets
else else
App.Com.ajax( @ajax(
id: 'dashboard_ticket_' + @key, id: 'dashboard_ticket_' + @key,
type: 'GET', type: 'GET',
url: @apiPath + '/ticket_overviews', url: @apiPath + '/ticket_overviews',

View file

@ -34,7 +34,7 @@ class Index extends App.Controller
# get data # get data
@locale = params['locale'] @locale = params['locale']
App.Com.ajax( @ajax(
id: 'preferences' id: 'preferences'
type: 'PUT' type: 'PUT'
url: @apiPath + '/users/preferences' url: @apiPath + '/users/preferences'

View file

@ -50,7 +50,7 @@ class Index extends App.Controller
uid = $(e.target).data('uid') uid = $(e.target).data('uid')
# get data # get data
App.Com.ajax( @ajax(
id: 'account' id: 'account'
type: 'DELETE' type: 'DELETE'
url: @apiPath + '/users/account' url: @apiPath + '/users/account'

View file

@ -35,7 +35,7 @@ class Index extends App.Controller
@formDisable(e) @formDisable(e)
# get data # get data
App.Com.ajax( @ajax(
id: 'password_reset' id: 'password_reset'
type: 'POST' type: 'POST'
url: @apiPath + '/users/password_change' url: @apiPath + '/users/password_change'

View file

@ -102,7 +102,7 @@ class App.TicketCreate extends App.Controller
@render() @render()
else else
App.Com.ajax( @ajax(
id: 'ticket_create' id: 'ticket_create'
type: 'GET' type: 'GET'
url: @apiPath + '/ticket_create' url: @apiPath + '/ticket_create'

View file

@ -10,7 +10,7 @@ class App.TicketHistory extends App.ControllerModal
fetch: (@ticket_id) -> fetch: (@ticket_id) ->
# get data # get data
App.Com.ajax( @ajax(
id: 'ticket_history', id: 'ticket_history',
type: 'GET', type: 'GET',
url: @apiPath + '/ticket_history/' + ticket_id, url: @apiPath + '/ticket_history/' + ticket_id,

View file

@ -6,7 +6,7 @@ class App.TicketMerge extends App.ControllerModal
fetch: -> fetch: ->
# merge tickets # merge tickets
App.Com.ajax( @ajax(
id: 'ticket_merge_list', id: 'ticket_merge_list',
type: 'GET', type: 'GET',
url: @apiPath + '/ticket_merge_list/' + @ticket_id, url: @apiPath + '/ticket_merge_list/' + @ticket_id,
@ -104,7 +104,7 @@ class App.TicketMerge extends App.ControllerModal
params = @formParam(e.target) params = @formParam(e.target)
# merge tickets # merge tickets
App.Com.ajax( @ajax(
id: 'ticket_merge', id: 'ticket_merge',
type: 'GET', type: 'GET',
url: @apiPath + '/ticket_merge/' + @ticket_id + '/' + params['master_ticket_number'], url: @apiPath + '/ticket_merge/' + @ticket_id + '/' + params['master_ticket_number'],

View file

@ -34,7 +34,7 @@ class Index extends App.ControllerContent
@render() @render()
else else
App.Com.ajax( @ajax(
id: 'ticket_create', id: 'ticket_create',
type: 'GET', type: 'GET',
url: @apiPath + '/ticket_create', url: @apiPath + '/ticket_create',

View file

@ -18,7 +18,7 @@ class Index extends App.ControllerContent
fetch: -> fetch: ->
# get data # get data
App.Com.ajax( @ajax(
id: 'getting_started', id: 'getting_started',
type: 'GET', type: 'GET',
url: @apiPath + '/getting_started', url: @apiPath + '/getting_started',

View file

@ -11,7 +11,7 @@ class App.LinkInfo extends App.Controller
fetch: () => fetch: () =>
# fetch item on demand # fetch item on demand
# get data # get data
App.Com.ajax( @ajax(
id: 'links_' + @object.id + '_' + @object_type, id: 'links_' + @object.id + '_' + @object_type,
type: 'GET', type: 'GET',
url: @apiPath + '/links', url: @apiPath + '/links',
@ -80,7 +80,7 @@ class App.LinkInfo extends App.Controller
link_object_target_value = @object.id link_object_target_value = @object.id
# get data # get data
App.Com.ajax( @ajax(
id: 'links_remove_' + @object.id + '_' + @object_type, id: 'links_remove_' + @object.id + '_' + @object_type,
type: 'GET', type: 'GET',
url: @apiPath + '/links/remove', url: @apiPath + '/links/remove',
@ -123,7 +123,7 @@ class App.LinkAdd extends App.ControllerModal
params = @formParam(e.target) params = @formParam(e.target)
# get data # get data
App.Com.ajax( @ajax(
id: 'links_add_' + @object.id + '_' + @object_type, id: 'links_add_' + @object.id + '_' + @object_type,
type: 'GET', type: 'GET',
url: @apiPath + '/links/add', url: @apiPath + '/links/add',

View file

@ -90,8 +90,8 @@ class App.Navigation extends App.Controller
@searchFocusSet = false @searchFocusSet = false
searchFunction = => searchFunction = =>
App.Com.ajax( App.Ajax.request(
id: 'ticket_search' id: 'search'
type: 'GET' type: 'GET'
url: @apiPath + '/search' url: @apiPath + '/search'
data: data:

View file

@ -13,7 +13,7 @@ class Index extends App.ControllerContent
@load() @load()
load: -> load: ->
App.Com.ajax( @ajax(
id: 'packages', id: 'packages',
type: 'GET', type: 'GET',
url: @apiPath + '/packages', url: @apiPath + '/packages',
@ -47,7 +47,7 @@ class Index extends App.ControllerContent
httpType = 'DELETE' httpType = 'DELETE'
if httpType if httpType
App.Com.ajax( @ajax(
id: 'packages', id: 'packages',
type: httpType, type: httpType,
url: @apiPath + '/packages', url: @apiPath + '/packages',

View file

@ -43,7 +43,7 @@ class Index extends App.ControllerContent
@formDisable(e) @formDisable(e)
# get data # get data
App.Com.ajax( @ajax(
id: 'password_reset' id: 'password_reset'
type: 'POST' type: 'POST'
url: @apiPath + '/users/password_reset' url: @apiPath + '/users/password_reset'
@ -83,7 +83,7 @@ class Verify extends App.ControllerContent
# get data # get data
params = {} params = {}
params['token'] = @token params['token'] = @token
App.Com.ajax( @ajax(
id: 'password_reset_verify' id: 'password_reset_verify'
type: 'POST' type: 'POST'
url: @apiPath + '/users/password_reset_verify' url: @apiPath + '/users/password_reset_verify'
@ -119,7 +119,7 @@ class Verify extends App.ControllerContent
@password = params['password'] @password = params['password']
# get data # get data
App.Com.ajax( @ajax(
id: 'password_reset_verify' id: 'password_reset_verify'
type: 'POST' type: 'POST'
url: @apiPath + '/users/password_reset_verify' url: @apiPath + '/users/password_reset_verify'

View file

@ -9,15 +9,15 @@ class Index extends App.ControllerContent
return if !@authenticate() return if !@authenticate()
@load() @load()
# @interval( @interval(
# => =>
# @load() @load()
# 10000 45000
# ) )
# fetch data, render view # fetch data, render view
load: -> load: ->
App.Com.ajax( @ajax(
id: 'sessions' id: 'sessions'
type: 'GET' type: 'GET'
url: @apiPath + '/sessions' url: @apiPath + '/sessions'
@ -43,7 +43,7 @@ class Index extends App.ControllerContent
destroy: (e) -> destroy: (e) ->
e.preventDefault() e.preventDefault()
sessionId = $( e.target ).data('session-id') sessionId = $( e.target ).data('session-id')
App.Com.ajax( @ajax(
id: 'sessions/' + sessionId id: 'sessions/' + sessionId
type: 'DELETE' type: 'DELETE'
url: @apiPath + '/sessions/' + sessionId url: @apiPath + '/sessions/' + sessionId

View file

@ -9,7 +9,7 @@ class App.TagWidget extends App.Controller
load: => load: =>
@attribute_id = 'tags_' + @object.id + '_' + @object_type @attribute_id = 'tags_' + @object.id + '_' + @object_type
App.Com.ajax( @ajax(
id: @attribute_id id: @attribute_id
type: 'GET' type: 'GET'
url: @apiPath + '/tags' url: @apiPath + '/tags'
@ -40,7 +40,7 @@ class App.TagWidget extends App.Controller
# @el.find('#tags').elastic() # @el.find('#tags').elastic()
onAddTag: (item) => onAddTag: (item) =>
App.Com.ajax( @ajax(
type: 'GET', type: 'GET',
url: @apiPath + '/tags/add', url: @apiPath + '/tags/add',
data: data:
@ -53,7 +53,7 @@ class App.TagWidget extends App.Controller
) )
onRemoveTag: (item) => onRemoveTag: (item) =>
App.Com.ajax( @ajax(
type: 'GET' type: 'GET'
url: @apiPath + '/tags/remove' url: @apiPath + '/tags/remove'
data: data:

View file

@ -64,7 +64,7 @@ class Table extends App.ControllerContent
# init fetch via ajax, all other updates on time via websockets # init fetch via ajax, all other updates on time via websockets
else else
App.Com.ajax( @ajax(
id: 'ticket_overview_' + @key, id: 'ticket_overview_' + @key,
type: 'GET', type: 'GET',
url: @apiPath + '/ticket_overviews', url: @apiPath + '/ticket_overviews',
@ -559,7 +559,7 @@ class Router extends App.Controller
@ticket_list = cache.ticket_list @ticket_list = cache.ticket_list
@redirect() @redirect()
else else
App.Com.ajax( @ajax(
type: 'GET' type: 'GET'
url: @apiPath + '/ticket_overviews' url: @apiPath + '/ticket_overviews'
data: data:

View file

@ -64,7 +64,7 @@ class App.TicketZoom extends App.Controller
return if !@Session.all() return if !@Session.all()
# get data # get data
App.Com.ajax( @ajax(
id: 'ticket_zoom_' + ticket_id id: 'ticket_zoom_' + ticket_id
type: 'GET' type: 'GET'
url: @apiPath + '/ticket_full/' + ticket_id + '?do_not_log=' + @doNotLog url: @apiPath + '/ticket_full/' + ticket_id + '?do_not_log=' + @doNotLog

View file

@ -29,7 +29,10 @@ class _trackSingleton
@log( 'start', 'notice', {} ) @log( 'start', 'notice', {} )
App.Interval.set @send, 60000 # start initial submit 10 sec. later to avoid ie10 cookie issues
delay = =>
App.Interval.set @send, 60000
App.Delay.set delay, 10000
# log clicks # log clicks
$(document).bind( $(document).bind(
@ -113,7 +116,7 @@ class _trackSingleton
catch e catch e
# nothing # nothing
App.Com.ajax( App.Ajax.request(
type: 'POST' type: 'POST'
url: @url url: @url
async: async async: async

View file

@ -1,9 +1,14 @@
class App.Com class App.Ajax
_instance = undefined # Must be declared here to force the closure on the class _instance = undefined # Must be declared here to force the closure on the class
@ajax: (args) -> # Must be a static method @request: (args) -> # Must be a static method
if _instance == undefined if _instance == undefined
_instance ?= new _ajaxSingleton _instance ?= new _ajaxSingleton
_instance.ajax(args) _instance.request(args)
@abort: (args) -> # Must be a static method
if _instance == undefined
_instance ?= new _ajaxSingleton
_instance.abort(args)
# The actual Singleton class # The actual Singleton class
class _ajaxSingleton class _ajaxSingleton
@ -61,19 +66,44 @@ class _ajaxSingleton
) )
) )
ajax: (params) -> request: (params) ->
data = $.extend({}, @defaults, params ) data = $.extend({}, @defaults, params )
# execute call with id, clear old call first if exists
if params['id'] if params['id']
if @current_request[ params['id'] ] @abort( params['id'] )
@current_request[ params['id'] ].abort()
@current_request[ params['id'] ] = $.ajax( data ) @current_request[ params['id'] ] = $.ajax( data )
return params['id']
# generate a uniq rand id
params['id'] = 'rand-' + new Date().getTime() + '-' + Math.floor( Math.random() * 99999 )
# queue request
if params['queue']
@queue_list.push data
if !@queue_running
@_run()
# execute request
else else
if params['queue'] @current_request[ params['id'] ] = $.ajax(data)
@queue_list.push data
if !@queue_running params['id']
@_run()
else abort: (id) =>
$.ajax(data)
# abort current_request
if @current_request[ id ]
@current_request[ id ].abort()
delete @current_request[ id ]
# remove from queue list
@queue_list = _.filter(
@queue_list
(item) ->
return item if item['id'] isnt id
return
)
_run: => _run: =>
if @queue_list && @queue_list[0] if @queue_list && @queue_list[0]
@ -82,7 +112,7 @@ class _ajaxSingleton
request.complete = => request.complete = =>
@queue_running = false @queue_running = false
@_run() @_run()
$.ajax( request ) @current_request[ request['id'] ] = $.ajax( request )
_show_spinner: => _show_spinner: =>
@count++ @count++

View file

@ -2,7 +2,7 @@ class App.Auth
@login: (params) -> @login: (params) ->
App.Log.notice 'Auth', 'login', params App.Log.notice 'Auth', 'login', params
App.Com.ajax( App.Ajax.request(
id: 'login', id: 'login',
type: 'POST', type: 'POST',
url: App.Config.get('api_path') + '/signin', url: App.Config.get('api_path') + '/signin',
@ -22,7 +22,7 @@ class App.Auth
@loginCheck: -> @loginCheck: ->
App.Log.notice 'Auth', 'loginCheck' App.Log.notice 'Auth', 'loginCheck'
App.Com.ajax( App.Ajax.request(
id: 'login_check' id: 'login_check'
async: false async: false
type: 'GET' type: 'GET'
@ -38,7 +38,7 @@ class App.Auth
@logout: -> @logout: ->
App.Log.notice 'Auth', 'logout' App.Log.notice 'Auth', 'logout'
App.Com.ajax( App.Ajax.request(
id: 'logout' id: 'logout'
type: 'DELETE' type: 'DELETE'
url: App.Config.get('api_path') + '/signout' url: App.Config.get('api_path') + '/signout'

View file

@ -14,8 +14,8 @@ class App.Browser
console.log('Browser not supported') console.log('Browser not supported')
return false return false
# disable Firefox 6 and older # disable Firefox 9 and older
else if data.browser == 'Firefox' && data.version <= 6 else if data.browser == 'Firefox' && data.version <= 9
@message(data) @message(data)
console.log('Browser not supported') console.log('Browser not supported')
return false return false

View file

@ -100,7 +100,7 @@ class _i18nSingleton extends Spine.Module
@locale = locale @locale = locale
@map = {} @map = {}
App.Com.ajax( App.Ajax.request(
id: 'i18n-set-' + locale, id: 'i18n-set-' + locale,
type: 'GET', type: 'GET',
url: App.Config.get('api_path') + '/translations/lang/' + locale, url: App.Config.get('api_path') + '/translations/lang/' + locale,

View file

@ -68,7 +68,6 @@ class _taskManagerSingleton extends App.Controller
@workersStarted = {} @workersStarted = {}
@allTasks = [] @allTasks = []
@tasksToUpdate = {} @tasksToUpdate = {}
@initialLoad = true
@activeTask = undefined @activeTask = undefined
@tasksInitial() @tasksInitial()
@ -76,8 +75,6 @@ class _taskManagerSingleton extends App.Controller
App.Event.bind( App.Event.bind(
'auth:login' 'auth:login'
=> =>
@initialLoad = true
@all()
@tasksInitial() @tasksInitial()
'task' 'task'
) )
@ -95,13 +92,6 @@ class _taskManagerSingleton extends App.Controller
all: -> all: ->
# initial load of taskbar collection
if @initialLoad
@initialLoad = false
tasks = App.Taskbar.all()
for task in tasks
@allTasks.push task.attributes()
# sort by prio # sort by prio
@allTasks = _(@allTasks).sortBy( (task) -> @allTasks = _(@allTasks).sortBy( (task) ->
return task.prio; return task.prio;
@ -130,8 +120,9 @@ class _taskManagerSingleton extends App.Controller
# create new task if not exists # create new task if not exists
task = @get( key ) task = @get( key )
#console.log('add', key, callback, params, to_not_show, task) console.log('add', key, callback, params, to_not_show, task)
if !task if !task
console.log('add, create new taskbar in backend')
task = new App.Taskbar task = new App.Taskbar
task.load( task.load(
key: key key: key
@ -211,7 +202,7 @@ class _taskManagerSingleton extends App.Controller
startController: (key, callback, params, to_not_show) => startController: (key, callback, params, to_not_show) =>
# console.log('controller started...', callback, key, params) console.log('controller start try...', callback, key)
# activate controller # activate controller
worker = @worker( key ) worker = @worker( key )
@ -221,6 +212,7 @@ class _taskManagerSingleton extends App.Controller
# return if controller is already started # return if controller is already started
return if @workersStarted[key] return if @workersStarted[key]
@workersStarted[key] = true @workersStarted[key] = true
console.log('controller start now...', callback, key)
# create new controller instanz # create new controller instanz
params_app = _.clone(params) params_app = _.clone(params)
@ -231,11 +223,14 @@ class _taskManagerSingleton extends App.Controller
params_app['doNotLog'] = 1 params_app['doNotLog'] = 1
a = new App[callback]( params_app ) a = new App[callback]( params_app )
@workers[ key ] = a @workers[ key ] = a
console.log('controller start now 2...', callback, key)
# activate controller # activate controller
if !to_not_show if !to_not_show
console.log('controller start now 2 activate...', callback, key)
a.activate() a.activate()
console.log('controller start now 2 return...', callback, key)
return a return a
get: ( key ) => get: ( key ) =>
@ -311,7 +306,7 @@ class _taskManagerSingleton extends App.Controller
@allTasks = [] @allTasks = []
@activeTask = undefined @activeTask = undefined
# clear inmem tasks # clear in mem tasks
App.Taskbar.deleteAll() App.Taskbar.deleteAll()
# rerender task bar # rerender task bar
@ -343,6 +338,7 @@ class _taskManagerSingleton extends App.Controller
if ui.tasksToUpdate[ @key ] is 'inProgress' if ui.tasksToUpdate[ @key ] is 'inProgress'
delete ui.tasksToUpdate[ @key ] delete ui.tasksToUpdate[ @key ]
error: (task) => error: (task) =>
ui.log 'error', "can't update task '#{task.id}'"
if ui.tasksToUpdate[ @key ] is 'inProgress' if ui.tasksToUpdate[ @key ] is 'inProgress'
delete ui.tasksToUpdate[ @key ] delete ui.tasksToUpdate[ @key ]
) )
@ -366,17 +362,19 @@ class _taskManagerSingleton extends App.Controller
tasksInitial: => tasksInitial: =>
# initial load of taskbar collection
tasks = App.Taskbar.all()
@allTasks = []
for task in tasks
@allTasks.push task.attributes()
# reopen tasks # reopen tasks
App.Event.trigger 'taskbar:init' App.Event.trigger 'taskbar:init'
# check if we have different
tasks = @all()
return if !tasks
task_count = 0 task_count = 0
for task in tasks for task in @allTasks
task_count += 1 task_count += 1
console.log('START', task)
App.Delay.set( App.Delay.set(
=> =>
task = tasks.shift() task = tasks.shift()

View file

@ -287,11 +287,9 @@ class _webSocketSingleton extends App.Controller
# return if init is already done and not forced # return if init is already done and not forced
return if @_ajaxInitDone && !data.force return if @_ajaxInitDone && !data.force
# stop init request if new one is started
if @_ajaxInitWorking
@_ajaxInitWorking.abort()
# call init request # call init request
@_ajaxInitWorking = App.Com.ajax( App.Ajax.request(
id: 'ws-login'
type: 'POST' type: 'POST'
url: @Config.get('api_path') + '/message_send' url: @Config.get('api_path') + '/message_send'
data: JSON.stringify({ data: { action: 'login' } }) data: JSON.stringify({ data: { action: 'login' } })
@ -304,10 +302,8 @@ class _webSocketSingleton extends App.Controller
@_ajaxReceive() @_ajaxReceive()
@_ajaxSendQueue() @_ajaxSendQueue()
@_ajaxInitDone = true @_ajaxInitDone = true
@_ajaxInitWorking = false
error: => error: =>
@_ajaxInitDone = true @_ajaxInitDone = true
@_ajaxInitWorking = false
# try reconnect on error after x sec. # try reconnect on error after x sec.
reconnect = => reconnect = =>
@ -327,7 +323,7 @@ class _webSocketSingleton extends App.Controller
_ajaxSendQueue: => _ajaxSendQueue: =>
while !_.isEmpty(@queue) while !_.isEmpty(@queue)
data = @queue.shift() data = @queue.shift()
App.Com.ajax( App.Ajax.request(
type: 'POST' type: 'POST'
url: @Config.get('api_path') + '/message_send' url: @Config.get('api_path') + '/message_send'
data: JSON.stringify({ client_id: @client_id, data: data }) data: JSON.stringify({ client_id: @client_id, data: data })
@ -346,7 +342,7 @@ class _webSocketSingleton extends App.Controller
return if !@client_id return if !@client_id
return if @_ajaxReceiveWorking is true return if @_ajaxReceiveWorking is true
@_ajaxReceiveWorking = true @_ajaxReceiveWorking = true
App.Com.ajax( App.Ajax.request(
id: 'message_receive', id: 'message_receive',
type: 'POST' type: 'POST'
url: @Config.get('api_path') + '/message_receive' url: @Config.get('api_path') + '/message_receive'

View file

@ -33,17 +33,29 @@ class App.Ticket extends App.Model
# customer # customer
if data.customer_id if data.customer_id
data.customer = App.User.find( data.customer_id ) if !App.User.exists( data.customer_id )
console.error("Can't find user for data.customer_id #{data.customer_id} for ticket #{data.id}")
else
data.customer = App.User.find( data.customer_id )
# owner # owner
if data.owner_id if data.owner_id
data.owner = App.User.find( data.owner_id ) if !App.User.exists( data.owner_id )
console.error("Can't find user for data.owner_id #{data.owner_id} for ticket #{data.id}")
else
data.owner = App.User.find( data.owner_id )
# add created & updated # add created & updated
if data.created_by_id if data.created_by_id
data.created_by = App.User.find( data.created_by_id ) if !App.User.exists( data.created_by_id )
console.error("Can't find user for data.created_by_id #{data.created_by_id} for ticket #{data.id}")
else
data.created_by = App.User.find( data.created_by_id )
if data.updated_by_id if data.updated_by_id
data.updated_by = App.User.find( data.updated_by_id ) if !App.User.exists( data.updated_by_id )
console.error("Can't find user for data.updated_by_id #{data.updated_by_id} for ticket #{data.id}")
else
data.updated_by = App.User.find( data.updated_by_id )
data data

View file

@ -27,7 +27,7 @@ class ApplicationController < ActionController::Base
headers['Access-Control-Allow-Origin'] = '*' headers['Access-Control-Allow-Origin'] = '*'
headers['Access-Control-Allow-Methods'] = 'POST, GET, PUT, DELETE, OPTIONS' headers['Access-Control-Allow-Methods'] = 'POST, GET, PUT, DELETE, OPTIONS'
headers['Access-Control-Max-Age'] = '1728000' headers['Access-Control-Max-Age'] = '1728000'
headers['Access-Control-Allow-Headers'] = 'Content-Type, Depth, User-Agent, X-File-Size, X-Requested-With, If-Modified-Since, X-File-Name, Cache-Control' headers['Access-Control-Allow-Headers'] = 'Content-Type, Depth, User-Agent, X-File-Size, X-Requested-With, If-Modified-Since, X-File-Name, Cache-Control, Accept-Language'
headers['Access-Control-Allow-Credentials'] = 'true' headers['Access-Control-Allow-Credentials'] = 'true'
end end
@ -39,7 +39,7 @@ class ApplicationController < ActionController::Base
if request.method == 'OPTIONS' if request.method == 'OPTIONS'
headers['Access-Control-Allow-Origin'] = '*' headers['Access-Control-Allow-Origin'] = '*'
headers['Access-Control-Allow-Methods'] = 'POST, GET, PUT, DELETE, OPTIONS' headers['Access-Control-Allow-Methods'] = 'POST, GET, PUT, DELETE, OPTIONS'
headers['Access-Control-Allow-Headers'] = 'Content-Type, Depth, User-Agent, X-File-Size, X-Requested-With, If-Modified-Since, X-File-Name, Cache-Control' headers['Access-Control-Allow-Headers'] = 'Content-Type, Depth, User-Agent, X-File-Size, X-Requested-With, If-Modified-Since, X-File-Name, Cache-Control, Accept-Language'
headers['Access-Control-Max-Age'] = '1728000' headers['Access-Control-Max-Age'] = '1728000'
headers['Access-Control-Allow-Credentials'] = 'true' headers['Access-Control-Allow-Credentials'] = 'true'
render :text => '', :content_type => 'text/plain' render :text => '', :content_type => 'text/plain'

View file

@ -8,7 +8,7 @@ Presort of group (highest sort priority).
X-Zammad-Owner: [login of agent] X-Zammad-Owner: [login of agent]
-------------------------------- --------------------------------
Assigne ticket to agent. Assign ticket to agent.
X-Zammad-Ignore: [yes|true] X-Zammad-Ignore: [yes|true]
------------------------- -------------------------
@ -26,9 +26,9 @@ X-Zammad-Article-Type: (email|phone|fax|sms|webrequest|note|twitter status|direc
------------------------------------------------------------------------------------------------------- -------------------------------------------------------------------------------------------------------
Article type (for whole list check your database). Article type (for whole list check your database).
X-Zammad-Article-Visability: (internal|external) X-Zammad-Article-Visibility: (internal|external)
------------------------------------------------ ------------------------------------------------
Article visability. Article visibility.
X-Zammad-Customer-Email: [email address] X-Zammad-Customer-Email: [email address]
---------------------------------------- ----------------------------------------

View file

@ -1,6 +1,6 @@
// ajax // ajax
App.Com.ajax({ App.Ajax.request({
type: 'GET', type: 'GET',
url: '/assets/tests/ajax-test.json', url: '/assets/tests/ajax-test.json',
success: function (data) { success: function (data) {
@ -18,7 +18,7 @@ App.Com.ajax({
}); });
// ajax queueing // ajax queueing
App.Com.ajax({ App.Ajax.request({
type: 'GET', type: 'GET',
url: '/tests/wait/2', url: '/tests/wait/2',
queue: true, queue: true,
@ -38,7 +38,7 @@ App.Com.ajax({
}); });
} }
}); });
App.Com.ajax({ App.Ajax.request({
type: 'GET', type: 'GET',
url: '/tests/wait/1', url: '/tests/wait/1',
queue: true, queue: true,
@ -60,7 +60,7 @@ App.Com.ajax({
}); });
// ajax parallel // ajax parallel
App.Com.ajax({ App.Ajax.request({
type: 'GET', type: 'GET',
url: '/tests/wait/2', url: '/tests/wait/2',
success: function (data) { success: function (data) {
@ -79,7 +79,7 @@ App.Com.ajax({
}); });
} }
}); });
App.Com.ajax({ App.Ajax.request({
type: 'GET', type: 'GET',
url: '/tests/wait/1', url: '/tests/wait/1',
success: function (data) { success: function (data) {
@ -210,7 +210,7 @@ App.Delay.set( function() {
App.Interval.clear('interval-test1') App.Interval.clear('interval-test1')
}); });
}, },
2500 2400
); );
App.Delay.set( function() { App.Delay.set( function() {
test( "interval - test 1 - 1/1", function() { test( "interval - test 1 - 1/1", function() {
@ -240,7 +240,7 @@ App.Delay.set( function() {
App.Interval.clearLevel('page') App.Interval.clearLevel('page')
}); });
}, },
2500 2400
); );
App.Delay.set( function() { App.Delay.set( function() {
test( "interval - test 2 - 1/1", function() { test( "interval - test 2 - 1/1", function() {

View file

@ -9,10 +9,6 @@ class AaaGettingStartedTest < TestCase
:instance => browser_instance, :instance => browser_instance,
:url => browser_url + '/', :url => browser_url + '/',
:action => [ :action => [
{
:execute => 'wait',
:value => 1,
},
{ {
:execute => 'check', :execute => 'check',
:css => '#form-master', :css => '#form-master',
@ -54,12 +50,7 @@ class AaaGettingStartedTest < TestCase
}, },
{ {
:execute => 'wait', :execute => 'wait',
:value => 4, :value => 3,
},
{
:execute => 'check',
:css => '#login',
:result => false,
}, },
{ {
:execute => 'check', :execute => 'check',
@ -80,10 +71,6 @@ class AaaGettingStartedTest < TestCase
:value => 'Invite Agents', :value => 'Invite Agents',
:match_result => true, :match_result => true,
}, },
{
:execute => 'wait',
:value => 4,
},
{ {
:execute => 'set', :execute => 'set',
:css => '#form-agent input[name="firstname"]', :css => '#form-agent input[name="firstname"]',

View file

@ -299,7 +299,7 @@ class AgentTicketActionsLevel3Test < TestCase
}, },
{ {
:execute => 'wait', :execute => 'wait',
:value => 2, :value => 4,
}, },
{ {
:where => :instance2, :where => :instance2,

View file

@ -23,10 +23,6 @@ class AgentUserManageTest < TestCase
:execute => 'click', :execute => 'click',
:css => 'a[href="#ticket_create/call_inbound"]', :css => 'a[href="#ticket_create/call_inbound"]',
}, },
{
:execute => 'wait',
:value => 5,
},
{ {
:execute => 'click', :execute => 'click',
:css => '.active .customer_new', :css => '.active .customer_new',
@ -76,10 +72,6 @@ class AgentUserManageTest < TestCase
}, },
# call new ticket screen again # call new ticket screen again
{
:execute => 'wait',
:value => 2,
},
{ {
:execute => 'click', :execute => 'click',
:css => '.taskbar span[data-type="close"]', :css => '.taskbar span[data-type="close"]',
@ -143,6 +135,10 @@ class AgentUserManageTest < TestCase
:css => '.active .ticket_create input[name="customer_id_autocompletion"]', :css => '.active .ticket_create input[name="customer_id_autocompletion"]',
:value => :tab, :value => :tab,
}, },
{
:execute => 'wait',
:value => 1,
},
{ {
:execute => 'match', :execute => 'match',
:css => '.active input[name="customer_id"]', :css => '.active input[name="customer_id"]',

View file

@ -1,7 +1,7 @@
# encoding: utf-8 # encoding: utf-8
require 'browser_test_helper' require 'browser_test_helper'
class AuthTest < TestCase class AuthCustomerTest < TestCase
def test_authentication def test_authentication
tests = [ tests = [
{ {
@ -37,10 +37,6 @@ class AuthTest < TestCase
{ {
:name => 'login', :name => 'login',
:action => [ :action => [
{
:execute => 'wait',
:value => 2,
},
{ {
:execute => 'check', :execute => 'check',
:css => '#login', :css => '#login',
@ -62,7 +58,7 @@ class AuthTest < TestCase
}, },
{ {
:execute => 'wait', :execute => 'wait',
:value => 3, :value => 5,
}, },
# check action # check action

View file

@ -1,6 +1,6 @@
# encoding: utf-8 # encoding: utf-8
require 'browser_test_helper' require 'browser_test_helper'
class AuthMasterTest < TestCase class AuthMasterTest < TestCase
def test_authentication def test_authentication
tests = [ tests = [
@ -37,10 +37,6 @@ class AuthMasterTest < TestCase
{ {
:name => 'login', :name => 'login',
:action => [ :action => [
{
:execute => 'wait',
:value => 2,
},
{ {
:execute => 'check', :execute => 'check',
:css => '#login', :css => '#login',
@ -82,4 +78,4 @@ class AuthMasterTest < TestCase
] ]
browser_single_test(tests) browser_single_test(tests)
end end
end end

49
test/browser/core.rb Normal file
View file

@ -0,0 +1,49 @@
# encoding: utf-8
require 'browser_test_helper'
class CoreTest < TestCase
def test_core
tests = [
{
:name => 'start',
:instance => browser_instance,
:url => browser_url + '/tests-core',
:action => [
{
:execute => 'wait',
:value => 8,
},
{
:execute => 'match',
:css => '.result .failed',
:value => '0',
:match_result => true,
},
],
},
]
browser_single_test(tests)
end
def test_form
tests = [
{
:name => 'start',
:instance => browser_instance,
:url => browser_url + '/tests-form',
:action => [
{
:execute => 'wait',
:value => 8,
},
{
:execute => 'match',
:css => '.result .failed',
:value => '0',
:match_result => true,
},
],
},
]
browser_single_test(tests)
end
end

View file

@ -11,10 +11,6 @@ class CustomerTicketCreateTest < TestCase
:execute => 'click', :execute => 'click',
:css => 'a[href="#customer_ticket_new"]', :css => 'a[href="#customer_ticket_new"]',
}, },
{
:execute => 'wait',
:value => 3,
},
{ {
:execute => 'check', :execute => 'check',
:css => '.ticket-create', :css => '.ticket-create',
@ -47,11 +43,6 @@ class CustomerTicketCreateTest < TestCase
:execute => 'wait', :execute => 'wait',
:value => 3, :value => 3,
}, },
{
:execute => 'check',
:css => '#login',
:result => false,
},
{ {
:execute => 'check', :execute => 'check',
:element => :url, :element => :url,

View file

@ -15,17 +15,14 @@ class PreferencesTest < TestCase
:execute => 'click', :execute => 'click',
:css => 'a[href="#profile"]', :css => 'a[href="#profile"]',
}, },
{
:execute => 'wait',
:value => 1,
},
{ {
:execute => 'click', :execute => 'click',
:css => 'a[href="#profile/language"]', :css => 'a[href="#profile/language"]',
}, },
{ {
:execute => 'wait', :execute => 'check',
:value => 1, :css => '#language',
:result => true,
}, },
{ {
:execute => 'select', :execute => 'select',
@ -40,11 +37,6 @@ class PreferencesTest < TestCase
:execute => 'wait', :execute => 'wait',
:value => 6, :value => 6,
}, },
{
:execute => 'check',
:css => '#login',
:result => false,
},
{ {
:execute => 'match', :execute => 'match',
:css => 'body', :css => 'body',

View file

@ -19,10 +19,6 @@ class SettingTest < TestCase
:execute => 'click', :execute => 'click',
:css => 'a[href="#settings/security/third_party_auth"]', :css => 'a[href="#settings/security/third_party_auth"]',
}, },
{
:execute => 'wait',
:value => 2,
},
{ {
:execute => 'check', :execute => 'check',
:css => '#auth_facebook select[name="auth_facebook"]', :css => '#auth_facebook select[name="auth_facebook"]',

View file

@ -55,15 +55,10 @@ class SignupTest < TestCase
}, },
{ {
:execute => 'wait', :execute => 'wait',
:value => 4, :value => 2,
}, },
# check action # check action
{
:execute => 'check',
:css => '#login',
:result => false,
},
{ {
:execute => 'check', :execute => 'check',
:css => '#form-signup', :css => '#form-signup',
@ -80,4 +75,4 @@ class SignupTest < TestCase
] ]
browser_single_test(tests) browser_single_test(tests)
end end
end end

View file

@ -23,19 +23,14 @@ class TestCase < Test::Unit::TestCase
if !@browsers if !@browsers
@browsers = [] @browsers = []
end end
if !ENV['REMOTE_URL'] if !ENV['REMOTE_URL'] || ENV['REMOTE_URL'].empty?
local_browser = Selenium::WebDriver.for( browser.to_sym ) local_browser = Selenium::WebDriver.for( browser.to_sym )
browser_instance_preferences(local_browser) browser_instance_preferences(local_browser)
@browsers.push local_browser @browsers.push local_browser
return local_browser return local_browser
end end
caps = Selenium::WebDriver::Remote::Capabilities.send( caps = Selenium::WebDriver::Remote::Capabilities.send( browser )
browser,
#:forceCreateProcess => true,
#:ensureCleanSession => true,
#:internetExplorerSwitches => 'InetCpl.cpl,ClearMyTracksByProcess 2',
)
caps.platform = ENV['BROWSER_OS'] || 'Windows 2008' caps.platform = ENV['BROWSER_OS'] || 'Windows 2008'
caps.version = ENV['BROWSER_VERSION'] || '8' caps.version = ENV['BROWSER_VERSION'] || '8'
local_browser = Selenium::WebDriver.for( local_browser = Selenium::WebDriver.for(
@ -61,9 +56,21 @@ class TestCase < Test::Unit::TestCase
def teardown def teardown
return if !@browsers return if !@browsers
@browsers.each{ |local_browser|
local_browser.quit # only shut down browser type once on local webdriver tests
} # otherwise this error will happen "Errno::ECONNREFUSED: Connection refused - connect(2)"
if !ENV['REMOTE_URL']
shutdown = {}
@browsers.each{ |local_browser|
next if shutdown[ local_browser.browser ]
shutdown[ local_browser.browser ] = true
local_browser.quit
}
else
@browsers.each{ |local_browser|
local_browser.quit
}
end
end end
# Add more helper methods to be used by all tests here... # Add more helper methods to be used by all tests here...
@ -204,13 +211,11 @@ puts "NOTICE #{Time.now.to_s}: " + action.inspect
elsif action[:element] == :alert elsif action[:element] == :alert
element = instance.switch_to.alert element = instance.switch_to.alert
elsif action[:execute] == 'login' elsif action[:execute] == 'login'
sleep 1 element = instance.find_element( { :css => '#login input[name="username"]' } )
login = instance.find_element( { :css => '#login' } ) if !element
if !login
assert( false, "(#{test[:name]}) no login box found!" ) assert( false, "(#{test[:name]}) no login box found!" )
return return
end end
element = instance.find_element( { :css => '#login input[name="username"]' } )
element.clear element.clear
element.send_keys( action[:username] ) element.send_keys( action[:username] )
element = instance.find_element( { :css => '#login input[name="password"]' } ) element = instance.find_element( { :css => '#login input[name="password"]' } )
@ -234,13 +239,12 @@ puts "NOTICE #{Time.now.to_s}: " + action.inspect
elsif action[:execute] == 'create_ticket' elsif action[:execute] == 'create_ticket'
instance.find_element( { :css => 'a[href="#new"]' } ).click instance.find_element( { :css => 'a[href="#new"]' } ).click
instance.find_element( { :css => 'a[href="#ticket_create/call_inbound"]' } ).click instance.find_element( { :css => 'a[href="#ticket_create/call_inbound"]' } ).click
sleep 4
element = instance.find_element( { :css => '.active .ticket_create' } ) element = instance.find_element( { :css => '.active .ticket_create' } )
if !element if !element
assert( false, "(#{test[:name]}) no ticket create screen found!" ) assert( false, "(#{test[:name]}) no ticket create screen found!" )
return return
end end
sleep 5 sleep 4
element = instance.find_element( { :css => '.active .ticket_create input[name="customer_id_autocompletion"]' } ) element = instance.find_element( { :css => '.active .ticket_create input[name="customer_id_autocompletion"]' } )
element.clear element.clear
element.send_keys( 'ma' ) element.send_keys( 'ma' )