-
Notifications
You must be signed in to change notification settings - Fork 2
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
10 changed files
with
247 additions
and
237 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file was deleted.
Oops, something went wrong.
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,153 @@ | ||
import email.mime.multipart | ||
from unittest import mock | ||
|
||
import pytest | ||
from django.test import TestCase, override_settings | ||
from django.core.cache import cache | ||
from celery.exceptions import Retry | ||
|
||
from django.conf import settings | ||
from mail.celery_tasks import manage_inbox, notify_users_of_rejected_licences | ||
import email.mime.multipart | ||
from mail.libraries.email_message_dto import EmailMessageDto | ||
from mail.celery_tasks import send_smtp_task | ||
from mail.celery_tasks import get_lite_api_url | ||
|
||
|
||
class NotifyUsersOfRejectedMailTests(TestCase): | ||
@override_settings(EMAIL_USER="[email protected]", NOTIFY_USERS=["[email protected]"]) # /PS-IGNORE | ||
@mock.patch("mail.celery_tasks.send_smtp_task") | ||
def test_send_success(self, mock_send): | ||
notify_users_of_rejected_licences("123", "CHIEF_SPIRE_licenceReply_202401180900_42557") | ||
mock_send.assert_called_once() | ||
|
||
self.assertEqual(len(mock_send.call_args_list), 1) | ||
message = mock_send.call_args[0][0] | ||
self.assertIsInstance(message, email.mime.multipart.MIMEMultipart) | ||
|
||
expected_headers = { | ||
"Content-Type": "multipart/mixed", | ||
"MIME-Version": "1.0", | ||
"From": "[email protected]", # /PS-IGNORE | ||
"To": "[email protected]", # /PS-IGNORE | ||
"Subject": "Licence rejected by HMRC", | ||
} | ||
self.assertDictEqual(dict(message), expected_headers) | ||
|
||
text_payload = message.get_payload(0) | ||
expected_body = "Mail (Id: 123) with subject CHIEF_SPIRE_licenceReply_202401180900_42557 has rejected licences" | ||
self.assertEqual(text_payload.get_payload(), expected_body) | ||
|
||
|
||
class ManageInboxTests(TestCase): | ||
@mock.patch("mail.celery_tasks.check_and_route_emails") | ||
def test_manage_inbox(self, mock_function): | ||
manage_inbox() | ||
mock_function.assert_called_once() | ||
|
||
@mock.patch("mail.celery_tasks.check_and_route_emails") | ||
def test_error_manage_inbox(self, mock_function): | ||
mock_function.side_effect = Exception("Test Error") | ||
with pytest.raises(Exception) as excinfo: | ||
manage_inbox() | ||
assert str(excinfo.value) == "Test Error" | ||
|
||
|
||
class GetLiteAPIUrlTests(TestCase): | ||
def test_get_url_with_no_path(self): | ||
with self.settings(LITE_API_URL="https://example.com"): | ||
result = get_lite_api_url() | ||
|
||
self.assertEqual(result, "https://example.com/licences/hmrc-integration/") | ||
|
||
def test_get_url_with_root_path(self): | ||
with self.settings(LITE_API_URL="https://example.com/"): | ||
result = get_lite_api_url() | ||
|
||
self.assertEqual(result, "https://example.com/licences/hmrc-integration/") | ||
|
||
def test_get_url_with_path_from_setting(self): | ||
with self.settings(LITE_API_URL="https://example.com/foo"): | ||
result = get_lite_api_url() | ||
|
||
self.assertEqual(result, "https://example.com/foo") | ||
|
||
|
||
class SendEmailTaskTests(TestCase): | ||
def setUp(self): | ||
attachment = "30 \U0001d5c4\U0001d5c6/\U0001d5c1 \u5317\u4EB0" | ||
self.email_message_dto = EmailMessageDto( | ||
run_number=1, | ||
sender=settings.HMRC_ADDRESS, | ||
receiver=settings.SPIRE_ADDRESS, | ||
date="Mon, 17 May 2021 14:20:18 +0100", | ||
body=None, | ||
subject="Some subject", | ||
attachment=["some filename", attachment], | ||
raw_data="", | ||
) | ||
|
||
@mock.patch("mail.celery_tasks.smtp_send") | ||
@mock.patch("mail.celery_tasks.cache") | ||
def test_locking_prevents_multiple_executions(self, mock_cache, mock_smtp_send): | ||
mock_cache.add.side_effect = [True, False] # First call acquires the lock, second call finds it locked | ||
|
||
# Simulate the lock being released after the first task finishes | ||
mock_cache.delete.return_value = None | ||
|
||
try: | ||
send_smtp_task(self.email_message_dto) | ||
except Retry: | ||
self.fail("First task execution should not raise Retry.") | ||
|
||
with self.assertRaises(Retry): | ||
send_smtp_task(self.email_message_dto) | ||
|
||
# Assert smtp_send was called once due to locking | ||
mock_smtp_send.assert_called_once() | ||
# After locked and being released | ||
self.assertEqual(mock_cache.add.call_count, 2) | ||
mock_cache.delete.assert_called_once_with("global_send_email_lock") | ||
|
||
@mock.patch("mail.celery_tasks.send_smtp_task.retry", side_effect=Retry) | ||
@mock.patch("mail.celery_tasks.smtp_send") | ||
@mock.patch("mail.celery_tasks.cache") | ||
def test_retry_on_lock_failure(self, mock_cache, mock_smtp_send, mock_retry): | ||
mock_cache.add.return_value = False | ||
mock_smtp_send.return_value = None | ||
|
||
with self.assertRaises(Retry): | ||
send_smtp_task(self.email_message_dto) | ||
|
||
mock_retry.assert_called_once() | ||
|
||
retry_call_args = mock_retry.call_args | ||
self.assertIn("countdown", retry_call_args[1]) | ||
retry_delay = retry_call_args[1]["countdown"] | ||
self.assertEqual(retry_delay, 180) | ||
|
||
|
||
class NotifyUsersOfRejectedMailTests(TestCase): | ||
@override_settings(EMAIL_USER="[email protected]", NOTIFY_USERS=["[email protected]"]) # /PS-IGNORE | ||
@mock.patch("mail.celery_tasks.smtp_send") | ||
def test_send_success(self, mock_send): | ||
notify_users_of_rejected_licences("123", "CHIEF_SPIRE_licenceReply_202401180900_42557") | ||
|
||
mock_send.assert_called_once() | ||
|
||
self.assertEqual(len(mock_send.call_args_list), 1) | ||
message = mock_send.call_args[0][0] | ||
self.assertIsInstance(message, email.mime.multipart.MIMEMultipart) | ||
|
||
expected_headers = { | ||
"Content-Type": "multipart/mixed", | ||
"MIME-Version": "1.0", | ||
"From": "[email protected]", # /PS-IGNORE | ||
"To": "[email protected]", # /PS-IGNORE | ||
"Subject": "Licence rejected by HMRC", | ||
} | ||
self.assertDictEqual(dict(message), expected_headers) | ||
|
||
text_payload = message.get_payload(0) | ||
expected_body = "Mail (Id: 123) with subject CHIEF_SPIRE_licenceReply_202401180900_42557 has rejected licences" | ||
self.assertEqual(text_payload.get_payload(), expected_body) |
Oops, something went wrong.