"""design_importer 회귀 테스트.""" import json import os import tempfile from pathlib import Path import pytest from app import design_importer @pytest.fixture def tmp_theme(tmp_path): """templates//pages/ 구조를 가진 임시 디렉토리.""" pages = tmp_path / "minimal" / "pages" pages.mkdir(parents=True) return tmp_path / "minimal" def _touch(pages_dir: Path, names: list[str]): for n in names: (pages_dir / n).write_bytes(b"") # 매핑 테스트는 dimension 검증 안 함 def test_auto_page_mapping_with_cover_and_cta(tmp_theme): """cover 키워드 → 1, cta 키워드 → 10, 나머지는 알파벳 순 2~9.""" _touch(tmp_theme / "pages", [ "insta_card_start.png", # start → page 1 (cover priority) "insta_card_keyword.png", "insta_card_highlight.png", "insta_card_observation.png", "insta_card_memo.png", "insta_card_oneline.png", "insta_card_checklist.png", "insta_card_study.png", "insta_card_cta.png", # cta → page 10 "insta_card_finish.png", # finish은 cta가 이미 채워 본문 풀로 ]) mapping = design_importer._resolve_page_mapping(tmp_theme / "pages") assert mapping["insta_card_start.png"] == 1 assert mapping["insta_card_cta.png"] == 10 # 본문 풀 (남은 8장)은 알파벳 정렬: checklist, finish, highlight, keyword, memo, observation, oneline, study body_pages = {p: n for n, p in mapping.items() if 2 <= p <= 9} assert body_pages[2] == "insta_card_checklist.png" assert body_pages[3] == "insta_card_finish.png" assert body_pages[9] == "insta_card_study.png" assert set(mapping.values()) == set(range(1, 11)) def test_explicit_order_json_overrides_auto_mapping(tmp_theme): """_order.json이 있으면 자동 매핑보다 우선.""" pages = tmp_theme / "pages" _touch(pages, [ "insta_card_start.png", "insta_card_cta.png", "insta_card_finish.png", ] + [f"insta_card_body{i}.png" for i in range(1, 8)]) (pages / "_order.json").write_text(json.dumps({ "insta_card_start.png": 1, "insta_card_finish.png": 10, # cta 대신 finish를 page 10으로 "insta_card_cta.png": 5, # cta를 본문 한가운데로 강제 "insta_card_body1.png": 2, "insta_card_body2.png": 3, "insta_card_body3.png": 4, "insta_card_body4.png": 6, "insta_card_body5.png": 7, "insta_card_body6.png": 8, "insta_card_body7.png": 9, }), encoding="utf-8") mapping = design_importer._resolve_page_mapping(pages) assert mapping["insta_card_finish.png"] == 10 assert mapping["insta_card_cta.png"] == 5 assert mapping["insta_card_start.png"] == 1 def test_validates_exactly_ten_pngs(tmp_theme): """PNG가 정확히 10장이 아니면 ValueError.""" _touch(tmp_theme / "pages", [f"x{i}.png" for i in range(5)]) # 5장 with pytest.raises(ValueError, match="10"): design_importer._resolve_page_mapping(tmp_theme / "pages") def _make_png(path: Path, size: tuple[int, int]) -> None: """size 픽셀의 단색 PNG를 생성.""" from PIL import Image Image.new("RGB", size, color=(200, 200, 200)).save(path, format="PNG") def test_validate_images_accepts_1080x1350(tmp_theme): pages = tmp_theme / "pages" for i in range(10): _make_png(pages / f"insta_card_{i:02d}.png", (1080, 1350)) # 예외 없이 통과해야 함 design_importer._validate_images(pages) def test_validate_images_rejects_wrong_dimensions(tmp_theme): pages = tmp_theme / "pages" for i in range(10): size = (800, 800) if i == 5 else (1080, 1350) _make_png(pages / f"insta_card_{i:02d}.png", size) with pytest.raises(ValueError, match="1080x1350"): design_importer._validate_images(pages)