From 1bf2ed0fd21d1d6400d18216854c0b86ede4a700 Mon Sep 17 00:00:00 2001 From: Mina Choi Date: Thu, 1 Oct 2026 11:41:46 +0900 Subject: [PATCH] =?UTF-8?q?[fix]=20solution/backend:=20=EB=AF=B8=EB=8B=88?= =?UTF-8?q?=EB=B8=94=EB=A1=9C=EA=B7=B8=20=EC=8A=B9=EC=9D=B8=20=EB=A9=94?= =?UTF-8?q?=EC=9D=BC=EC=9D=80=20=EA=B7=B8=EB=82=A0=20=EB=B0=B0=EC=A0=95?= =?UTF-8?q?=EB=90=9C=20=EA=B8=80=EB=A7=8C=20=E2=80=94=20=EB=B0=80=EB=A6=B0?= =?UTF-8?q?=20=EA=B8=80=EC=9D=B4=20=EC=98=A4=EB=8A=98=20=EA=B8=80=20?= =?UTF-8?q?=EB=8C=80=EC=8B=A0=20=EB=82=98=EA=B0=80=EB=8D=98=20=EA=B2=83?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 승인 알림보내기·아침 9시 발송이 배정일 오늘 이전 글 중 가장 오래된 것을 골라, 10/1 에 9/23 글이 메일로 갔다. - post_crud: due_for_mail · next_due_for_mail 를 scheduled_date == today 로 테스트 1건 추가. 블로그 70 passed Co-Authored-By: Claude Opus 5.5 --- solution/backend/crud/post_crud.py | 8 +++---- solution/backend/tests/test_blog_owner.py | 28 +++++++++++++++++++++++ 2 files changed, 32 insertions(+), 4 deletions(-) diff --git a/solution/backend/crud/post_crud.py b/solution/backend/crud/post_crud.py index 75f8052..e31f1ad 100644 --- a/solution/backend/crud/post_crud.py +++ b/solution/backend/crud/post_crud.py @@ -42,12 +42,12 @@ class PostCRUD: return result.scalar() async def due_for_mail(self, cdb: AsyncSession, status: int, today, limit: int): - """배정일이 오늘까지 온 것 중 업장당 1건만, 이른 날짜순.""" + """배정일이 오늘인 것만, 업장당 1건.""" result = await cdb.execute( select(place_posts) .where( place_posts.status == status, place_posts.deleted == False, # noqa: E712 - place_posts.scheduled_date <= today, + place_posts.scheduled_date == today, ) .distinct(place_posts.place_id) .order_by(place_posts.place_id, place_posts.scheduled_date) @@ -62,9 +62,9 @@ class PostCRUD: .where( place_posts.place_id == place_id, place_posts.status == status, place_posts.deleted == False, # noqa: E712 - place_posts.scheduled_date <= today, + place_posts.scheduled_date == today, ) - .order_by(place_posts.scheduled_date) + .order_by(place_posts.created_at) .limit(1) ) return result.scalars().first() diff --git a/solution/backend/tests/test_blog_owner.py b/solution/backend/tests/test_blog_owner.py index 60fa008..6209cc6 100644 --- a/solution/backend/tests/test_blog_owner.py +++ b/solution/backend/tests/test_blog_owner.py @@ -1275,3 +1275,31 @@ async def test_send_now_mail_failure_alerts_once_and_recovers(client, db_engine, outcome["ok"] = True assert (await client.post(f"/v1/place/{place_id}/post/send-now", headers=h)).json()["result"]["success"] is True assert await kinds() == [("blog_send_failed", True), ("recovery", False)] + + +async def test_mail_goes_only_for_todays_post_not_backlog(client, db_engine, auth_headers, monkeypatch): + from services import blog_jobs, mail_service + + monkeypatch.setattr(mail_service, "is_configured", lambda: True) + sent_calls = [] + monkeypatch.setattr(mail_service, "send", lambda **kwargs: sent_calls.append(kwargs) or True) + + h = await auth_headers("bloggen-today") + place_id = await _place(client, h, name="오늘글펜션") + async with db_engine.begin() as conn: + await conn.execute( + text("INSERT INTO sites (site_id, place_id, domain, status) VALUES (:sid, :pid, :dom, :st)"), + {"sid": uuid.uuid4(), "pid": place_id, "dom": f"blog-test-{uuid.uuid4().hex[:8]}", "st": SiteStatus.PUBLISHED.value}, + ) + await conn.execute(text("UPDATE users SET email = :e WHERE id = :id"), {"e": "today@example.com", "id": "bloggen-today"}) + old_post = await _seed_post(db_engine, place_id, scheduled=date.today() - timedelta(days=8)) + today_post = await _seed_post(db_engine, place_id, scheduled=date.today()) + + res = await client.post(f"/v1/place/{place_id}/post/send-now", headers=h) + assert res.json()["result"]["success"] is True + assert await _status(db_engine, today_post) == PostStatus.SENT.value + assert await _status(db_engine, old_post) == PostStatus.REVIEWED.value + + assert await blog_jobs.send_reviewed() == 0 + assert await _status(db_engine, old_post) == PostStatus.REVIEWED.value + assert len(sent_calls) == 1