1+ from unittest import mock
12from unittest .mock import patch
23import time_machine
34from django .core import mail
4- from notifications .tasks import send_pending_emails
5+ from notifications .tasks import send_pending_email
56from notifications .models import SentEmail
67from notifications .tests .factories import SentEmailFactory
78
89
9- def test_send_pending_emails_does_nothing_with_no_pending_emails ():
10- SentEmailFactory (status = SentEmail .Status .sent , sent_at = "2020-01-01 12:00Z" )
11- SentEmailFactory (status = SentEmail .Status .sent , sent_at = "2020-01-01 12:00Z" )
12- SentEmailFactory (status = SentEmail .Status .sent , sent_at = "2020-01-01 12:00Z" )
13- SentEmailFactory (status = SentEmail .Status .sent , sent_at = "2020-01-01 12:00Z" )
10+ def test_send_pending_email_does_nothing_with_non_pending_email ():
11+ sent_email = SentEmailFactory (
12+ status = SentEmail .Status .sent , sent_at = "2020-01-01 12:00Z"
13+ )
1414
15- send_pending_emails ( )
15+ send_pending_email ( sent_email . id )
1616
1717 assert len (mail .outbox ) == 0
1818
1919
20- def test_send_pending_emails_task_sends_data_correctly ():
20+ def test_send_pending_email_task_sends_data_correctly ():
2121 pending_email_1 = SentEmailFactory (
2222 status = SentEmail .Status .pending ,
2323@@ -29,7 +29,8 @@ def test_send_pending_emails_task_sends_data_correctly():
2929 subject = "subject" ,
3030 )
3131
32- send_pending_emails ()
32+ with time_machine .travel ("2021-01-01 12:00Z" , tick = False ):
33+ send_pending_email (pending_email_1 .id )
3334
3435 assert len (mail .outbox ) == 1
3536
@@ -42,8 +43,16 @@ def test_send_pending_emails_task_sends_data_correctly():
4243 assert mail .outbox [0 ].alternatives == [("html body" , "text/html" )]
4344 assert mail .outbox [0 ].subject == "subject"
4445
46+ pending_email_1 .refresh_from_db ()
47+
48+ assert len (mail .outbox ) == 1
49+
50+ assert pending_email_1 .status == SentEmail .Status .sent
51+ assert pending_email_1 .message_id .startswith ("local-" )
52+ assert pending_email_1 .sent_at .isoformat () == "2021-01-01T12:00:00+00:00"
4553
46- def test_send_pending_emails_task_doesnt_double_send ():
54+
55+ def test_send_pending_email_task_doesnt_double_send ():
4756 pending_email_1 = SentEmailFactory (status = SentEmail .Status .pending )
4857 original_qs = SentEmail .objects .select_for_update (skip_locked = True ).filter (
4958 id = pending_email_1 .id
@@ -57,52 +66,17 @@ def side_effect(*args, **kwargs):
5766 "notifications.tasks.SentEmail.objects.select_for_update" ,
5867 side_effect = side_effect ,
5968 ):
60- send_pending_emails ( )
69+ send_pending_email ( pending_email_1 . id )
6170
6271 pending_email_1 .refresh_from_db ()
6372
6473 assert len (mail .outbox ) == 0
6574
6675
67- def test_send_pending_emails_task ():
68- pending_email_1 = SentEmailFactory (status = SentEmail .Status .pending )
69- pending_email_2 = SentEmailFactory (status = SentEmail .Status .pending )
70- sent_email_1 = SentEmailFactory (
71- status = SentEmail .Status .sent , message_id = "abc-abc" , sent_at = "2020-01-01 12:00Z"
72- )
73-
74- with time_machine .travel ("2021-01-01 12:00Z" , tick = False ):
75- send_pending_emails ()
76-
77- pending_email_1 .refresh_from_db ()
78- pending_email_2 .refresh_from_db ()
79- sent_email_1 .refresh_from_db ()
80-
81- assert len (mail .outbox ) == 2
82-
83- assert mail .outbox [0 ].to == [pending_email_1 .recipient_email ]
84- assert mail .outbox [1 ].to == [pending_email_2 .recipient_email ]
85-
86- assert pending_email_1 .status == SentEmail .Status .sent
87- assert pending_email_1 .message_id .startswith ("local-" )
88- assert pending_email_1 .sent_at .isoformat () == "2021-01-01T12:00:00+00:00"
89-
90- assert pending_email_2 .status == SentEmail .Status .sent
91- assert pending_email_2 .message_id .startswith ("local-" )
92- assert pending_email_2 .sent_at .isoformat () == "2021-01-01T12:00:00+00:00"
93-
94- assert sent_email_1 .status == SentEmail .Status .sent
95- assert sent_email_1 .message_id == "abc-abc"
96- assert sent_email_1 .sent_at .isoformat () == "2020-01-01T12:00:00+00:00"
97-
98-
99- def test_send_pending_emails_handles_failures (mocker ):
76+ def test_send_pending_email_handles_failures (mocker ):
10077 pending_email_1 = SentEmailFactory (
10178 status = SentEmail .Status .pending , created = "2020-01-01 12:00Z"
10279 )
103- pending_email_2 = SentEmailFactory (
104- status = SentEmail .Status .pending , created = "2020-01-02 12:00Z"
105- )
10680
10781 original_method = SentEmail .mark_as_sent
10882
@@ -111,27 +85,19 @@ def _side_effect(*args, **kwargs):
11185 _side_effect .counter = 1
11286 raise ValueError ("test" )
11387
114- return original_method (pending_email_2 , * args , ** kwargs )
88+ return original_method (pending_email_1 , * args , ** kwargs )
11589
11690 _side_effect .counter = 0
11791
11892 mocker .patch ("notifications.tasks.SentEmail.mark_as_sent" , side_effect = _side_effect )
11993
120- with time_machine .travel ("2021-01-01 12:00Z" , tick = False ):
121- send_pending_emails ()
94+ with time_machine .travel ("2021-01-01 12:00Z" , tick = False ), mock .patch (
95+ "celery.app.task.Task.request"
96+ ) as mock_task_request :
97+ mock_task_request .retries = 10
98+ send_pending_email (pending_email_1 .id )
12299
123100 pending_email_1 .refresh_from_db ()
124- pending_email_2 .refresh_from_db ()
125-
126- assert len (mail .outbox ) == 2
127-
128- assert mail .outbox [0 ].to == [pending_email_1 .recipient_email ]
129- assert mail .outbox [1 ].to == [pending_email_2 .recipient_email ]
130101
102+ assert len (mail .outbox ) == 0
131103 assert pending_email_1 .status == SentEmail .Status .failed
132- assert pending_email_1 .message_id == ""
133- assert pending_email_1 .sent_at is None
134-
135- assert pending_email_2 .status == SentEmail .Status .sent
136- assert pending_email_2 .message_id .startswith ("local-" )
137- assert pending_email_2 .sent_at .isoformat () == "2021-01-01T12:00:00+00:00"
0 commit comments