"""Plain Python checks, including real FFmpeg encoding when installed.""" import binascii import os from pathlib import Path import shutil import struct import sys import tempfile import unittest import zlib sys.path.insert(0, str(Path(__file__).resolve().parents[1] / "Content/Python")) from ue_workshop.paths import slug from ue_workshop.video import encode def png(path, rgb): def chunk(kind, data): return struct.pack(">I", len(data)) + kind + data + struct.pack(">I", binascii.crc32(kind + data) & 0xffffffff) path.write_bytes(b"\x89PNG\r\n\x1a\n" + chunk(b"IHDR", struct.pack(">IIBBBBB", 4, 4, 8, 2, 0, 0, 0)) + chunk(b"IDAT", zlib.compress((b"\x00" + bytes(rgb) * 4) * 4)) + chunk(b"IEND", b"")) class OfflineTests(unittest.TestCase): def test_generated_asset_name_cannot_escape_folder(self): for value in ["../Outside", "A/B", "", "A.B", "0Shot", "A B"]: with self.subTest(value=value), self.assertRaises(ValueError): slug(value) self.assertEqual(slug("MyShot_2"), "MyShot_2") def test_missing_frames_are_rejected_before_encoding(self): with tempfile.TemporaryDirectory() as directory: folder = Path(directory) png(folder / "frame_0001.png", (255, 0, 0)) with self.assertRaisesRegex(RuntimeError, "numeracji"): encode(folder, 24) def test_incomplete_render_is_not_encoded(self): with tempfile.TemporaryDirectory() as directory: folder = Path(directory) png(folder / "frame_0000.png", (255, 0, 0)) with self.assertRaisesRegex(RuntimeError, "zamiast 2"): encode(folder, 24, expected_frames=2) @unittest.skipUnless(shutil.which("ffmpeg") or os.environ.get("WORKSHOP_FFMPEG"), "FFmpeg missing") def test_real_mp4_encoding(self): with tempfile.TemporaryDirectory() as directory: folder = Path(directory) / "frames" folder.mkdir() png(folder / "frame_0000.png", (255, 0, 0)) png(folder / "frame_0001.png", (0, 0, 255)) movie = encode(folder, 24, expected_frames=2) self.assertGreater(movie.stat().st_size, 100) self.assertIn(b"ftyp", movie.read_bytes()[:32]) if __name__ == "__main__": unittest.main()