Clipping / tests /test_comprehensive_e2e.py
aliSaac510's picture
save fix
7af5aaa
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()