| import json |
| import os |
| import sys |
| import time |
| from fastapi.testclient import TestClient |
|
|
| |
| 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) |
| |
| |
| video_name = create_mock_video_if_needed() |
| audio_file_path = create_mock_audio() |
| |
| |
| 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.") |
|
|
| |
| |
| 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) |
| |
| |
| 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) |
| |
| |
| 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.") |
|
|
| |
| 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.") |
|
|
| |
| 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() |
|
|