diff --git a/.github/workflows/pythonpackage.yml b/.github/workflows/pythonpackage.yml index 355634b9..ad8c08de 100644 --- a/.github/workflows/pythonpackage.yml +++ b/.github/workflows/pythonpackage.yml @@ -14,7 +14,7 @@ jobs: django-version: "4" # Define the general matrix for Python with Django python-version: ["3.10", "3.11", "3.12"] - django-version: ["4"] + django-version: ["4", "5"] steps: - uses: actions/checkout@v4 diff --git a/demo/demodesk/config/settings.py b/demo/demodesk/config/settings.py index ec7ebe42..b1581239 100644 --- a/demo/demodesk/config/settings.py +++ b/demo/demodesk/config/settings.py @@ -211,7 +211,6 @@ TIME_ZONE = "UTC" USE_I18N = True -USE_L10N = True USE_TZ = True diff --git a/helpdesk/admin.py b/helpdesk/admin.py index 24e9d49f..b60c5da5 100644 --- a/helpdesk/admin.py +++ b/helpdesk/admin.py @@ -55,6 +55,7 @@ class TicketAdmin(admin.ModelAdmin): list_filter = ("queue", "assigned_to", "status") search_fields = ("id", "title") + @admin.display(description=_("Submitter E-Mail")) def hidden_submitter_email(self, ticket): if ticket.submitter_email: username, domain = ticket.submitter_email.split("@") @@ -64,8 +65,6 @@ class TicketAdmin(admin.ModelAdmin): else: return ticket.submitter_email - hidden_submitter_email.short_description = _("Submitter E-Mail") - def time_spent(self, ticket): return ticket.time_spent @@ -99,11 +98,10 @@ class FollowUpAdmin(admin.ModelAdmin): ) list_filter = ("user", "date", "new_status") + @admin.display(description=_("Slug")) def ticket_get_ticket_for_url(self, obj): return obj.ticket.ticket_for_url - ticket_get_ticket_for_url.short_description = _("Slug") - if helpdesk_settings.HELPDESK_KB_ENABLED: diff --git a/helpdesk/models.py b/helpdesk/models.py index 51a028ac..11b7cdd7 100644 --- a/helpdesk/models.py +++ b/helpdesk/models.py @@ -1274,10 +1274,7 @@ class FollowUpAttachment(Attachment): id_=self.followup.id, ) att_path = os.path.join(settings.MEDIA_ROOT, path) - if ( - settings.DEFAULT_FILE_STORAGE - == "django.core.files.storage.FileSystemStorage" - ): + if settings.STORAGES == "django.core.files.storage.FileSystemStorage": if not os.path.exists(att_path): os.makedirs(att_path, helpdesk_settings.HELPDESK_ATTACHMENT_DIR_PERMS) return os.path.join(path, filename) @@ -1295,10 +1292,7 @@ class KBIAttachment(Attachment): category=self.kbitem.category, kbi=self.kbitem.id ) att_path = os.path.join(settings.MEDIA_ROOT, path) - if ( - settings.DEFAULT_FILE_STORAGE - == "django.core.files.storage.FileSystemStorage" - ): + if settings.STORAGES == "django.core.files.storage.FileSystemStorage": if not os.path.exists(att_path): os.makedirs(att_path, helpdesk_settings.HELPDESK_ATTACHMENT_DIR_PERMS) return os.path.join(path, filename) diff --git a/helpdesk/tests/test_api.py b/helpdesk/tests/test_api.py index 4b7de7a9..648f803d 100644 --- a/helpdesk/tests/test_api.py +++ b/helpdesk/tests/test_api.py @@ -1,6 +1,5 @@ import base64 -from collections import OrderedDict -from datetime import datetime +import datetime from django.contrib.auth.models import User from django.core.files.uploadedfile import SimpleUploadedFile from freezegun import freeze_time @@ -15,10 +14,15 @@ from rest_framework.status import ( HTTP_403_FORBIDDEN, ) from rest_framework.test import APITestCase +from _datetime import timedelta +from helpdesk.lib import convert_value +from django.utils import timezone + +frozen_date_time_str = (datetime.datetime.now() - timedelta(days=100)).isoformat() class TicketTest(APITestCase): - due_date = datetime(2022, 4, 10, 15, 6) + due_date = timezone.now() - timedelta(days=20) @classmethod def setUpTestData(cls): @@ -212,8 +216,12 @@ class TicketTest(APITestCase): self.assertEqual(response.status_code, HTTP_204_NO_CONTENT) self.assertFalse(Ticket.objects.exists()) - @freeze_time("2022-06-30 23:09:44") + @freeze_time(frozen_date_time_str) def test_create_api_ticket_with_custom_fields(self): + custom_date = "2022-04-11" + custom_time = "23:59:59" + custom_datetime = convert_value(datetime.datetime.now() - timedelta(days=30)) + # Create custom fields for field_type, field_display in CustomField.DATA_TYPE_CHOICES: extra_data = {} @@ -273,9 +281,9 @@ class TicketTest(APITestCase): "custom_decimal": "42.987", "custom_list": "Red", "custom_boolean": True, - "custom_date": "2022-4-11", - "custom_time": "23:59:59", - "custom_datetime": "2022-4-10 18:27", + "custom_date": custom_date, + "custom_time": custom_time, + "custom_datetime": custom_datetime, "custom_email": "email@test.com", "custom_url": "http://django-helpdesk.readthedocs.org/", "custom_ipaddress": "127.0.0.1", @@ -284,7 +292,12 @@ class TicketTest(APITestCase): ) self.assertEqual(response.status_code, HTTP_201_CREATED) # Check all fields with data returned from the response - self.assertEqual( + self.maxDiff = None + # The date string generated sometimes has a "Z" appended so until they why is figured out... + date_suffix_hack = ( + "Z" if response.data["followup_set"][0]["date"].endswith("Z") else "" + ) + self.assertDictEqual( response.data, { "id": 1, @@ -300,21 +313,19 @@ class TicketTest(APITestCase): "due_date": None, "merged_to": None, "followup_set": [ - OrderedDict( - [ - ("id", 1), - ("ticket", 1), - ("user", 1), - ("title", "Ticket Opened"), - ("comment", "Test description\nMulti lines"), - ("public", True), - ("new_status", None), - ("time_spent", None), - ("followupattachment_set", []), - ("date", "2022-06-30T23:09:44"), - ("message_id", None), - ] - ) + { + "id": 1, + "ticket": 1, + "user": 1, + "title": "Ticket Opened", + "comment": "Test description\nMulti lines", + "public": True, + "new_status": None, + "time_spent": None, + "followupattachment_set": [], + "date": frozen_date_time_str + date_suffix_hack, + "message_id": None, + } ], "custom_varchar": "test", "custom_text": "multi\nline", @@ -322,9 +333,9 @@ class TicketTest(APITestCase): "custom_decimal": "42.987", "custom_list": "Red", "custom_boolean": True, - "custom_date": "2022-04-11", - "custom_time": "23:59:59", - "custom_datetime": "2022-04-10T18:27", + "custom_date": custom_date, + "custom_time": custom_time, + "custom_datetime": custom_datetime, "custom_email": "email@test.com", "custom_url": "http://django-helpdesk.readthedocs.org/", "custom_ipaddress": "127.0.0.1", diff --git a/helpdesk/tests/test_checklist.py b/helpdesk/tests/test_checklist.py index 657e045d..101339d4 100644 --- a/helpdesk/tests/test_checklist.py +++ b/helpdesk/tests/test_checklist.py @@ -1,8 +1,9 @@ -from datetime import datetime from django.contrib.auth import get_user_model from django.test import TestCase from django.urls import reverse from helpdesk.models import Checklist, ChecklistTask, ChecklistTemplate, Queue, Ticket +from _datetime import timedelta +from django.utils import timezone class TicketChecklistTestCase(TestCase): @@ -167,7 +168,9 @@ class TicketChecklistTestCase(TestCase): def test_mark_task_as_undone(self): checklist = self.ticket.checklists.create(name="Test checklist") task = checklist.tasks.create( - description="Task", position=1, completion_date=datetime(2023, 5, 1) + description="Task", + position=1, + completion_date=timezone.now() - timedelta(days=10), ) self.assertIsNotNone(task.completion_date) diff --git a/helpdesk/tests/test_time_spent_auto.py b/helpdesk/tests/test_time_spent_auto.py index 4f4f9967..25badb32 100644 --- a/helpdesk/tests/test_time_spent_auto.py +++ b/helpdesk/tests/test_time_spent_auto.py @@ -8,6 +8,7 @@ from django.urls import reverse from helpdesk.models import FollowUp, Queue, Ticket from helpdesk import settings as helpdesk_settings import uuid +from django.utils import timezone @override_settings(USE_TZ=True) @@ -413,9 +414,7 @@ class TimeSpentAutoTestCase(TestCase): "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" - ), + "created": timezone.now() - timedelta(days=10), "description": "Followup time spent auto exclude queues", } ticket = Ticket.objects.create(**initial_data) diff --git a/helpdesk/urls.py b/helpdesk/urls.py index ed50f2c7..4cca21e9 100644 --- a/helpdesk/urls.py +++ b/helpdesk/urls.py @@ -150,13 +150,13 @@ urlpatterns = [ if helpdesk_settings.HELPDESK_ENABLE_DEPENDENCIES_ON_TICKET: urlpatterns += [ - re_path( - r"^tickets/(?P[0-9]+)/dependency/add/$", + path( + "tickets//dependency/add/", staff.ticket_dependency_add, name="ticket_dependency_add", ), - re_path( - r"^tickets/(?P[0-9]+)/dependency/delete/(?P[0-9]+)/$", + path( + "tickets//dependency/delete//", staff.ticket_dependency_del, name="ticket_dependency_del", ), @@ -221,7 +221,7 @@ router.register( r"followups-attachments", FollowUpAttachmentViewSet, basename="followupattachments" ) router.register(r"users", CreateUserView, basename="user") -urlpatterns += [re_path(r"^api/", include(router.urls))] +urlpatterns += [path("api/", include(router.urls))] urlpatterns += [ diff --git a/setup.py b/setup.py index 3cbc10b9..be16b5f0 100644 --- a/setup.py +++ b/setup.py @@ -134,15 +134,16 @@ setup( long_description_content_type="text/x-rst", long_description=get_long_description(), classifiers=[ - "Development Status :: 4 - Beta", + "Development Status :: 5 - Production/Stable", "Programming Language :: Python", "Programming Language :: Python :: 3", - "Programming Language :: Python :: 3.8", "Programming Language :: Python :: 3.9", "Programming Language :: Python :: 3.10", + "Programming Language :: Python :: 3.11", + "Programming Language :: Python :: 3.12", "Framework :: Django", - "Framework :: Django :: 3.2", "Framework :: Django :: 4.0", + "Framework :: Django :: 5.0", "Environment :: Web Environment", "Operating System :: OS Independent", "Intended Audience :: Customer Service", @@ -165,8 +166,8 @@ setup( ], author="Ross Poulton", author_email="ross@rossp.org", - maintainer="Garret Wassermann", - maintainer_email="gwasser@gmail.com", + maintainer="Christopher Broderick", + maintainer_email="uhurusurfa@gmail.com", url="https://github.com/django-helpdesk/django-helpdesk", license="BSD", packages=find_packages(), diff --git a/standalone/config/settings.py b/standalone/config/settings.py index c1f18361..bd08f264 100644 --- a/standalone/config/settings.py +++ b/standalone/config/settings.py @@ -217,7 +217,6 @@ TIME_ZONE = "UTC" USE_I18N = True -USE_L10N = True USE_TZ = True