From 3bfa0cd8c80574f0ad86616f710f90537c234cd6 Mon Sep 17 00:00:00 2001 From: Sam Splunks <72095718+samsplunks@users.noreply.github.com> Date: Tue, 27 Feb 2024 09:58:15 +0000 Subject: [PATCH 01/15] Documen,ting testing a single file set of tests --- README.rst | 3 +++ 1 file changed, 3 insertions(+) diff --git a/README.rst b/README.rst index caa1d400..05dc5489 100644 --- a/README.rst +++ b/README.rst @@ -104,6 +104,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 -------------------------------- From 0be6282bfe577626f03ce1033a696cdaa3ea47c4 Mon Sep 17 00:00:00 2001 From: Sam Splunks <72095718+samsplunks@users.noreply.github.com> Date: Tue, 27 Feb 2024 14:49:18 +0000 Subject: [PATCH 02/15] Basic auto time_spent calculation test --- helpdesk/tests/test_time_spent_auto.py | 67 ++++++++++++++++++++++++++ 1 file changed, 67 insertions(+) create mode 100644 helpdesk/tests/test_time_spent_auto.py diff --git a/helpdesk/tests/test_time_spent_auto.py b/helpdesk/tests/test_time_spent_auto.py new file mode 100644 index 00000000..89c8a9e5 --- /dev/null +++ b/helpdesk/tests/test_time_spent_auto.py @@ -0,0 +1,67 @@ + +import datetime +from django.contrib.auth.hashers import make_password +from django.contrib.auth.models import User +from django.test import TestCase +from django.test.client import Client +from helpdesk.models import FollowUp, Queue, Ticket +from helpdesk import settings as helpdesk_settings +import uuid + + +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=datetime.timedelta(minutes=60) + ) + + self.ticket_data = { + 'title': 'Test Ticket', + 'description': 'Some Test Ticket', + } + + ticket_data = dict(queue=self.queue_public, **self.ticket_data) + self.ticket = Ticket.objects.create(**ticket_data) + + self.client = Client() + + user1_kwargs = { + 'username': 'staff', + 'email': 'staff@example.com', + 'password': make_password('Test1234'), + 'is_staff': True, + 'is_superuser': False, + 'is_active': True + } + self.user = User.objects.create(**user1_kwargs) + + def test_add_followup_time_spent_auto(self): + """Tests automatic time_spent calculation.""" + + helpdesk_settings.FOLLOWUP_TIME_SPENT_AUTO = True + + message_id = uuid.uuid4().hex + followup = FollowUp.objects.create( + ticket=self.ticket, + date=self.ticket.created + datetime.timedelta(minutes=30), + title="Testing followup", + comment="Testing followup time spent", + public=True, + user=self.user, + new_status=1, + message_id=message_id, + time_spent=None + ) + followup.save() + + self.assertEqual(followup.time_spent.seconds, 1800) + self.assertEqual(self.ticket.time_spent.seconds, 1800) + self.assertEqual(self.queue_public.time_spent.seconds, 1800) + self.assertTrue( + self.queue_public.dedicated_time.seconds > self.queue_public.time_spent.seconds + ) \ No newline at end of file From cf81e0d4522e7fafcf1e045d0a41349e9e257e34 Mon Sep 17 00:00:00 2001 From: Sam Splunks <72095718+samsplunks@users.noreply.github.com> Date: Tue, 26 Mar 2024 11:54:23 +0000 Subject: [PATCH 03/15] Update simple follow-up time spent calculation --- helpdesk/tests/test_time_spent_auto.py | 110 ++++++++++++++++--------- 1 file changed, 71 insertions(+), 39 deletions(-) diff --git a/helpdesk/tests/test_time_spent_auto.py b/helpdesk/tests/test_time_spent_auto.py index 89c8a9e5..3dba8f25 100644 --- a/helpdesk/tests/test_time_spent_auto.py +++ b/helpdesk/tests/test_time_spent_auto.py @@ -1,5 +1,5 @@ -import datetime +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 @@ -17,51 +17,83 @@ class TimeSpentAutoTestCase(TestCase): title='Queue 1', slug='q1', allow_public_submission=True, - dedicated_time=datetime.timedelta(minutes=60) + dedicated_time=timedelta(minutes=60) ) - self.ticket_data = { - 'title': 'Test Ticket', - 'description': 'Some Test Ticket', - } - - ticket_data = dict(queue=self.queue_public, **self.ticket_data) - self.ticket = Ticket.objects.create(**ticket_data) + self.ticket_data = dict(queue=self.queue_public, + title='test ticket', + description='test ticket description') self.client = Client() - user1_kwargs = { - 'username': 'staff', - 'email': 'staff@example.com', - 'password': make_password('Test1234'), - 'is_staff': True, - 'is_superuser': False, - 'is_active': True - } - self.user = User.objects.create(**user1_kwargs) - - def test_add_followup_time_spent_auto(self): - """Tests automatic time_spent calculation.""" + 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 - message_id = uuid.uuid4().hex - followup = FollowUp.objects.create( - ticket=self.ticket, - date=self.ticket.created + datetime.timedelta(minutes=30), - title="Testing followup", - comment="Testing followup time spent", - public=True, - user=self.user, - new_status=1, - message_id=message_id, - time_spent=None + # 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=24)), + ('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)), ) - followup.save() - self.assertEqual(followup.time_spent.seconds, 1800) - self.assertEqual(self.ticket.time_spent.seconds, 1800) - self.assertEqual(self.queue_public.time_spent.seconds, 1800) - self.assertTrue( - self.queue_public.dedicated_time.seconds > self.queue_public.time_spent.seconds - ) \ No newline at end of file + 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 = datetime.strptime(ticket_time, "%Y-%m-%dT%H:%M:%S%z") + ticket.created = ticket_time + ticket.modified = ticket_time + ticket.save() + + fup_time = datetime.strptime(fup_time, "%Y-%m-%dT%H:%M:%S%z") + followup1 = FollowUp.objects.create( + ticket=ticket, + date=fup_time, + 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 1 hour later + hour_delta = timedelta(hours=1) + followup2 = FollowUp.objects.create( + ticket=ticket, + date=followup1.date + hour_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() + + # we have a special case with the last second of the day being added if day ends at 23:59:59 + day_overlap = followup2.date.toordinal() - followup1.date.toordinal() + hour_delta = hour_delta - timedelta(seconds=1 * day_overlap) + + self.assertEqual(followup2.time_spent.total_seconds(), hour_delta.total_seconds()) + self.assertEqual(ticket.time_spent.total_seconds(), assertion_delta.total_seconds() + hour_delta.total_seconds()) \ No newline at end of file From f4bde195112d431dd7ce5ce876e971073e43a502 Mon Sep 17 00:00:00 2001 From: Sam Splunks <72095718+samsplunks@users.noreply.github.com> Date: Wed, 27 Mar 2024 14:19:15 +0000 Subject: [PATCH 04/15] Fixing a bug to differentiate between 23:59:59 and 24:00:00 end times --- helpdesk/lib.py | 12 ++++++++---- helpdesk/models.py | 6 +++--- 2 files changed, 11 insertions(+), 7 deletions(-) diff --git a/helpdesk/lib.py b/helpdesk/lib.py index 481d4cbb..d18241e4 100644 --- a/helpdesk/lib.py +++ b/helpdesk/lib.py @@ -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,8 +217,12 @@ 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, add a second to the time spent + if latest_f >= 24: + time_spent_seconds += 1 + if earliest_f < start: earliest = earliest.replace(hour=start_hour, minute=start_minute, second=start_second) elif earliest_f >= end: @@ -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 \ No newline at end of file diff --git a/helpdesk/models.py b/helpdesk/models.py index 4409d901..1781093f 100644 --- a/helpdesk/models.py +++ b/helpdesk/models.py @@ -994,7 +994,7 @@ class FollowUp(models.Model): if helpdesk_settings.FOLLOWUP_TIME_SPENT_AUTO and not self.time_spent: self.time_spent = self.time_spent_calculation() - + super(FollowUp, self).save(*args, **kwargs) def get_markdown(self): @@ -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 From d6b37f1c11f2611b5bc476c1c1f49ac320cebcec Mon Sep 17 00:00:00 2001 From: Sam Splunks <72095718+samsplunks@users.noreply.github.com> Date: Wed, 27 Mar 2024 14:20:34 +0000 Subject: [PATCH 05/15] Updating time_spent test with multiple follow-ups at multiple time intervals --- helpdesk/tests/test_time_spent_auto.py | 50 +++++++++++++------------- 1 file changed, 25 insertions(+), 25 deletions(-) diff --git a/helpdesk/tests/test_time_spent_auto.py b/helpdesk/tests/test_time_spent_auto.py index 3dba8f25..2ec48e54 100644 --- a/helpdesk/tests/test_time_spent_auto.py +++ b/helpdesk/tests/test_time_spent_auto.py @@ -45,7 +45,7 @@ class TimeSpentAutoTestCase(TestCase): # 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=24)), + ('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)), @@ -54,15 +54,15 @@ class TimeSpentAutoTestCase(TestCase): 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 = datetime.strptime(ticket_time, "%Y-%m-%dT%H:%M:%S%z") - ticket.created = ticket_time - ticket.modified = ticket_time + 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 = datetime.strptime(fup_time, "%Y-%m-%dT%H:%M:%S%z") + fup_time_p = datetime.strptime(fup_time, "%Y-%m-%dT%H:%M:%S%z") followup1 = FollowUp.objects.create( ticket=ticket, - date=fup_time, + date=fup_time_p, title="Testing followup", comment="Testing followup time spent", public=True, @@ -76,24 +76,24 @@ class TimeSpentAutoTestCase(TestCase): 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 1 hour later - hour_delta = timedelta(hours=1) - followup2 = FollowUp.objects.create( - ticket=ticket, - date=followup1.date + hour_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() + # 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() - # we have a special case with the last second of the day being added if day ends at 23:59:59 - day_overlap = followup2.date.toordinal() - followup1.date.toordinal() - hour_delta = hour_delta - timedelta(seconds=1 * day_overlap) + self.assertEqual(followup2.time_spent.total_seconds(), delta.total_seconds()) + self.assertEqual(ticket.time_spent.total_seconds(), assertion_delta.total_seconds() + delta.total_seconds()) - self.assertEqual(followup2.time_spent.total_seconds(), hour_delta.total_seconds()) - self.assertEqual(ticket.time_spent.total_seconds(), assertion_delta.total_seconds() + hour_delta.total_seconds()) \ No newline at end of file + # delete second follow-up as we test it with many intervals + followup2.delete() \ No newline at end of file From f0fb8039efac381afb904cc83a9a48e3d7419e42 Mon Sep 17 00:00:00 2001 From: Sam Splunks <72095718+samsplunks@users.noreply.github.com> Date: Wed, 27 Mar 2024 14:30:56 +0000 Subject: [PATCH 06/15] Adding USE_TZ = True to comply with 32bits tests --- helpdesk/tests/test_time_spent_auto.py | 22 ++++++++++++++++++++-- 1 file changed, 20 insertions(+), 2 deletions(-) diff --git a/helpdesk/tests/test_time_spent_auto.py b/helpdesk/tests/test_time_spent_auto.py index 2ec48e54..9a9da421 100644 --- a/helpdesk/tests/test_time_spent_auto.py +++ b/helpdesk/tests/test_time_spent_auto.py @@ -2,13 +2,14 @@ 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 +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): @@ -96,4 +97,21 @@ class TimeSpentAutoTestCase(TestCase): 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() \ No newline at end of file + followup2.delete() + + + 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)), + ) \ No newline at end of file From 3be5bbed449d35ca352ed30e5fd45b113ad89854 Mon Sep 17 00:00:00 2001 From: Sam Splunks <72095718+samsplunks@users.noreply.github.com> Date: Wed, 27 Mar 2024 14:32:56 +0000 Subject: [PATCH 07/15] Removed begining of next test --- helpdesk/tests/test_time_spent_auto.py | 17 ----------------- 1 file changed, 17 deletions(-) diff --git a/helpdesk/tests/test_time_spent_auto.py b/helpdesk/tests/test_time_spent_auto.py index 9a9da421..abb8d131 100644 --- a/helpdesk/tests/test_time_spent_auto.py +++ b/helpdesk/tests/test_time_spent_auto.py @@ -98,20 +98,3 @@ class TimeSpentAutoTestCase(TestCase): # delete second follow-up as we test it with many intervals followup2.delete() - - - 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)), - ) \ No newline at end of file From 1d8fc2ad429a96dbf886dc86619f5434b6bcda19 Mon Sep 17 00:00:00 2001 From: Sam Splunks <72095718+samsplunks@users.noreply.github.com> Date: Wed, 27 Mar 2024 15:56:55 +0000 Subject: [PATCH 08/15] Opening hours tests and bug fix --- helpdesk/lib.py | 4 +- helpdesk/tests/test_time_spent_auto.py | 72 ++++++++++++++++++++++++++ 2 files changed, 74 insertions(+), 2 deletions(-) diff --git a/helpdesk/lib.py b/helpdesk/lib.py index d18241e4..bd8c4a42 100644 --- a/helpdesk/lib.py +++ b/helpdesk/lib.py @@ -219,8 +219,8 @@ def daily_time_spent_calculation(earliest, latest, open_hours): earliest_f = earliest.hour + earliest.minute / 60 + earliest.second / 3600 latest_f = latest.hour + latest.minute / 60 + latest.second / (60 * 60) + latest.microsecond / (60 * 60 * 999999) - # if latest time is midnight, add a second to the time spent - if latest_f >= 24: + # if latest time is midnight and close hour is midnight, add a second to the time spent + if latest_f >= 24 and end == MIDNIGHT: time_spent_seconds += 1 if earliest_f < start: diff --git a/helpdesk/tests/test_time_spent_auto.py b/helpdesk/tests/test_time_spent_auto.py index abb8d131..285302bb 100644 --- a/helpdesk/tests/test_time_spent_auto.py +++ b/helpdesk/tests/test_time_spent_auto.py @@ -40,6 +40,7 @@ class TimeSpentAutoTestCase(TestCase): """Tests automatic time_spent calculation""" # activate automatic calculation helpdesk_settings.FOLLOWUP_TIME_SPENT_AUTO = True + helpdesk_settings.USE_TZ = True # ticket creation date, follow-up creation date, assertion value TEST_VALUES = ( @@ -98,3 +99,74 @@ class TimeSpentAutoTestCase(TestCase): # 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""" + # 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), + } + + # 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)), + ) + + 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()) From acecc41ec8142552b417b2c61698efed477b108a Mon Sep 17 00:00:00 2001 From: Sam Splunks <72095718+samsplunks@users.noreply.github.com> Date: Wed, 27 Mar 2024 15:59:25 +0000 Subject: [PATCH 09/15] Using MIDNIGHT constant instead of number --- helpdesk/lib.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/helpdesk/lib.py b/helpdesk/lib.py index bd8c4a42..96bb430f 100644 --- a/helpdesk/lib.py +++ b/helpdesk/lib.py @@ -220,7 +220,7 @@ def daily_time_spent_calculation(earliest, latest, open_hours): 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 >= 24 and end == MIDNIGHT: + if latest_f >= MIDNIGHT and end == MIDNIGHT: time_spent_seconds += 1 if earliest_f < start: From e3a745f81a790563b51d4001dbaf43e8681b9135 Mon Sep 17 00:00:00 2001 From: Sam Splunks <72095718+samsplunks@users.noreply.github.com> Date: Wed, 27 Mar 2024 16:04:30 +0000 Subject: [PATCH 10/15] Testing holidays --- helpdesk/tests/test_time_spent_auto.py | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/helpdesk/tests/test_time_spent_auto.py b/helpdesk/tests/test_time_spent_auto.py index 285302bb..f925c30c 100644 --- a/helpdesk/tests/test_time_spent_auto.py +++ b/helpdesk/tests/test_time_spent_auto.py @@ -115,6 +115,11 @@ class TimeSpentAutoTestCase(TestCase): "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 @@ -144,6 +149,10 @@ class TimeSpentAutoTestCase(TestCase): # 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: From 5e0df47a4f84975c72db897997a5d505207be849 Mon Sep 17 00:00:00 2001 From: Sam Splunks <72095718+samsplunks@users.noreply.github.com> Date: Wed, 27 Mar 2024 16:15:15 +0000 Subject: [PATCH 11/15] Adding status exclusion test --- helpdesk/tests/test_time_spent_auto.py | 44 ++++++++++++++++++++++++-- 1 file changed, 42 insertions(+), 2 deletions(-) diff --git a/helpdesk/tests/test_time_spent_auto.py b/helpdesk/tests/test_time_spent_auto.py index f925c30c..9ad84d67 100644 --- a/helpdesk/tests/test_time_spent_auto.py +++ b/helpdesk/tests/test_time_spent_auto.py @@ -37,7 +37,7 @@ class TimeSpentAutoTestCase(TestCase): ) def test_add_two_followups_time_spent_auto(self): - """Tests automatic time_spent calculation""" + """Tests automatic time_spent calculation.""" # activate automatic calculation helpdesk_settings.FOLLOWUP_TIME_SPENT_AUTO = True helpdesk_settings.USE_TZ = True @@ -102,7 +102,8 @@ class TimeSpentAutoTestCase(TestCase): def test_followup_time_spent_auto_opening_hours(self): - """Tests automatic time_spent calculation""" + """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 = { @@ -179,3 +180,42 @@ class TimeSpentAutoTestCase(TestCase): self.assertEqual(followup1.time_spent.total_seconds(), assertion_delta.total_seconds()) self.assertEqual(ticket.time_spent.total_seconds(), assertion_delta.total_seconds()) + + + 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 = () \ No newline at end of file From c16d1891042511684a406ef082c0e731a40ee283 Mon Sep 17 00:00:00 2001 From: Sam Splunks <72095718+samsplunks@users.noreply.github.com> Date: Wed, 27 Mar 2024 16:19:33 +0000 Subject: [PATCH 12/15] Testing queues exclusion --- helpdesk/tests/test_time_spent_auto.py | 41 +++++++++++++++++++++++++- 1 file changed, 40 insertions(+), 1 deletion(-) diff --git a/helpdesk/tests/test_time_spent_auto.py b/helpdesk/tests/test_time_spent_auto.py index 9ad84d67..ee01d7fc 100644 --- a/helpdesk/tests/test_time_spent_auto.py +++ b/helpdesk/tests/test_time_spent_auto.py @@ -218,4 +218,43 @@ class TimeSpentAutoTestCase(TestCase): self.assertEqual(ticket.time_spent.total_seconds(), 0.0) # Remove status exclusion - helpdesk_settings.FOLLOWUP_TIME_SPENT_EXCLUDE_STATUSES = () \ No newline at end of file + 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 = () \ No newline at end of file From 57ad29f46bf5804dbe15d0716e97d32ae2d82ce3 Mon Sep 17 00:00:00 2001 From: Sam Splunks <72095718+samsplunks@users.noreply.github.com> Date: Wed, 27 Mar 2024 16:20:22 +0000 Subject: [PATCH 13/15] Removed useless setting --- helpdesk/tests/test_time_spent_auto.py | 1 - 1 file changed, 1 deletion(-) diff --git a/helpdesk/tests/test_time_spent_auto.py b/helpdesk/tests/test_time_spent_auto.py index ee01d7fc..cd534910 100644 --- a/helpdesk/tests/test_time_spent_auto.py +++ b/helpdesk/tests/test_time_spent_auto.py @@ -40,7 +40,6 @@ class TimeSpentAutoTestCase(TestCase): """Tests automatic time_spent calculation.""" # activate automatic calculation helpdesk_settings.FOLLOWUP_TIME_SPENT_AUTO = True - helpdesk_settings.USE_TZ = True # ticket creation date, follow-up creation date, assertion value TEST_VALUES = ( From f5bff3af4e50f738d4f1b90e0e22a04efc84f281 Mon Sep 17 00:00:00 2001 From: Sam Splunks <72095718+samsplunks@users.noreply.github.com> Date: Wed, 27 Mar 2024 16:22:14 +0000 Subject: [PATCH 14/15] Clearing some settings at the end of test --- helpdesk/tests/test_time_spent_auto.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/helpdesk/tests/test_time_spent_auto.py b/helpdesk/tests/test_time_spent_auto.py index cd534910..6658b675 100644 --- a/helpdesk/tests/test_time_spent_auto.py +++ b/helpdesk/tests/test_time_spent_auto.py @@ -40,6 +40,7 @@ class TimeSpentAutoTestCase(TestCase): """Tests automatic time_spent calculation.""" # activate automatic calculation helpdesk_settings.FOLLOWUP_TIME_SPENT_AUTO = True + helpdesk_settings.USE_TZ = True # ticket creation date, follow-up creation date, assertion value TEST_VALUES = ( @@ -180,6 +181,9 @@ class TimeSpentAutoTestCase(TestCase): 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.""" From b99514f5855faebcf3f64c036db4335b4789b64f Mon Sep 17 00:00:00 2001 From: Sam Splunks <72095718+samsplunks@users.noreply.github.com> Date: Wed, 27 Mar 2024 16:27:32 +0000 Subject: [PATCH 15/15] Removed useless USE_TZ --- helpdesk/tests/test_time_spent_auto.py | 1 - 1 file changed, 1 deletion(-) diff --git a/helpdesk/tests/test_time_spent_auto.py b/helpdesk/tests/test_time_spent_auto.py index 6658b675..d40d2800 100644 --- a/helpdesk/tests/test_time_spent_auto.py +++ b/helpdesk/tests/test_time_spent_auto.py @@ -40,7 +40,6 @@ class TimeSpentAutoTestCase(TestCase): """Tests automatic time_spent calculation.""" # activate automatic calculation helpdesk_settings.FOLLOWUP_TIME_SPENT_AUTO = True - helpdesk_settings.USE_TZ = True # ticket creation date, follow-up creation date, assertion value TEST_VALUES = (