Files
web-page-backend/blog-lab/tests/test_pipeline_integration.py
2026-04-07 01:02:40 +09:00

147 lines
5.0 KiB
Python

"""4단계 파이프라인 통합 테스트."""
import os
import pytest
from unittest.mock import patch
from fastapi.testclient import TestClient
@pytest.fixture(autouse=True)
def setup_db(tmp_path):
test_db = str(tmp_path / "test.db")
import app.config as config
config.DB_PATH = test_db
from app import db
db.DB_PATH = test_db
db.init_db()
yield
@pytest.fixture
def client():
from app.main import app
return TestClient(app)
def test_full_pipeline_status_flow(client):
"""draft → marketed → reviewed → published 상태 흐름."""
from app import db
# 1. 키워드 분석 결과 직접 삽입
analysis = db.add_keyword_analysis({
"keyword": "무선 이어폰",
"blog_total": 1000,
"shop_total": 500,
"competition": 45,
"opportunity": 60,
"top_products": [{"title": "에어팟", "lprice": 200000, "mallName": "애플"}],
"top_blogs": [{"title": "리뷰", "link": "https://blog.naver.com/user/123", "content": "본문"}],
})
# 2. 브랜드 링크 등록
resp = client.post("/api/blog-marketing/links", json={
"keyword_id": analysis["id"],
"url": "https://link.coupang.com/abc",
"product_name": "삼성 버즈3",
"description": "노이즈캔슬링",
})
assert resp.status_code == 201
# 3. 포스트 직접 생성 (generate는 Claude API 필요)
post = db.add_post({
"keyword_id": analysis["id"],
"title": "무선 이어폰 추천",
"body": "<p>초안 본문</p>",
"excerpt": "요약",
"tags": ["이어폰"],
"status": "draft",
})
db.link_brand_links_to_post(keyword_id=analysis["id"], post_id=post["id"])
# 4. 상태 확인: draft
resp = client.get(f"/api/blog-marketing/posts/{post['id']}")
assert resp.json()["status"] == "draft"
# 5. marketed 상태
db.update_post(post["id"], {"status": "marketed", "body": "<p>마케팅된 본문</p>"})
resp = client.get(f"/api/blog-marketing/posts/{post['id']}")
assert resp.json()["status"] == "marketed"
# 6. reviewed 상태 (점수 48/60 = 통과)
db.update_post(post["id"], {
"status": "reviewed",
"review_score": 48,
"review_detail": {
"scores": {"empathy": 8, "click_appeal": 8, "conversion": 8, "seo": 8, "format": 8, "link_natural": 8},
"total": 48, "pass": True, "feedback": "우수"
},
})
resp = client.get(f"/api/blog-marketing/posts/{post['id']}")
assert resp.json()["status"] == "reviewed"
assert resp.json()["review_score"] == 48
# 7. 발행
resp = client.post(f"/api/blog-marketing/posts/{post['id']}/publish", json={
"naver_url": "https://blog.naver.com/mypost/123",
})
assert resp.json()["status"] == "published"
def test_links_associated_with_post(client):
"""keyword_id로 등록한 링크가 post 생성 후 post_id로도 조회 가능."""
from app import db
analysis = db.add_keyword_analysis({"keyword": "테스트", "blog_total": 10, "shop_total": 5})
client.post("/api/blog-marketing/links", json={
"keyword_id": analysis["id"],
"url": "https://link.com/1",
"product_name": "상품1",
})
post = db.add_post({"keyword_id": analysis["id"], "title": "제목", "body": "본문", "status": "draft"})
db.link_brand_links_to_post(keyword_id=analysis["id"], post_id=post["id"])
resp = client.get(f"/api/blog-marketing/links?post_id={post['id']}")
links = resp.json()["links"]
assert len(links) == 1
assert links[0]["product_name"] == "상품1"
@patch("app.main.ANTHROPIC_API_KEY", "fake-key-for-test")
def test_market_endpoint_returns_404_for_missing_post(client):
"""존재하지 않는 post_id로 마케터 호출 시 404."""
resp = client.post("/api/blog-marketing/market/9999")
assert resp.status_code == 404
@patch("app.main.ANTHROPIC_API_KEY", "fake-key-for-test")
def test_review_endpoint_returns_404_for_missing_post(client):
"""존재하지 않는 post_id로 리뷰 호출 시 404."""
resp = client.post("/api/blog-marketing/review/9999")
assert resp.status_code == 404
def test_multiple_links_per_keyword(client):
"""하나의 키워드에 복수 링크 등록 가능."""
from app import db
analysis = db.add_keyword_analysis({"keyword": "테스트", "blog_total": 10, "shop_total": 5})
for i in range(3):
resp = client.post("/api/blog-marketing/links", json={
"keyword_id": analysis["id"],
"url": f"https://link.com/{i}",
"product_name": f"상품{i}",
})
assert resp.status_code == 201
resp = client.get(f"/api/blog-marketing/links?keyword_id={analysis['id']}")
assert len(resp.json()["links"]) == 3
def test_dashboard_still_works(client):
"""대시보드 API가 여전히 정상 작동."""
resp = client.get("/api/blog-marketing/dashboard")
assert resp.status_code == 200
data = resp.json()
assert "total_posts" in data
assert "published_posts" in data