From 01adfa4dea0a2fe7b333dd9929d23b17a08eb809 Mon Sep 17 00:00:00 2001 From: Thorsten Eckel Date: Fri, 26 Jun 2015 14:00:10 +0200 Subject: [PATCH] Reworked iCal functionality and integration tests, now CalendarSubscriptions. --- .../_profile/calendar_subscriptions.js.coffee | 21 +-- .../profile/calendar_subscriptions.jst.eco | 4 +- ...b => calendar_subscriptions_controller.rb} | 26 ++- config/routes/calendar_subscriptions.rb | 6 + config/routes/i_cal.rb | 6 - ..._defaults_calendar_subscriptions_ticket.rb | 29 +++ db/seeds.rb | 23 +++ lib/{i_cal.rb => calendar_subscriptions.rb} | 20 ++- lib/calendar_subscriptions/tickets.rb | 164 +++++++++++++++++ lib/i_cal/i_cal_ticket.rb | 168 ------------------ ...=> calendar_subscriptions_tickets_test.rb} | 63 ++++--- 11 files changed, 297 insertions(+), 233 deletions(-) rename app/controllers/{i_cal_controller.rb => calendar_subscriptions_controller.rb} (61%) create mode 100644 config/routes/calendar_subscriptions.rb delete mode 100644 config/routes/i_cal.rb create mode 100644 db/migrate/20150626121711_defaults_calendar_subscriptions_ticket.rb rename lib/{i_cal.rb => calendar_subscriptions.rb} (64%) create mode 100644 lib/calendar_subscriptions/tickets.rb delete mode 100644 lib/i_cal/i_cal_ticket.rb rename test/integration/{i_cal_ticket_test.rb => calendar_subscriptions_tickets_test.rb} (83%) diff --git a/app/assets/javascripts/app/controllers/_profile/calendar_subscriptions.js.coffee b/app/assets/javascripts/app/controllers/_profile/calendar_subscriptions.js.coffee index 73d7e142e..96f76ed08 100644 --- a/app/assets/javascripts/app/controllers/_profile/calendar_subscriptions.js.coffee +++ b/app/assets/javascripts/app/controllers/_profile/calendar_subscriptions.js.coffee @@ -21,20 +21,11 @@ class CalendarSubscriptions extends App.Controller render: => userPreferences = @Session.get('preferences') - @preferences = - new_open: - own: true - not_assigned: false - pending: - own: true - not_assigned: false - escalation: - own: true - not_assigned: false + @preferences = App.Config.get('defaults_calendar_subscriptions_tickets') - if userPreferences.ical - if userPreferences.ical.ticket - _.extend(@preferences, userPreferences.ical.ticket) + if userPreferences.calendar_subscriptions + if userPreferences.calendar_subscriptions.tickets + _.extend(@preferences, userPreferences.calendar_subscriptions.tickets) @html App.view('profile/calendar_subscriptions') baseurl: window.location.origin @@ -67,8 +58,8 @@ class CalendarSubscriptions extends App.Controller # get data data = user: - ical: - ticket: @preferences + calendar_subscriptions: + tickets: @preferences @ajax( id: 'preferences' diff --git a/app/assets/javascripts/app/views/profile/calendar_subscriptions.jst.eco b/app/assets/javascripts/app/views/profile/calendar_subscriptions.jst.eco index f7bab0810..56a3d82e3 100644 --- a/app/assets/javascripts/app/views/profile/calendar_subscriptions.jst.eco +++ b/app/assets/javascripts/app/views/profile/calendar_subscriptions.jst.eco @@ -8,7 +8,7 @@

<%= @T('See your tickets from within your favorite calendar by adding the following url to your calendar app.') %>

<%= @T('Combined Url') %>

- +

<%= @T('Subscription Settings') %>

