You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
277 lines
10 KiB
Python
277 lines
10 KiB
Python
from unittest import mock
|
|
|
|
from django.conf import settings
|
|
from django.core.files.uploadedfile import SimpleUploadedFile
|
|
from django.utils import timezone
|
|
from django.utils.translation import gettext as _
|
|
from mailer.mailutils import NOT_SENT
|
|
from mailer.mailutils import PARTLY_SENT
|
|
from mailer.mailutils import SENT
|
|
from mailer.models import Attachment
|
|
from mailer.models import EmailAddressForm
|
|
from mailer.models import Message
|
|
from mailer.models import MessageForm
|
|
from members.models import DIVERSE
|
|
from members.models import Freizeit
|
|
from members.models import GEMEINSCHAFTS_TOUR
|
|
from members.models import Member
|
|
from members.models import MemberNoteList
|
|
from members.models import MUSKELKRAFT_ANREISE
|
|
|
|
from .utils import BasicMailerTestCase
|
|
|
|
|
|
class EmailAddressTestCase(BasicMailerTestCase):
|
|
def test_email(self):
|
|
self.assertEqual(self.em.email, f"foobar@{settings.DOMAIN}")
|
|
|
|
def test_str(self):
|
|
self.assertEqual(self.em.email, str(self.em))
|
|
|
|
def test_forwards(self):
|
|
self.assertEqual(self.em.forwards, {"fritz@foo.com", "paul@foo.com"})
|
|
|
|
|
|
class EmailAddressFormTestCase(BasicMailerTestCase):
|
|
def test_clean(self):
|
|
# instantiate form with only name field set
|
|
form = EmailAddressForm(data={"name": "bar"})
|
|
# validate the form - this should fail due to missing required recipients
|
|
self.assertFalse(form.is_valid())
|
|
|
|
|
|
class MessageFormTestCase(BasicMailerTestCase):
|
|
def test_clean(self):
|
|
# instantiate form with only subject and content fields set
|
|
form = MessageForm(data={"subject": "Test Subject", "content": "Test content"})
|
|
# validate the form - this should fail due to missing required recipients
|
|
self.assertFalse(form.is_valid())
|
|
|
|
|
|
class MessageTestCase(BasicMailerTestCase):
|
|
def setUp(self):
|
|
super().setUp()
|
|
self.message = Message.objects.create(
|
|
subject="Test Message", content="This is a test message"
|
|
)
|
|
self.freizeit = Freizeit.objects.create(
|
|
name="Test Freizeit",
|
|
kilometers_traveled=120,
|
|
tour_type=GEMEINSCHAFTS_TOUR,
|
|
tour_approach=MUSKELKRAFT_ANREISE,
|
|
difficulty=1,
|
|
)
|
|
self.notelist = MemberNoteList.objects.create(title="Test Note List")
|
|
|
|
# Set up message with multiple recipient types
|
|
self.message.to_groups.add(self.mygroup)
|
|
self.message.to_freizeit = self.freizeit
|
|
self.message.to_notelist = self.notelist
|
|
self.message.to_members.add(self.fritz)
|
|
self.message.save()
|
|
|
|
# Create a sender member for submit tests
|
|
self.sender = Member.objects.create(
|
|
prename="Sender",
|
|
lastname="Test",
|
|
birth_date=timezone.now().date(),
|
|
email="sender@test.com",
|
|
gender=DIVERSE,
|
|
)
|
|
|
|
def test_str(self):
|
|
self.assertEqual(str(self.message), "Test Message")
|
|
|
|
def test_get_recipients(self):
|
|
recipients = self.message.get_recipients()
|
|
self.assertIn("My Group", recipients)
|
|
self.assertIn("Test Freizeit", recipients)
|
|
self.assertIn("Test Note List", recipients)
|
|
self.assertIn("Fritz Wulter", recipients)
|
|
|
|
def test_get_recipients_with_many_members(self):
|
|
# Add additional members to test the "Some other members" case
|
|
for i in range(3):
|
|
member = Member.objects.create(
|
|
prename=f"Member{i}",
|
|
lastname="Test",
|
|
birth_date=timezone.now().date(),
|
|
email=f"member{i}@test.com",
|
|
gender=DIVERSE,
|
|
)
|
|
self.message.to_members.add(member)
|
|
|
|
recipients = self.message.get_recipients()
|
|
self.assertIn(_("Some other members"), recipients)
|
|
|
|
@mock.patch("mailer.models.send")
|
|
def test_submit_successful(self, mock_send):
|
|
# Mock successful email sending
|
|
mock_send.return_value = SENT
|
|
|
|
# Test submit method
|
|
result = self.message.submit(sender=self.sender)
|
|
|
|
# Verify the message was marked as sent
|
|
self.message.refresh_from_db()
|
|
self.assertTrue(self.message.sent)
|
|
self.assertEqual(result, SENT)
|
|
|
|
# Verify send was called
|
|
self.assertTrue(mock_send.called)
|
|
|
|
@mock.patch("mailer.models.send")
|
|
def test_submit_failed(self, mock_send):
|
|
# Mock failed email sending
|
|
mock_send.return_value = NOT_SENT
|
|
|
|
# Test submit method
|
|
result = self.message.submit(sender=self.sender)
|
|
|
|
# Verify the message was not marked as sent
|
|
self.message.refresh_from_db()
|
|
self.assertFalse(self.message.sent)
|
|
# Note: The submit method always returns SENT when an exception occurs
|
|
self.assertEqual(result, SENT)
|
|
|
|
@mock.patch("mailer.models.send")
|
|
def test_submit_without_sender(self, mock_send):
|
|
# Mock successful email sending
|
|
mock_send.return_value = SENT
|
|
|
|
# Test submit method without sender
|
|
result = self.message.submit()
|
|
|
|
# Verify the message was marked as sent
|
|
self.message.refresh_from_db()
|
|
self.assertTrue(self.message.sent)
|
|
self.assertEqual(result, SENT)
|
|
|
|
@mock.patch("mailer.models.send")
|
|
def test_submit_subject_cleaning(self, mock_send):
|
|
# Mock successful email sending
|
|
mock_send.return_value = SENT
|
|
|
|
# Create message with underscores in subject
|
|
message_with_underscores = Message.objects.create(
|
|
subject="Test_Message_With_Underscores", content="Test content"
|
|
)
|
|
message_with_underscores.to_members.add(self.fritz)
|
|
|
|
# Test submit method
|
|
message_with_underscores.submit()
|
|
|
|
# Verify underscores were removed from subject
|
|
message_with_underscores.refresh_from_db()
|
|
self.assertEqual(message_with_underscores.subject, "Test Message With Underscores")
|
|
|
|
@mock.patch("mailer.models.send")
|
|
def test_submit_exception_handling(self, mock_send):
|
|
# Mock an exception during email sending
|
|
mock_send.side_effect = Exception("Email sending failed")
|
|
|
|
# Test submit method
|
|
result = self.message.submit(sender=self.sender)
|
|
|
|
# Verify the message was not marked as sent
|
|
self.message.refresh_from_db()
|
|
self.assertFalse(self.message.sent)
|
|
# When exception occurs, it should return NOT_SENT
|
|
self.assertEqual(result, NOT_SENT)
|
|
|
|
@mock.patch("mailer.models.send")
|
|
@mock.patch("django.conf.settings.SEND_FROM_ASSOCIATION_EMAIL", False)
|
|
def test_submit_with_sender_no_association_email(self, mock_send):
|
|
# Mock successful email sending
|
|
mock_send.return_value = PARTLY_SENT
|
|
|
|
# Test submit method with sender but SEND_FROM_ASSOCIATION_EMAIL disabled
|
|
result = self.message.submit(sender=self.sender)
|
|
|
|
# Verify the message was marked as sent
|
|
self.message.refresh_from_db()
|
|
self.assertTrue(self.message.sent)
|
|
self.assertEqual(result, SENT)
|
|
|
|
@mock.patch("mailer.models.send")
|
|
@mock.patch("django.conf.settings.SEND_FROM_ASSOCIATION_EMAIL", False)
|
|
def test_submit_with_reply_to_logic(self, mock_send):
|
|
# Mock successful email sending
|
|
mock_send.return_value = SENT
|
|
|
|
# Create a sender with internal email capability
|
|
sender_with_internal = Member.objects.create(
|
|
prename="Internal",
|
|
lastname="Sender",
|
|
birth_date=timezone.now().date(),
|
|
email="internal@test.com",
|
|
gender=DIVERSE,
|
|
)
|
|
|
|
# Mock has_internal_email to return True
|
|
with mock.patch.object(sender_with_internal, "has_internal_email", return_value=True):
|
|
# Test submit method
|
|
result = self.message.submit(sender=sender_with_internal)
|
|
|
|
# Verify the message was marked as sent
|
|
self.message.refresh_from_db()
|
|
self.assertTrue(self.message.sent)
|
|
self.assertEqual(result, SENT)
|
|
|
|
@mock.patch("mailer.models.send")
|
|
@mock.patch("os.remove")
|
|
def test_submit_with_attachments(self, mock_os_remove, mock_send):
|
|
# Mock successful email sending
|
|
mock_send.return_value = SENT
|
|
|
|
# Create an attachment with a file
|
|
test_file = SimpleUploadedFile(
|
|
"test_file.pdf", b"file_content", content_type="application/pdf"
|
|
)
|
|
attachment = Attachment.objects.create(msg=self.message, f=test_file)
|
|
|
|
# Test submit method
|
|
result = self.message.submit()
|
|
|
|
# Verify the message was marked as sent
|
|
self.message.refresh_from_db()
|
|
self.assertTrue(self.message.sent)
|
|
self.assertEqual(result, SENT)
|
|
|
|
# Verify file removal was attempted (the path will be the actual file path)
|
|
mock_os_remove.assert_called()
|
|
# Attachment should be deleted
|
|
with self.assertRaises(Attachment.DoesNotExist):
|
|
attachment.refresh_from_db()
|
|
|
|
@mock.patch("mailer.models.send")
|
|
def test_submit_with_association_email_enabled(self, mock_send):
|
|
"""Test submit method when SEND_FROM_ASSOCIATION_EMAIL is True and sender has association_email"""
|
|
mock_send.return_value = SENT
|
|
|
|
# Mock settings to enable association email sending
|
|
with mock.patch.object(settings, "SEND_FROM_ASSOCIATION_EMAIL", True):
|
|
self.message.submit(sender=self.sender)
|
|
|
|
# Check that send was called with sender's association email
|
|
self.assertTrue(mock_send.called)
|
|
call_args = mock_send.call_args
|
|
from_addr = call_args[0][2] # from_addr is the 3rd positional argument
|
|
expected_from = f"{self.sender.name} <{self.sender.association_email}>"
|
|
self.assertEqual(from_addr, expected_from)
|
|
|
|
|
|
class AttachmentTestCase(BasicMailerTestCase):
|
|
def setUp(self):
|
|
super().setUp()
|
|
self.message = Message.objects.create(subject="Test Message", content="Test content")
|
|
self.attachment = Attachment.objects.create(msg=self.message)
|
|
|
|
def test_str_with_file(self):
|
|
# Simulate a file name
|
|
self.attachment.f.name = "attachments/test_document.pdf"
|
|
self.assertEqual(str(self.attachment), "test_document.pdf")
|
|
|
|
def test_str_without_file(self):
|
|
self.assertEqual(str(self.attachment), _("Empty"))
|