mirror of
https://gitea.mueller.network/extern/django-helpdesk.git
synced 2024-11-25 01:13:31 +01:00
Merge pull request #1164 from samsplunks/main
Test set for automatic time tracking of follow-ups
This commit is contained in:
commit
c9ca97516a
@ -110,6 +110,9 @@ From the command line you can run the tests using: `make test`
|
||||
|
||||
See `quicktest.py` for usage details.
|
||||
|
||||
If you need to create tests for new features, add your tests in a test file to the `tests` module and call them in the test VENV with::
|
||||
python quicktest.py helpdesk.tests.test_my_new_features -v 2
|
||||
|
||||
Upgrading from previous versions
|
||||
--------------------------------
|
||||
|
||||
|
@ -198,6 +198,8 @@ def convert_value(value):
|
||||
def daily_time_spent_calculation(earliest, latest, open_hours):
|
||||
"""Returns the number of seconds for a single day time interval according to open hours."""
|
||||
|
||||
time_spent_seconds = 0
|
||||
|
||||
# avoid rendering day in different locale
|
||||
weekday = ('monday', 'tuesday', 'wednesday', 'thursday',
|
||||
'friday', 'saturday', 'sunday')[earliest.weekday()]
|
||||
@ -215,7 +217,11 @@ def daily_time_spent_calculation(earliest, latest, open_hours):
|
||||
|
||||
# translate time for delta calculation
|
||||
earliest_f = earliest.hour + earliest.minute / 60 + earliest.second / 3600
|
||||
latest_f = latest.hour + latest.minute / 60 + latest.second / 3600
|
||||
latest_f = latest.hour + latest.minute / 60 + latest.second / (60 * 60) + latest.microsecond / (60 * 60 * 999999)
|
||||
|
||||
# if latest time is midnight and close hour is midnight, add a second to the time spent
|
||||
if latest_f >= MIDNIGHT and end == MIDNIGHT:
|
||||
time_spent_seconds += 1
|
||||
|
||||
if earliest_f < start:
|
||||
earliest = earliest.replace(hour=start_hour, minute=start_minute, second=start_second)
|
||||
@ -230,8 +236,6 @@ def daily_time_spent_calculation(earliest, latest, open_hours):
|
||||
day_delta = latest - earliest
|
||||
|
||||
# returns up to 86399 seconds, add one second if full day
|
||||
time_spent_seconds = day_delta.seconds
|
||||
if time_spent_seconds == 86399:
|
||||
time_spent_seconds += 1
|
||||
time_spent_seconds += day_delta.seconds
|
||||
|
||||
return time_spent_seconds
|
@ -1045,14 +1045,14 @@ class FollowUp(models.Model):
|
||||
# close single day case
|
||||
end_day_time = latest
|
||||
else:
|
||||
end_day_time = earliest.replace(hour=23, minute=59, second=59)
|
||||
end_day_time = earliest.replace(hour=23, minute=59, second=59, microsecond=999999)
|
||||
elif day == days:
|
||||
start_day_time = latest.replace(hour=0, minute=0, second=0)
|
||||
end_day_time = latest
|
||||
else:
|
||||
middle_day_time = earliest + datetime.timedelta(days=day)
|
||||
start_day_time = middle_day_time.replace(hour=0, minute=0, second=0)
|
||||
end_day_time = middle_day_time.replace(hour=23, minute=59, second=59)
|
||||
end_day_time = middle_day_time.replace(hour=23, minute=59, second=59, microsecond=999999)
|
||||
|
||||
if (start_day_time.strftime("%Y-%m-%d") not in holidays and
|
||||
prev_status not in exclude_statuses and
|
||||
|
262
helpdesk/tests/test_time_spent_auto.py
Normal file
262
helpdesk/tests/test_time_spent_auto.py
Normal file
@ -0,0 +1,262 @@
|
||||
|
||||
from datetime import datetime, timedelta
|
||||
from django.contrib.auth.hashers import make_password
|
||||
from django.contrib.auth.models import User
|
||||
from django.test import TestCase, override_settings
|
||||
from django.test.client import Client
|
||||
from helpdesk.models import FollowUp, Queue, Ticket
|
||||
from helpdesk import settings as helpdesk_settings
|
||||
import uuid
|
||||
|
||||
|
||||
@override_settings(USE_TZ=True)
|
||||
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,
|
||||
dedicated_time=timedelta(minutes=60)
|
||||
)
|
||||
|
||||
self.ticket_data = dict(queue=self.queue_public,
|
||||
title='test ticket',
|
||||
description='test ticket description')
|
||||
|
||||
self.client = Client()
|
||||
|
||||
self.user = User.objects.create(
|
||||
username='staff',
|
||||
email='staff@example.com',
|
||||
password=make_password('Test1234'),
|
||||
is_staff=True,
|
||||
is_superuser=False,
|
||||
is_active=True
|
||||
)
|
||||
|
||||
def test_add_two_followups_time_spent_auto(self):
|
||||
"""Tests automatic time_spent calculation."""
|
||||
# activate automatic calculation
|
||||
helpdesk_settings.FOLLOWUP_TIME_SPENT_AUTO = True
|
||||
|
||||
# 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-01T00:00:00+00:00', '2024-03-01T23:59:59+00:00', timedelta(hours=23, minutes=59, seconds=59)),
|
||||
('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)),
|
||||
)
|
||||
|
||||
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
|
||||
)
|
||||
followup1.save()
|
||||
|
||||
self.assertEqual(followup1.time_spent.total_seconds(), assertion_delta.total_seconds())
|
||||
self.assertEqual(ticket.time_spent.total_seconds(), assertion_delta.total_seconds())
|
||||
|
||||
# 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
|
||||
)
|
||||
followup2.save()
|
||||
|
||||
self.assertEqual(followup2.time_spent.total_seconds(), delta.total_seconds())
|
||||
self.assertEqual(ticket.time_spent.total_seconds(), assertion_delta.total_seconds() + delta.total_seconds())
|
||||
|
||||
# delete second follow-up as we test it with many intervals
|
||||
followup2.delete()
|
||||
|
||||
|
||||
def test_followup_time_spent_auto_opening_hours(self):
|
||||
"""Tests automatic time_spent calculation with opening hours and holidays."""
|
||||
|
||||
# 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),
|
||||
}
|
||||
|
||||
# adding holidays
|
||||
helpdesk_settings.FOLLOWUP_TIME_SPENT_EXCLUDE_HOLIDAYS = (
|
||||
'2024-03-18', '2024-03-19', '2024-03-20', '2024-03-21', '2024-03-22',
|
||||
)
|
||||
|
||||
# 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)),
|
||||
|
||||
# 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)),
|
||||
)
|
||||
|
||||
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
|
||||
)
|
||||
followup1.save()
|
||||
|
||||
self.assertEqual(followup1.time_spent.total_seconds(), assertion_delta.total_seconds())
|
||||
self.assertEqual(ticket.time_spent.total_seconds(), assertion_delta.total_seconds())
|
||||
|
||||
# removing opening hours and holidays
|
||||
helpdesk_settings.FOLLOWUP_TIME_SPENT_OPENING_HOURS = {}
|
||||
helpdesk_settings.FOLLOWUP_TIME_SPENT_EXCLUDE_HOLIDAYS = ()
|
||||
|
||||
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
|
||||
)
|
||||
followup1.save()
|
||||
|
||||
# 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
|
||||
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
|
||||
)
|
||||
followup1.save()
|
||||
|
||||
# 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
|
||||
helpdesk_settings.FOLLOWUP_TIME_SPENT_EXCLUDE_QUEUES = ()
|
Loading…
Reference in New Issue
Block a user