import sys import os import unittest from pathlib import Path from PIL import Image, ImageFont # Add root and core directories to python path ROOT_DIR = Path(__file__).resolve().parent.parent sys.path.insert(0, str(ROOT_DIR)) sys.path.insert(0, str(ROOT_DIR / "core")) import layout_engine class TestLayoutEngine(unittest.TestCase): def test_load_settings(self): settings = layout_engine.load_settings() self.assertIsInstance(settings, dict) self.assertIn("layout", settings) self.assertIn("overlays", settings) self.assertIn("colors", settings) # Check defaults are populated self.assertIn("dpi", settings["layout"]) self.assertIn("grid_rows", settings["layout"]) self.assertIn("grid_cols", settings["layout"]) def test_to_arabic_digits(self): translated = layout_engine._to_arabic_digits("1234567890") self.assertEqual(translated, "١٢٣٤٥٦٧٨٩٠") def test_reshape_arabic(self): # Even if raqm or bidi is present/absent, it should return reshaped text or original text = "مرحبا" reshaped = layout_engine._reshape_arabic(text) self.assertIsNotNone(reshaped) self.assertNotEqual(reshaped, "") def test_resize_to_fit(self): # Create an image of 1000x2000 (aspect ratio 1:2) img = Image.new("RGB", (1000, 2000)) # Resize to fit in max 100x100 resized = layout_engine._resize_to_fit(img, 100, 100) self.assertEqual(resized.size[0], 50) self.assertEqual(resized.size[1], 100) # Resize to fit in max 300x100 resized2 = layout_engine._resize_to_fit(img, 300, 100) self.assertEqual(resized2.size[0], 50) self.assertEqual(resized2.size[1], 100) def test_add_inner_stroke(self): img = Image.new("RGB", (100, 100), (255, 255, 255)) stroked = layout_engine._add_inner_stroke(img, color=(0, 0, 0), width=2) self.assertEqual(stroked.size, (100, 100)) # Top-left pixel should be stroke color (0, 0, 0) self.assertEqual(stroked.getpixel((0, 0)), (0, 0, 0)) # Center pixel should still be white (255, 255, 255) self.assertEqual(stroked.getpixel((50, 50)), (255, 255, 255)) def test_generate_layout(self): # Create a dummy portrait image img = Image.new("RGB", (300, 420), (200, 200, 200)) # Call generate_layout with various options canvas = layout_engine.generate_layout( img, person_name="Test User", id_number="12345", add_studio_name=True, add_logo=False, # Avoid logo file requirements add_date=True, frame_color=(50, 50, 50) ) # Verify result is a PIL Image with output dimensions self.assertIsInstance(canvas, Image.Image) expected_w = round(layout_engine.S["layout"]["output_w_cm"] / 2.54 * layout_engine.DPI) expected_h = round(layout_engine.S["layout"]["output_h_cm"] / 2.54 * layout_engine.DPI) self.assertEqual(canvas.size[0], expected_w) self.assertEqual(canvas.size[1], expected_h) self.assertIn("dpi", canvas.info) if __name__ == "__main__": unittest.main()