Refactoring: Migrate ticket_escalation_test to RSpec

This commit is contained in:
Ryan Lue 2019-04-08 21:50:21 +08:00 committed by Thorsten Eckel
parent 48cccd186b
commit 74e1fa8722
3 changed files with 196 additions and 225 deletions

View file

@ -4,6 +4,7 @@ FactoryBot.define do
timezone { 'Europe/Berlin' }
default { true }
ical_url { nil }
business_hours do
{
mon: {
@ -36,7 +37,43 @@ FactoryBot.define do
}
}
end
created_by_id { 1 }
updated_by_id { 1 }
trait :'24/7' do
business_hours do
{
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'] ]
},
}
end
end
end
end

View file

@ -380,6 +380,165 @@ RSpec.describe Ticket, type: :model do
end
end
end
describe '#escalation_at' do
before { travel_to(Time.current) } # freeze time
let(:sla) { create(:sla, calendar: calendar, first_response_time: 60, update_time: 180, solution_time: 240) }
let(:calendar) { create(:calendar, :'24/7') }
context 'with no SLAs in the system' do
it 'defaults to nil' do
expect(ticket.escalation_at).to be(nil)
end
end
context 'with an SLA in the system' do
before { sla } # create sla
it 'is set based on SLAs #first_response_time' do
expect(ticket.escalation_at.to_i)
.to eq(1.hour.from_now.to_i)
end
context 'after first agents response' do
before { ticket } # create ticket
let(:article) { create(:ticket_article, ticket: ticket, sender_name: 'Agent') }
it 'is updated based on the SLAs #update_time' do
travel(1.minute) # time is frozen: if we don't travel forward, pre- and post-update values will be the same
expect { article }
.to change { ticket.reload.escalation_at.to_i }
.to eq(3.hours.from_now.to_i)
end
context 'when new #update_time is later than original #solution_time' do
it 'is updated based on the original #solution_time' do
travel(2.hours) # time is frozen: if we don't travel forward, pre- and post-update values will be the same
expect { article }
.to change { ticket.reload.escalation_at.to_i }
.to eq(4.hours.after(ticket.created_at).to_i)
end
end
end
end
context 'when updated after an SLA has been added to the system' do
before { ticket } # create ticket
before { sla } # create sla
it 'is updated based on the new SLAs #first_response_time' do
expect { ticket.save! }
.to change { ticket.escalation_at.to_i }.from(0).to(1.hour.from_now.to_i)
end
end
context 'when updated after all SLAs have been removed from the system' do
before { sla } # create sla
before { ticket } # create ticket
before { sla.destroy }
it 'is set to nil' do
expect { ticket.save! }
.to change { ticket.escalation_at }.to(nil)
end
end
end
describe '#first_response_escalation_at' do
before { travel_to(Time.current) } # freeze time
let(:sla) { create(:sla, calendar: calendar, first_response_time: 60, update_time: 180, solution_time: 240) }
let(:calendar) { create(:calendar, :'24/7') }
context 'with no SLAs in the system' do
it 'defaults to nil' do
expect(ticket.first_response_escalation_at).to be(nil)
end
end
context 'with an SLA in the system' do
before { sla } # create sla
it 'is set based on SLAs #first_response_time' do
expect(ticket.first_response_escalation_at.to_i)
.to eq(1.hour.from_now.to_i)
end
context 'after first agents response' do
before { ticket } # create ticket
let(:article) { create(:ticket_article, ticket: ticket, sender_name: 'Agent') }
it 'does not change' do
expect { article }.not_to change { ticket.first_response_escalation_at }
end
end
end
end
describe '#update_escalation_at' do
before { travel_to(Time.current) } # freeze time
let(:sla) { create(:sla, calendar: calendar, first_response_time: 60, update_time: 180, solution_time: 240) }
let(:calendar) { create(:calendar, :'24/7') }
context 'with no SLAs in the system' do
it 'defaults to nil' do
expect(ticket.update_escalation_at).to be(nil)
end
end
context 'with an SLA in the system' do
before { sla } # create sla
it 'is set based on SLAs #update_time' do
expect(ticket.update_escalation_at.to_i)
.to eq(3.hours.from_now.to_i)
end
context 'after first agents response' do
before { ticket } # create ticket
let(:article) { create(:ticket_article, ticket: ticket, sender_name: 'Agent') }
it 'is updated based on the SLAs #update_time' do
travel(1.minute) # time is frozen: if we don't travel forward, pre- and post-update values will be the same
expect { article }
.to change { ticket.reload.update_escalation_at.to_i }
.to(3.hours.from_now.to_i)
end
end
end
end
describe '#close_escalation_at' do
before { travel_to(Time.current) } # freeze time
let(:sla) { create(:sla, calendar: calendar, first_response_time: 60, update_time: 180, solution_time: 240) }
let(:calendar) { create(:calendar, :'24/7') }
context 'with no SLAs in the system' do
it 'defaults to nil' do
expect(ticket.close_escalation_at).to be(nil)
end
end
context 'with an SLA in the system' do
before { sla } # create sla
it 'is set based on SLAs #solution_time' do
expect(ticket.close_escalation_at.to_i)
.to eq(4.hours.from_now.to_i)
end
context 'after first agents response' do
before { ticket } # create ticket
let(:article) { create(:ticket_article, ticket: ticket, sender_name: 'Agent') }
it 'does not change' do
expect { article }.not_to change { ticket.close_escalation_at }
end
end
end
end
end
describe 'Associations:' do

