django-helpdesk/helpdesk/tests/test_attachments.py
2025-03-22 15:29:19 -10:00

177 lines
6.6 KiB
Python

# vim: set fileencoding=utf-8 :
from django.core.files.uploadedfile import SimpleUploadedFile
from django.test import override_settings, TestCase
from django.urls import reverse
from django.utils.encoding import smart_str
from helpdesk import lib, models
import os
import shutil
from tempfile import gettempdir
from unittest import mock
from unittest.case import skip
MEDIA_DIR = os.path.join(gettempdir(), "helpdesk_test_media")
@override_settings(MEDIA_ROOT=MEDIA_DIR)
class AttachmentIntegrationTests(TestCase):
fixtures = ["emailtemplate.json"]
def setUp(self):
self.queue_public = models.Queue.objects.create(
title="Public Queue",
slug="pub_q",
allow_public_submission=True,
new_ticket_cc="new.public@example.com",
updated_ticket_cc="update.public@example.com",
)
self.queue_private = models.Queue.objects.create(
title="Private Queue",
slug="priv_q",
allow_public_submission=False,
new_ticket_cc="new.private@example.com",
updated_ticket_cc="update.private@example.com",
)
self.ticket_data = {
"title": "Test Ticket Title",
"body": "Test Ticket Desc",
"priority": 3,
"submitter_email": "submitter@example.com",
}
def test_create_pub_ticket_with_attachment(self):
test_file = SimpleUploadedFile(
"test_att.txt", b"attached file content", "text/plain"
)
post_data = self.ticket_data.copy()
post_data.update(
{
"queue": self.queue_public.id,
"attachment": test_file,
}
)
# Ensure ticket form submits with attachment successfully
response = self.client.post(reverse("helpdesk:home"), post_data, follow=True)
self.assertContains(response, test_file.name)
# Ensure attachment is available with correct content
att = models.FollowUpAttachment.objects.get(
followup__ticket=response.context["ticket"]
)
with open(os.path.join(MEDIA_DIR, att.file.name)) as file_on_disk:
disk_content = file_on_disk.read()
self.assertEqual(disk_content, "attached file content")
def test_create_pub_ticket_with_attachment_utf8(self):
test_file = SimpleUploadedFile("ß°äöü.txt", "โจ".encode("utf-8"), "text/utf-8")
post_data = self.ticket_data.copy()
post_data.update(
{
"queue": self.queue_public.id,
"attachment": test_file,
}
)
# Ensure ticket form submits with attachment successfully
response = self.client.post(reverse("helpdesk:home"), post_data, follow=True)
self.assertContains(response, test_file.name)
# Ensure attachment is available with correct content
att = models.FollowUpAttachment.objects.get(
followup__ticket=response.context["ticket"]
)
with open(
os.path.join(MEDIA_DIR, att.file.name), encoding="utf-8"
) as file_on_disk:
disk_content = smart_str(file_on_disk.read(), "utf-8")
self.assertEqual(disk_content, "โจ")
@mock.patch.object(models.FollowUp, "save", autospec=True)
@mock.patch.object(models.FollowUpAttachment, "save", autospec=True)
@mock.patch.object(models.Ticket, "save", autospec=True)
@mock.patch.object(models.Queue, "save", autospec=True)
class AttachmentUnitTests(TestCase):
def setUp(self):
self.file_attrs = {
"filename": "°ßäöü.txt",
"content": "โจ".encode("utf-8"),
"content-type": "text/utf8",
}
self.test_file = SimpleUploadedFile.from_dict(self.file_attrs)
self.follow_up = models.FollowUp.objects.create(
ticket=models.Ticket.objects.create(queue=models.Queue.objects.create())
)
@skip("Rework with model relocation")
def test_unicode_attachment_filename(
self, mock_att_save, mock_queue_save, mock_ticket_save, mock_follow_up_save
):
"""check utf-8 data is parsed correctly"""
filename, fileobj = lib.process_attachments(self.follow_up, [self.test_file])[0]
mock_att_save.assert_called_with(
file=self.test_file,
filename=self.file_attrs["filename"],
mime_type=self.file_attrs["content-type"],
size=len(self.file_attrs["content"]),
followup=self.follow_up,
)
self.assertEqual(filename, self.file_attrs["filename"])
def test_autofill(
self, mock_att_save, mock_queue_save, mock_ticket_save, mock_follow_up_save
):
"""check utf-8 data is parsed correctly"""
obj = models.FollowUpAttachment.objects.create(
followup=self.follow_up, file=self.test_file
)
obj.save()
self.assertEqual(obj.file.name, self.file_attrs["filename"])
self.assertEqual(obj.file.size, len(self.file_attrs["content"]))
self.assertEqual(obj.file.file.content_type, "text/utf8")
def test_kbi_attachment(
self, mock_att_save, mock_queue_save, mock_ticket_save, mock_follow_up_save
):
"""check utf-8 data is parsed correctly"""
kbcategory = models.KBCategory.objects.create(
title="Title", slug="slug", description="Description"
)
kbitem = models.KBItem.objects.create(
category=kbcategory, title="Title", question="Question", answer="Answer"
)
obj = models.KBIAttachment.objects.create(kbitem=kbitem, file=self.test_file)
obj.save()
self.assertEqual(obj.filename, self.file_attrs["filename"])
self.assertEqual(obj.file.size, len(self.file_attrs["content"]))
self.assertEqual(obj.mime_type, "text/plain")
@skip("model in lib not patched")
@override_settings(MEDIA_ROOT=MEDIA_DIR)
def test_unicode_filename_to_filesystem(
self, mock_att_save, mock_queue_save, mock_ticket_save, mock_follow_up_save
):
"""don't mock saving to filesystem to test file renames caused by storage layer"""
filename, fileobj = lib.process_attachments(self.follow_up, [self.test_file])[0]
# Attachment object was zeroth positional arg (i.e. self) of att.save
# call
attachment_obj = mock_att_save.return_value
mock_att_save.assert_called_once_with(attachment_obj)
self.assertIsInstance(attachment_obj, models.FollowUpAttachment)
self.assertEqual(attachment_obj.filename, self.file_attrs["filename"])
def tearDownModule():
try:
shutil.rmtree(MEDIA_DIR)
except OSError:
pass