Skip to content

Commit ba4630a

Browse files
committed
Расширены тесты, убран личшний N+1 запрос в БД
1 parent 416f2b7 commit ba4630a

3 files changed

Lines changed: 60 additions & 24 deletions

File tree

mailing/tasks.py

Lines changed: 12 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -35,23 +35,27 @@ def _get_programs_for_scenario(scenario, target_date):
3535
raise ValueError(f"Unsupported trigger: {scenario.trigger}")
3636

3737

38-
def _get_recipients(scenario, program_id: int, target_date):
38+
def _get_recipients(scenario, program, target_date):
3939
match scenario.recipient_rule:
4040
case RecipientRule.ALL_PARTICIPANTS:
41-
return program_participants(program_id)
41+
return program_participants(program.id)
4242
case RecipientRule.NO_PROJECT_IN_PROGRAM:
43-
return program_participants_without_project(program_id)
43+
return program_participants_without_project(program.id)
4444
case RecipientRule.NO_PROJECT_IN_PROGRAM_REGISTERED_ON_DATE:
4545
return program_participants_without_project_registered_on(
46-
program_id, target_date
46+
program.id, target_date
4747
)
4848
case RecipientRule.PROJECT_NOT_SUBMITTED:
49-
return program_participants_with_unsubmitted_project(program_id)
49+
return program_participants_with_unsubmitted_project(program.id)
5050
case RecipientRule.INACTIVE_ACCOUNT_IN_PROGRAM:
51-
return program_participants_with_inactive_account(program_id)
51+
return program_participants_with_inactive_account(
52+
program.id, program.datetime_started
53+
)
5254
case RecipientRule.INACTIVE_ACCOUNT_IN_PROGRAM_REGISTERED_ON_DATE:
5355
return program_participants_with_inactive_account_registered_on(
54-
program_id, target_date
56+
program.id,
57+
target_date,
58+
program.datetime_started,
5559
)
5660
case _:
5761
raise ValueError(f"Unsupported recipient rule: {scenario.recipient_rule}")
@@ -63,7 +67,7 @@ def _deadline_date(program):
6367

6468

6569
def _send_scenario_for_program(scenario, program, scheduled_for, target_date):
66-
recipients = _get_recipients(scenario, program.id, target_date)
70+
recipients = _get_recipients(scenario, program, target_date)
6771
if not recipients.exists():
6872
return 0
6973

mailing/tests.py

Lines changed: 46 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -96,7 +96,9 @@ def test_participants_with_inactive_account(self):
9696
last_activity=self._dt(self.today - timedelta(days=1))
9797
)
9898

99-
recipients = program_participants_with_inactive_account(program.id)
99+
recipients = program_participants_with_inactive_account(
100+
program.id, program.datetime_started
101+
)
100102
recipient_ids = set(recipients.values_list("id", flat=True))
101103

102104
self.assertIn(inactive_no_activity.id, recipient_ids)
@@ -114,7 +116,7 @@ def test_participants_with_inactive_account_registered_on_date(self):
114116
self._register_user(registered_other_day, program, self.today - timedelta(days=2))
115117

116118
recipients = program_participants_with_inactive_account_registered_on(
117-
program.id, target_date
119+
program.id, target_date, program.datetime_started
118120
)
119121
recipient_ids = set(recipients.values_list("id", flat=True))
120122

@@ -152,8 +154,11 @@ def _register_user(self, user: CustomUser, program: PartnerProgram, registered_o
152154
datetime_created=self._dt(registered_on)
153155
)
154156

155-
@patch("mailing.tasks.send_mass_mail_from_template", _fake_send_mass_mail_from_template)
156-
def test_registration_plus_3_inactive_account_scenario(self):
157+
@patch(
158+
"mailing.tasks.send_mass_mail_from_template",
159+
side_effect=_fake_send_mass_mail_from_template,
160+
)
161+
def test_registration_plus_3_inactive_account_scenario(self, send_mail_mock):
157162
target_registration_date = self.today - timedelta(days=3)
158163