View file

@ -1,225 +0,0 @@
require 'test_helper'
class TicketEscalationTest < ActiveSupport::TestCase
test 'ticket create' do
ticket = Ticket.new(
title: 'some value 123',
group: Group.lookup(name: 'Users'),
customer_id: 2,
updated_by_id: 1,
created_by_id: 1,
)
ticket.save!
assert(ticket, 'ticket created')
assert_not(ticket.escalation_at)
assert_not(ticket.has_changes_to_save?)
article = Ticket::Article.create!(
ticket_id: ticket.id,
type_id: Ticket::Article::Type.find_by(name: 'note').id,
sender_id: Ticket::Article::Sender.find_by(name: 'Customer').id,
body: 'some body',
internal: false,
updated_by_id: 1,
created_by_id: 1,
)
assert_not(article.has_changes_to_save?)
assert_not(ticket.has_changes_to_save?)
calendar = Calendar.create_or_update(
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,
updated_by_id: 1,
created_by_id: 1,
)
sla = Sla.create_or_update(
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,
updated_by_id: 1,
created_by_id: 1,
)
ticket = Ticket.new(
title: 'some value 123',
group: Group.lookup(name: 'Users'),
customer_id: 2,
updated_by_id: 1,
created_by_id: 1,
)
ticket.save!
assert(ticket, 'ticket created')
ticket_escalation_at = ticket.escalation_at
assert(ticket.escalation_at)
assert_not(ticket.has_changes_to_save?)
article = Ticket::Article.create!(
ticket_id: ticket.id,
type_id: Ticket::Article::Type.find_by(name: 'note').id,
sender_id: Ticket::Article::Sender.find_by(name: 'Customer').id,
body: 'some body',
internal: false,
updated_by_id: 1,
created_by_id: 1,
)
assert_not(article.has_changes_to_save?)
assert_not(ticket.has_changes_to_save?)
travel 1.second
sla.first_response_time = 30
sla.save!
ticket.save!
assert_not(ticket.has_changes_to_save?)
assert(ticket.escalation_at)
assert_in_delta((ticket_escalation_at - 30.minutes).to_i, ticket.escalation_at.to_i, 90)
sla.destroy!
calendar.destroy!
ticket.save!
assert_not(ticket.has_changes_to_save?)
assert_not(ticket.escalation_at)
end
test 'email process and reply via email' do
calendar = Calendar.create_or_update(
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,
updated_by_id: 1,
created_by_id: 1,
)
sla = Sla.create_or_update(
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,
updated_by_id: 1,
created_by_id: 1,
)
email = "From: Bob Smith <customer@example.com>
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
article = nil
ticket_p.with_lock do
article = Ticket::Article.create!(
ticket_id: ticket_p.id,
from: 'some_sender@example.com',
to: 'some_recipient@example.com',
subject: 'some subject',
message_id: 'some@id',
body: 'some message',
internal: false,
sender: Ticket::Article::Sender.where(name: 'Agent').first,
type: Ticket::Article::Type.where(name: 'email').first,
updated_by_id: 1,
created_by_id: 1,
)
end
ticket_p.reload
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