Skip to content

Commit 0c0c2d7

Browse files
Fix pre-registration review issues
1 parent bdc8928 commit 0c0c2d7

6 files changed

Lines changed: 106 additions & 4 deletions

File tree

wacruit/src/apps/pre_registration/repositories.py

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
from fastapi import Depends
22
from sqlalchemy import delete
3+
from sqlalchemy import func
34
from sqlalchemy import select
45
from sqlalchemy import true
56
from sqlalchemy.orm import Session
@@ -59,6 +60,22 @@ def create_pre_registration_user(
5960
self.session.add(pre_registration_user)
6061
return pre_registration_user
6162

63+
def count_pre_registration_users(
64+
self,
65+
pre_registration_id: int | None,
66+
active_only: bool,
67+
) -> int:
68+
query = (
69+
select(func.count()).select_from(PreRegistrationUser).join(PreRegistration)
70+
)
71+
if pre_registration_id is not None:
72+
query = query.where(
73+
PreRegistrationUser.pre_registration_id == pre_registration_id
74+
)
75+
if active_only:
76+
query = query.where(PreRegistration.is_active == true())
77+
return int(self.session.execute(query).scalar_one())
78+
6279
def get_pre_registration_users(
6380
self,
6481
pre_registration_id: int | None,

wacruit/src/apps/pre_registration/schemas.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,3 +61,4 @@ class SendPreRegistrationEmailResponse(BaseModel):
6161
total_count: int
6262
queued_count: int
6363
recipient_limit: int
64+
is_truncated: bool

wacruit/src/apps/pre_registration/services.py

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import logging
12
from typing import Annotated
23

34
from fastapi import BackgroundTasks
@@ -23,6 +24,8 @@
2324
from wacruit.src.apps.pre_registration.schemas import SendPreRegistrationEmailResponse
2425
from wacruit.src.apps.pre_registration.schemas import UpdatePreRegistrationRequest
2526

27+
logger = logging.getLogger(__name__)
28+
2629
PRE_REGISTRATION_EMAIL_BATCH_LIMIT = 200
2730

2831

@@ -155,6 +158,10 @@ def send_email_to_pre_registration_users(
155158
request: SendPreRegistrationEmailRequest,
156159
background_tasks: BackgroundTasks,
157160
) -> SendPreRegistrationEmailResponse:
161+
total_count = self.pre_registration_repository.count_pre_registration_users(
162+
pre_registration_id=request.pre_registration_id,
163+
active_only=request.active_only,
164+
)
158165
pre_registration_users = (
159166
self.pre_registration_repository.get_pre_registration_users(
160167
pre_registration_id=request.pre_registration_id,
@@ -176,9 +183,10 @@ def send_email_to_pre_registration_users(
176183

177184
return SendPreRegistrationEmailResponse(
178185
status="queued",
179-
total_count=len(recipient_emails),
186+
total_count=total_count,
180187
queued_count=len(recipient_emails),
181188
recipient_limit=PRE_REGISTRATION_EMAIL_BATCH_LIMIT,
189+
is_truncated=total_count > len(recipient_emails),
182190
)
183191

184192
def _send_email_to_recipients(
@@ -196,5 +204,15 @@ def _send_email_to_recipients(
196204
content=content,
197205
html_content=html_content,
198206
)
199-
except (MailConfigException, MailSendFailedException):
207+
except MailConfigException:
208+
logger.exception(
209+
"Pre-registration email configuration failed for recipient %s",
210+
recipient_email,
211+
)
212+
break
213+
except MailSendFailedException:
214+
logger.exception(
215+
"Failed to send pre-registration email to recipient %s",
216+
recipient_email,
217+
)
200218
continue

wacruit/src/database/connection.py

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -64,5 +64,9 @@ def __exit__(self, exc_type, exc_val, exc_tb) -> bool:
6464
self._session.rollback()
6565
return False
6666

67-
self._session.flush()
67+
try:
68+
self._session.flush()
69+
except Exception:
70+
self._session.rollback()
71+
raise
6872
return True

wacruit/src/tests/pre_registration/conftest.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
import pytest
44
from sqlalchemy.orm import Session
55

6+
from wacruit.src.apps.mail.exceptions import MailConfigException
67
from wacruit.src.apps.mail.exceptions import MailSendFailedException
78
from wacruit.src.apps.mail.services import EmailService
89
from wacruit.src.apps.pre_registration.models import PreRegistration
@@ -17,6 +18,7 @@ class FakeEmailService(EmailService):
1718
def __init__(self) -> None:
1819
self.sent_emails: list[tuple[str, str, str, str | None]] = []
1920
self.failed_emails: set[str] = set()
21+
self.config_failed_emails: set[str] = set()
2022

2123
def send_email(
2224
self,
@@ -25,6 +27,8 @@ def send_email(
2527
content: str,
2628
html_content: str | None = None,
2729
) -> None:
30+
if to_email in self.config_failed_emails:
31+
raise MailConfigException()
2832
if to_email in self.failed_emails:
2933
raise MailSendFailedException()
3034
self.sent_emails.append((to_email, subject, content, html_content))

wacruit/src/tests/pre_registration/test_pre_resgistration_service.py

Lines changed: 59 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import logging
12
from typing import List
23
from typing import cast
34

@@ -215,6 +216,15 @@ def test_create_duplicate_pre_registration_user(
215216
with pytest.raises(PreRegistUserAlreadyExistException):
216217
pre_registration_service.create_pre_registration_user(request)
217218

219+
users = pre_registration_service.get_pre_registration_users(
220+
pre_registration_id=created_active_pre_registration.id,
221+
active_only=False,
222+
limit=50,
223+
offset=0,
224+
)
225+
226+
assert users == []
227+
218228

219229
def test_get_active_pre_registration_users(
220230
db_session: Session,
@@ -319,6 +329,7 @@ def test_send_email_to_active_pre_registration_users_queues_background_task(
319329
assert response.total_count == 1
320330
assert response.queued_count == 1
321331
assert response.recipient_limit == PRE_REGISTRATION_EMAIL_BATCH_LIMIT
332+
assert response.is_truncated is False
322333
assert fake_email_service.sent_emails == []
323334
assert len(background_tasks.tasks) == 1
324335

@@ -361,12 +372,59 @@ def test_send_email_to_pre_registration_users_applies_recipient_cap(
361372
)
362373

363374
assert response.status == "queued"
364-
assert response.total_count == PRE_REGISTRATION_EMAIL_BATCH_LIMIT
375+
assert response.total_count == user_count
365376
assert response.queued_count == PRE_REGISTRATION_EMAIL_BATCH_LIMIT
366377
assert response.recipient_limit == PRE_REGISTRATION_EMAIL_BATCH_LIMIT
378+
assert response.is_truncated is True
367379
assert fake_email_service.sent_emails == []
368380

369381
[background_task] = background_tasks.tasks
370382
background_task.func(*background_task.args, **background_task.kwargs)
371383

372384
assert len(fake_email_service.sent_emails) == PRE_REGISTRATION_EMAIL_BATCH_LIMIT
385+
386+
387+
def test_send_email_to_recipients_logs_send_failure_and_continues(
388+
pre_registration_service: PreRegistrationService,
389+
fake_email_service: FakeEmailService,
390+
caplog: pytest.LogCaptureFixture,
391+
):
392+
fake_email_service.failed_emails.add("failed@example.com")
393+
394+
with caplog.at_level(
395+
logging.ERROR, logger="wacruit.src.apps.pre_registration.services"
396+
):
397+
pre_registration_service._send_email_to_recipients(
398+
recipient_emails=["failed@example.com", "success@example.com"],
399+
subject="subject",
400+
content="content",
401+
html_content=None,
402+
)
403+
404+
assert fake_email_service.sent_emails == [
405+
("success@example.com", "subject", "content", None)
406+
]
407+
assert "Failed to send pre-registration email" in caplog.text
408+
assert "failed@example.com" in caplog.text
409+
410+
411+
def test_send_email_to_recipients_logs_config_failure_and_stops(
412+
pre_registration_service: PreRegistrationService,
413+
fake_email_service: FakeEmailService,
414+
caplog: pytest.LogCaptureFixture,
415+
):
416+
fake_email_service.config_failed_emails.add("config@example.com")
417+
418+
with caplog.at_level(
419+
logging.ERROR, logger="wacruit.src.apps.pre_registration.services"
420+
):
421+
pre_registration_service._send_email_to_recipients(
422+
recipient_emails=["config@example.com", "skipped@example.com"],
423+
subject="subject",
424+
content="content",
425+
html_content=None,
426+
)
427+
428+
assert fake_email_service.sent_emails == []
429+
assert "Pre-registration email configuration failed" in caplog.text
430+
assert "config@example.com" in caplog.text

0 commit comments

Comments
 (0)