2024-02-27 15:49:18 +01:00
|
|
|
|
2024-03-26 12:54:23 +01:00
|
|
|
from datetime import datetime, timedelta
|
2024-02-27 15:49:18 +01:00
|
|
|
from django.contrib.auth.hashers import make_password
|
|
|
|
from django.contrib.auth.models import User
|
2024-04-09 15:27:42 +02:00
|
|
|
from django.contrib.auth import get_user_model
|
2024-03-27 15:30:56 +01:00
|
|
|
from django.test import TestCase, override_settings
|
2024-04-09 15:27:42 +02:00
|
|
|
from django.test.client import Client
|
|
|
|
from django.urls import reverse
|
2024-02-27 15:49:18 +01:00
|
|
|
from helpdesk.models import FollowUp, Queue, Ticket
|
|
|
|
from helpdesk import settings as helpdesk_settings
|
|
|
|
import uuid
|
|
|
|
|
|
|
|
|
2024-03-27 15:30:56 +01:00
|
|
|
@override_settings(USE_TZ=True)
|
2024-02-27 15:49:18 +01:00
|
|
|
class TimeSpentAutoTestCase(TestCase):
|
|
|
|
|
|
|
|
def setUp(self):
|
|
|
|
"""Creates a queue, ticket and user."""
|
|
|
|
self.queue_public = Queue.objects.create(
|
|
|
|
title='Queue 1',
|
|
|
|
slug='q1',
|
|
|
|
allow_public_submission=True,
|
2024-03-26 12:54:23 +01:00
|
|
|
dedicated_time=timedelta(minutes=60)
|
2024-02-27 15:49:18 +01:00
|
|
|
)
|
|
|
|
|
2024-03-26 12:54:23 +01:00
|
|
|
self.ticket_data = dict(queue=self.queue_public,
|
|
|
|
title='test ticket',
|
|
|
|
description='test ticket description')
|
2024-02-27 15:49:18 +01:00
|
|
|
|
2024-03-26 12:54:23 +01:00
|
|
|
self.user = User.objects.create(
|
|
|
|
username='staff',
|
|
|
|
email='staff@example.com',
|
|
|
|
password=make_password('Test1234'),
|
|
|
|
is_staff=True,
|
|
|
|
is_superuser=False,
|
|
|
|
is_active=True
|
|
|
|
)
|
2024-02-27 15:49:18 +01:00
|
|
|
|
2024-04-09 15:27:42 +02:00
|
|
|
self.client = Client()
|
|
|
|
|
|
|
|
|
|
|
|
def loginUser(self, is_staff=True):
|
|
|
|
"""Create a staff user and login"""
|
|
|
|
User = get_user_model()
|
|
|
|
self.user = User.objects.create(
|
|
|
|
username='User_1',
|
|
|
|
is_staff=is_staff,
|
|
|
|
)
|
|
|
|
self.user.set_password('pass')
|
|
|
|
self.user.save()
|
|
|
|
self.client.login(username='User_1', password='pass')
|
|
|
|
|
|
|
|
|
2024-03-26 12:54:23 +01:00
|
|
|
def test_add_two_followups_time_spent_auto(self):
|
2024-03-27 17:15:15 +01:00
|
|
|
"""Tests automatic time_spent calculation."""
|
2024-03-26 12:54:23 +01:00
|
|
|
# activate automatic calculation
|
2024-02-27 15:49:18 +01:00
|
|
|
helpdesk_settings.FOLLOWUP_TIME_SPENT_AUTO = True
|
|
|
|
|
2024-03-26 12:54:23 +01:00
|
|
|
# ticket creation date, follow-up creation date, assertion value
|
|
|
|
TEST_VALUES = (
|
|
|
|
# friday
|
|
|
|
('2024-03-01T00:00:00+00:00', '2024-03-01T09:30:10+00:00', timedelta(hours=9, minutes=30, seconds=10)),
|
|
|
|
('2024-03-01T00:00:00+00:00', '2024-03-01T23:59:58+00:00', timedelta(hours=23, minutes=59, seconds=58)),
|
2024-03-27 15:20:34 +01:00
|
|
|
('2024-03-01T00:00:00+00:00', '2024-03-01T23:59:59+00:00', timedelta(hours=23, minutes=59, seconds=59)),
|
2024-03-26 12:54:23 +01:00
|
|
|
('2024-03-01T00:00:00+00:00', '2024-03-02T00:00:00+00:00', timedelta(hours=24)),
|
|
|
|
('2024-03-01T00:00:00+00:00', '2024-03-02T09:00:00+00:00', timedelta(hours=33)),
|
|
|
|
('2024-03-01T00:00:00+00:00', '2024-03-03T00:00:00+00:00', timedelta(hours=48)),
|
2024-02-27 15:49:18 +01:00
|
|
|
)
|
|
|
|
|
2024-03-26 12:54:23 +01:00
|
|
|
for (ticket_time, fup_time, assertion_delta) in TEST_VALUES:
|
|
|
|
# create and setup test ticket time
|
|
|
|
ticket = Ticket.objects.create(**self.ticket_data)
|
2024-03-27 15:20:34 +01:00
|
|
|
ticket_time_p = datetime.strptime(ticket_time, "%Y-%m-%dT%H:%M:%S%z")
|
|
|
|
ticket.created = ticket_time_p
|
|
|
|
ticket.modified = ticket_time_p
|
2024-03-26 12:54:23 +01:00
|
|
|
ticket.save()
|
|
|
|
|
2024-03-27 15:20:34 +01:00
|
|
|
fup_time_p = datetime.strptime(fup_time, "%Y-%m-%dT%H:%M:%S%z")
|
2024-03-26 12:54:23 +01:00
|
|
|
followup1 = FollowUp.objects.create(
|
|
|
|
ticket=ticket,
|
2024-03-27 15:20:34 +01:00
|
|
|
date=fup_time_p,
|
2024-03-26 12:54:23 +01:00
|
|
|
title="Testing followup",
|
|
|
|
comment="Testing followup time spent",
|
|
|
|
public=True,
|
|
|
|
user=self.user,
|
|
|
|
new_status=1,
|
|
|
|
message_id=uuid.uuid4().hex,
|
|
|
|
time_spent=None
|
|
|
|
)
|
|
|
|
|
|
|
|
self.assertEqual(followup1.time_spent.total_seconds(), assertion_delta.total_seconds())
|
|
|
|
self.assertEqual(ticket.time_spent.total_seconds(), assertion_delta.total_seconds())
|
|
|
|
|
2024-03-27 15:20:34 +01:00
|
|
|
# adding a second follow-up at different intervals
|
|
|
|
for delta in (timedelta(seconds=1), timedelta(minutes=1), timedelta(hours=1), timedelta(days=1), timedelta(days=10)):
|
|
|
|
|
|
|
|
followup2 = FollowUp.objects.create(
|
|
|
|
ticket=ticket,
|
|
|
|
date=followup1.date + delta,
|
|
|
|
title="Testing followup 2",
|
|
|
|
comment="Testing followup time spent 2",
|
|
|
|
public=True,
|
|
|
|
user=self.user,
|
|
|
|
new_status=1,
|
|
|
|
message_id=uuid.uuid4().hex,
|
|
|
|
time_spent=None
|
|
|
|
)
|
2024-03-26 12:54:23 +01:00
|
|
|
|
2024-03-27 15:20:34 +01:00
|
|
|
self.assertEqual(followup2.time_spent.total_seconds(), delta.total_seconds())
|
|
|
|
self.assertEqual(ticket.time_spent.total_seconds(), assertion_delta.total_seconds() + delta.total_seconds())
|
2024-03-26 12:54:23 +01:00
|
|
|
|
2024-03-27 15:20:34 +01:00
|
|
|
# delete second follow-up as we test it with many intervals
|
2024-03-27 15:30:56 +01:00
|
|
|
followup2.delete()
|
2024-03-27 16:56:55 +01:00
|
|
|
|
|
|
|
|
|
|
|
def test_followup_time_spent_auto_opening_hours(self):
|
2024-03-27 17:15:15 +01:00
|
|
|
"""Tests automatic time_spent calculation with opening hours and holidays."""
|
|
|
|
|
2024-03-27 16:56:55 +01:00
|
|
|
# activate automatic calculation
|
|
|
|
helpdesk_settings.FOLLOWUP_TIME_SPENT_AUTO = True
|
|
|
|
helpdesk_settings.FOLLOWUP_TIME_SPENT_OPENING_HOURS = {
|
|
|
|
"monday": (0, 23.9999),
|
|
|
|
"tuesday": (8, 18),
|
|
|
|
"wednesday": (8.5, 18.5),
|
|
|
|
"thursday": (0, 10),
|
|
|
|
"friday": (13, 23),
|
|
|
|
"saturday": (0, 0),
|
|
|
|
"sunday": (0, 0),
|
|
|
|
}
|
|
|
|
|
2024-03-27 17:04:30 +01:00
|
|
|
# adding holidays
|
|
|
|
helpdesk_settings.FOLLOWUP_TIME_SPENT_EXCLUDE_HOLIDAYS = (
|
|
|
|
'2024-03-18', '2024-03-19', '2024-03-20', '2024-03-21', '2024-03-22',
|
|
|
|
)
|
|
|
|
|
2024-03-27 16:56:55 +01:00
|
|
|
# ticket creation date, follow-up creation date, assertion value
|
|
|
|
TEST_VALUES = (
|
|
|
|
# monday
|
|
|
|
('2024-03-04T00:00:00+00:00', '2024-03-04T09:30:10+00:00', timedelta(hours=9, minutes=30, seconds=10)),
|
|
|
|
# tuesday
|
|
|
|
('2024-03-05T07:00:00+00:00', '2024-03-05T09:00:00+00:00', timedelta(hours=1)),
|
|
|
|
('2024-03-05T17:50:00+00:00', '2024-03-05T17:51:00+00:00', timedelta(minutes=1)),
|
|
|
|
('2024-03-05T17:50:00+00:00', '2024-03-05T19:51:00+00:00', timedelta(minutes=10)),
|
|
|
|
('2024-03-05T18:00:00+00:00', '2024-03-05T23:59:59+00:00', timedelta(hours=0)),
|
|
|
|
('2024-03-05T20:00:00+00:00', '2024-03-05T20:59:59+00:00', timedelta(hours=0)),
|
|
|
|
# wednesday
|
|
|
|
('2024-03-06T08:00:00+00:00', '2024-03-06T09:01:00+00:00', timedelta(minutes=31)),
|
|
|
|
('2024-03-06T01:00:00+00:00', '2024-03-06T19:30:10+00:00', timedelta(hours=10)),
|
|
|
|
('2024-03-06T18:01:00+00:00', '2024-03-06T19:00:00+00:00', timedelta(minutes=29)),
|
|
|
|
# thursday
|
|
|
|
('2024-03-07T00:00:00+00:00', '2024-03-07T09:30:10+00:00', timedelta(hours=9, minutes=30, seconds=10)),
|
|
|
|
('2024-03-07T09:30:00+00:00', '2024-03-07T10:30:00+00:00', timedelta(minutes=30)),
|
|
|
|
# friday
|
|
|
|
('2024-03-08T00:00:00+00:00', '2024-03-08T23:30:10+00:00', timedelta(hours=10)),
|
|
|
|
# saturday
|
|
|
|
('2024-03-09T00:00:00+00:00', '2024-03-09T09:30:10+00:00', timedelta(hours=0)),
|
|
|
|
# sunday
|
|
|
|
('2024-03-10T00:00:00+00:00', '2024-03-10T09:30:10+00:00', timedelta(hours=0)),
|
|
|
|
|
|
|
|
# monday to sunday
|
|
|
|
('2024-03-04T04:00:00+00:00', '2024-03-10T09:00:00+00:00', timedelta(hours=60)),
|
|
|
|
|
|
|
|
# two weeks
|
|
|
|
('2024-03-04T04:00:00+00:00', '2024-03-17T09:00:00+00:00', timedelta(hours=124)),
|
2024-03-27 17:04:30 +01:00
|
|
|
|
|
|
|
# three weeks, the third one is holidays
|
|
|
|
('2024-03-04T04:00:00+00:00', '2024-03-24T09:00:00+00:00', timedelta(hours=124)),
|
|
|
|
('2024-03-18T04:00:00+00:00', '2024-03-24T09:00:00+00:00', timedelta(hours=0)),
|
2024-03-27 16:56:55 +01:00
|
|
|
)
|
|
|
|
|
|
|
|
for (ticket_time, fup_time, assertion_delta) in TEST_VALUES:
|
|
|
|
# create and setup test ticket time
|
|
|
|
ticket = Ticket.objects.create(**self.ticket_data)
|
|
|
|
ticket_time_p = datetime.strptime(ticket_time, "%Y-%m-%dT%H:%M:%S%z")
|
|
|
|
ticket.created = ticket_time_p
|
|
|
|
ticket.modified = ticket_time_p
|
|
|
|
ticket.save()
|
|
|
|
|
|
|
|
fup_time_p = datetime.strptime(fup_time, "%Y-%m-%dT%H:%M:%S%z")
|
|
|
|
followup1 = FollowUp.objects.create(
|
|
|
|
ticket=ticket,
|
|
|
|
date=fup_time_p,
|
|
|
|
title="Testing followup",
|
|
|
|
comment="Testing followup time spent",
|
|
|
|
public=True,
|
|
|
|
user=self.user,
|
|
|
|
new_status=1,
|
|
|
|
message_id=uuid.uuid4().hex,
|
|
|
|
time_spent=None
|
|
|
|
)
|
|
|
|
|
|
|
|
self.assertEqual(followup1.time_spent.total_seconds(), assertion_delta.total_seconds())
|
|
|
|
self.assertEqual(ticket.time_spent.total_seconds(), assertion_delta.total_seconds())
|
2024-03-27 17:15:15 +01:00
|
|
|
|
2024-03-27 17:22:14 +01:00
|
|
|
# removing opening hours and holidays
|
|
|
|
helpdesk_settings.FOLLOWUP_TIME_SPENT_OPENING_HOURS = {}
|
|
|
|
helpdesk_settings.FOLLOWUP_TIME_SPENT_EXCLUDE_HOLIDAYS = ()
|
2024-03-27 17:15:15 +01:00
|
|
|
|
|
|
|
def test_followup_time_spent_auto_exclude_statuses(self):
|
|
|
|
"""Tests automatic time_spent calculation OPEN_STATUS exclusion."""
|
|
|
|
|
|
|
|
# activate automatic calculation
|
|
|
|
helpdesk_settings.FOLLOWUP_TIME_SPENT_AUTO = True
|
|
|
|
|
|
|
|
# Follow-ups with OPEN_STATUS are excluded from time counting
|
|
|
|
helpdesk_settings.FOLLOWUP_TIME_SPENT_EXCLUDE_STATUSES = (Ticket.OPEN_STATUS,)
|
|
|
|
|
|
|
|
|
|
|
|
# create and setup test ticket time
|
|
|
|
ticket = Ticket.objects.create(**self.ticket_data)
|
|
|
|
ticket_time_p = datetime.strptime('2024-03-04T00:00:00+00:00', "%Y-%m-%dT%H:%M:%S%z")
|
|
|
|
ticket.created = ticket_time_p
|
|
|
|
ticket.modified = ticket_time_p
|
|
|
|
ticket.save()
|
|
|
|
|
|
|
|
fup_time_p = datetime.strptime('2024-03-10T00:00:00+00:00', "%Y-%m-%dT%H:%M:%S%z")
|
|
|
|
followup1 = FollowUp.objects.create(
|
|
|
|
ticket=ticket,
|
|
|
|
date=fup_time_p,
|
|
|
|
title="Testing followup",
|
|
|
|
comment="Testing followup time spent",
|
|
|
|
public=True,
|
|
|
|
user=self.user,
|
|
|
|
new_status=1,
|
|
|
|
message_id=uuid.uuid4().hex,
|
|
|
|
time_spent=None
|
|
|
|
)
|
|
|
|
|
|
|
|
# The Follow-up time_spent should be zero as the default OPEN_STATUS was excluded from calculation
|
|
|
|
self.assertEqual(followup1.time_spent.total_seconds(), 0.0)
|
|
|
|
self.assertEqual(ticket.time_spent.total_seconds(), 0.0)
|
|
|
|
|
|
|
|
# Remove status exclusion
|
2024-03-27 17:19:33 +01:00
|
|
|
helpdesk_settings.FOLLOWUP_TIME_SPENT_EXCLUDE_STATUSES = ()
|
|
|
|
|
|
|
|
|
|
|
|
def test_followup_time_spent_auto_exclude_queues(self):
|
|
|
|
"""Tests automatic time_spent calculation queues exclusion."""
|
|
|
|
|
|
|
|
# activate automatic calculation
|
|
|
|
helpdesk_settings.FOLLOWUP_TIME_SPENT_AUTO = True
|
|
|
|
|
|
|
|
# Follow-ups within the default queue are excluded from time counting
|
|
|
|
helpdesk_settings.FOLLOWUP_TIME_SPENT_EXCLUDE_QUEUES = ('q1',)
|
|
|
|
|
|
|
|
|
|
|
|
# create and setup test ticket time
|
|
|
|
ticket = Ticket.objects.create(**self.ticket_data)
|
|
|
|
ticket_time_p = datetime.strptime('2024-03-04T00:00:00+00:00', "%Y-%m-%dT%H:%M:%S%z")
|
|
|
|
ticket.created = ticket_time_p
|
|
|
|
ticket.modified = ticket_time_p
|
|
|
|
ticket.save()
|
|
|
|
|
|
|
|
fup_time_p = datetime.strptime('2024-03-10T00:00:00+00:00', "%Y-%m-%dT%H:%M:%S%z")
|
|
|
|
followup1 = FollowUp.objects.create(
|
|
|
|
ticket=ticket,
|
|
|
|
date=fup_time_p,
|
|
|
|
title="Testing followup",
|
|
|
|
comment="Testing followup time spent",
|
|
|
|
public=True,
|
|
|
|
user=self.user,
|
|
|
|
new_status=1,
|
|
|
|
message_id=uuid.uuid4().hex,
|
|
|
|
time_spent=None
|
|
|
|
)
|
|
|
|
|
|
|
|
# The Follow-up time_spent should be zero as the default queue was excluded from calculation
|
|
|
|
self.assertEqual(followup1.time_spent.total_seconds(), 0.0)
|
|
|
|
self.assertEqual(ticket.time_spent.total_seconds(), 0.0)
|
|
|
|
|
|
|
|
# Remove queues exclusion
|
2024-04-09 15:27:42 +02:00
|
|
|
helpdesk_settings.FOLLOWUP_TIME_SPENT_EXCLUDE_QUEUES = ()
|
|
|
|
|
|
|
|
def test_http_followup_time_spent_auto_exclude_queues(self):
|
|
|
|
"""Tests automatic time_spent calculation queues exclusion with client"""
|
|
|
|
|
|
|
|
# activate automatic calculation
|
|
|
|
helpdesk_settings.FOLLOWUP_TIME_SPENT_AUTO = True
|
|
|
|
helpdesk_settings.FOLLOWUP_TIME_SPENT_EXCLUDE_QUEUES = ('stop1', 'stop2')
|
|
|
|
|
|
|
|
# make staff user
|
|
|
|
self.loginUser()
|
|
|
|
|
|
|
|
# create queues
|
|
|
|
queues_sequence = ('new', 'stop1', 'resume1', 'stop2', 'resume2', 'end')
|
|
|
|
queues = dict()
|
|
|
|
for slug in queues_sequence:
|
|
|
|
queues[slug] = Queue.objects.create(
|
|
|
|
title=slug,
|
|
|
|
slug=slug,
|
|
|
|
)
|
|
|
|
|
|
|
|
# create ticket
|
|
|
|
initial_data = {
|
|
|
|
'title': 'Queue change ticket test',
|
|
|
|
'queue': queues['new'],
|
|
|
|
'assigned_to': self.user,
|
|
|
|
'status': Ticket.OPEN_STATUS,
|
|
|
|
'created': datetime.strptime('2024-04-09T08:00:00+00:00', "%Y-%m-%dT%H:%M:%S%z")
|
|
|
|
}
|
|
|
|
ticket = Ticket.objects.create(**initial_data)
|
|
|
|
|
|
|
|
# create a change queue follow-up every hour
|
|
|
|
# first follow-up created at the same time of the ticket without queue change
|
2024-04-09 15:33:20 +02:00
|
|
|
# new --1h--> stop1 --0h--> resume1 --1h--> stop2 --0h--> resume2 --1h--> end
|
2024-04-09 15:27:42 +02:00
|
|
|
for (i, queue) in enumerate(queues_sequence):
|
|
|
|
# create follow-up
|
|
|
|
post_data = {
|
|
|
|
'comment': 'ticket in queue {}'.format(queue),
|
|
|
|
'queue': queues[queue].id,
|
|
|
|
}
|
|
|
|
response = self.client.post(reverse('helpdesk:update', kwargs={
|
|
|
|
'ticket_id': ticket.id}), post_data)
|
|
|
|
latest_fup = ticket.followup_set.latest('id')
|
2024-04-09 15:45:41 +02:00
|
|
|
latest_fup.date = ticket.created + timedelta(hours=i)
|
2024-04-09 15:27:42 +02:00
|
|
|
latest_fup.time_spent = None
|
|
|
|
latest_fup.save()
|
|
|
|
|
|
|
|
# total ticket time for followups is 5 hours
|
|
|
|
self.assertEqual(latest_fup.date - ticket.created, timedelta(hours=5))
|
|
|
|
# calculated time spent with 2 hours exclusion is 3 hours
|
2024-04-09 15:45:41 +02:00
|
|
|
self.assertEqual(ticket.time_spent.total_seconds(), timedelta(hours=3).total_seconds())
|
2024-04-09 15:32:11 +02:00
|
|
|
|
|
|
|
# remove queues exclusion
|
|
|
|
helpdesk_settings.FOLLOWUP_TIME_SPENT_EXCLUDE_QUEUES = ()
|