159164
program = PartnerProgram.objects.create(
@@ -192,9 +197,28 @@ def test_registration_plus_3_inactive_account_scenario(self):
192197
)
193198
self.assertEqual(sent_logs.count(), 1)
194199
self.assertEqual(sent_logs.first().user_id, inactive_user.id)
200+
self.assertEqual(send_mail_mock.call_count, 1)
201+
202+
second_run_sent_count = run_program_mailings()
203+
self.assertEqual(second_run_sent_count, 0)
204+
self.assertEqual(send_mail_mock.call_count, 1)
205+
206+
all_logs = MailingScenarioLog.objects.filter(
207+
scenario_code="program_registration_plus_3_inactive_account",
208+
program=program,
209+
scheduled_for=self.today,
210+
)
211+
self.assertEqual(all_logs.count(), 1)
212+
self.assertEqual(
213+
all_logs.first().status,
214+
MailingScenarioLog.Status.SENT,
215+
)
195216

196-
@patch("mailing.tasks.send_mass_mail_from_template", _fake_send_mass_mail_from_template)
197-
def test_registration_end_plus_3_inactive_account_scenario(self):
217+
@patch(
218+
"mailing.tasks.send_mass_mail_from_template",
219+
side_effect=_fake_send_mass_mail_from_template,
220+
)
221+
def test_registration_end_plus_3_inactive_account_scenario(self, send_mail_mock):
198222
target_registration_end_date = self.today - timedelta(days=3)
199223

200224
program = PartnerProgram.objects.create(
@@ -227,3 +251,19 @@ def test_registration_end_plus_3_inactive_account_scenario(self):
227251
)
228252
self.assertEqual(sent_logs.count(), 1)
229253
self.assertEqual(sent_logs.first().user_id, inactive_user.id)
254+
self.assertEqual(send_mail_mock.call_count, 1)
255+
256+
second_run_sent_count = run_program_mailings()
257+
self.assertEqual(second_run_sent_count, 0)
258+
self.assertEqual(send_mail_mock.call_count, 1)
259+
260+
all_logs = MailingScenarioLog.objects.filter(
261+
scenario_code="program_registration_end_plus_3_inactive_account",
262+
program=program,
263+
scheduled_for=self.today,
264+
)
265+
self.assertEqual(all_logs.count(), 1)
266+
self.assertEqual(
267+
all_logs.first().status,
268+
MailingScenarioLog.Status.SENT,
269+
)

partner_programs/selectors.py

Lines changed: 2 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -41,12 +41,6 @@ def _participant_profiles(program_id: int):
4141
)
4242

4343

44-
def _program_start_datetime(program_id: int):
45-
return PartnerProgram.objects.only("datetime_started").get(
46-
id=program_id
47-
).datetime_started
48-
49-
5044
def _inactive_program_users(user_ids, program_started_at):
5145
effective_last_seen = Greatest(
5246
Coalesce(
@@ -133,17 +127,15 @@ def program_participants_with_unsubmitted_project(program_id: int):
133127
).distinct()
134128

135129

136-
def program_participants_with_inactive_account(program_id: int):
130+
def program_participants_with_inactive_account(program_id: int, program_started_at):
137131
participant_ids = _participant_profiles(program_id).values_list("user_id", flat=True)
138-
program_started_at = _program_start_datetime(program_id)
139132
return _inactive_program_users(participant_ids, program_started_at)
140133

141134

142135
def program_participants_with_inactive_account_registered_on(
143-
program_id: int, target_date
136+
program_id: int, target_date, program_started_at
144137
):
145138
participant_ids = _participant_profiles(program_id).filter(
146139
datetime_created__date=target_date
147140
).values_list("user_id", flat=True)
148-
program_started_at = _program_start_datetime(program_id)
149141
return _inactive_program_users(participant_ids, program_started_at)

0 commit comments

Comments
 (0)