import json import os import sys import time from fastapi.testclient import TestClient # Setup path current_dir = os.path.dirname(os.path.abspath(__file__)) clipping_dir = os.path.dirname(current_dir) if clipping_dir not in sys.path: sys.path.append(clipping_dir) from main import app from routers.video import ORIGINALS_DIR, TEMP_DIR, PROCESSED_DIR client = TestClient(app) def create_mock_video_if_needed(filename="0eb30aa9_original_my_movie.mp4"): path = os.path.join(ORIGINALS_DIR, filename) if not os.path.exists(path): print(f"Creating mock video at {path}...") import imageio_ffmpeg import subprocess exe = imageio_ffmpeg.get_ffmpeg_exe() subprocess.run([ exe, '-f', 'lavfi', '-i', 'testsrc=duration=5:size=640x360:rate=30', '-f', 'lavfi', '-i', 'sine=frequency=1000:duration=5', '-c:v', 'libx264', '-t', '5', path, '-y' ], capture_output=True) return filename def create_mock_audio(): audio_filename = "test_bg_music.mp3" path = os.path.join(TEMP_DIR, audio_filename) if not os.path.exists(path): print(f"Creating mock audio at {path}...") import imageio_ffmpeg import subprocess exe = imageio_ffmpeg.get_ffmpeg_exe() subprocess.run([ exe, '-f', 'lavfi', '-i', 'sine=frequency=440:duration=5', '-t', '5', path, '-y' ], capture_output=True) return path def test_full_workflow(): print("\n" + "="*50) print("🚀 STARTING MULTI-PRESET CINEMATIC E2E TEST") print("="*50) # 1. Ensure mock assets exist video_name = create_mock_video_if_needed() audio_file_path = create_mock_audio() # List of default presets to test default_presets = ["youtube_casual", "gaming", "professional", "storyteller"] transcription = [ { "text": "Testing all default presets with cinematic style", "start": 0.0, "end": 5.0, "words": [ {"word": "Testing", "start": 0.0, "end": 1.0}, {"word": "all", "start": 1.0, "end": 1.5}, {"word": "default", "start": 1.5, "end": 2.5}, {"word": "presets", "start": 2.5, "end": 3.5}, {"word": "cinematic", "start": 3.5, "end": 5.0} ] } ] for preset in default_presets: print(f"\n[Feature Test] 🎬 Cinematic Style + 🎨 Preset: {preset}") process_data = { "original_filename": (None, video_name), "aspect_ratio": (None, "9:16"), "style": (None, "cinematic"), "subtitle_style": (None, preset), "transcription": (None, json.dumps(transcription)), "timestamps": (None, json.dumps([{"start_time": 0, "end_time": 5}])), "music_volume": (None, "0.3"), "video_volume": (None, "1.0"), "loop_music": (None, "true") } with open(audio_file_path, "rb") as f: files = {"background_music": ("bg.mp3", f, "audio/mpeg")} resp = client.post("/api/video/process-saved", data=process_data, files=files) assert resp.status_code == 200, f"Process failed for preset {preset}: {resp.text}" print(f"✅ Preset '{preset}' processed successfully in Cinematic style.") # 2. Test Custom Pro Preset with Background Box Color # 2. Test Word-Based Box Highlight (Box moves with word) print(f"\n[Feature Test] 🏃 Word-Based Box Highlight (Moving Box)") word_preset_name = "word_box_moving" word_preset_data = { "name": (None, word_preset_name), "font_name": (None, "Impact"), "font_size": "60", "primary_color": (None, "#FFFFFF"), # نص أبيض "secondary_color": (None, "#0000FF"), # صندوق أزرق "box_highlight_type": (None, "word"), # الصندوق يتحرك مع الكلمة "back_box_enabled": (None, "true"), "pop_up_scale": (None, "1.3"), # بوب أب للكلمة "background_opacity": (None, "0.8") } client.post("/api/presets/save", data=word_preset_data) # 3. Test Sentence-Based Box Highlight (Static Box + Word Popup) print(f"\n[Feature Test] 🖼️ Sentence-Based Box Highlight (Static Box + Word Popup)") sent_preset_name = "sent_box_static" sent_preset_data = { "name": (None, sent_preset_name), "font_name": (None, "Arial"), "font_size": "55", "primary_color": (None, "#FFFFFF"), "secondary_color": (None, "#00FF00"), # هايلايت أخضر "box_highlight_type": (None, "sentence"), # صندوق حول الجملة كلها "box_rounding": (None, "15"), "back_box_enabled": (None, "true"), "pop_up_scale": (None, "1.4"), # بوب أب للكلمة داخل الصندوق "background_opacity": (None, "0.6") } client.post("/api/presets/save", data=sent_preset_data) # Run a test for both for p_name in [word_preset_name, sent_preset_name]: process_data = { "original_filename": (None, video_name), "aspect_ratio": (None, "9:16"), "style": (None, "cinematic"), "subtitle_style": (None, p_name), "transcription": (None, json.dumps(transcription)) } resp = client.post("/api/video/process-saved", data=process_data) assert resp.status_code == 200 print(f"✅ Tested {p_name} successfully.") # Cleanup client.delete(f"/api/presets/delete/{word_preset_name}") client.delete(f"/api/presets/delete/{sent_preset_name}") process_data_custom = { "original_filename": (None, video_name), "aspect_ratio": (None, "9:16"), "style": (None, "cinematic"), "subtitle_style": (None, preset_name), "transcription": (None, json.dumps(transcription)) } resp = client.post("/api/video/process-saved", data=process_data_custom) assert resp.status_code == 200 print(f"✅ Custom Preset with Blue Box processed successfully.") # 3. Cleanup client.delete(f"/api/presets/delete/{preset_name}") if os.path.exists(audio_file_path): os.remove(audio_file_path) print("\n" + "="*50) print("🏁 ALL MULTI-PRESET TESTS PASSED!") print("="*50) if __name__ == "__main__": test_full_workflow()