"""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": "

초안 본문

", "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": "

마케팅된 본문

"}) 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