Refactoring: Migrate stats_ticket_waiting_time_test to RSpec
This commit is contained in:
parent
9d7485bf71
commit
97530e0d78
2 changed files with 159 additions and 264 deletions
159
spec/lib/stats/ticket_waiting_time_spec.rb
Normal file
159
spec/lib/stats/ticket_waiting_time_spec.rb
Normal file
|
@ -0,0 +1,159 @@
|
|||
require 'rails_helper'
|
||||
|
||||
RSpec.describe Stats::TicketWaitingTime do
|
||||
describe '.generate' do
|
||||
let(:user) { create(:agent_user, groups: [group]) }
|
||||
let(:group) { create(:group) }
|
||||
|
||||
context 'when given an agent with no tickets' do
|
||||
it 'returns a hash with 1-day average ticket wait time for user (in minutes)' do
|
||||
expect(Stats::TicketWaitingTime.generate(user)).to include(handling_time: 0)
|
||||
end
|
||||
|
||||
it 'returns a hash with 1-day average ticket wait time across user’s groups (in minutes)' do
|
||||
expect(Stats::TicketWaitingTime.generate(user)).to include(average_per_agent: 0)
|
||||
end
|
||||
|
||||
it 'returns a hash with verbal grade for average ticket wait time' do
|
||||
expect(Stats::TicketWaitingTime.generate(user)).to include(state: 'supergood')
|
||||
end
|
||||
|
||||
it 'returns a hash with decimal score (0–1) of user’s risk of falling to a lower grade' do
|
||||
expect(Stats::TicketWaitingTime.generate(user)).to include(percent: 0.0)
|
||||
end
|
||||
|
||||
context 'and who belongs to a group with other tickets' do
|
||||
let(:ticket) { create(:ticket, group: group) }
|
||||
|
||||
before do
|
||||
create(:ticket_article, sender_name: 'Customer', ticket: ticket, created_at: Time.current + 1.hour)
|
||||
create(:ticket_article, sender_name: 'Agent', ticket: ticket, created_at: Time.current + 2.hours)
|
||||
end
|
||||
|
||||
it 'returns a hash with 1-day average ticket wait time across user’s groups (in minutes)' do
|
||||
expect(Stats::TicketWaitingTime.generate(user)).to include(average_per_agent: 60)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
context 'when given an agent with recent (since start-of-day) customer exchanges' do
|
||||
let(:ticket) { create(:ticket, group: group, owner_id: user.id) }
|
||||
|
||||
before do
|
||||
create(:ticket_article, sender_name: 'Customer', ticket: ticket, created_at: Time.current + 1.hour)
|
||||
create(:ticket_article, sender_name: 'Agent', ticket: ticket, created_at: Time.current + 2.hours)
|
||||
end
|
||||
|
||||
it 'returns a hash with 1-day average ticket wait time for user (in minutes)' do
|
||||
expect(Stats::TicketWaitingTime.generate(user)).to include(handling_time: 60)
|
||||
end
|
||||
|
||||
it 'returns a hash with 1-day average ticket wait time across user’s groups (in minutes)' do
|
||||
expect(Stats::TicketWaitingTime.generate(user)).to include(average_per_agent: 60)
|
||||
end
|
||||
|
||||
it 'returns a hash with verbal grade for average ticket wait time' do
|
||||
expect(Stats::TicketWaitingTime.generate(user)).to include(state: 'supergood')
|
||||
end
|
||||
|
||||
it 'returns a hash with decimal score (0–1) of user’s risk of falling to a lower grade' do
|
||||
expect(Stats::TicketWaitingTime.generate(user)).to include(percent: 1.0)
|
||||
end
|
||||
|
||||
context 'and who belongs to a group with other tickets' do
|
||||
let(:other_ticket) { create(:ticket, group: group) }
|
||||
|
||||
before do
|
||||
create(:ticket_article, sender_name: 'Customer', ticket: other_ticket, created_at: Time.current + 1.hour)
|
||||
create(:ticket_article, sender_name: 'Agent', ticket: other_ticket, created_at: Time.current + 3.hours)
|
||||
end
|
||||
|
||||
it 'returns a hash with 1-day average ticket wait time across user’s groups (in minutes)' do
|
||||
expect(Stats::TicketWaitingTime.generate(user)).to include(average_per_agent: 90)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe '.calculate_average' do
|
||||
let(:ticket) { create(:ticket) }
|
||||
let(:start_time) { Time.current.beginning_of_day }
|
||||
|
||||
context 'with empty tickets (no articles)' do
|
||||
it 'returns 0' do
|
||||
expect(Stats::TicketWaitingTime.calculate_average(ticket.id, start_time)).to eq(0)
|
||||
end
|
||||
end
|
||||
|
||||
context 'with old articles (last message predates given start time)' do
|
||||
before do
|
||||
create(:ticket_article, sender_name: 'Customer', ticket: ticket, created_at: 1.day.ago)
|
||||
create(:ticket_article, sender_name: 'Agent', ticket: ticket, created_at: 1.day.ago)
|
||||
end
|
||||
|
||||
it 'returns 0' do
|
||||
expect(Stats::TicketWaitingTime.calculate_average(ticket.id, start_time)).to eq(0)
|
||||
end
|
||||
end
|
||||
|
||||
context 'with a single exchange' do
|
||||
before do
|
||||
create(:ticket_article, sender_name: 'Customer', ticket: ticket, created_at: start_time + 1.minute)
|
||||
create(:ticket_article, sender_name: 'Agent', ticket: ticket, created_at: start_time + 2.minutes)
|
||||
end
|
||||
|
||||
it 'returns elapsed time' do
|
||||
expect(Stats::TicketWaitingTime.calculate_average(ticket.id, start_time)).to eq(1.minute)
|
||||
end
|
||||
end
|
||||
|
||||
context 'with internal notes' do
|
||||
before do
|
||||
create(:ticket_article, sender_name: 'Customer', ticket: ticket, created_at: start_time + 1.minute)
|
||||
create(:ticket_article, sender_name: 'Agent', ticket: ticket, created_at: start_time + 2.minutes, internal: true)
|
||||
create(:ticket_article, sender_name: 'Agent', ticket: ticket, created_at: start_time + 3.minutes)
|
||||
end
|
||||
|
||||
it 'ignores them (and measures time to actual response)' do
|
||||
expect(Stats::TicketWaitingTime.calculate_average(ticket.id, start_time)).to eq(2.minutes)
|
||||
end
|
||||
end
|
||||
|
||||
context 'with multiple exchanges' do
|
||||
before do
|
||||
create(:ticket_article, sender_name: 'Customer', ticket: ticket, created_at: start_time + 1.minute)
|
||||
create(:ticket_article, sender_name: 'Agent', ticket: ticket, created_at: start_time + 2.minutes)
|
||||
create(:ticket_article, sender_name: 'Customer', ticket: ticket, created_at: start_time + 10.minutes)
|
||||
create(:ticket_article, sender_name: 'Agent', ticket: ticket, created_at: start_time + 15.minutes)
|
||||
end
|
||||
|
||||
it 'returns average of elapsed times' do
|
||||
expect(Stats::TicketWaitingTime.calculate_average(ticket.id, start_time)).to eq(3.minutes)
|
||||
end
|
||||
end
|
||||
|
||||
context 'with all above cases combined' do
|
||||
before do
|
||||
# empty ticket
|
||||
create(:ticket)
|
||||
|
||||
# old messages
|
||||
create(:ticket_article, sender_name: 'Customer', ticket: ticket, created_at: 1.day.ago)
|
||||
create(:ticket_article, sender_name: 'Agent', ticket: ticket, created_at: 1.day.ago)
|
||||
|
||||
# first exchange, with internal notes
|
||||
create(:ticket_article, sender_name: 'Customer', ticket: ticket, created_at: start_time + 1.minute)
|
||||
create(:ticket_article, sender_name: 'Agent', ticket: ticket, created_at: start_time + 90.seconds, internal: true)
|
||||
create(:ticket_article, sender_name: 'Agent', ticket: ticket, created_at: start_time + 2.minutes)
|
||||
|
||||
# second exchange
|
||||
create(:ticket_article, sender_name: 'Customer', ticket: ticket, created_at: start_time + 10.minutes)
|
||||
create(:ticket_article, sender_name: 'Agent', ticket: ticket, created_at: start_time + 15.minutes)
|
||||
end
|
||||
|
||||
it 'ignores all edge cases and returns only specified average response time' do
|
||||
expect(Stats::TicketWaitingTime.calculate_average(ticket.id, start_time)).to eq(3.minutes)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -1,264 +0,0 @@
|
|||
require 'test_helper'
|
||||
require 'stats/ticket_waiting_time'
|
||||
|
||||
class StatsTicketWaitingTimeTest < ActiveSupport::TestCase
|
||||
|
||||
test 'single ticket' do
|
||||
|
||||
group1 = Group.create!(
|
||||
name: 'Group 1',
|
||||
active: true,
|
||||
email_address: EmailAddress.first,
|
||||
created_by_id: 1,
|
||||
updated_by_id: 1,
|
||||
)
|
||||
roles = Role.where(name: 'Agent')
|
||||
user1 = User.create!(
|
||||
login: 'assets_stats1@example.org',
|
||||
firstname: 'assets_stats1',
|
||||
lastname: 'assets_stats1',
|
||||
email: 'assets_stats1@example.org',
|
||||
password: 'some_pass',
|
||||
active: true,
|
||||
groups: [group1],
|
||||
roles: roles,
|
||||
created_by_id: 1,
|
||||
updated_by_id: 1,
|
||||
)
|
||||
user2 = User.create!(
|
||||
login: 'assets_stats2@example.org',
|
||||
firstname: 'assets_stats2',
|
||||
lastname: 'assets_stats2',
|
||||
email: 'assets_sla2@example.org',
|
||||
password: 'some_pass',
|
||||
active: true,
|
||||
groups: [group1],
|
||||
roles: roles,
|
||||
created_by_id: 1,
|
||||
updated_by_id: 1,
|
||||
)
|
||||
|
||||
result = Stats::TicketWaitingTime.generate(user1)
|
||||
assert_equal(0, result[:handling_time])
|
||||
assert_equal('supergood', result[:state])
|
||||
assert_equal(0, result[:average_per_agent])
|
||||
assert_equal(0, result[:percent])
|
||||
|
||||
ticket1 = Ticket.create!(
|
||||
title: 'com test 1',
|
||||
group: group1,
|
||||
customer_id: 2,
|
||||
state: Ticket::State.lookup(name: 'new'),
|
||||
priority: Ticket::Priority.lookup(name: '2 normal'),
|
||||
updated_by_id: 1,
|
||||
created_by_id: 1,
|
||||
)
|
||||
|
||||
# communication 1: waiting time 2 hours (BUT too old yesterday)
|
||||
Ticket::Article.create!(
|
||||
ticket_id: ticket1.id,
|
||||
from: 'a@example.com',
|
||||
to: 'a@example.com',
|
||||
subject: 'com test 1',
|
||||
message_id: 'some@id_com_1',
|
||||
body: 'some message 123',
|
||||
internal: false,
|
||||
sender: Ticket::Article::Sender.find_by(name: 'Customer'),
|
||||
type: Ticket::Article::Type.find_by(name: 'email'),
|
||||
updated_by_id: 1,
|
||||
created_by_id: 1,
|
||||
created_at: '2017-04-12 08:00',
|
||||
updated_at: '2017-04-12 08:00',
|
||||
)
|
||||
Ticket::Article.create!(
|
||||
ticket_id: ticket1.id,
|
||||
from: 'a@example.com',
|
||||
to: 'a@example.com',
|
||||
subject: 'com test 1',
|
||||
message_id: 'some@id_com_1',
|
||||
body: 'some message 123',
|
||||
internal: false,
|
||||
sender: Ticket::Article::Sender.find_by(name: 'Agent'),
|
||||
type: Ticket::Article::Type.find_by(name: 'email'),
|
||||
updated_by_id: 1,
|
||||
created_by_id: 1,
|
||||
created_at: '2017-04-12 10:00',
|
||||
updated_at: '2017-04-12 10:00',
|
||||
)
|
||||
|
||||
# communication 2: waiting time 2 hours
|
||||
Ticket::Article.create!(
|
||||
ticket_id: ticket1.id,
|
||||
from: 'a@example.com',
|
||||
to: 'a@example.com',
|
||||
subject: 'com test 1',
|
||||
message_id: 'some@id_com_1',
|
||||
body: 'some message 123',
|
||||
internal: false,
|
||||
sender: Ticket::Article::Sender.find_by(name: 'Customer'),
|
||||
type: Ticket::Article::Type.find_by(name: 'email'),
|
||||
updated_by_id: 1,
|
||||
created_by_id: 1,
|
||||
created_at: '2017-04-13 08:00',
|
||||
updated_at: '2017-04-13 08:00',
|
||||
)
|
||||
Ticket::Article.create!(
|
||||
ticket_id: ticket1.id,
|
||||
from: 'a@example.com',
|
||||
to: 'a@example.com',
|
||||
subject: 'com test 1',
|
||||
message_id: 'some@id_com_1',
|
||||
body: 'some message 123',
|
||||
internal: false,
|
||||
sender: Ticket::Article::Sender.find_by(name: 'Agent'),
|
||||
type: Ticket::Article::Type.find_by(name: 'email'),
|
||||
updated_by_id: 1,
|
||||
created_by_id: 1,
|
||||
created_at: '2017-04-13 10:00',
|
||||
updated_at: '2017-04-13 10:00',
|
||||
)
|
||||
|
||||
# communication 3: waiting time 4 hours
|
||||
Ticket::Article.create!(
|
||||
ticket_id: ticket1.id,
|
||||
from: 'a@example.com',
|
||||
to: 'a@example.com',
|
||||
subject: 'com test 1',
|
||||
message_id: 'some@id_com_1',
|
||||
body: 'some message 123',
|
||||
internal: false,
|
||||
sender: Ticket::Article::Sender.find_by(name: 'Customer'),
|
||||
type: Ticket::Article::Type.find_by(name: 'email'),
|
||||
updated_by_id: 1,
|
||||
created_by_id: 1,
|
||||
created_at: '2017-04-13 11:00',
|
||||
updated_at: '2017-04-13 11:00',
|
||||
)
|
||||
Ticket::Article.create!(
|
||||
ticket_id: ticket1.id,
|
||||
from: 'a@example.com',
|
||||
to: 'a@example.com',
|
||||
subject: 'com test 1',
|
||||
message_id: 'some@id_com_1',
|
||||
body: 'some message 123',
|
||||
internal: false,
|
||||
sender: Ticket::Article::Sender.find_by(name: 'System'),
|
||||
type: Ticket::Article::Type.find_by(name: 'email'),
|
||||
updated_by_id: 1,
|
||||
created_by_id: 1,
|
||||
created_at: '2017-04-13 15:00',
|
||||
updated_at: '2017-04-13 15:00',
|
||||
)
|
||||
|
||||
# communication 4: INVALID waiting time 1 hour (because internal)
|
||||
Ticket::Article.create!(
|
||||
ticket_id: ticket1.id,
|
||||
from: 'a@example.com',
|
||||
to: 'a@example.com',
|
||||
subject: 'com test 1',
|
||||
message_id: 'some@id_com_1',
|
||||
body: 'some message 123',
|
||||
internal: true,
|
||||
sender: Ticket::Article::Sender.find_by(name: 'Customer'),
|
||||
type: Ticket::Article::Type.find_by(name: 'email'),
|
||||
updated_by_id: 1,
|
||||
created_by_id: 1,
|
||||
created_at: '2017-04-13 15:00',
|
||||
updated_at: '2017-04-13 15:00',
|
||||
)
|
||||
Ticket::Article.create!(
|
||||
ticket_id: ticket1.id,
|
||||
from: 'a@example.com',
|
||||
to: 'a@example.com',
|
||||
subject: 'com test 1',
|
||||
message_id: 'some@id_com_1',
|
||||
body: 'some message 123',
|
||||
internal: true,
|
||||
sender: Ticket::Article::Sender.find_by(name: 'System'),
|
||||
type: Ticket::Article::Type.find_by(name: 'email'),
|
||||
updated_by_id: 1,
|
||||
created_by_id: 1,
|
||||
created_at: '2017-04-13 15:10',
|
||||
updated_at: '2017-04-13 15:10',
|
||||
)
|
||||
|
||||
ticket2 = Ticket.create!(
|
||||
title: 'com test 2',
|
||||
group: group1,
|
||||
customer_id: 2,
|
||||
state: Ticket::State.lookup(name: 'new'),
|
||||
priority: Ticket::Priority.lookup(name: '2 normal'),
|
||||
updated_by_id: 1,
|
||||
created_by_id: 1,
|
||||
)
|
||||
|
||||
average_time = Stats::TicketWaitingTime.calculate_average([ticket1.id, ticket2.id], '2017-04-13 00:00:00')
|
||||
|
||||
expected_average_time = 60 * 60 * 2 # for communication 2
|
||||
expected_average_time += 60 * 60 * 4 # for communication 3
|
||||
expected_average_time = expected_average_time / 2 # for average
|
||||
|
||||
travel_to Time.zone.local(2017, 0o4, 13, 23, 0o0, 44)
|
||||
|
||||
assert_equal(expected_average_time, average_time)
|
||||
|
||||
result = Stats::TicketWaitingTime.generate(user1)
|
||||
assert_equal(0, result[:handling_time])
|
||||
assert_equal('supergood', result[:state])
|
||||
assert_equal(180, result[:average_per_agent])
|
||||
assert_equal(0.0, result[:percent])
|
||||
|
||||
ticket3 = Ticket.create!(
|
||||
title: 'com test 3',
|
||||
group: group1,
|
||||
customer_id: 2,
|
||||
owner: user1,
|
||||
state: Ticket::State.lookup(name: 'new'),
|
||||
priority: Ticket::Priority.lookup(name: '2 normal'),
|
||||
updated_by_id: 1,
|
||||
created_by_id: 1,
|
||||
)
|
||||
|
||||
# communication 1: waiting time 2 hours (BUT too old yesterday)
|
||||
Ticket::Article.create!(
|
||||
ticket_id: ticket3.id,
|
||||
from: 'a@example.com',
|
||||
to: 'a@example.com',
|
||||
subject: 'com test 3',
|
||||
message_id: 'some@id_com_1',
|
||||
body: 'some message 123',
|
||||
internal: false,
|
||||
sender: Ticket::Article::Sender.find_by(name: 'Customer'),
|
||||
type: Ticket::Article::Type.find_by(name: 'email'),
|
||||
updated_by_id: 1,
|
||||
created_by_id: 1,
|
||||
created_at: '2017-04-13 08:00',
|
||||
updated_at: '2017-04-13 08:00',
|
||||
)
|
||||
Ticket::Article.create!(
|
||||
ticket_id: ticket3.id,
|
||||
from: 'a@example.com',
|
||||
to: 'a@example.com',
|
||||
subject: 'com test 3',
|
||||
message_id: 'some@id_com_1',
|
||||
body: 'some message 123',
|
||||
internal: false,
|
||||
sender: Ticket::Article::Sender.find_by(name: 'Agent'),
|
||||
type: Ticket::Article::Type.find_by(name: 'email'),
|
||||
updated_by_id: 1,
|
||||
created_by_id: 1,
|
||||
created_at: '2017-04-13 09:00',
|
||||
updated_at: '2017-04-13 09:00',
|
||||
)
|
||||
|
||||
result = Stats::TicketWaitingTime.generate(user1)
|
||||
assert_equal(60, result[:handling_time])
|
||||
assert_equal('supergood', result[:state])
|
||||
assert_equal(140, result[:average_per_agent])
|
||||
assert_equal(1.0, result[:percent])
|
||||
|
||||
travel_back
|
||||
|
||||
end
|
||||
|
||||
end
|
Loading…
Reference in a new issue