feat(insta-lab): import_design_theme — Vision 호출 + Jinja sanity + 백업 저장
This commit is contained in:
@@ -101,3 +101,68 @@ def test_validate_images_rejects_wrong_dimensions(tmp_theme):
|
||||
_make_png(pages / f"insta_card_{i:02d}.png", size)
|
||||
with pytest.raises(ValueError, match="1080x1350"):
|
||||
design_importer._validate_images(pages)
|
||||
|
||||
|
||||
def test_import_design_theme_writes_html_via_mocked_vision(tmp_theme, monkeypatch):
|
||||
"""Vision mock이 정상 HTML 반환 시 card.html.j2 파일이 저장되고 결과 dict 반환."""
|
||||
pages = tmp_theme / "pages"
|
||||
names = [
|
||||
"insta_card_start.png",
|
||||
"insta_card_cta.png",
|
||||
] + [f"insta_card_body{i}.png" for i in range(8)]
|
||||
for n in names:
|
||||
_make_png(pages / n, (1080, 1350))
|
||||
|
||||
fake_html = """<!DOCTYPE html><html><body>
|
||||
{% if page_no == 1 %}<div class="cover">{{ headline }}</div>{% endif %}
|
||||
{% if page_no >= 2 and page_no <= 9 %}<div class="body">{{ headline }}<p>{{ body }}</p></div>{% endif %}
|
||||
{% if page_no == 10 %}<div class="cta">{{ headline }}<p>{{ cta }}</p></div>{% endif %}
|
||||
</body></html>"""
|
||||
|
||||
def fake_vision_call(images_with_pages, theme_name):
|
||||
return {"html": fake_html, "tokens": 12345, "summary": "test summary"}
|
||||
|
||||
monkeypatch.setattr(design_importer, "_call_vision", fake_vision_call)
|
||||
|
||||
result = design_importer.import_design_theme(str(tmp_theme))
|
||||
assert result["theme_name"] == "minimal"
|
||||
assert "card.html.j2" in result["html_path"]
|
||||
assert (tmp_theme / "card.html.j2").exists()
|
||||
assert (tmp_theme / "card.html.j2").read_text(encoding="utf-8") == fake_html
|
||||
assert "insta_card_start.png" in result["page_mapping"]
|
||||
assert result["tokens_used"] == 12345
|
||||
|
||||
|
||||
def test_import_design_theme_raises_on_jinja_parse_failure(tmp_theme, monkeypatch):
|
||||
"""Vision이 깨진 Jinja 반환 시 ValueError + .error.txt 보존."""
|
||||
pages = tmp_theme / "pages"
|
||||
for i in range(10):
|
||||
_make_png(pages / f"insta_card_{i:02d}.png", (1080, 1350))
|
||||
|
||||
broken_html = "<div>{% if page_no == 1 unclosed"
|
||||
|
||||
monkeypatch.setattr(design_importer, "_call_vision",
|
||||
lambda imgs, name: {"html": broken_html, "tokens": 100, "summary": ""})
|
||||
|
||||
with pytest.raises(ValueError, match="Jinja"):
|
||||
design_importer.import_design_theme(str(tmp_theme))
|
||||
assert (tmp_theme / "card.html.j2.error.txt").exists()
|
||||
|
||||
|
||||
def test_import_design_theme_backs_up_existing_html(tmp_theme, monkeypatch):
|
||||
"""기존 card.html.j2가 있으면 .bak.YYYYMMDD-HHMMSS로 백업 후 새로 작성."""
|
||||
pages = tmp_theme / "pages"
|
||||
for i in range(10):
|
||||
_make_png(pages / f"insta_card_{i:02d}.png", (1080, 1350))
|
||||
(tmp_theme / "card.html.j2").write_text("OLD HTML", encoding="utf-8")
|
||||
|
||||
monkeypatch.setattr(design_importer, "_call_vision",
|
||||
lambda imgs, name: {"html": "<div>{{ headline }}</div>", "tokens": 50, "summary": ""})
|
||||
|
||||
design_importer.import_design_theme(str(tmp_theme))
|
||||
# .bak.* 파일이 생성되었어야 함
|
||||
backups = list(tmp_theme.glob("card.html.j2.bak.*"))
|
||||
assert len(backups) == 1
|
||||
assert backups[0].read_text(encoding="utf-8") == "OLD HTML"
|
||||
# 새 파일은 새 내용
|
||||
assert "headline" in (tmp_theme / "card.html.j2").read_text(encoding="utf-8")
|
||||
|
||||
Reference in New Issue
Block a user