This commit is contained in:
hbyang 2026-09-22 11:44:00 +09:00
commit acd5383b0f
3 changed files with 75 additions and 8 deletions

View File

@ -4,6 +4,7 @@ import json
from sqlalchemy import text
from common.database.db_session_manager import DB_SESSION_MNG
from common.database.model.models import place_social_posts as Post
from common.enums import JobType
async def transaction(fn):
@ -41,7 +42,7 @@ async def decide(s, post_id, sha, approve, via):
)
).first()
if row and approve and row.account_id:
await enqueue(s, post_id, 9)
await enqueue(s, post_id, JobType.SOCIAL_POST.value)
return bool(row)

View File

@ -19,7 +19,7 @@ from common.database.model.models import (
place_facts,
owner_social_accounts as Account,
)
from common.enums import SiteStatus, ErrorType, PUBLISHABLE_FACT_STATUSES, SocialProvider
from common.enums import SiteStatus, ErrorType, JobType, PUBLISHABLE_FACT_STATUSES, SocialProvider
from crud.place_crud import PlaceCRUD
from crud import social_crud as db
from services import site_payload, social_account_service as accounts
@ -238,7 +238,7 @@ async def create_draft(user_id, place_id, provider=2):
await s.flush()
row_id = row.post_id
if row_id:
await db.enqueue(s, row.post_id, 8)
await db.enqueue(s, row.post_id, JobType.SOCIAL_DRAFT.value)
return public_post(row)
return await db.transaction(run)
@ -619,7 +619,7 @@ async def publish_reused_text(user_id, place_id, body: str):
)
).scalar_one_or_none()
if row_id:
await db.enqueue(s, row_id, 9)
await db.enqueue(s, row_id, JobType.SOCIAL_POST.value)
return row_id
try:

View File

@ -87,10 +87,76 @@ async def test_draft_dedup_owner_scope(client, auth_headers, db_engine):
)
async with db_engine.begin() as c:
assert (
await c.execute(text("SELECT count(*) FROM jobs WHERE job_type=8"))
await c.execute(text("SELECT count(*) FROM jobs WHERE job_type=9"))
).scalar_one() == 1
async def test_social_job_types_dispatch_to_the_right_handler():
"""실측(2026-09-22): 큐에 넣는 쪽(social_crud.decide, social_service.create_draft/
publish_reused_text)은 job_type 숫자를 하드코딩(8/9)하고, 디스패처(worker/handlers.py)는
JobType.SOCIAL_DRAFT(9)/SOCIAL_POST(10) enum 값으로 등록돼 있었다. 번호가 어긋나 있어서
"쓰레드에 게시" 잡이 run_draft 로, "초안 생성" 잡이 run_rollback 으로 잘못 배달됐다 —
잡은 에러 없이 DONE 으로 끝나지만 아무 일도 안 일어나는 조용한 실패였다. 큐 삽입 값만
보던 기존 테스트들(job_type=N 카운트)은 그 N 이 실제 핸들러와 맞는지는 확인하지
않아서 이 어긋남을 못 잡았다. 여기서는 워커가 실제로 쓰는 배달 경로
(worker.handlers.HANDLERS)가 큐 삽입 쪽이 쓰는 것과 같은 JobType enum 값을 가리키는지
직접 대조한다 — 숫자가 다시 어긋나면(둘 중 하나가 하드코딩으로 되돌아가면) 여기서 잡힌다."""
from common.enums import JobType
from services.social_service import run_draft, run_post
from worker.handlers import HANDLERS
assert HANDLERS[JobType.SOCIAL_DRAFT.value] is run_draft
assert HANDLERS[JobType.SOCIAL_POST.value] is run_post
async def test_draft_and_post_jobs_enqueue_with_dispatchable_job_types(
client, auth_headers, db_engine, monkeypatch
):
"""create_draft 가 넣는 job_type 이 실제로 run_draft 로, decide 가 넣는 job_type 이
실제로 run_post 로 배달되는지 엔드투엔드로 확인한다(위 테스트의 정적 대조를 실제
큐 삽입 값으로 한 번 더 검증). 같은 사업장에 site_version 을 새로 하나 더 발급해
(place_id, site_version_id) 유니크 인덱스와 안 부딪히게 한다 — seed() 를 두 번 부르면
도메인('social-stay') 유니크 인덱스와 부딪힌다."""
from worker.handlers import HANDLERS
monkeypatch.setattr(service, "posting_enabled", lambda: True)
h, pid, uid, v1 = await seed(client, auth_headers, db_engine)
draft_res = await client.post(f"/v1/social/place/{pid}/draft", headers=h, json={})
assert draft_res.status_code == 200, draft_res.text
draft_post_id = draft_res.json()["post_id"]
async with db_engine.begin() as c:
draft_job_type = (
await c.execute(
text("SELECT job_type FROM jobs WHERE dedupe_key LIKE :k"),
{"k": f"social:%:{draft_post_id}"},
)
).scalar_one()
assert HANDLERS[draft_job_type] is service.run_draft
v2 = uuid.uuid4()
async with db_engine.begin() as c:
await c.execute(
text("UPDATE sites SET current_version_id=:v WHERE place_id=:p"),
{"v": v2, "p": pid},
)
post_id, token = await pending(db_engine, pid, uid, v2)
approve = await client.post(
f"/v1/social/approval/{post_id}/decision", json={"t": token, "approve": True}
)
assert approve.json()["applied"] is True
async with db_engine.begin() as c:
post_job_type = (
await c.execute(
text("SELECT job_type FROM jobs WHERE dedupe_key LIKE :k"),
{"k": f"social:%:{post_id}"},
)
).scalar_one()
assert HANDLERS[post_job_type] is service.run_post
async def test_requires_fixed_domain(client, auth_headers, db_engine):
h, pid, uid, v = await seed(client, auth_headers, db_engine)
async with db_engine.begin() as c:
@ -120,7 +186,7 @@ async def test_prefetch_read_only_one_time_cas(client, auth_headers, db_engine):
assert second.json()["applied"] is False
async with db_engine.begin() as c:
assert (
await c.execute(text("SELECT count(*) FROM jobs WHERE job_type=9"))
await c.execute(text("SELECT count(*) FROM jobs WHERE job_type=10"))
).scalar_one() == 1
@ -266,7 +332,7 @@ async def test_screen_approval_without_contract_never_queues_post(
assert approved.json()["applied"] is True
async with db_engine.begin() as c:
assert (
await c.execute(text("SELECT count(*) FROM jobs WHERE job_type=9"))
await c.execute(text("SELECT count(*) FROM jobs WHERE job_type=10"))
).scalar_one() == 0
@ -588,7 +654,7 @@ async def test_publish_reused_text_inserts_approved_post_with_link_and_enqueues_
assert row.decided_via == "mini_blog"
assert row.account_id == account_id
job_count = (
await c.execute(text("SELECT count(*) FROM jobs WHERE job_type=9"))
await c.execute(text("SELECT count(*) FROM jobs WHERE job_type=10"))
).scalar_one()
assert job_count == 1