From 2c654404ce81063a8733820f10980db981d7ef89 Mon Sep 17 00:00:00 2001 From: Martin Edenhofer Date: Fri, 22 Jun 2018 12:51:42 +0200 Subject: [PATCH] Follow up fix for issue #2082 - escalation_at are not updated correctly. --- .../observer/ticket/escalation_update.rb | 4 +- .../tickets_controller_escalation_test.rb | 190 ++++++++++++++++++ test/unit/ticket_sla_test.rb | 6 +- 3 files changed, 195 insertions(+), 5 deletions(-) create mode 100644 test/controllers/tickets_controller_escalation_test.rb diff --git a/app/models/observer/ticket/escalation_update.rb b/app/models/observer/ticket/escalation_update.rb index 085bce371..9de4d5877 100644 --- a/app/models/observer/ticket/escalation_update.rb +++ b/app/models/observer/ticket/escalation_update.rb @@ -14,8 +14,8 @@ class Observer::Ticket::EscalationUpdate < ActiveRecord::Observer # return if we run import mode return true if Setting.get('import_mode') - return true if record.destroyed? - + return true if !Ticket.exists?(record.id) + record.reload record.escalation_calculation end end diff --git a/test/controllers/tickets_controller_escalation_test.rb b/test/controllers/tickets_controller_escalation_test.rb new file mode 100644 index 000000000..ae808f7df --- /dev/null +++ b/test/controllers/tickets_controller_escalation_test.rb @@ -0,0 +1,190 @@ + +require 'test_helper' + +class TicketsControllerEscalationTest < ActionDispatch::IntegrationTest + setup do + + # set accept header + @headers = { 'ACCEPT' => 'application/json', 'CONTENT_TYPE' => 'application/json' } + + # create agent + roles = Role.where(name: %w[Admin Agent]) + groups = Group.all + + UserInfo.current_user_id = 1 + @admin = User.create!( + login: 'tickets-admin', + firstname: 'Tickets', + lastname: 'Admin', + email: 'tickets-admin@example.com', + password: 'adminpw', + active: true, + roles: roles, + groups: groups, + ) + + # create agent + roles = Role.where(name: 'Agent') + @agent = User.create!( + login: 'tickets-agent@example.com', + firstname: 'Tickets', + lastname: 'Agent', + email: 'tickets-agent@example.com', + password: 'agentpw', + active: true, + roles: roles, + groups: groups, + ) + + # create customer without org + roles = Role.where(name: 'Customer') + @customer_without_org = User.create!( + login: 'tickets-customer1@example.com', + firstname: 'Tickets', + lastname: 'Customer1', + email: 'tickets-customer1@example.com', + password: 'customer1pw', + active: true, + roles: roles, + ) + + @calendar = Calendar.create!( + name: 'Escalation Test', + timezone: 'Europe/Berlin', + business_hours: { + mon: { + active: true, + timeframes: [ ['00:00', '23:59'] ] + }, + tue: { + active: true, + timeframes: [ ['00:00', '23:59'] ] + }, + wed: { + active: true, + timeframes: [ ['00:00', '23:59'] ] + }, + thu: { + active: true, + timeframes: [ ['00:00', '23:59'] ] + }, + fri: { + active: true, + timeframes: [ ['00:00', '23:59'] ] + }, + sat: { + active: true, + timeframes: [ ['00:00', '23:59'] ] + }, + sun: { + active: true, + timeframes: [ ['00:00', '23:59'] ] + }, + }, + default: true, + ical_url: nil, + ) + + @sla = Sla.create!( + name: 'test sla 1', + condition: { + 'ticket.title' => { + operator: 'contains', + value: 'some value 123', + }, + }, + first_response_time: 60, + update_time: 180, + solution_time: 240, + calendar_id: @calendar.id, + ) + + UserInfo.current_user_id = nil + + end + + test '01.01 ticket created via web' do + credentials = ActionController::HttpAuthentication::Basic.encode_credentials('tickets-customer1@example.com', 'customer1pw') + params = { + title: 'some value 123', + group: 'Users', + article: { + body: 'some test 123', + }, + } + + post '/api/v1/tickets', params: params.to_json, headers: @headers.merge('Authorization' => credentials) + assert_response(201) + + result = JSON.parse(@response.body) + assert_equal(Hash, result.class) + assert_equal(Ticket::State.lookup(name: 'new').id, result['state_id']) + assert_equal('some value 123', result['title']) + assert_equal(@customer_without_org.id, result['updated_by_id']) + assert_equal(@customer_without_org.id, result['created_by_id']) + + ticket_p = Ticket.find(result['id']) + + assert_equal(ticket_p['escalation_at'].iso8601, result['escalation_at'].sub(/.\d\d\dZ$/, 'Z')) + assert_equal(ticket_p['first_response_escalation_at'].iso8601, result['first_response_escalation_at'].sub(/.\d\d\dZ$/, 'Z')) + assert_equal(ticket_p['update_escalation_at'].iso8601, result['update_escalation_at'].sub(/.\d\d\dZ$/, 'Z')) + assert_equal(ticket_p['close_escalation_at'].iso8601, result['close_escalation_at'].sub(/.\d\d\dZ$/, 'Z')) + + assert(ticket_p.escalation_at) + assert_in_delta(ticket_p.first_response_escalation_at.to_i, (ticket_p.created_at + 1.hour).to_i, 90) + assert_in_delta(ticket_p.update_escalation_at.to_i, (ticket_p.created_at + 3.hours).to_i, 90) + assert_in_delta(ticket_p.close_escalation_at.to_i, (ticket_p.created_at + 4.hours).to_i, 90) + assert_in_delta(ticket_p.escalation_at.to_i, (ticket_p.created_at + 1.hour).to_i, 90) + end + + test '01.02 ticket got created via email - reply by agent via web' do + + email = "From: Bob Smith +To: zammad@example.com +Subject: some value 123 + +Some Text" + + ticket_p, article_p, user_p, mail = Channel::EmailParser.new.process({}, email) + ticket_p.reload + assert(ticket_p.escalation_at) + assert_in_delta(ticket_p.first_response_escalation_at.to_i, (ticket_p.created_at + 1.hour).to_i, 90) + assert_in_delta(ticket_p.update_escalation_at.to_i, (ticket_p.created_at + 3.hours).to_i, 90) + assert_in_delta(ticket_p.close_escalation_at.to_i, (ticket_p.created_at + 4.hours).to_i, 90) + assert_in_delta(ticket_p.escalation_at.to_i, (ticket_p.created_at + 1.hour).to_i, 90) + + travel 3.hours + + credentials = ActionController::HttpAuthentication::Basic.encode_credentials('tickets-agent@example.com', 'agentpw') + params = { + title: 'some value 123 - update', + article: { + body: 'some test 123', + type: 'email', + to: 'customer@example.com', + }, + } + put "/api/v1/tickets/#{ticket_p.id}", params: params.to_json, headers: @headers.merge('Authorization' => credentials) + + assert_response(200) + result = JSON.parse(@response.body) + assert_equal(Hash, result.class) + assert_equal(Ticket::State.lookup(name: 'open').id, result['state_id']) + assert_equal('some value 123 - update', result['title']) + assert_equal(@agent.id, result['updated_by_id']) + assert_equal(user_p.id, result['created_by_id']) + + ticket_p.reload + assert_equal(ticket_p['escalation_at'].iso8601, result['escalation_at'].sub(/.\d\d\dZ$/, 'Z')) + assert_equal(ticket_p['first_response_escalation_at'].iso8601, result['first_response_escalation_at'].sub(/.\d\d\dZ$/, 'Z')) + assert_equal(ticket_p['update_escalation_at'].iso8601, result['update_escalation_at'].sub(/.\d\d\dZ$/, 'Z')) + assert_equal(ticket_p['close_escalation_at'].iso8601, result['close_escalation_at'].sub(/.\d\d\dZ$/, 'Z')) + + assert_in_delta(ticket_p.first_response_escalation_at.to_i, (ticket_p.created_at + 1.hour).to_i, 90) + assert_in_delta(ticket_p.update_escalation_at.to_i, (ticket_p.last_contact_agent_at + 3.hours).to_i, 90) + assert_in_delta(ticket_p.close_escalation_at.to_i, (ticket_p.created_at + 4.hours).to_i, 90) + assert_in_delta(ticket_p.escalation_at.to_i, (ticket_p.created_at + 4.hours).to_i, 90) + + end + +end diff --git a/test/unit/ticket_sla_test.rb b/test/unit/ticket_sla_test.rb index dd226aba3..9a7441d8d 100644 --- a/test/unit/ticket_sla_test.rb +++ b/test/unit/ticket_sla_test.rb @@ -1881,7 +1881,7 @@ class TicketSlaTest < ActiveSupport::TestCase message_id: 'some@id', body: 'some message', internal: false, - sender: Ticket::Article::Sender.where(name: 'Customer').first, + sender: Ticket::Article::Sender.where(name: 'Agent').first, type: Ticket::Article::Type.where(name: 'email').first, updated_by_id: 1, created_by_id: 1, @@ -1891,9 +1891,9 @@ class TicketSlaTest < ActiveSupport::TestCase Scheduler.worker(true) ticket = Ticket.find(ticket.id) - assert_equal(ticket.escalation_at.gmtime.to_s, '2016-11-09 09:27:00 UTC', 'ticket.escalation_at verify 1') + assert_equal(ticket.escalation_at.gmtime.to_s, '2016-11-09 09:26:36 UTC', 'ticket.escalation_at verify 1') assert_equal(ticket.first_response_escalation_at.gmtime.to_s, '2016-11-02 09:00:00 UTC', 'ticket.first_response_escalation_at verify 1') - assert_equal(ticket.update_escalation_at.gmtime.to_s, '2016-11-09 09:27:00 UTC', 'ticket.update_escalation_at verify 1') + assert_equal(ticket.update_escalation_at.gmtime.to_s, '2016-11-09 09:26:36 UTC', 'ticket.update_escalation_at verify 1') assert_nil(ticket.close_escalation_at, 'ticket.close_escalation_at verify 1') article_agent = Ticket::Article.create!(