Refactoring: Migrate ticket_escalation_test to RSpec
This commit is contained in:
parent
48cccd186b
commit
74e1fa8722
3 changed files with 196 additions and 225 deletions
|
@ -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
|
||||
|
|
|
@ -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 SLA’s #first_response_time' do
|
||||
expect(ticket.escalation_at.to_i)
|
||||
.to eq(1.hour.from_now.to_i)
|
||||
end
|
||||
|
||||
context 'after first agent’s response' do
|
||||
before { ticket } # create ticket
|
||||
let(:article) { create(:ticket_article, ticket: ticket, sender_name: 'Agent') }
|
||||
|
||||
it 'is updated based on the SLA’s #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 SLA’s #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 SLA’s #first_response_time' do
|
||||
expect(ticket.first_response_escalation_at.to_i)
|
||||
.to eq(1.hour.from_now.to_i)
|
||||
end
|
||||
|
||||
context 'after first agent’s 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 SLA’s #update_time' do
|
||||
expect(ticket.update_escalation_at.to_i)
|
||||
.to eq(3.hours.from_now.to_i)
|
||||
end
|
||||
|
||||
context 'after first agent’s response' do
|
||||
before { ticket } # create ticket
|
||||
let(:article) { create(:ticket_article, ticket: ticket, sender_name: 'Agent') }
|
||||
|
||||
it 'is updated based on the SLA’s #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 SLA’s #solution_time' do
|
||||
expect(ticket.close_escalation_at.to_i)
|
||||
.to eq(4.hours.from_now.to_i)
|
||||
end
|
||||
|
||||
context 'after first agent’s 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
|
||||
|
|
|
@ -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
|
Loading…
Reference in a new issue