diff --git a/insta-lab/app/main.py b/insta-lab/app/main.py index e08d974..b2fbe2e 100644 --- a/insta-lab/app/main.py +++ b/insta-lab/app/main.py @@ -258,11 +258,13 @@ def download_package(slate_id: int): if not assets: raise HTTPException(409, "아직 렌더된 카드가 없습니다") buf = io.BytesIO() + written = 0 with zipfile.ZipFile(buf, "w", zipfile.ZIP_DEFLATED) as z: for a in assets: fp = a["file_path"] if os.path.exists(fp): z.write(fp, arcname=f"{a['page_index']:02d}.png") + written += 1 caption = (slate.get("suggested_caption") or "").strip() tags = slate.get("hashtags") or [] if isinstance(tags, str): @@ -272,6 +274,8 @@ def download_package(slate_id: int): tags = [] caption_full = caption + ("\n\n" + " ".join(tags) if tags else "") z.writestr("caption.txt", caption_full) + if written == 0: + raise HTTPException(409, "렌더된 카드 파일이 없습니다") buf.seek(0) return StreamingResponse(buf, media_type="application/zip", headers={ "Content-Disposition": f'attachment; filename="insta_slate_{slate_id}.zip"' diff --git a/insta-lab/app/test_package_api.py b/insta-lab/app/test_package_api.py index 70f83d6..48f2850 100644 --- a/insta-lab/app/test_package_api.py +++ b/insta-lab/app/test_package_api.py @@ -43,3 +43,25 @@ def test_package_zip_contains_pngs_and_caption(monkeypatch): assert "caption.txt" in names cap = z.read("caption.txt").decode("utf-8") assert "캡션입니다" in cap and "#a" in cap + + +def test_package_unknown_slate_404(monkeypatch): + client, db, tmp = _client(monkeypatch) + r = client.get("/api/insta/slates/999999/package") + assert r.status_code == 404 + + +def test_package_no_assets_409(monkeypatch): + client, db, tmp = _client(monkeypatch) + sid = db.add_card_slate({ + "keyword": "k", + "category": "economy", + "status": "draft", + "cover_copy": {"headline": "h"}, + "body_copies": [{"headline": "b", "body": "x"}] * 8, + "cta_copy": {}, + "suggested_caption": "c", + "hashtags": [], + }) + r = client.get(f"/api/insta/slates/{sid}/package") + assert r.status_code == 409