diff --git a/app/assets/javascripts/app/controllers/ticket_zoom.js.coffee b/app/assets/javascripts/app/controllers/ticket_zoom.js.coffee index 8a960be21..d2da185fd 100644 --- a/app/assets/javascripts/app/controllers/ticket_zoom.js.coffee +++ b/app/assets/javascripts/app/controllers/ticket_zoom.js.coffee @@ -365,15 +365,16 @@ class App.TicketZoom extends App.Controller @autosaveLast = @taskGet() update = => #console.log('AR', @formParam( @el.find('.article-add') ) ) + currentStoreTicket = @ticket.attributes() + delete currentStoreTicket.article currentStore = - ticket: @ticket.attributes() - article: { + ticket: currentStoreTicket + article: to: '' cc: '' type: 'note' body: '' internal: '' - } currentParams = ticket: @formParam( @el.find('.edit') ) article: @formParam( @el.find('.article-add') ) @@ -390,13 +391,13 @@ class App.TicketZoom extends App.Controller # get diff of last save changedBetweenLastSave = _.isEqual(currentParams, @autosaveLast ) if !changedBetweenLastSave - console.log('model DIFF ', modelDiff) + #console.log('model DIFF ', modelDiff) @autosaveLast = clone(currentParams) @markFormDiff( modelDiff ) @taskUpdateAll( modelDiff ) - @interval( update, 3000, 'autosave' ) + @interval( update, 4000, 'autosave' ) markFormDiff: (diff = {}) => ticketForm = @$('.edit') @@ -407,7 +408,7 @@ class App.TicketZoom extends App.Controller params = {} params.ticket = @formParam( ticketForm ) params.article = @formParam( articleForm ) - console.log('markFormDiff', diff, params) + #console.log('markFormDiff', diff, params) # clear all changes if _.isEmpty(diff.ticket) && _.isEmpty(diff.article) diff --git a/app/assets/javascripts/app/lib/app_post/searchable_select.js.coffee b/app/assets/javascripts/app/lib/app_post/searchable_select.js.coffee index de10d3130..7cc58e9d6 100644 --- a/app/assets/javascripts/app/lib/app_post/searchable_select.js.coffee +++ b/app/assets/javascripts/app/lib/app_post/searchable_select.js.coffee @@ -77,7 +77,9 @@ class App.SearchableSelect extends Spine.Controller selectItem: (event) -> @input.val event.currentTarget.textContent.trim() + @input.trigger('change') @shadowInput.val event.currentTarget.getAttribute('data-value') + @shadowInput.trigger('change') onTab: (event) -> return if not @isOpen @@ -93,7 +95,9 @@ class App.SearchableSelect extends Spine.Controller event.preventDefault() @input.val @values.filter('.is-active').text().trim() + @input.trigger('change') @shadowInput.val @values.filter('.is-active').attr('data-value') + @shadowInput.trigger('change') @toggle() filterList: (event) => diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb index 247d5d316..9ac15fd70 100644 --- a/app/controllers/application_controller.rb +++ b/app/controllers/application_controller.rb @@ -5,7 +5,6 @@ class ApplicationController < ActionController::Base helper_method :current_user, :authentication_check, - :authentication_check_action_token, :config_frontend, :role?, :model_create_render, @@ -96,89 +95,108 @@ class ApplicationController < ActionController::Base session[:user_agent] = request.env['HTTP_USER_AGENT'] end - def authentication_check_only + def authentication_check_only(auth_param) logger.debug 'authentication_check' - session[:request_type] = 1 #logger.debug params.inspect #logger.debug session.inspect #logger.debug cookies.inspect - # check http basic auth - authenticate_with_http_basic do |username, password| - logger.debug 'http basic auth check' - session[:request_type] = 2 + # already logged in, early exit + if session.id && session[:user_id] + userdata = User.find( session[:user_id] ) + current_user_set(userdata) - userdata = User.authenticate( username, password ) - message = '' - if !userdata - message = 'authentication failed' - end + return { + auth: true + } + end - # return auth ok - if message == '' + error_message = 'authentication failed' - # remember user - session[:user_id] = userdata.id + # check logon session + if params['logon_session'] + logon_session = ActiveRecord::SessionStore::Session.where( session_id: params['logon_session'] ).first - # set basic auth user to current user + # set logon session user to current user + if logon_session + userdata = User.find( logon_session.data[:user_id] ) current_user_set(userdata) + + session[:persistent] = true + return { auth: true } end - # return auth not ok + error_message = 'no valid session, user_id' + end + + # check sso + sso_userdata = User.sso(params) + if sso_userdata + + current_user_set(sso_userdata) + + session[:persistent] = true + return { - auth: false, - message: message, + auth: true } end - # check logon session - if params['logon_session'] - logon_session = ActiveRecord::SessionStore::Session.where( session_id: params['logon_session'] ).first - if logon_session - userdata = User.find( logon_session.data[:user_id] ) - end + # check http basic auth + authenticate_with_http_basic do |username, password| + logger.debug "http basic auth check '#{username}'" - session[:request_type] = 3 + userdata = User.authenticate( username, password ) - # set logon session user to current user + next if !userdata + + # set basic auth user to current user current_user_set(userdata) return { auth: true } end - # check sso - if !session[:user_id] + # check token + if auth_param[:token_action] + authenticate_with_http_token do |token, _options| + logger.debug "token auth check #{token}" - user = User.sso(params) + userdata = Token.check( + action: auth_param[:token_action], + name: token, + ) - # Log the authorizing user in. - if user - session[:user_id] = user.id + next if !userdata + + # set token user to current user + current_user_set(userdata) + + return { + auth: true + } end end - # return auth not ok (no session exists) - if !session[:user_id] - logger.debug 'no valid session, user_id' - message = 'no valid session, user_id' - return { - auth: false, - message: message, - } - end - + logger.debug error_message { - auth: true + auth: false, + message: error_message, } end - def authentication_check - result = authentication_check_only + def authentication_check( auth_param = {} ) + result = authentication_check_only(auth_param) + + # check if basic_auth fallback is possible + if auth_param[:basic_auth_promt] && result[:auth] == false + + return request_http_basic_authentication + end # return auth not ok if result[:auth] == false @@ -191,28 +209,13 @@ class ApplicationController < ActionController::Base return false end + # store current user id into the session + session[:user_id] = current_user.id + # return auth ok true end - def authentication_check_action_token(action) - - user = Token.check( - action: action, - name: params[:action_token], - ) - - if !user - logger.debug params.inspect - response_access_deny - return - end - - current_user_set( user ) - - true - end - def role?( role_name ) return false if !current_user current_user.role?( role_name ) diff --git a/app/controllers/ical_tickets_controller.rb b/app/controllers/ical_tickets_controller.rb index 47993c1d5..bd6cdff10 100644 --- a/app/controllers/ical_tickets_controller.rb +++ b/app/controllers/ical_tickets_controller.rb @@ -3,190 +3,83 @@ require 'icalendar' class IcalTicketsController < ApplicationController - before_action { authentication_check_action_token 'iCal' } + before_action { authentication_check( { basic_auth_promt: true, token_action: 'iCal' } ) } - # @path [GET] /ical/tickets_all/:action_token + # @path [GET] /ical/tickets # # @summary Returns an iCal file with all tickets (open, new, pending, esclation) as events. # - # @parameter action_token(required) [String] The action_token identifying the requested User privileged for 'iCal' action. - # # @response_message 200 [String] iCal file ready to import in calendar applications. # @response_message 401 Permission denied. def all - - new_open_events_data = new_open_events_data_get - pending_events_data = pending_events_data_get - escalation_events_data = escalation_events_data_get + new_open_events_data = ICal::Ticket.new_open(current_user) + pending_events_data = ICal::Ticket.pending(current_user) + escalation_events_data = ICal::Ticket.escalation(current_user) events_data = new_open_events_data + pending_events_data + escalation_events_data - events_data_to_ical( events_data ) + ical = ICal.to_ical( events_data ) + + send_data( + ical, + filename: 'zammad_tickets.ical', + type: 'text/plain', + disposition: 'inline' + ) end - # @path [GET] /ical/tickets_new_open/:action_token + # @path [GET] /ical/tickets_new_open # # @summary Returns an iCal file with all new and open tickets as events. # - # @parameter action_token(required) [String] The action_token identifying the requested User privileged for 'iCal' action. - # # @response_message 200 [String] iCal file ready to import in calendar applications. # @response_message 401 Permission denied. def new_open + events_data = ICal::Ticket.new_open(current_user) - events_data = new_open_events_data_get + ical = ICal.to_ical( events_data ) - events_data_to_ical( events_data ) + send_data( + ical, + filename: 'zammad_tickets_new_open.ical', + type: 'text/plain', + disposition: 'inline' + ) end - # @path [GET] /ical/tickets_pending/:action_token + # @path [GET] /ical/tickets_pending # # @summary Returns an iCal file with all pending tickets as events. # - # @parameter action_token(required) [String] The action_token identifying the requested User privileged for 'iCal' action. - # # @response_message 200 [String] iCal file ready to import in calendar applications. # @response_message 401 Permission denied. def pending - events_data = pending_events_data_get + events_data = ICal::Ticket.pending(current_user) - events_data_to_ical( events_data ) + ical = ICal.to_ical( events_data ) + + send_data( + ical, + filename: 'zammad_tickets_pending.ical', + type: 'text/plain', + disposition: 'inline' + ) end - # @path [GET] /ical/ticket_escalation/:action_token + # @path [GET] /ical/ticket_escalation # # @summary Returns an iCal file with all escalation times for tickets as events. # - # @parameter action_token(required) [String] The action_token identifying the requested User privileged for 'iCal' action. - # # @response_message 200 [String] iCal file ready to import in calendar applications. # @response_message 401 Permission denied. def escalation - events_data = escalation_events_data_get + events_data = ICal::Ticket.escalation(current_user) - events_data_to_ical( events_data ) - end - - private - - def new_open_events_data_get - - condition = { - 'tickets.owner_id' => current_user.id, - 'tickets.state_id' => Ticket::State.where( - state_type_id: Ticket::StateType.where( - name: %w(new open), - ), - ), - } - - tickets = Ticket.search( - current_user: current_user, - condition: condition, - ) - - events_data = [] - tickets.each do |ticket| - - event_data = {} - - event_data[:dtstart] = Icalendar::Values::Date.new( Time.zone.today ) - event_data[:dtend] = Icalendar::Values::Date.new( Time.zone.today ) - event_data[:summary] = "#{ ticket.state.name } ticket: '#{ ticket.title }'" - event_data[:description] = "T##{ ticket.number }" - - events_data.push event_data - end - - events_data - end - - def pending_events_data_get - - condition = { - 'tickets.owner_id' => current_user.id, - 'tickets.state_id' => Ticket::State.where( - state_type_id: Ticket::StateType.where( - name: [ - 'pending reminder', - 'pending action', - ], - ), - ), - } - - tickets = Ticket.search( - current_user: current_user, - condition: condition, - ) - - events_data = [] - tickets.each do |ticket| - - event_data = {} - - # rubocop:disable Rails/TimeZone - event_data[:dtstart] = Icalendar::Values::DateTime.new( ticket.pending_time ) - event_data[:dtend] = Icalendar::Values::DateTime.new( ticket.pending_time ) - # rubocop:enable Rails/TimeZone - event_data[:summary] = "#{ ticket.state.name } ticket: '#{ ticket.title }'" - event_data[:description] = "T##{ ticket.number }" - - events_data.push event_data - end - - events_data - end - - def escalation_events_data_get - - condition = [ - 'tickets.escalation_time IS NOT NULL', - 'tickets.owner_id = ?', current_user.id - ] - - tickets = Ticket.search( - current_user: current_user, - condition: condition, - ) - - events_data = [] - tickets.each do |ticket| - - event_data = {} - - # rubocop:disable Rails/TimeZone - event_data[:dtstart] = Icalendar::Values::DateTime.new( ticket.escalation_time ) - event_data[:dtend] = Icalendar::Values::DateTime.new( ticket.escalation_time ) - # rubocop:enable Rails/TimeZone - event_data[:summary] = "ticket escalation: '#{ ticket.title }'" - event_data[:description] = "T##{ ticket.number }" - - events_data.push event_data - end - - events_data - end - - def events_data_to_ical(events_data) - - cal = Icalendar::Calendar.new - - events_data.each do |event_data| - - cal.event do |e| - e.dtstart = event_data[:dtstart] - e.dtend = event_data[:dtend] - e.summary = event_data[:summary] - e.description = event_data[:description] - e.ip_class = 'PRIVATE' - end - - end + ical = ICal.to_ical( events_data ) send_data( - cal.to_ical, - filename: 'zammad.ical', + ical, + filename: 'zammad_tickets_escalation.ical', type: 'text/plain', disposition: 'inline' ) diff --git a/app/controllers/sessions_controller.rb b/app/controllers/sessions_controller.rb index f0d530207..079ad10d8 100644 --- a/app/controllers/sessions_controller.rb +++ b/app/controllers/sessions_controller.rb @@ -54,6 +54,10 @@ class SessionsController < ApplicationController # ) end + # sessions created via this + # controller are persistent + session[:persistent] = true + # return new session data render status: :created, json: { diff --git a/app/controllers/tickets_controller.rb b/app/controllers/tickets_controller.rb index 922ea3277..e7e0cb549 100644 --- a/app/controllers/tickets_controller.rb +++ b/app/controllers/tickets_controller.rb @@ -329,7 +329,6 @@ class TicketsController < ApplicationController query: params[:term], condition: params[:condition], current_user: current_user, - detail: params[:detail] ) assets = {} ticket_result = [] @@ -372,10 +371,8 @@ class TicketsController < ApplicationController } user_tickets_open = Ticket.search( limit: limit, - #:query => params[:term], condition: condition, current_user: current_user, - detail: true, ) user_tickets_open_ids = assets_of_tickets(user_tickets_open, assets) @@ -386,10 +383,8 @@ class TicketsController < ApplicationController } user_tickets_closed = Ticket.search( limit: limit, - #:query => params[:term], condition: condition, current_user: current_user, - detail: true, ) user_tickets_closed_ids = assets_of_tickets(user_tickets_closed, assets) @@ -438,10 +433,8 @@ class TicketsController < ApplicationController } org_tickets_open = Ticket.search( limit: limit, - #:query => params[:term], condition: condition, current_user: current_user, - detail: true, ) org_tickets_open_ids = assets_of_tickets(org_tickets_open, assets) @@ -452,10 +445,8 @@ class TicketsController < ApplicationController } org_tickets_closed = Ticket.search( limit: limit, - #:query => params[:term], condition: condition, current_user: current_user, - detail: true, ) org_tickets_closed_ids = assets_of_tickets(org_tickets_closed, assets) diff --git a/app/models/observer/session.rb b/app/models/observer/session.rb index cd051fb21..5a2f490ee 100644 --- a/app/models/observer/session.rb +++ b/app/models/observer/session.rb @@ -13,15 +13,17 @@ class Observer::Session < ActiveRecord::Observer check(record) end + # move the persistent attribute from the sub structure + # to the first level so it gets stored in the database + # column to make the cleanup lookup more performant def check(record) return if !record.data - return if record[:request_type] + return if record[:persistent] - # remember request type - return if !record.data['request_type'] + return if !record.data['persistent'] - record[:request_type] = record.data['request_type'] - record.data.delete('request_type') + record[:persistent] = record.data['persistent'] + record.data.delete('persistent') end end diff --git a/app/models/ticket/search.rb b/app/models/ticket/search.rb index 766baafa3..138406051 100644 --- a/app/models/ticket/search.rb +++ b/app/models/ticket/search.rb @@ -22,7 +22,7 @@ search tickets via search index :current_user => User.find(123), :query => 'search something', :limit => 15, - :full => 0 + :full => false, ) returns @@ -33,10 +33,19 @@ search tickets via database result = Ticket.search( :current_user => User.find(123), - :condition => '', - :detail => true, + :condition => { + 'tickets.owner_id' => user.id, + 'tickets.state_id' => Ticket::State.where( + state_type_id: Ticket::StateType.where( + name: [ + 'pending reminder', + 'pending action', + ], + ), + ), + }, :limit => 15, - :full => 0 + :full => false, ) returns @@ -57,7 +66,7 @@ returns end # try search index backend - if !params[:detail] && SearchIndexBackend.enabled? + if !params[:condition] && SearchIndexBackend.enabled? query_extention = {} query_extention['bool'] = {} query_extention['bool']['must'] = [] diff --git a/app/models/token.rb b/app/models/token.rb index 0d65900f2..54bdb3a68 100644 --- a/app/models/token.rb +++ b/app/models/token.rb @@ -21,7 +21,7 @@ class Token < ActiveRecord::Base return end - # return token if valid + # return token user token.user end diff --git a/config/routes/ical_tickets.rb b/config/routes/ical_tickets.rb index 324c30007..38c24f043 100644 --- a/config/routes/ical_tickets.rb +++ b/config/routes/ical_tickets.rb @@ -2,8 +2,8 @@ Zammad::Application.routes.draw do api_path = Rails.configuration.api_path # ical ticket - match api_path + '/ical/tickets/:action_token', to: 'ical_tickets#all', via: :get - match api_path + '/ical/tickets_new_open/:action_token', to: 'ical_tickets#new_open', via: :get - match api_path + '/ical/tickets_pending/:action_token', to: 'ical_tickets#pending', via: :get - match api_path + '/ical/tickets_escalation/:action_token', to: 'ical_tickets#escalation', via: :get + match api_path + '/ical/tickets', to: 'ical_tickets#all', via: :get + match api_path + '/ical/tickets_new_open', to: 'ical_tickets#new_open', via: :get + match api_path + '/ical/tickets_pending', to: 'ical_tickets#pending', via: :get + match api_path + '/ical/tickets_escalation', to: 'ical_tickets#escalation', via: :get end diff --git a/db/migrate/20150623145511_session_changes.rb b/db/migrate/20150623145511_session_changes.rb new file mode 100644 index 000000000..4fd08afd3 --- /dev/null +++ b/db/migrate/20150623145511_session_changes.rb @@ -0,0 +1,24 @@ +class SessionChanges < ActiveRecord::Migration + def up + + ActiveRecord::SessionStore::Session.delete_all + + remove_index :sessions, :request_type + remove_column :sessions, :request_type + + add_column :sessions, :persistent, :boolean, null: true + add_index :sessions, :persistent + end + + def down + + ActiveRecord::SessionStore::Session.delete_all + + remove_index :sessions, :persistent + remove_column :sessions, :persistent + + add_column :sessions, :request_type, :integer, null: true + add_index :sessions, :request_type + end + +end diff --git a/lib/i_cal.rb b/lib/i_cal.rb new file mode 100644 index 000000000..7f8be5683 --- /dev/null +++ b/lib/i_cal.rb @@ -0,0 +1,24 @@ +# Copyright (C) 2012-2013 Zammad Foundation, http://zammad-foundation.org/ + +module ICal + + def self.to_ical(events_data) + + cal = Icalendar::Calendar.new + + events_data.each do |event_data| + + cal.event do |e| + e.dtstart = event_data[:dtstart] + e.dtend = event_data[:dtend] + e.summary = event_data[:summary] + e.description = event_data[:description] + e.ip_class = 'PRIVATE' + end + + end + + cal.to_ical + end + +end diff --git a/lib/i_cal/ticket.rb b/lib/i_cal/ticket.rb new file mode 100644 index 000000000..0363845fc --- /dev/null +++ b/lib/i_cal/ticket.rb @@ -0,0 +1,108 @@ +# Copyright (C) 2012-2013 Zammad Foundation, http://zammad-foundation.org/ + +module ICal::Ticket + + def self.new_open(user) + + condition = { + 'tickets.owner_id' => user.id, + 'tickets.state_id' => Ticket::State.where( + state_type_id: Ticket::StateType.where( + name: %w(new open), + ), + ), + } + + tickets = Ticket.search( + current_user: user, + condition: condition, + ) + + events_data = [] + tickets.each do |ticket| + + event_data = {} + + event_data[:dtstart] = Icalendar::Values::Date.new( Time.zone.today ) + event_data[:dtend] = Icalendar::Values::Date.new( Time.zone.today ) + event_data[:summary] = "#{ticket.state.name} ticket: '#{ticket.title}'" + event_data[:description] = "T##{ticket.number}" + + events_data.push event_data + end + + events_data + end + + def self.pending(user) + + condition = { + 'tickets.owner_id' => user.id, + 'tickets.state_id' => Ticket::State.where( + state_type_id: Ticket::StateType.where( + name: [ + 'pending reminder', + 'pending action', + ], + ), + ), + } + + tickets = Ticket.search( + current_user: user, + condition: condition, + ) + + events_data = [] + tickets.each do |ticket| + + next if !ticket.pending_time + + event_data = {} + + # rubocop:disable Rails/TimeZone + event_data[:dtstart] = Icalendar::Values::DateTime.new( ticket.pending_time ) + event_data[:dtend] = Icalendar::Values::DateTime.new( ticket.pending_time ) + # rubocop:enable Rails/TimeZone + event_data[:summary] = "#{ticket.state.name} ticket: '#{ticket.title}'" + event_data[:description] = "T##{ticket.number}" + + events_data.push event_data + end + + events_data + end + + def self.escalation(user) + + condition = [ + 'tickets.escalation_time IS NOT NULL', + 'tickets.owner_id = ?', user.id + ] + + tickets = Ticket.search( + current_user: user, + condition: condition, + ) + + events_data = [] + tickets.each do |ticket| + + next if !ticket.escalation_time + + event_data = {} + + # rubocop:disable Rails/TimeZone + event_data[:dtstart] = Icalendar::Values::DateTime.new( ticket.escalation_time ) + event_data[:dtend] = Icalendar::Values::DateTime.new( ticket.escalation_time ) + # rubocop:enable Rails/TimeZone + event_data[:summary] = "ticket escalation: '#{ticket.title}'" + event_data[:description] = "T##{ticket.number}" + + events_data.push event_data + end + + events_data + end + +end diff --git a/lib/session_helper.rb b/lib/session_helper.rb index ffba462ae..7c74addf2 100644 --- a/lib/session_helper.rb +++ b/lib/session_helper.rb @@ -28,11 +28,12 @@ module SessionHelper def self.cleanup_expired - # web sessions - ActiveRecord::SessionStore::Session.where('request_type = ? AND updated_at < ?', 1, Time.zone.now - 90.days ).delete_all + # delete temp. sessions + ActiveRecord::SessionStore::Session.where('persistent IS NULL AND updated_at < ?', Time.zone.now - 1.days ).delete_all + + # web sessions older the x days + ActiveRecord::SessionStore::Session.where('updated_at < ?', Time.zone.now - 90.days ).delete_all - # http basic auth calls - ActiveRecord::SessionStore::Session.where('request_type = ? AND updated_at < ?', 2, Time.zone.now - 2.days ).delete_all end def self.get(id) diff --git a/test/browser/prefereces_test.rb b/test/browser/prefereces_test.rb index fb4779f73..2c7ec2a07 100644 --- a/test/browser/prefereces_test.rb +++ b/test/browser/prefereces_test.rb @@ -65,7 +65,7 @@ class PreferencesTest < TestCase click( css: '#navigation a[href="#dashboard"]' ) watch_for( css: '.content.active', - value: 'Meine zugewiesenen' + value: 'Meine Statistik' ) # check language in overview @@ -179,7 +179,7 @@ class PreferencesTest < TestCase click( css: '#navigation a[href="#dashboard"]' ) watch_for( css: '.content.active', - value: 'My assig' + value: 'My Stats' ) # check language in overview @@ -305,7 +305,7 @@ class PreferencesTest < TestCase click( css: '#navigation a[href="#dashboard"]' ) watch_for( css: '.content.active', - value: 'Meine' + value: 'Meine Statistik' ) # check language in overview diff --git a/test/browser_test_helper.rb b/test/browser_test_helper.rb index 4c15fe52d..717062540 100644 --- a/test/browser_test_helper.rb +++ b/test/browser_test_helper.rb @@ -1225,7 +1225,7 @@ wait untill text in selector disabppears if data[:state] || data[:group] || data[:body] found = nil - (1..5).each { + (1..10).each { if !found begin text = instance.find_elements( { css: '.content.active .js-reset' } )[0].text diff --git a/test/integration/i_cal_ticket_test.rb b/test/integration/i_cal_ticket_test.rb new file mode 100644 index 000000000..895228569 --- /dev/null +++ b/test/integration/i_cal_ticket_test.rb @@ -0,0 +1,171 @@ +# encoding: utf-8 +require 'integration_test_helper' + +class ICalTicketTest < ActiveSupport::TestCase + + user = User.create( + firstname: 'iCal', + lastname: 'Testuser', + email: 'ical_testuser@example.com', + updated_by_id: 1, + created_by_id: 1, + ); + + sla = Sla.create( + name: 'sla 1', + condition: {}, + data: { + 'Mon' => 'Mon', 'Tue' => 'Tue', 'Wed' => 'Wed', 'Thu' => 'Thu', 'Fri' => 'Fri', 'Sat' => 'Sat', 'Sun' => 'Sun', + 'beginning_of_workday' => '9:00', + 'end_of_workday' => '18:00', + }, + timezone: 'Europe/Berlin', + first_response_time: 10, + update_time: 10, + close_time: 10, + active: true, + updated_by_id: 1, + created_by_id: 1, + ) + + tickets = [ + { + owner: user, + title: 'new 1', + group: Group.lookup( name: 'Users'), + customer_id: user.id, + state: Ticket::State.lookup( name: 'new' ), + priority: Ticket::Priority.lookup( name: '2 normal' ), + updated_by_id: 1, + created_by_id: 1, + }, + { + owner: user, + title: 'open 1', + group: Group.lookup( name: 'Users'), + customer_id: user.id, + state: Ticket::State.lookup( name: 'open' ), + priority: Ticket::Priority.lookup( name: '2 normal' ), + updated_by_id: 1, + created_by_id: 1, + }, + { + owner: user, + title: 'pending reminder 1', + group: Group.lookup( name: 'Users'), + customer_id: user.id, + state: Ticket::State.lookup( name: 'pending reminder' ), + pending_time: Time.zone.parse('1977-10-27 22:00:00 +0000'), + priority: Ticket::Priority.lookup( name: '2 normal' ), + updated_by_id: 1, + created_by_id: 1, + }, + { + owner: user, + title: 'pending reminder 2', + group: Group.lookup( name: 'Users'), + customer_id: user.id, + state: Ticket::State.lookup( name: 'pending reminder' ), + pending_time: DateTime.tomorrow, + priority: Ticket::Priority.lookup( name: '2 normal' ), + updated_by_id: 1, + created_by_id: 1, + }, + { + owner: user, + title: 'pending close 1', + group: Group.lookup( name: 'Users'), + customer_id: user.id, + state: Ticket::State.lookup( name: 'pending close' ), + pending_time: Time.zone.parse('1977-10-27 22:00:00 +0000'), + priority: Ticket::Priority.lookup( name: '2 normal' ), + updated_by_id: 1, + created_by_id: 1, + }, + { + owner: user, + title: 'pending close 2', + group: Group.lookup( name: 'Users'), + customer_id: user.id, + state: Ticket::State.lookup( name: 'pending close' ), + pending_time: DateTime.tomorrow, + priority: Ticket::Priority.lookup( name: '2 normal' ), + updated_by_id: 1, + created_by_id: 1, + }, + { + owner: user, + title: 'escalation 1', + group: Group.lookup( name: 'Users'), + customer_id: user.id, + state: Ticket::State.lookup( name: 'open' ), + priority: Ticket::Priority.lookup( name: '2 normal' ), + created_at: '2013-03-21 09:30:00 UTC', + updated_at: '2013-03-21 09:30:00 UTC', + updated_by_id: 1, + created_by_id: 1, + }, + ] + + tickets.each { |ticket| + + Ticket.create( ticket ) + } + + test 'new_open' do + + event_data = ICal::Ticket.new_open( user ) + + assert_equal( 3, event_data.length, 'event count' ) + + ical = ICal.to_ical( event_data ) + + event_data.each{ |event| + + contained = false + if ical =~ /#{event[:summary]}/ + contained = true + end + + assert( contained, "ical contains '#{event[:summary]}'" ) + } + end + + test 'pending' do + + event_data = ICal::Ticket.pending( user ) + + assert_equal( 4, event_data.length, 'event count' ) + + ical = ICal.to_ical( event_data ) + + event_data.each{ |event| + + contained = false + if ical =~ /#{event[:summary]}/ + contained = true + end + + assert( contained, "ical contains '#{event[:summary]}'" ) + } + end + + test 'escalation' do + + event_data = ICal::Ticket.escalation( user ) + + assert_equal( 7, event_data.length, 'event count' ) + + ical = ICal.to_ical( event_data ) + + event_data.each{ |event| + + contained = false + if ical =~ /#{event[:summary]}/ + contained = true + end + + assert( contained, "ical contains '#{event[:summary]}'" ) + } + end +end