@@ -25,7 +25,7 @@ <% end %> diff --git a/app/controllers/i_cal_controller.rb b/app/controllers/calendar_subscriptions_controller.rb similarity index 61% rename from app/controllers/i_cal_controller.rb rename to app/controllers/calendar_subscriptions_controller.rb index e8d1587ec..9612e8cac 100644 --- a/app/controllers/i_cal_controller.rb +++ b/app/controllers/calendar_subscriptions_controller.rb @@ -2,18 +2,18 @@ require 'icalendar' -class ICalController < ApplicationController - before_action { authentication_check( { basic_auth_promt: true, token_action: 'iCal' } ) } +class CalendarSubscriptionsController < ApplicationController + before_action { authentication_check( { basic_auth_promt: true, token_action: 'CalendarSubscriptions' } ) } - # @path [GET] /ical + # @path [GET] /calendar_subscriptions # - # @summary Returns an iCal file with all objects matching the iCal preferences of the current user as events. + # @summary Returns an iCal file with all objects matching the calendar subscriptions preferences of the current user as events. # # @response_message 200 [String] iCal file ready to import in calendar applications. # @response_message 401 Permission denied. def all - ical_object = ICal.new( current_user ) - ical = ical_object.all + calendar_subscriptions = CalendarSubscriptions.new( current_user ) + ical = calendar_subscriptions.all send_data( ical, @@ -27,20 +27,16 @@ class ICalController < ApplicationController render json: { error: e.message }, status: :unprocessable_entity end - # @path [GET] /ical/:object - # @path [GET] /ical/:object/:method + # @path [GET] /calendar_subscriptions/:object + # @path [GET] /calendar_subscriptions/:object/:method # - # @summary Returns an iCal file of the given object (and method) matching the iCal preferences of the current user as events. + # @summary Returns an iCal file of the given object (and method) matching the calendar subscriptions preferences of the current user as events. # # @response_message 200 [String] iCal file ready to import in calendar applications. # @response_message 401 Permission denied. def object - ical_object = ICal.new( current_user ) - - # remove the last char (s/plural) from the object name - object_name = params[:object].to_s[0...-1].to_sym - - ical = ical_object.generic( object_name, params[:method] ) + calendar_subscriptions = CalendarSubscriptions.new( current_user ) + ical = calendar_subscriptions.generic( params[:object], params[:method] ) send_data( ical, diff --git a/config/routes/calendar_subscriptions.rb b/config/routes/calendar_subscriptions.rb new file mode 100644 index 000000000..ef609e982 --- /dev/null +++ b/config/routes/calendar_subscriptions.rb @@ -0,0 +1,6 @@ +Zammad::Application.routes.draw do + + match '/calendar_subscriptions', to: 'calendar_subscriptions#all', via: :get + match '/calendar_subscriptions/:object', to: 'calendar_subscriptions#object', via: :get + match '/calendar_subscriptions/:object/:method', to: 'calendar_subscriptions#object', via: :get +end diff --git a/config/routes/i_cal.rb b/config/routes/i_cal.rb deleted file mode 100644 index 3152ffbd1..000000000 --- a/config/routes/i_cal.rb +++ /dev/null @@ -1,6 +0,0 @@ -Zammad::Application.routes.draw do - - match '/ical', to: 'i_cal#all', via: :get - match '/ical/:object', to: 'i_cal#object', via: :get - match '/ical/:object/:method', to: 'i_cal#object', via: :get -end diff --git a/db/migrate/20150626121711_defaults_calendar_subscriptions_ticket.rb b/db/migrate/20150626121711_defaults_calendar_subscriptions_ticket.rb new file mode 100644 index 000000000..b502fcbf7 --- /dev/null +++ b/db/migrate/20150626121711_defaults_calendar_subscriptions_ticket.rb @@ -0,0 +1,29 @@ +class DefaultsCalendarSubscriptionsTickets < ActiveRecord::Migration + def up + Setting.create_if_not_exists( + title: 'Default calendar Tickets subscriptions', + name: 'defaults_calendar_subscriptions_tickets', + area: 'Defaults::CalendarSubscriptions', + description: 'Defines the default calendar Tickets subscription settings.', + options: {}, + state: { + escalation: { + own: true, + not_assigned: false, + }, + new_open: { + own: true, + not_assigned: false, + }, + pending: { + own: true, + not_assigned: false, + } + }, + frontend: true + ) + end + + def down + end +end diff --git a/db/seeds.rb b/db/seeds.rb index 0ecb00093..67402ce53 100644 --- a/db/seeds.rb +++ b/db/seeds.rb @@ -1259,6 +1259,29 @@ Setting.create_if_not_exists( frontend: false ) +Setting.create_if_not_exists( + title: 'Default calendar Tickets subscriptions', + name: 'defaults_calendar_subscriptions_tickets', + area: 'Defaults::CalendarSubscriptions', + description: 'Defines the default calendar Tickets subscription settings.', + options: {}, + state: { + escalation: { + own: true, + not_assigned: false, + }, + new_open: { + own: true, + not_assigned: false, + }, + pending: { + own: true, + not_assigned: false, + } + }, + frontend: true +) + email_address = EmailAddress.create_if_not_exists( id: 1, realname: 'Zammad', diff --git a/lib/i_cal.rb b/lib/calendar_subscriptions.rb similarity index 64% rename from lib/i_cal.rb rename to lib/calendar_subscriptions.rb index 3e260f9e2..2d826ecd3 100644 --- a/lib/i_cal.rb +++ b/lib/calendar_subscriptions.rb @@ -1,15 +1,23 @@ # Copyright (C) 2012-2013 Zammad Foundation, http://zammad-foundation.org/ -class ICal +class CalendarSubscriptions def initialize(user) @user = user @preferences = {} + default_preferences = Setting.where( area: 'Defaults::CalendarSubscriptions' ) + default_preferences.each { |calendar_subscription| - if @user.preferences[:ical] && !@user.preferences[:ical].empty? - @preferences = @user.preferences[:ical] - end + next if calendar_subscription.name !~ /\Adefaults_calendar_subscriptions_(.*)\z/ + + object_name = $1 + @preferences[ object_name ] = calendar_subscription.state[:value] + } + + return if !@user.preferences[:calendar_subscriptions] + return if @user.preferences[:calendar_subscriptions].empty? + @preferences = @preferences.merge( @user.preferences[:calendar_subscriptions] ) end def all @@ -34,10 +42,10 @@ class ICal events_data = [] if @preferences[ object_name ] && !@preferences[ object_name ].empty? sub_class_name = object_name.to_s.capitalize - object = Object.const_get('ICal').const_get("ICal#{sub_class_name}") + object = Object.const_get("CalendarSubscriptions::#{sub_class_name}") instance = object.new( @user, @preferences[ object_name ] ) method = instance.method( method_name ) - events_data += method.call + events_data += method.call end events_data end diff --git a/lib/calendar_subscriptions/tickets.rb b/lib/calendar_subscriptions/tickets.rb new file mode 100644 index 000000000..33b92d9b3 --- /dev/null +++ b/lib/calendar_subscriptions/tickets.rb @@ -0,0 +1,164 @@ +# Copyright (C) 2012-2013 Zammad Foundation, http://zammad-foundation.org/ + +class CalendarSubscriptions::Tickets + + def initialize(user, preferences) + @user = user + @preferences = preferences + end + + def all + + events_data = [] + return events_data if @preferences.empty? + + events_data += new_open + events_data += pending + events_data += escalation + + events_data + end + + def owner_ids(method) + + owner_ids = [] + + return owner_ids if @preferences.empty? + return owner_ids if !@preferences[ method ] + return owner_ids if @preferences[ method ].empty? + + preferences = @preferences[ method ] + + if preferences[:own] + owner_ids = [ @user.id ] + end + if preferences[:not_assigned] + owner_ids.push( 1 ) + end + + owner_ids + end + + def new_open + + events_data = [] + owner_ids = owner_ids(:new_open) + return events_data if owner_ids.empty? + + condition = { + 'tickets.owner_id' => owner_ids, + '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 pending + + events_data = [] + owner_ids = owner_ids(:pending) + return events_data if owner_ids.empty? + + condition = { + 'tickets.owner_id' => owner_ids, + '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 = {} + + pending_time = ticket.pending_time + if pending_time < Time.zone.today + pending_time = Time.zone.today + end + + # rubocop:disable Rails/TimeZone + event_data[:dtstart] = Icalendar::Values::DateTime.new( pending_time ) + event_data[:dtend] = Icalendar::Values::DateTime.new( 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 = [] + owner_ids = owner_ids(:escalation) + return events_data if owner_ids.empty? + + condition = [ + 'tickets.owner_id IN (?) AND tickets.escalation_time IS NOT NULL', owner_ids + ] + + tickets = Ticket.search( + current_user: @user, + condition: condition, + ) + + tickets.each do |ticket| + + next if !ticket.escalation_time + + event_data = {} + + escalation_time = ticket.escalation_time + if escalation_time < Time.zone.today + escalation_time = Time.zone.today + end + + # rubocop:disable Rails/TimeZone + event_data[:dtstart] = Icalendar::Values::DateTime.new( escalation_time ) + event_data[:dtend] = Icalendar::Values::DateTime.new( 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/i_cal/i_cal_ticket.rb b/lib/i_cal/i_cal_ticket.rb deleted file mode 100644 index a902c8faf..000000000 --- a/lib/i_cal/i_cal_ticket.rb +++ /dev/null @@ -1,168 +0,0 @@ -# Copyright (C) 2012-2013 Zammad Foundation, http://zammad-foundation.org/ - -class ICal - - class ICalTicket - - def initialize(user, preferences) - @user = user - @preferences = preferences - end - - def all - - events_data = [] - return events_data if @preferences.empty? - - events_data += new_open - events_data += pending - events_data += escalation - - events_data - end - - def owner_ids(method) - - owner_ids = [] - - return owner_ids if @preferences.empty? - return owner_ids if !@preferences[ method ] - return owner_ids if @preferences[ method ].empty? - - preferences = @preferences[ method ] - - if preferences[:own] - owner_ids = [ @user.id ] - end - if preferences[:not_assigned] - owner_ids.push( 1 ) - end - - owner_ids - end - - def new_open - - events_data = [] - owner_ids = owner_ids(:new_open) - return events_data if owner_ids.empty? - - condition = { - 'tickets.owner_id' => owner_ids, - '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 pending - - events_data = [] - owner_ids = owner_ids(:pending) - return events_data if owner_ids.empty? - - condition = { - 'tickets.owner_id' => owner_ids, - '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 = {} - - pending_time = ticket.pending_time - if pending_time < Time.zone.today - pending_time = Time.zone.today - end - - # rubocop:disable Rails/TimeZone - event_data[:dtstart] = Icalendar::Values::DateTime.new( pending_time ) - event_data[:dtend] = Icalendar::Values::DateTime.new( 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 = [] - owner_ids = owner_ids(:escalation) - return events_data if owner_ids.empty? - - condition = [ - 'tickets.owner_id IN (?) AND tickets.escalation_time IS NOT NULL', owner_ids - ] - - tickets = Ticket.search( - current_user: @user, - condition: condition, - ) - - tickets.each do |ticket| - - next if !ticket.escalation_time - - event_data = {} - - escalation_time = ticket.escalation_time - if escalation_time < Time.zone.today - escalation_time = Time.zone.today - end - - # rubocop:disable Rails/TimeZone - event_data[:dtstart] = Icalendar::Values::DateTime.new( escalation_time ) - event_data[:dtend] = Icalendar::Values::DateTime.new( 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 - -end diff --git a/test/integration/i_cal_ticket_test.rb b/test/integration/calendar_subscriptions_tickets_test.rb similarity index 83% rename from test/integration/i_cal_ticket_test.rb rename to test/integration/calendar_subscriptions_tickets_test.rb index 7c737762b..e7866c10d 100644 --- a/test/integration/i_cal_ticket_test.rb +++ b/test/integration/calendar_subscriptions_tickets_test.rb @@ -1,12 +1,12 @@ ## encoding: utf-8 require 'integration_test_helper' -class ICalTicketTest < ActiveSupport::TestCase +class CalendarSubscriptionsTicketsTest < ActiveSupport::TestCase user = User.create( - firstname: 'iCal', + firstname: 'CalendarSubscriptions', lastname: 'Testuser', - email: 'ical_testuser@example.com', + email: 'calendar_subscriptions_testuser@example.com', updated_by_id: 1, created_by_id: 1, ) @@ -190,6 +190,21 @@ class ICalTicketTest < ActiveSupport::TestCase Ticket.create( ticket ) } + defaults_disabled = { + escalation: { + own: false, + not_assigned: false, + }, + new_open: { + own: false, + not_assigned: false, + }, + pending: { + own: false, + not_assigned: false, + } + } + test 'new_open' do tests = [ @@ -241,16 +256,18 @@ class ICalTicketTest < ActiveSupport::TestCase tests.each { |test_data| - user.preferences[:ical] = {} - user.preferences[:ical][:ticket] = test_data[:preferences] + preferences = defaults_disabled.merge( test_data[:preferences] ) - ical_ticket = ICal::ICalTicket.new( user, test_data[:preferences] ) - event_data = ical_ticket.new_open + user.preferences[:calendar_subscriptions] = {} + user.preferences[:calendar_subscriptions][:tickets] = preferences + + calendar_subscriptions_ticket = CalendarSubscriptions::Tickets.new( user, preferences ) + event_data = calendar_subscriptions_ticket.new_open assert_equal( test_data[:count], event_data.length, "#{test_data[:name]} event count" ) - ical_object = ICal.new( user ) - ical = ical_object.all + calendar_subscriptions = CalendarSubscriptions.new( user ) + ical = calendar_subscriptions.all event_data.each { |event| @@ -315,16 +332,18 @@ class ICalTicketTest < ActiveSupport::TestCase tests.each { |test_data| - user.preferences[:ical] = {} - user.preferences[:ical][:ticket] = test_data[:preferences] + preferences = defaults_disabled.merge( test_data[:preferences] ) - ical_ticket = ICal::ICalTicket.new( user, test_data[:preferences] ) - event_data = ical_ticket.pending + user.preferences[:calendar_subscriptions] = {} + user.preferences[:calendar_subscriptions][:tickets] = preferences + + calendar_subscriptions_ticket = CalendarSubscriptions::Tickets.new( user, preferences ) + event_data = calendar_subscriptions_ticket.pending assert_equal( test_data[:count], event_data.length, "#{test_data[:name]} event count" ) - ical_object = ICal.new( user ) - ical = ical_object.all + calendar_subscriptions = CalendarSubscriptions.new( user ) + ical = calendar_subscriptions.all event_data.each { |event| @@ -389,16 +408,18 @@ class ICalTicketTest < ActiveSupport::TestCase tests.each { |test_data| - user.preferences[:ical] = {} - user.preferences[:ical][:ticket] = test_data[:preferences] + preferences = defaults_disabled.merge( test_data[:preferences] ) - ical_ticket = ICal::ICalTicket.new( user, test_data[:preferences] ) - event_data = ical_ticket.escalation + user.preferences[:calendar_subscriptions] = {} + user.preferences[:calendar_subscriptions][:tickets] = preferences + + calendar_subscriptions_ticket = CalendarSubscriptions::Tickets.new( user, preferences ) + event_data = calendar_subscriptions_ticket.escalation assert_equal( test_data[:count], event_data.length, "#{test_data[:name]} event count" ) - ical_object = ICal.new( user ) - ical = ical_object.all + calendar_subscriptions = CalendarSubscriptions.new( user ) + ical = calendar_subscriptions.all event_data.each { |event|
<%= @translationTable[stateType] %> - +