From 70847f2b41e027d12e9ec09c8b9116f41653742e Mon Sep 17 00:00:00 2001 From: Martin Edenhofer Date: Tue, 20 Mar 2018 13:16:17 +0100 Subject: [PATCH] Improved fetching activity stream, online notifications and recent viewed items. Improved REST API with full and expaned attributes. --- .../_application_controller_generic.coffee | 23 +++- .../_dashboard/activity_stream.coffee | 7 +- .../app/controllers/navigation.coffee | 5 +- .../controllers/organization_profile.coffee | 47 +++---- .../app/controllers/ticket_overview.coffee | 3 +- .../app/controllers/user_profile.coffee | 55 ++++---- .../widget/online_notification.coffee | 14 +- .../app/models/_application_model.coffee | 53 +++++--- .../app/models/activity_stream.coffee | 4 + app/controllers/activity_stream_controller.rb | 32 ++++- .../online_notifications_controller.rb | 31 ++++- app/controllers/recent_view_controller.rb | 32 ++++- app/controllers/sessions/collection_base.rb | 12 +- app/controllers/tickets_controller.rb | 10 +- app/models/activity_stream.rb | 18 +-- app/models/activity_stream/assets.rb | 56 ++++++++ app/models/online_notification.rb | 73 +++-------- app/models/online_notification/assets.rb | 56 ++++++++ app/models/recent_view.rb | 63 +++++---- app/models/recent_view/assets.rb | 55 ++++++++ app/models/user.rb | 21 ++- lib/sessions/backend/activity_stream.rb | 12 +- public/assets/tests/model.js | 44 +++---- .../api_auth_on_behalf_of_controller_test.rb | 31 ++++- test/unit/activity_stream_test.rb | 120 +++++++++--------- test/unit/recent_view_test.rb | 16 +-- 26 files changed, 585 insertions(+), 308 deletions(-) create mode 100644 app/assets/javascripts/app/models/activity_stream.coffee create mode 100644 app/models/activity_stream/assets.rb create mode 100644 app/models/online_notification/assets.rb create mode 100644 app/models/recent_view/assets.rb diff --git a/app/assets/javascripts/app/controllers/_application_controller_generic.coffee b/app/assets/javascripts/app/controllers/_application_controller_generic.coffee index 9b2c87cc8..fba868be0 100644 --- a/app/assets/javascripts/app/controllers/_application_controller_generic.coffee +++ b/app/assets/javascripts/app/controllers/_application_controller_generic.coffee @@ -1171,7 +1171,7 @@ class App.CollectionController extends App.Controller class App.ObserverController extends App.Controller model: 'Ticket' - template: 'ticket_zoom/title' + template: 'tba' globalRerender: true ### @@ -1251,3 +1251,24 @@ class App.ObserverController extends App.Controller #console.trace() @log 'debug', 'release', @object_id, @model, @subscribeId App[@model].unsubscribe(@subscribeId) + +class App.ObserverActionRow extends App.ObserverController + constructor: -> + super + + render: (object) => + return if _.isEmpty(object) + actions = @actions() + @html App.view('generic/actions')( + items: actions + type: @type + ) + + for item in actions + do (item) => + @$("[data-type=\"#{item.name}\"]").on( + 'click' + (e) -> + e.preventDefault() + item.callback(object) + ) diff --git a/app/assets/javascripts/app/controllers/_dashboard/activity_stream.coffee b/app/assets/javascripts/app/controllers/_dashboard/activity_stream.coffee index bf274e434..a1df4842b 100644 --- a/app/assets/javascripts/app/controllers/_dashboard/activity_stream.coffee +++ b/app/assets/javascripts/app/controllers/_dashboard/activity_stream.coffee @@ -27,7 +27,7 @@ class App.DashboardActivityStream extends App.CollectionController @ajax( id: 'dashoard_activity_stream' type: 'GET' - url: "#{@apiPath}/activity_stream" + url: "#{@apiPath}/activity_stream?full=true" data: limit: @limit || 8 processData: true @@ -37,8 +37,9 @@ class App.DashboardActivityStream extends App.CollectionController load: (data) => App.SessionStorage.set('activity_stream', data) - @items = data.activity_stream + App.ActivityStream.refresh([], clear: true) App.Collection.loadAssets(data.assets) + @items = App.ActivityStream.search(sortBy: 'created_at', order: 'DESC') @collectionSync(@items) itemGet: (key) => @@ -49,7 +50,7 @@ class App.DashboardActivityStream extends App.CollectionController # nothing itemsAll: => - @items + @items || [] onRenderEnd: => return if _.isEmpty(@items) diff --git a/app/assets/javascripts/app/controllers/navigation.coffee b/app/assets/javascripts/app/controllers/navigation.coffee index e9f88670e..171551886 100644 --- a/app/assets/javascripts/app/controllers/navigation.coffee +++ b/app/assets/javascripts/app/controllers/navigation.coffee @@ -448,10 +448,9 @@ class App.Navigation extends App.ControllerWidgetPermanent @Config.set('NavBarRight', NavBarRight) fetchRecentView: => - load = (data) => - App.RecentView.refresh(data.stream, clear: true) + load = => @renderPersonal() - App.RecentView.fetchFull(load) + App.RecentView.fetchFull(load, clear: true) toggleNotifications: (e) -> e.stopPropagation() diff --git a/app/assets/javascripts/app/controllers/organization_profile.coffee b/app/assets/javascripts/app/controllers/organization_profile.coffee index 1386f2f8c..d3ed34840 100644 --- a/app/assets/javascripts/app/controllers/organization_profile.coffee +++ b/app/assets/javascripts/app/controllers/organization_profile.coffee @@ -73,50 +73,43 @@ class App.OrganizationProfile extends App.Controller currentPosition: => @$('.profile').scrollTop() -class ActionRow extends App.ObserverController +class ActionRow extends App.ObserverActionRow model: 'Organization' observe: member_ids: true - render: (organization) => + showHistory: (organization) => + new App.OrganizationHistory( + organization_id: organization.id + container: @el.closest('.content') + ) - # start action controller - showHistory = => - new App.OrganizationHistory( - organization_id: organization.id - container: @el.closest('.content') - ) - - editOrganization = => - new App.ControllerGenericEdit( - id: organization.id - genericObject: 'Organization' - screen: 'edit' - pageData: - title: 'Organizations' - object: 'Organization' - objects: 'Organizations' - container: @el.closest('.content') - ) + editOrganization: (organization) => + new App.ControllerGenericEdit( + id: organization.id + genericObject: 'Organization' + screen: 'edit' + pageData: + title: 'Organizations' + object: 'Organization' + objects: 'Organizations' + container: @el.closest('.content') + ) + actions: => actions = [ { name: 'edit' title: 'Edit' - callback: editOrganization + callback: @editOrganization } { name: 'history' title: 'History' - callback: showHistory + callback: @showHistory } ] - new App.ActionRow( - el: @el - items: actions - ) - class Object extends App.ObserverController model: 'Organization' observeNot: diff --git a/app/assets/javascripts/app/controllers/ticket_overview.coffee b/app/assets/javascripts/app/controllers/ticket_overview.coffee index abaa9131f..4e70e80a4 100644 --- a/app/assets/javascripts/app/controllers/ticket_overview.coffee +++ b/app/assets/javascripts/app/controllers/ticket_overview.coffee @@ -574,11 +574,12 @@ class App.TicketOverview extends App.Controller @activeFocus = 'nav' ) - @bind 'overview:fetch', => + @bind('overview:fetch', => return if !@view update = => App.OverviewListCollection.fetch(@view) @delay(update, 2800, 'overview:fetch') + ) renderBatchOverlay: (elLocal) => if elLocal diff --git a/app/assets/javascripts/app/controllers/user_profile.coffee b/app/assets/javascripts/app/controllers/user_profile.coffee index 5e2d7bc85..fa12a6fc2 100644 --- a/app/assets/javascripts/app/controllers/user_profile.coffee +++ b/app/assets/javascripts/app/controllers/user_profile.coffee @@ -80,58 +80,51 @@ class App.UserProfile extends App.Controller currentPosition: => @$('.profile').scrollTop() -class ActionRow extends App.ObserverController +class ActionRow extends App.ObserverActionRow model: 'User' observe: organization_id: true - render: (user) => + showHistory: (user) => + new App.UserHistory( + user_id: user.id + container: @el.closest('.content') + ) - # start action controller - showHistory = => - new App.UserHistory( - user_id: user.id - container: @el.closest('.content') - ) + editUser: (user) => + new App.ControllerGenericEdit( + id: user.id + genericObject: 'User' + screen: 'edit' + pageData: + title: 'Users' + object: 'User' + objects: 'Users' + container: @el.closest('.content') + ) - editUser = => - new App.ControllerGenericEdit( - id: user.id - genericObject: 'User' - screen: 'edit' - pageData: - title: 'Users' - object: 'User' - objects: 'Users' - container: @el.closest('.content') - ) + newTicket: (user) => + @navigate("ticket/create/customer/#{user.id}") - newTicket = => - @navigate("ticket/create/customer/#{user.id}") - - actions = [ + actions: => + [ { name: 'edit' title: 'Edit' - callback: editUser + callback: @editUser } { name: 'history' title: 'History' - callback: showHistory + callback: @showHistory } { name: 'ticket' title: 'New Ticket' - callback: newTicket + callback: @newTicket } ] - new App.ActionRow( - el: @el - items: actions - ) - class Object extends App.ObserverController model: 'User' observeNot: diff --git a/app/assets/javascripts/app/controllers/widget/online_notification.coffee b/app/assets/javascripts/app/controllers/widget/online_notification.coffee index b4e41b673..8f7b99f2f 100644 --- a/app/assets/javascripts/app/controllers/widget/online_notification.coffee +++ b/app/assets/javascripts/app/controllers/widget/online_notification.coffee @@ -20,16 +20,17 @@ class App.OnlineNotificationWidget extends App.Controller super # at runtime if a online notifiction has changed - @bind 'OnlineNotification::changed', => + @bind('OnlineNotification::changed', => @delay( => @fetch() 2200 'online-notification-changed' ) + ) # after new websocket connection has been established @ignoreInitLogin = false - @bind 'ws:login', => + @bind('ws:login', => if @ignoreInitLogin @delay( => @fetch() @@ -37,15 +38,17 @@ class App.OnlineNotificationWidget extends App.Controller 'online-notification-changed' ) @ignoreInitLogin = true + ) # rebuild widget on auth - @bind 'auth', (user) => + @bind('auth', (user) => if !user @counterUpdate(0) return if !@access() @counterUpdate(0) return + ) $(window).on 'click.notifications', @hide @@ -150,10 +153,9 @@ class App.OnlineNotificationWidget extends App.Controller ) fetch: => - load = (data) => + load = => @fetchedData = true - App.OnlineNotification.refresh(data.stream, clear: true) - App.OnlineNotification.fetchFull(load) + App.OnlineNotification.fetchFull(load, clear: true) toggle: => if @shown diff --git a/app/assets/javascripts/app/models/_application_model.coffee b/app/assets/javascripts/app/models/_application_model.coffee index ce05630e6..1f262cbe6 100644 --- a/app/assets/javascripts/app/models/_application_model.coffee +++ b/app/assets/javascripts/app/models/_application_model.coffee @@ -273,11 +273,11 @@ set new attributes of model (remove already available attributes) # subscribe and reload data / fetch new data if triggered subscribeId = undefined if bind - subscribeId = App[ @className ].subscribeItem(id, callback) + subscribeId = App[@className].subscribeItem(id, callback) # execute if object already exists - if !force && App[ @className ].exists(id) - data = App[ @className ].find(id) + if !force && App[@className].exists(id) + data = App[@className].find(id) data = @_fillUp(data) if callback callback(data, 'full') @@ -312,17 +312,18 @@ set new attributes of model (remove already available attributes) # find / load object else - App[ @className ].refresh(data) + App[@className].refresh(data) # execute callbacks if @FULL_CALLBACK[ data.id ] for key, callback of @FULL_CALLBACK[ data.id ] - callback( @_fillUp( App[ @className ].find(data.id) ) ) + callback( @_fillUp( App[@className].find(data.id) ) ) delete @FULL_CALLBACK[ data.id ][ key ] if _.isEmpty @FULL_CALLBACK[ data.id ] delete @FULL_CALLBACK[ data.id ] - error: (xhr, statusText, error) -> + error: (xhr, statusText, error) => + @FULL_FETCH[ data.id ] = false App.Log.error('Model', statusText, error, url) ) subscribeId @@ -455,8 +456,8 @@ set new attributes of model (remove already available attributes) items = [items] App.Log.debug('Model', "local change #{@className}", items) for item in items - for key, callback of App[ @className ].SUBSCRIPTION_ITEM[ item.id ] - callback(App[ @className ]._fillUp(item), 'change') + for key, callback of App[@className].SUBSCRIPTION_ITEM[ item.id ] + callback(App[@className]._fillUp(item), 'change') ) @bind( 'destroy' @@ -467,8 +468,8 @@ set new attributes of model (remove already available attributes) items = [items] App.Log.debug('Model', "local destroy #{@className}", items) for item in items - for key, callback of App[ @className ].SUBSCRIPTION_ITEM[ item.id ] - callback(App[ @className ]._fillUp(item), 'destroy') + for key, callback of App[@className].SUBSCRIPTION_ITEM[ item.id ] + callback(App[@className]._fillUp(item), 'destroy') ) @changeTable = {} @@ -481,7 +482,7 @@ set new attributes of model (remove already available attributes) items = [items] App.Log.debug('Model', "local refresh #{@className}", items) for item in items - for key, callback of App[ @className ].SUBSCRIPTION_ITEM[ item.id ] + for key, callback of App[@className].SUBSCRIPTION_ITEM[ item.id ] # only trigger callbacks if object has changed if !@changeTable[key] || @changeTable[key] < item.updated_at @@ -498,8 +499,8 @@ set new attributes of model (remove already available attributes) App.Log.debug('Model', "server change on #{@className}.find(#{item.id}) #{item.updated_at}") callback = => genericObject = undefined - if App[ @className ].exists(item.id) - genericObject = App[ @className ].find(item.id) + if App[@className].exists(item.id) + genericObject = App[@className].find(item.id) if !genericObject || new Date(item.updated_at) > new Date(genericObject.updated_at) App.Log.debug('Model', "request #{@className}.find(#{item.id}) from server") @full(item.id, false, true) @@ -512,8 +513,8 @@ set new attributes of model (remove already available attributes) events (item) => return if !@SUBSCRIPTION_ITEM || !@SUBSCRIPTION_ITEM[ item.id ] - return if !App[ @className ].exists(item.id) - genericObject = App[ @className ].find(item.id) + return if !App[@className].exists(item.id) + genericObject = App[@className].find(item.id) App.Log.debug('Model', "server delete on #{@className}.find(#{item.id}) #{item.updated_at}") callback = -> genericObject.trigger('destroy', genericObject) @@ -565,16 +566,30 @@ set new attributes of model (remove already available attributes) @fetchFull: (callback, params = {}) -> url = "#{@url}/?full=true" App.Log.debug('Model', "fetchFull collection #{@className}", url) + + # request already active, queue callback + queueManagerName = "#{@className}::fetchFull" if params.force is false && App[@className].count() isnt 0 if callback - callback(App[@className].all()) + localCallback = => + callback(App[@className].all(), 'full') + App.QueueManager.add(queueManagerName, localCallback) + App.QueueManager.run(queueManagerName) return + if callback + localCallback = => + callback(App[@className].all()) + App.QueueManager.add(queueManagerName, localCallback) + + return if @fetchFullActive is true + @fetchFullActive = true App.Ajax.request( type: 'GET' url: url processData: true, success: (data, status, xhr) => + @fetchFullActive = false App.Log.debug('Model', "got fetchFull collection #{@className}", data) @@ -594,10 +609,10 @@ set new attributes of model (remove already available attributes) else App[@className].refresh(data) - if callback - callback(data) + App.QueueManager.run(queueManagerName) - error: (xhr, statusText, error) -> + error: (xhr, statusText, error) => + @fetchFullActive = false App.Log.error('Model', statusText, error, url) ) diff --git a/app/assets/javascripts/app/models/activity_stream.coffee b/app/assets/javascripts/app/models/activity_stream.coffee new file mode 100644 index 000000000..6c707bf92 --- /dev/null +++ b/app/assets/javascripts/app/models/activity_stream.coffee @@ -0,0 +1,4 @@ +class App.ActivityStream extends App.Model + @configure 'ActivityStream', 'name' + @extend Spine.Model.Ajax + @url: @apiPath + '/activity_steams' diff --git a/app/controllers/activity_stream_controller.rb b/app/controllers/activity_stream_controller.rb index bd9c99e2b..8ab25f151 100644 --- a/app/controllers/activity_stream_controller.rb +++ b/app/controllers/activity_stream_controller.rb @@ -5,10 +5,36 @@ class ActivityStreamController < ApplicationController # GET /api/v1/activity_stream def show - activity_stream = current_user.activity_stream(params[:limit], true) + activity_stream = current_user.activity_stream(params[:limit]) - # return result - render json: activity_stream + if response_expand? + list = [] + activity_stream.each do |item| + list.push item.attributes_with_association_names + end + render json: list, status: :ok + return + end + + if response_full? + assets = {} + item_ids = [] + activity_stream.each do |item| + item_ids.push item.id + assets = item.assets(assets) + end + render json: { + record_ids: item_ids, + assets: assets, + }, status: :ok + return + end + + all = [] + activity_stream.each do |item| + all.push item.attributes_with_association_ids + end + render json: all, status: :ok end end diff --git a/app/controllers/online_notifications_controller.rb b/app/controllers/online_notifications_controller.rb index a7fd3cf44..efa36016e 100644 --- a/app/controllers/online_notifications_controller.rb +++ b/app/controllers/online_notifications_controller.rb @@ -47,13 +47,36 @@ curl http://localhost/api/v1/online_notifications.json -v -u #{login}:#{password =end def index - if response_full? - render json: OnlineNotification.list_full(current_user, 200) + online_notifications = OnlineNotification.list(current_user, 200) + + if response_expand? + list = [] + online_notifications.each do |item| + list.push item.attributes_with_association_names + end + render json: list, status: :ok return end - notifications = OnlineNotification.list(current_user, 200) - model_index_render_result(notifications) + if response_full? + assets = {} + item_ids = [] + online_notifications.each do |item| + item_ids.push item.id + assets = item.assets(assets) + end + render json: { + record_ids: item_ids, + assets: assets, + }, status: :ok + return + end + + all = [] + online_notifications.each do |item| + all.push item.attributes_with_association_ids + end + render json: all, status: :ok end =begin diff --git a/app/controllers/recent_view_controller.rb b/app/controllers/recent_view_controller.rb index bd1b275d3..032404efd 100644 --- a/app/controllers/recent_view_controller.rb +++ b/app/controllers/recent_view_controller.rb @@ -19,10 +19,36 @@ curl http://localhost/api/v1/recent_view -v -u #{login}:#{password} -H "Content- =end def index - recent_viewed = RecentView.list_full(current_user, 10) + recent_viewed = RecentView.list(current_user, 10) - # return result - render json: recent_viewed + if response_expand? + list = [] + recent_viewed.each do |item| + list.push item.attributes_with_association_names + end + render json: list, status: :ok + return + end + + if response_full? + assets = {} + item_ids = [] + recent_viewed.each do |item| + item_ids.push item.id + assets = item.assets(assets) + end + render json: { + record_ids: item_ids, + assets: assets, + }, status: :ok + return + end + + all = [] + recent_viewed.each do |item| + all.push item.attributes_with_association_ids + end + render json: all, status: :ok end =begin diff --git a/app/controllers/sessions/collection_base.rb b/app/controllers/sessions/collection_base.rb index 29415fb7e..87464301a 100644 --- a/app/controllers/sessions/collection_base.rb +++ b/app/controllers/sessions/collection_base.rb @@ -11,11 +11,15 @@ module ExtraCollection assets = item.assets(assets) end - collections[ OnlineNotification.to_app_model ] = OnlineNotification.list(user, 200) - assets = ApplicationModel.assets_of_object_list(collections[ OnlineNotification.to_app_model ], assets) + collections[ OnlineNotification.to_app_model ] = [] + OnlineNotification.list(user, 200).each do |item| + assets = item.assets(assets) + end - collections[ RecentView.to_app_model ] = RecentView.list(user, 10) - assets = RecentView.assets_of_object_list(collections[ RecentView.to_app_model ], assets) + collections[ RecentView.to_app_model ] = [] + RecentView.list(user, 10).each do |item| + assets = item.assets(assets) + end collections[ Permission.to_app_model ] = [] Permission.all.each do |item| diff --git a/app/controllers/tickets_controller.rb b/app/controllers/tickets_controller.rb index 2ee14e46d..cab614ae5 100644 --- a/app/controllers/tickets_controller.rb +++ b/app/controllers/tickets_controller.rb @@ -335,12 +335,12 @@ class TicketsController < ApplicationController end ticket_ids_recent_viewed = [] - recent_views = RecentView.list(current_user, 8, 'Ticket').delete_if { |object| object['o_id'] == ticket.id } + recent_views = RecentView.list(current_user, 8, 'Ticket') recent_views.each do |recent_view| - next if recent_view['object'] != 'Ticket' - ticket_ids_recent_viewed.push recent_view['o_id'] - recent_view_ticket = Ticket.find(recent_view['o_id']) - next if recent_view_ticket.state.state_type.name == 'merged' + next if recent_view.object.name != 'Ticket' + next if recent_view.o_id == ticket.id + ticket_ids_recent_viewed.push recent_view.o_id + recent_view_ticket = Ticket.find(recent_view.o_id) assets = recent_view_ticket.assets(assets) end diff --git a/app/models/activity_stream.rb b/app/models/activity_stream.rb index 882f36126..d79c70ee0 100644 --- a/app/models/activity_stream.rb +++ b/app/models/activity_stream.rb @@ -1,9 +1,12 @@ # Copyright (C) 2012-2016 Zammad Foundation, http://zammad-foundation.org/ class ActivityStream < ApplicationModel + load 'activity_stream/assets.rb' + include ActivityStream::Assets + self.table_name = 'activity_streams' - belongs_to :activity_stream_type, class_name: 'TypeLookup' - belongs_to :activity_stream_object, class_name: 'ObjectLookup' + belongs_to :object, class_name: 'ObjectLookup', foreign_key: 'activity_stream_object_id' + belongs_to :type, class_name: 'TypeLookup', foreign_key: 'activity_stream_type_id' =begin @@ -108,16 +111,7 @@ return all activity entries of an user .order('created_at DESC, id DESC') .limit(limit) end - list = [] - stream.each do |item| - data = item.attributes - data['object'] = ObjectLookup.by_id( data['activity_stream_object_id'] ) - data['type'] = TypeLookup.by_id( data['activity_stream_type_id'] ) - data.delete('activity_stream_object_id') - data.delete('activity_stream_type_id') - list.push data - end - list + stream end =begin diff --git a/app/models/activity_stream/assets.rb b/app/models/activity_stream/assets.rb new file mode 100644 index 000000000..a08f9043b --- /dev/null +++ b/app/models/activity_stream/assets.rb @@ -0,0 +1,56 @@ +# Copyright (C) 2012-2016 Zammad Foundation, http://zammad-foundation.org/ + +class ActivityStream + module Assets + +=begin + +get all assets / related models for this activity stream item + + activity_stream = ActivityStream.find(123) + result = activity_stream.assets(assets_if_exists) + +returns + + result = { + :ActivityStream => { + 123 => activity_stream_model_123, + 1234 => activity_stream_model_1234, + } + } + +=end + + def assets(data) + + app_model = self.class.to_app_model + + if !data[ app_model ] + data[ app_model ] = {} + end + if !data[ app_model ][ id ] + local_attributes = attributes_with_association_ids + + local_attributes['object'] = ObjectLookup.by_id(local_attributes['activity_stream_object_id']) + local_attributes['type'] = TypeLookup.by_id(local_attributes['activity_stream_type_id']) + + # set temp. current attributes to assets pool to prevent + # loops, will be updated with lookup attributes later + data[ app_model ][ id ] = local_attributes + + ApplicationModel.assets_of_object_list([local_attributes], data) + end + + return data if !self['created_by_id'] + app_model_user = User.to_app_model + %w[created_by_id].each do |local_user_id| + next if !self[ local_user_id ] + next if data[ app_model_user ] && data[ app_model_user ][ self[ local_user_id ] ] + user = User.lookup(id: self[ local_user_id ]) + next if !user + data = user.assets(data) + end + data + end + end +end diff --git a/app/models/online_notification.rb b/app/models/online_notification.rb index e50229c50..3e64937ac 100644 --- a/app/models/online_notification.rb +++ b/app/models/online_notification.rb @@ -1,8 +1,11 @@ # Copyright (C) 2012-2016 Zammad Foundation, http://zammad-foundation.org/ class OnlineNotification < ApplicationModel - belongs_to :type_lookup, class_name: 'TypeLookup' - belongs_to :object_lookup, class_name: 'ObjectLookup' + load 'online_notification/assets.rb' + include OnlineNotification::Assets + + belongs_to :type, class_name: 'TypeLookup', foreign_key: 'type_lookup_id' + belongs_to :object, class_name: 'ObjectLookup', foreign_key: 'object_lookup_id' belongs_to :user after_create :notify_clients_after_change @@ -49,7 +52,7 @@ add a new online notification for this user updated_at: data[:updated_at] || Time.zone.now, } - OnlineNotification.create(record) + OnlineNotification.create!(record) end =begin @@ -92,9 +95,9 @@ remove whole online notifications of an object by type =end - def self.remove_by_type(object_name, o_id, type, user) + def self.remove_by_type(object_name, o_id, type_name, user) object_id = ObjectLookup.by_name(object_name) - type_id = TypeLookup.by_name(type) + type_id = TypeLookup.by_name(type_name) OnlineNotification.where( object_lookup_id: object_id, type_lookup_id: type_id, @@ -112,20 +115,9 @@ return all online notifications of an user =end def self.list(user, limit) - - notifications = OnlineNotification.where(user_id: user.id) - .order('created_at DESC, id DESC') - .limit(limit) - list = [] - notifications.each do |item| - data = item.attributes - data['object'] = ObjectLookup.by_id(data['object_lookup_id']) - data['type'] = TypeLookup.by_id(data['type_lookup_id']) - data.delete('object_lookup_id') - data.delete('type_lookup_id') - list.push data - end - list + OnlineNotification.where(user_id: user.id) + .order('created_at DESC, id DESC') + .limit(limit) end =begin @@ -169,31 +161,6 @@ mark online notification as seen by object true end -=begin - -return all online notifications of an user with assets - - OnlineNotification.list_full(user) - -returns: - - list = { - stream: notifications, - assets: assets, - } - -=end - - def self.list_full(user, limit) - - notifications = OnlineNotification.list(user, limit) - assets = ApplicationModel.assets_of_object_list(notifications) - { - stream: notifications, - assets: assets - } - end - def notify_clients_after_change Sessions.send_to( user_id, @@ -216,8 +183,8 @@ returns: =end - def self.all_seen?(object, o_id) - notifications = OnlineNotification.list_by_object(object, o_id) + def self.all_seen?(object_name, o_id) + notifications = OnlineNotification.list_by_object(object_name, o_id) notifications.each do |onine_notification| return false if !onine_notification['seen'] end @@ -237,15 +204,17 @@ returns: =end # rubocop:disable Metrics/ParameterLists - def self.exists?(user, object, o_id, type, created_by_user, seen) + def self.exists?(user, object_name, o_id, type_name, created_by_user, seen) # rubocop:enable Metrics/ParameterLists + object_id = ObjectLookup.by_name(object_name) + type_id = TypeLookup.by_name(type_name) notifications = OnlineNotification.list(user, 10) notifications.each do |notification| - next if notification['o_id'] != o_id - next if notification['object'] != object - next if notification['type'] != type - next if notification['created_by_id'] != created_by_user.id - next if notification['seen'] != seen + next if notification.o_id != o_id + next if notification.object_lookup_id != object_id + next if notification.type_lookup_id != type_id + next if notification.created_by_id != created_by_user.id + next if notification.seen != seen return true end false diff --git a/app/models/online_notification/assets.rb b/app/models/online_notification/assets.rb new file mode 100644 index 000000000..68e50a234 --- /dev/null +++ b/app/models/online_notification/assets.rb @@ -0,0 +1,56 @@ +# Copyright (C) 2012-2016 Zammad Foundation, http://zammad-foundation.org/ + +class OnlineNotification + module Assets + +=begin + +get all assets / related models for this online notification item + + online_notification = OnlineNotification.find(123) + result = online_notification.assets(assets_if_exists) + +returns + + result = { + :OnlineNotification => { + 123 => online_notification_model_123, + 1234 => online_notification_model_1234, + } + } + +=end + + def assets(data) + + app_model = self.class.to_app_model + + if !data[ app_model ] + data[ app_model ] = {} + end + if !data[ app_model ][ id ] + local_attributes = attributes_with_association_ids + + local_attributes['object'] = ObjectLookup.by_id(local_attributes['object_lookup_id']) + local_attributes['type'] = TypeLookup.by_id(local_attributes['type_lookup_id']) + + # set temp. current attributes to assets pool to prevent + # loops, will be updated with lookup attributes later + data[ app_model ][ id ] = local_attributes + + ApplicationModel.assets_of_object_list([local_attributes], data) + end + + return data if !self['created_by_id'] && !self['updated_by_id'] + app_model_user = User.to_app_model + %w[created_by_id updated_by_id].each do |local_user_id| + next if !self[ local_user_id ] + next if data[ app_model_user ] && data[ app_model_user ][ self[ local_user_id ] ] + user = User.lookup(id: self[ local_user_id ]) + next if !user + data = user.assets(data) + end + data + end + end +end diff --git a/app/models/recent_view.rb b/app/models/recent_view.rb index b8db53d8b..714259fce 100644 --- a/app/models/recent_view.rb +++ b/app/models/recent_view.rb @@ -1,8 +1,10 @@ # Copyright (C) 2012-2016 Zammad Foundation, http://zammad-foundation.org/ class RecentView < ApplicationModel - belongs_to :object_lookup, class_name: 'ObjectLookup' - belongs_to :ticket, class_name: 'Ticket', foreign_key: 'o_id' + load 'recent_view/assets.rb' + include RecentView::Assets + + belongs_to :object, class_name: 'ObjectLookup', foreign_key: 'recent_view_object_id' after_create :notify_clients after_update :notify_clients @@ -36,53 +38,46 @@ class RecentView < ApplicationModel RecentView.where(created_by_id: user.id).destroy_all end - def self.list(user, limit = 10, type = nil) - recent_views = if !type - RecentView.select('o_id, recent_view_object_id, MAX(created_at) as created_at, MAX(id) as id') - .group(:o_id, :recent_view_object_id) + def self.list(user, limit = 10, object_name = nil) + recent_views = if !object_name + RecentView.select('o_id, recent_view_object_id, MAX(created_at) as created_at, MAX(id) as id, created_by_id') + .group(:o_id, :recent_view_object_id, :created_by_id) .where(created_by_id: user.id) .limit(limit) - elsif type == 'Ticket' + elsif object_name == 'Ticket' state_ids = Ticket::State.by_category(:viewable_agent_new).pluck(:id) - RecentView.joins(:ticket) - .select('recent_views.o_id as o_id, recent_views.recent_view_object_id as recent_view_object_id, MAX(recent_views.created_at) as created_at, MAX(recent_views.id) as id') - .group(:o_id, :recent_view_object_id) - .where('recent_views.created_by_id = ? AND recent_views.recent_view_object_id = ? AND tickets.state_id IN (?)', user.id, ObjectLookup.by_name('Ticket'), state_ids ) - .limit(limit) + local_recent_views = RecentView.select('o_id, recent_view_object_id, MAX(created_at) as created_at, MAX(id) as id, created_by_id') + .group(:o_id, :recent_view_object_id, :created_by_id) + .where(created_by_id: user.id, recent_view_object_id: ObjectLookup.by_name(object_name)) + .limit(limit + 10) + clear_list = [] + local_recent_views.each do |item| + ticket = Ticket.find_by(id: item.o_id) + next if !ticket + next if !state_ids.include?(ticket.state_id) + clear_list.push item + break if clear_list.count == limit + end + clear_list else - RecentView.select('o_id, recent_view_object_id, MAX(created_at) as created_at, MAX(id) as id') - .group(:o_id, :recent_view_object_id) - .where(created_by_id: user.id, recent_view_object_id: ObjectLookup.by_name(type)) + RecentView.select('o_id, recent_view_object_id, MAX(created_at) as created_at, MAX(id) as id, created_by_id') + .group(:o_id, :recent_view_object_id, :created_by_id) + .where(created_by_id: user.id, recent_view_object_id: ObjectLookup.by_name(object_name)) .limit(limit) end list = [] recent_views.each do |item| - data = item.attributes - data['object'] = ObjectLookup.by_id(data['recent_view_object_id']) - data.delete('recent_view_object_id') # access check - next if !access(data['object'], data['o_id'], user) + next if !access(ObjectLookup.by_id(item['recent_view_object_id']), item['o_id'], user) # add to result list - list.push data + list.push item end list end - def self.list_full(user, limit = 10) - recent_viewed = list(user, limit) - - # get related object - assets = ApplicationModel.assets_of_object_list(recent_viewed) - - { - stream: recent_viewed, - assets: assets, - } - end - def notify_clients Sessions.send_to( created_by_id, @@ -117,11 +112,11 @@ cleanup old entries optional you can put the max oldest entries as argument - RecentView.cleanup(1.month) + RecentView.cleanup(3.month) =end - def self.cleanup(diff = 1.month) + def self.cleanup(diff = 3.months) RecentView.where('created_at < ?', Time.zone.now - diff).delete_all true end diff --git a/app/models/recent_view/assets.rb b/app/models/recent_view/assets.rb new file mode 100644 index 000000000..63817f377 --- /dev/null +++ b/app/models/recent_view/assets.rb @@ -0,0 +1,55 @@ +# Copyright (C) 2012-2016 Zammad Foundation, http://zammad-foundation.org/ + +class RecentView + module Assets + +=begin + +get all assets / related models for this recend view item + + recent_view = RecentView.find(123) + result = recent_view.assets(assets_if_exists) + +returns + + result = { + :RecentView => { + 123 => recent_view_model_123, + 1234 => recent_view_model_1234, + } + } + +=end + + def assets(data) + + app_model = self.class.to_app_model + + if !data[ app_model ] + data[ app_model ] = {} + end + if !data[ app_model ][ id ] + local_attributes = attributes_with_association_ids + + local_attributes['object'] = ObjectLookup.by_id(local_attributes['recent_view_object_id']) + + # set temp. current attributes to assets pool to prevent + # loops, will be updated with lookup attributes later + data[ app_model ][ id ] = local_attributes + + ApplicationModel.assets_of_object_list([local_attributes], data) + end + + return data if !self['created_by_id'] + app_model_user = User.to_app_model + %w[created_by_id].each do |local_user_id| + next if !self[ local_user_id ] + next if data[ app_model_user ] && data[ app_model_user ][ self[ local_user_id ] ] + user = User.lookup(id: self[ local_user_id ]) + next if !user + data = user.assets(data) + end + data + end + end +end diff --git a/app/models/user.rb b/app/models/user.rb index c3f6e0d7c..6d78906bb 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -44,7 +44,7 @@ class User < ApplicationModel before_update :check_preferences_default, :validate_ooo, :reset_login_failed, :validate_agent_limit_by_attributes, :last_admin_check_by_attribute after_create :avatar_for_email_check after_update :avatar_for_email_check - after_destroy :avatar_destroy, :user_device_destroy + before_destroy :avatar_destroy, :user_device_destroy, :cit_caller_id_destroy, :task_destroy has_and_belongs_to_many :roles, after_add: %i[cache_update check_notifications], after_remove: :cache_update, before_add: %i[validate_agent_limit_by_role validate_roles], before_remove: :last_admin_check_by_role, class_name: 'Role' has_and_belongs_to_many :organizations, after_add: :cache_update, after_remove: :cache_update, class_name: 'Organization' @@ -257,14 +257,17 @@ returns =end def activity_stream(limit, fulldata = false) - activity_stream = ActivityStream.list(self, limit) - return activity_stream if !fulldata + stream = ActivityStream.list(self, limit) + return stream if !fulldata # get related objects - assets = ApplicationModel.assets_of_object_list(activity_stream) + assets = {} + stream.each do |item| + assets = item.assets(assets) + end { - activity_stream: activity_stream, + stream: stream, assets: assets, } end @@ -1132,6 +1135,14 @@ raise 'Minimum one user need to have admin permissions' UserDevice.remove(id) end + def cit_caller_id_destroy + Cti::CallerId.where(user_id: id).destroy_all + end + + def task_destroy + Taskbar.where(user_id: id).destroy_all + end + def ensure_password return true if password_empty? return true if PasswordHash.crypted?(password) diff --git a/lib/sessions/backend/activity_stream.rb b/lib/sessions/backend/activity_stream.rb index 9a024c502..950773f75 100644 --- a/lib/sessions/backend/activity_stream.rb +++ b/lib/sessions/backend/activity_stream.rb @@ -26,7 +26,17 @@ class Sessions::Backend::ActivityStream @last_change = activity_stream.first['created_at'] end - @user.activity_stream(25, true) + assets = {} + item_ids = [] + activity_stream.each do |item| + item_ids.push item.id + assets = item.assets(assets) + end + + { + record_ids: item_ids, + assets: assets, + } end def client_key diff --git a/public/assets/tests/model.js b/public/assets/tests/model.js index 7b17fa409..22251f219 100644 --- a/public/assets/tests/model.js +++ b/public/assets/tests/model.js @@ -235,18 +235,18 @@ test( "model search tests", function() { }, ] ) priorities = App.TicketPriority.search({sortBy:'created_at', order: 'ASC'}) - equal( '2 normal', priorities[0].name, 'check 1 entry') - equal( '3 high', priorities[1].name, 'check 2 entry') - equal( '4 very high', priorities[2].name, 'check 3 entry') - equal( '1 low', priorities[3].name, 'check 4 entry') - equal( undefined, priorities[4], 'check 5 entry') + equal('2 normal', priorities[0].name, 'check 1 entry') + equal('3 high', priorities[1].name, 'check 2 entry') + equal('4 very high', priorities[2].name, 'check 3 entry') + equal('1 low', priorities[3].name, 'check 4 entry') + equal(undefined, priorities[4], 'check 5 entry') priorities = App.TicketPriority.search({sortBy:'created_at', order: 'DESC'}) - equal( '1 low', priorities[0].name, 'check 4 entry') - equal( '4 very high', priorities[1].name, 'check 3 entry') - equal( '3 high', priorities[2].name, 'check 2 entry') - equal( '2 normal', priorities[3].name, 'check 1 entry') - equal( undefined, priorities[4], 'check 5 entry') + equal('1 low', priorities[0].name, 'check 4 entry') + equal('4 very high', priorities[1].name, 'check 3 entry') + equal('3 high', priorities[2].name, 'check 2 entry') + equal('2 normal', priorities[3].name, 'check 1 entry') + equal(undefined, priorities[4], 'check 5 entry') }); @@ -255,12 +255,12 @@ test( "model loadAssets tests - 1", function() { window.refreshCounter1 = 0 var callback1 = function(state, triggerType) { window.refreshCounter1 = window.refreshCounter1 + 1 - equal( state.id, 9999, 'id check') + equal(state.id, 9999, 'id check') if (window.refreshCounter1 == 1) { - equal( 'full', triggerType, 'trigger type check') + equal('full', triggerType, 'trigger type check') } else { - equal( 'refresh', triggerType, 'trigger type check') + equal('refresh', triggerType, 'trigger type check') } if ( window.refreshCounter1 == 1 ) { @@ -298,7 +298,7 @@ test( "model loadAssets tests - 1", function() { App.Delay.set( function() { test( "model loadAssets tests - 1 / check refresh counter", function() { - equal( window.refreshCounter1, 2, 'check refresh counter') + equal(window.refreshCounter1, 2, 'check refresh counter') }); }, 1000 @@ -308,12 +308,12 @@ test( "model loadAssets tests - 2", function() { window.refreshCounter2 = 0 var callback2 = function(state, triggerType) { window.refreshCounter2 = window.refreshCounter2 + 1 - equal( state.id, 10000, 'id check') + equal(state.id, 10000, 'id check') if (window.refreshCounter2 == 1) { - equal( 'full', triggerType, 'trigger type check') + equal('full', triggerType, 'trigger type check') } else { - equal( 'refresh', triggerType, 'trigger type check') + equal('refresh', triggerType, 'trigger type check') } if ( window.refreshCounter2 == 1 ) { App.Collection.loadAssets({ @@ -349,7 +349,7 @@ test( "model loadAssets tests - 2", function() { App.Delay.set( function() { test( "model loadAssets tests - 2 / check refresh counter", function() { - equal( window.refreshCounter2, 2, 'check refresh counter') + equal(window.refreshCounter2, 2, 'check refresh counter') }); }, 1200 @@ -359,12 +359,12 @@ test( "model loadAssets tests - 3", function() { window.refreshCounter3 = 0 var callback3 = function(state, triggerType) { window.refreshCounter3 = window.refreshCounter3 + 1 - equal( state.id, 10001, 'id check') + equal(state.id, 10001, 'id check') if (window.refreshCounter3 == 1) { - equal( 'full', triggerType, 'trigger type check') + equal('full', triggerType, 'trigger type check') } else { - equal( 'refresh', triggerType, 'trigger type check') + equal('refresh', triggerType, 'trigger type check') } if ( window.refreshCounter3 == 1 ) { @@ -401,7 +401,7 @@ test( "model loadAssets tests - 3", function() { App.Delay.set( function() { test( "model loadAssets tests - 3 / check refresh counter", function() { - equal( window.refreshCounter3, 3, 'check refresh counter') + equal(window.refreshCounter3, 3, 'check refresh counter') }); }, 1400 diff --git a/test/controllers/api_auth_on_behalf_of_controller_test.rb b/test/controllers/api_auth_on_behalf_of_controller_test.rb index 0863759c1..61c1e119d 100644 --- a/test/controllers/api_auth_on_behalf_of_controller_test.rb +++ b/test/controllers/api_auth_on_behalf_of_controller_test.rb @@ -91,15 +91,38 @@ class ApiAuthControllerTest < ActionDispatch::IntegrationTest assert_equal(Hash, result_ticket_create.class) assert_equal(result_ticket_create['created_by_id'], @customer.id) - get '/api/v1/activity_stream', params: {}, headers: admin_headers + get '/api/v1/activity_stream?full=true', params: {}, headers: admin_headers assert_response(200) result_activity_stream = JSON.parse(@response.body) assert_equal(Hash, result_activity_stream.class) - ticket_created = result_activity_stream['activity_stream'].find { |activity| activity['object'] == 'Ticket' && activity['o_id'] == result_ticket_create['id'] } + ticket_created = nil + result_activity_stream['record_ids'].each do |record_id| + activity_stream = ActivityStream.find(record_id) + next if activity_stream.object.name != 'Ticket' + next if activity_stream.o_id != result_ticket_create['id'] + ticket_created = activity_stream + end + + assert(ticket_created) + assert_equal(ticket_created.created_by_id, @customer.id) + + get '/api/v1/activity_stream', params: {}, headers: admin_headers + assert_response(200) + result_activity_stream = JSON.parse(@response.body) + assert_equal(Array, result_activity_stream.class) + + ticket_created = nil + result_activity_stream.each do |record| + activity_stream = ActivityStream.find(record['id']) + next if activity_stream.object.name != 'Ticket' + next if activity_stream.o_id != result_ticket_create['id'] + ticket_created = activity_stream + end + + assert(ticket_created) + assert_equal(ticket_created.created_by_id, @customer.id) - assert_equal(Hash, ticket_created.class) - assert_equal(ticket_created['created_by_id'], @customer.id) end test 'X-On-Behalf-Of auth - ticket create admin for customer by email' do diff --git a/test/unit/activity_stream_test.rb b/test/unit/activity_stream_test.rb index 4c2a3843f..f7a6f71de 100644 --- a/test/unit/activity_stream_test.rb +++ b/test/unit/activity_stream_test.rb @@ -62,24 +62,24 @@ class ActivityStreamTest < ActiveSupport::TestCase # check activity_stream stream = @admin_user.activity_stream(4) - assert_equal(stream[0]['group_id'], ticket.group_id) - assert_equal(stream[0]['o_id'], ticket.id) - assert_equal(stream[0]['created_by_id'], @current_user.id) - assert_equal(stream[0]['created_at'].to_s, updated_at.to_s) - assert_equal(stream[0]['object'], 'Ticket') - assert_equal(stream[0]['type'], 'update') - assert_equal(stream[1]['group_id'], ticket.group_id) - assert_equal(stream[1]['o_id'], article.id) - assert_equal(stream[1]['created_by_id'], @current_user.id) - assert_equal(stream[1]['created_at'].to_s, article.created_at.to_s) - assert_equal(stream[1]['object'], 'Ticket::Article') - assert_equal(stream[1]['type'], 'create') - assert_equal(stream[2]['group_id'], ticket.group_id) - assert_equal(stream[2]['o_id'], ticket.id) - assert_equal(stream[2]['created_by_id'], @current_user.id) - assert_equal(stream[2]['created_at'].to_s, ticket.created_at.to_s) - assert_equal(stream[2]['object'], 'Ticket') - assert_equal(stream[2]['type'], 'create') + assert_equal(stream[0].group_id, ticket.group_id) + assert_equal(stream[0].o_id, ticket.id) + assert_equal(stream[0].created_by_id, @current_user.id) + assert_equal(stream[0].created_at.to_s, updated_at.to_s) + assert_equal(stream[0].object.name, 'Ticket') + assert_equal(stream[0].type.name, 'update') + assert_equal(stream[1].group_id, ticket.group_id) + assert_equal(stream[1].o_id, article.id) + assert_equal(stream[1].created_by_id, @current_user.id) + assert_equal(stream[1].created_at.to_s, article.created_at.to_s) + assert_equal(stream[1].object.name, 'Ticket::Article') + assert_equal(stream[1].type.name, 'create') + assert_equal(stream[2].group_id, ticket.group_id) + assert_equal(stream[2].o_id, ticket.id) + assert_equal(stream[2].created_by_id, @current_user.id) + assert_equal(stream[2].created_at.to_s, ticket.created_at.to_s) + assert_equal(stream[2].object.name, 'Ticket') + assert_equal(stream[2].type.name, 'create') assert_not(stream[3]) stream = @current_user.activity_stream(4) @@ -90,18 +90,18 @@ class ActivityStreamTest < ActiveSupport::TestCase # check activity_stream stream = @admin_user.activity_stream(4) - assert_equal(stream[0]['group_id'], ticket.group_id) - assert_equal(stream[0]['o_id'], ticket.id) - assert_equal(stream[0]['created_by_id'], @current_user.id) - assert_equal(stream[0]['created_at'].to_s, updated_at.to_s) - assert_equal(stream[0]['object'], 'Ticket') - assert_equal(stream[0]['type'], 'update') - assert_equal(stream[1]['group_id'], ticket.group_id) - assert_equal(stream[1]['o_id'], ticket.id) - assert_equal(stream[1]['created_by_id'], @current_user.id) - assert_equal(stream[1]['created_at'].to_s, ticket.created_at.to_s) - assert_equal(stream[1]['object'], 'Ticket') - assert_equal(stream[1]['type'], 'create') + assert_equal(stream[0].group_id, ticket.group_id) + assert_equal(stream[0].o_id, ticket.id) + assert_equal(stream[0].created_by_id, @current_user.id) + assert_equal(stream[0].created_at.to_s, updated_at.to_s) + assert_equal(stream[0].object.name, 'Ticket') + assert_equal(stream[0].type.name, 'update') + assert_equal(stream[1].group_id, ticket.group_id) + assert_equal(stream[1].o_id, ticket.id) + assert_equal(stream[1].created_by_id, @current_user.id) + assert_equal(stream[1].created_at.to_s, ticket.created_at.to_s) + assert_equal(stream[1].object.name, 'Ticket') + assert_equal(stream[1].type.name, 'create') assert_not(stream[2]) stream = @current_user.activity_stream(4) @@ -129,18 +129,18 @@ class ActivityStreamTest < ActiveSupport::TestCase # check activity_stream stream = @admin_user.activity_stream(3) - assert_not(stream[0]['group_id']) - assert_equal(stream[0]['o_id'], organization.id) - assert_equal(stream[0]['created_by_id'], @current_user.id) - assert_equal(stream[0]['created_at'].to_s, updated_at.to_s) - assert_equal(stream[0]['object'], 'Organization') - assert_equal(stream[0]['type'], 'update') - assert_not(stream[1]['group_id']) - assert_equal(stream[1]['o_id'], organization.id) - assert_equal(stream[1]['created_by_id'], @current_user.id) - assert_equal(stream[1]['created_at'].to_s, organization.created_at.to_s) - assert_equal(stream[1]['object'], 'Organization') - assert_equal(stream[1]['type'], 'create') + assert_not(stream[0].group_id) + assert_equal(stream[0].o_id, organization.id) + assert_equal(stream[0].created_by_id, @current_user.id) + assert_equal(stream[0].created_at.to_s, updated_at.to_s) + assert_equal(stream[0].object.name, 'Organization') + assert_equal(stream[0].type.name, 'update') + assert_not(stream[1].group_id) + assert_equal(stream[1].o_id, organization.id) + assert_equal(stream[1].created_by_id, @current_user.id) + assert_equal(stream[1].created_at.to_s, organization.created_at.to_s) + assert_equal(stream[1].object.name, 'Organization') + assert_equal(stream[1].type.name, 'create') assert_not(stream[2]) stream = @current_user.activity_stream(4) @@ -167,12 +167,12 @@ class ActivityStreamTest < ActiveSupport::TestCase # check activity_stream stream = @admin_user.activity_stream(3) - assert_not(stream[0]['group_id']) - assert_equal(stream[0]['o_id'], user.id) - assert_equal(stream[0]['created_by_id'], @current_user.id) - assert_equal(stream[0]['created_at'].to_s, user.created_at.to_s) - assert_equal(stream[0]['object'], 'User') - assert_equal(stream[0]['type'], 'create') + assert_not(stream[0].group_id) + assert_equal(stream[0].o_id, user.id) + assert_equal(stream[0].created_by_id, @current_user.id) + assert_equal(stream[0].created_at.to_s, user.created_at.to_s) + assert_equal(stream[0].object.name, 'User') + assert_equal(stream[0].type.name, 'create') assert_not(stream[1]) stream = @current_user.activity_stream(4) @@ -208,18 +208,18 @@ class ActivityStreamTest < ActiveSupport::TestCase # check activity_stream stream = @admin_user.activity_stream(3) - assert_not(stream[0]['group_id']) - assert_equal(stream[0]['o_id'], user.id) - assert_equal(stream[0]['created_by_id'], @current_user.id) - assert_equal(stream[0]['created_at'].to_s, updated_at.to_s) - assert_equal(stream[0]['object'], 'User') - assert_equal(stream[0]['type'], 'update') - assert_not(stream[1]['group_id']) - assert_equal(stream[1]['o_id'], user.id) - assert_equal(stream[1]['created_by_id'], @current_user.id) - assert_equal(stream[1]['created_at'].to_s, user.created_at.to_s) - assert_equal(stream[1]['object'], 'User') - assert_equal(stream[1]['type'], 'create') + assert_not(stream[0].group_id) + assert_equal(stream[0].o_id, user.id) + assert_equal(stream[0].created_by_id, @current_user.id) + assert_equal(stream[0].created_at.to_s, updated_at.to_s) + assert_equal(stream[0].object.name, 'User') + assert_equal(stream[0].type.name, 'update') + assert_not(stream[1].group_id) + assert_equal(stream[1].o_id, user.id) + assert_equal(stream[1].created_by_id, @current_user.id) + assert_equal(stream[1].created_at.to_s, user.created_at.to_s) + assert_equal(stream[1].object.name, 'User') + assert_equal(stream[1].type.name, 'create') assert_not(stream[2]) stream = @current_user.activity_stream(4) diff --git a/test/unit/recent_view_test.rb b/test/unit/recent_view_test.rb index aabd1fe5f..fdd6b4cb9 100644 --- a/test/unit/recent_view_test.rb +++ b/test/unit/recent_view_test.rb @@ -37,11 +37,11 @@ class RecentViewTest < ActiveSupport::TestCase RecentView.log(ticket1.class.to_s, ticket1.id, user1) list = RecentView.list(user1) - assert(list[0]['o_id'], ticket1.id) - assert(list[0]['object'], 'Ticket') + assert(list[0].o_id, ticket1.id) + assert(list[0].object.name, 'Ticket') - assert(list[1]['o_id'], ticket2.id) - assert(list[1]['object'], 'Ticket') + assert(list[1].o_id, ticket2.id) + assert(list[1].object.name, 'Ticket') assert_equal(2, list.count) ticket1.destroy @@ -156,8 +156,8 @@ class RecentViewTest < ActiveSupport::TestCase # check if list is empty list = RecentView.list(customer) - assert(list[0]['o_id'], ticket1.id) - assert(list[0]['object'], 'Ticket') + assert(list[0].o_id, ticket1.id) + assert(list[0].object.name, 'Ticket') assert_not(list[1], 'check if recent view list is empty') # log entry @@ -178,8 +178,8 @@ class RecentViewTest < ActiveSupport::TestCase # check if list is empty list = RecentView.list(agent) - assert(list[0]['o_id'], organization1.id) - assert(list[0]['object'], 'Organization') + assert(list[0].o_id, organization1.id) + assert(list[0].object.name, 'Organization') assert_not(list[1], 'check if recent view list is empty') organization2.destroy