import json import os import tempfile from unittest.mock import patch, MagicMock import pytest from app import db as db_module from app import card_writer @pytest.fixture def tmp_db(monkeypatch): fd, path = tempfile.mkstemp(suffix=".db") os.close(fd) monkeypatch.setattr(db_module, "DB_PATH", path) db_module.init_db() yield path import gc gc.collect() for ext in ("", "-wal", "-shm"): try: os.remove(path + ext) except OSError: pass SAMPLE_LLM_JSON = { "cover_copy": {"headline": "금리 인상 단행", "body": "왜 지금?", "accent_color": "#0F62FE"}, "body_copies": [ {"headline": f"포인트 {i+1}", "body": f"본문 {i+1}"} for i in range(8) ], "cta_copy": {"headline": "정리", "body": "바로 확인", "cta": "팔로우"}, "suggested_caption": "금리에 대해 알아보자", "hashtags": ["#금리", "#경제"], } def _fake_messages_create(*_args, **_kwargs): msg = MagicMock() block = MagicMock() block.text = json.dumps(SAMPLE_LLM_JSON, ensure_ascii=False) msg.content = [block] return msg def test_write_slate_persists_full_payload(tmp_db, monkeypatch): db_module.add_news_article({ "category": "economy", "title": "기준금리 인상 단행", "link": "https://example.com/1", "summary": "한국은행 발표", }) fake_client = MagicMock() fake_client.messages.create = _fake_messages_create monkeypatch.setattr(card_writer, "_client", lambda: fake_client) sid = card_writer.write_slate(keyword="기준금리", category="economy") slate = db_module.get_card_slate(sid) assert slate["status"] == "draft" body_copies = json.loads(slate["body_copies"]) assert len(body_copies) == 8 assert body_copies[0]["headline"] == "포인트 1" assert json.loads(slate["cover_copy"])["accent_color"] == "#0F62FE" def test_write_slate_raises_on_invalid_json(tmp_db, monkeypatch): fake_client = MagicMock() bad_msg = MagicMock() bad_block = MagicMock() bad_block.text = "not json" bad_msg.content = [bad_block] fake_client.messages.create.return_value = bad_msg monkeypatch.setattr(card_writer, "_client", lambda: fake_client) with pytest.raises(ValueError): card_writer.write_slate(keyword="x", category="economy")