This repository has been archived on 2026-03-24. You can view files and clone it. You cannot open issues or pull requests or push a commit.
Files
Timmy-time-dashboard/tests/test_video_tools.py
Claude 1103da339c feat: add full creative studio + DevOps tools (Pixel, Lyra, Reel personas)
Adds 3 new personas (Pixel, Lyra, Reel) and 5 new tool modules:

- Git/DevOps tools (GitPython): clone, status, diff, log, blame, branch,
  add, commit, push, pull, stash — wired to Forge and Helm personas
- Image generation (FLUX via diffusers): text-to-image, storyboards,
  variations — Pixel persona
- Music generation (ACE-Step 1.5): full songs with vocals+instrumentals,
  instrumental tracks, vocal-only tracks — Lyra persona
- Video generation (Wan 2.1 via diffusers): text-to-video, image-to-video
  clips — Reel persona
- Creative Director pipeline: multi-step orchestration that chains
  storyboard → music → video → assembly into 3+ minute final videos
- Video assembler (MoviePy + FFmpeg): stitch clips, overlay audio,
  title cards, subtitles, final export

Also includes:
- Spark Intelligence tool-level + creative pipeline event capture
- Creative Studio dashboard page (/creative/ui) with 4 tabs
- Config settings for all new models and output directories
- pyproject.toml creative optional extra for GPU dependencies
- 107 new tests covering all modules (624 total, all passing)

https://claude.ai/code/session_01KJm6jQkNi3aA3yoQJn636c
2026-02-24 16:31:47 +00:00

94 lines
3.2 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
"""Tests for tools.video_tools — Video generation (Reel persona).
Heavy AI model tests are skipped; only catalogue, interface, and
resolution preset tests run in CI.
"""
import pytest
from unittest.mock import patch, MagicMock
from tools.video_tools import (
VIDEO_TOOL_CATALOG,
RESOLUTION_PRESETS,
VIDEO_STYLES,
list_video_styles,
generate_video_clip,
image_to_video,
)
class TestVideoToolCatalog:
def test_catalog_has_all_tools(self):
expected = {"generate_video_clip", "image_to_video", "list_video_styles"}
assert expected == set(VIDEO_TOOL_CATALOG.keys())
def test_catalog_entries_have_required_keys(self):
for tool_id, info in VIDEO_TOOL_CATALOG.items():
assert "name" in info
assert "description" in info
assert "fn" in info
assert callable(info["fn"])
class TestResolutionPresets:
def test_480p_preset(self):
assert RESOLUTION_PRESETS["480p"] == (854, 480)
def test_720p_preset(self):
assert RESOLUTION_PRESETS["720p"] == (1280, 720)
class TestVideoStyles:
def test_common_styles_present(self):
for style in ["cinematic", "anime", "documentary"]:
assert style in VIDEO_STYLES
class TestListVideoStyles:
def test_returns_styles_and_resolutions(self):
result = list_video_styles()
assert result["success"]
assert "cinematic" in result["styles"]
assert "480p" in result["resolutions"]
assert "720p" in result["resolutions"]
class TestGenerateVideoClipInterface:
def test_raises_without_creative_deps(self):
with patch("tools.video_tools._t2v_pipeline", None):
with patch("tools.video_tools._get_t2v_pipeline", side_effect=ImportError("no diffusers")):
with pytest.raises(ImportError):
generate_video_clip("a sunset")
def test_duration_clamped(self):
"""Duration is clamped to 210 range."""
import sys
mock_pipe = MagicMock()
mock_pipe.device = "cpu"
mock_result = MagicMock()
mock_result.frames = [[MagicMock() for _ in range(48)]]
mock_pipe.return_value = mock_result
mock_torch = MagicMock()
mock_torch.Generator.return_value = MagicMock()
out_dir = MagicMock()
out_dir.__truediv__ = MagicMock(return_value=MagicMock(__str__=lambda s: "/fake/clip.mp4"))
with patch.dict(sys.modules, {"torch": mock_torch}):
with patch("tools.video_tools._get_t2v_pipeline", return_value=mock_pipe):
with patch("tools.video_tools._export_frames_to_mp4"):
with patch("tools.video_tools._output_dir", return_value=out_dir):
with patch("tools.video_tools._save_metadata"):
result = generate_video_clip("test", duration=50)
assert result["duration"] == 10 # clamped
class TestImageToVideoInterface:
def test_raises_without_creative_deps(self):
with patch("tools.video_tools._t2v_pipeline", None):
with patch("tools.video_tools._get_t2v_pipeline", side_effect=ImportError("no diffusers")):
with pytest.raises(ImportError):
image_to_video("/fake/image.png", "animate")