import io import tempfile from pathlib import Path from PIL import Image as PilImage from logimage.infrastructure.pdf.reportlab_exporter import ReportLabPdfExporter from logimage.domain.entities.puzzle import NonogramPuzzle from logimage.domain.value_objects.grid import Grid def _make_puzzle(rows: int = 10, cols: int = 10, title: str = "Test") -> NonogramPuzzle: cells = [[i % 3 == 0] * cols for i in range(rows)] grid = Grid.from_list(cells) return NonogramPuzzle.from_grid(grid, title) def test_export_creates_pdf_file() -> None: exporter = ReportLabPdfExporter() with tempfile.TemporaryDirectory() as tmp: path = Path(tmp) / "output.pdf" exporter.export([_make_puzzle()], path) assert path.exists() assert path.stat().st_size > 1000 def test_export_multiple_puzzles_creates_larger_file() -> None: exporter = ReportLabPdfExporter() with tempfile.TemporaryDirectory() as tmp: path_single = Path(tmp) / "single.pdf" path_multi = Path(tmp) / "multi.pdf" exporter.export([_make_puzzle()], path_single) exporter.export([_make_puzzle(), _make_puzzle(), _make_puzzle()], path_multi) assert path_multi.stat().st_size > path_single.stat().st_size def test_export_with_solution_creates_larger_file() -> None: exporter = ReportLabPdfExporter() with tempfile.TemporaryDirectory() as tmp: path_no_sol = Path(tmp) / "no_solution.pdf" path_with_sol = Path(tmp) / "with_solution.pdf" puzzle = _make_puzzle() exporter.export([puzzle], path_no_sol, with_solution=False) exporter.export([puzzle], path_with_sol, with_solution=True) assert path_with_sol.stat().st_size > path_no_sol.stat().st_size def test_export_starts_with_pdf_magic_bytes() -> None: exporter = ReportLabPdfExporter() with tempfile.TemporaryDirectory() as tmp: path = Path(tmp) / "output.pdf" exporter.export([_make_puzzle()], path) assert path.read_bytes()[:4] == b"%PDF" def _make_puzzle_with_image(rows: int = 10, cols: int = 10) -> NonogramPuzzle: buf = io.BytesIO() PilImage.new("RGB", (40, 40), color=(100, 150, 200)).save(buf, format="JPEG") cells = [[i % 3 == 0] * cols for i in range(rows)] grid = Grid.from_list(cells) return NonogramPuzzle.from_grid(grid, "Test With Image", buf.getvalue()) def test_solution_with_image_bytes_creates_larger_file() -> None: exporter = ReportLabPdfExporter() puzzle_no_img = _make_puzzle() puzzle_with_img = _make_puzzle_with_image() with tempfile.TemporaryDirectory() as tmp: path_no_img = Path(tmp) / "no_img.pdf" path_with_img = Path(tmp) / "with_img.pdf" exporter.export([puzzle_no_img], path_no_img, with_solution=True) exporter.export([puzzle_with_img], path_with_img, with_solution=True) assert path_with_img.stat().st_size > path_no_img.stat().st_size def test_solution_without_image_bytes_still_produces_valid_pdf() -> None: exporter = ReportLabPdfExporter() puzzle = _make_puzzle() # image_bytes is None with tempfile.TemporaryDirectory() as tmp: path = Path(tmp) / "sol.pdf" exporter.export([puzzle], path, with_solution=True) assert path.read_bytes()[:4] == b"%PDF"