Files
video-gen/tests/unit/test_cli.py

188 lines
6.2 KiB
Python

"""
Tests for CLI module.
"""
import pytest
import tempfile
from pathlib import Path
from unittest.mock import patch, MagicMock
from typer.testing import CliRunner
from src.cli.main import app
runner = CliRunner()
# Valid storyboard JSON template
VALID_STORYBOARD = """
{
"schema_version": "1.0",
"project": {
"title": "Test Storyboard",
"fps": 24,
"target_duration_s": 20,
"resolution": {"width": 1280, "height": 720},
"aspect_ratio": "16:9"
},
"shots": [
{
"id": "shot_001",
"duration_s": 4,
"prompt": "A test shot description",
"camera": {"framing": "wide", "movement": "static"},
"generation": {"seed": 42, "steps": 30, "cfg_scale": 6.0}
}
],
"output": {
"container": "mp4",
"codec": "h264",
"crf": 18,
"preset": "medium"
}
}
"""
class TestValidateCommand:
"""Test the validate command."""
def test_validate_nonexistent_file(self):
"""Test validation with non-existent file."""
result = runner.invoke(app, ["validate", "nonexistent.json"])
assert result.exit_code == 1
assert "not found" in result.output
def test_validate_valid_storyboard(self):
"""Test validation with valid storyboard."""
with tempfile.TemporaryDirectory() as tmpdir:
storyboard_file = Path(tmpdir) / "test.json"
storyboard_file.write_text(VALID_STORYBOARD)
result = runner.invoke(app, ["validate", str(storyboard_file)])
assert result.exit_code == 0
assert "valid" in result.output
assert "Test Storyboard" in result.output
def test_validate_verbose(self):
"""Test validation with verbose flag."""
with tempfile.TemporaryDirectory() as tmpdir:
storyboard_file = Path(tmpdir) / "test.json"
storyboard_file.write_text(VALID_STORYBOARD)
result = runner.invoke(app, ["validate", str(storyboard_file), "--verbose"])
assert result.exit_code == 0
assert "Shots" in result.output
class TestListBackendsCommand:
"""Test the list-backends command."""
def test_list_backends(self):
"""Test listing available backends."""
result = runner.invoke(app, ["list-backends"])
assert result.exit_code == 0
assert "wan" in result.output
assert "Available Backends" in result.output
class TestGenerateCommand:
"""Test the generate command."""
@pytest.fixture
def mock_storyboard(self):
"""Create a mock storyboard file."""
with tempfile.TemporaryDirectory() as tmpdir:
storyboard_file = Path(tmpdir) / "test.json"
storyboard_file.write_text(VALID_STORYBOARD)
yield storyboard_file
def test_generate_dry_run(self, mock_storyboard):
"""Test generate command with dry-run flag."""
result = runner.invoke(app, [
"generate",
str(mock_storyboard),
"--dry-run"
])
assert result.exit_code == 0
assert "Dry run complete" in result.output
def test_generate_nonexistent_storyboard(self):
"""Test generate with non-existent storyboard."""
result = runner.invoke(app, ["generate", "nonexistent.json"])
assert result.exit_code == 1
assert "not found" in result.output
class TestResumeCommand:
"""Test the resume command."""
def test_resume_nonexistent_project(self):
"""Test resume with non-existent project."""
with tempfile.TemporaryDirectory() as tmpdir:
result = runner.invoke(app, [
"resume",
"nonexistent_project",
"--output", tmpdir
])
assert result.exit_code == 1
assert "No checkpoint found" in result.output
def test_resume_existing_project(self):
"""Test resume with existing project checkpoint."""
with tempfile.TemporaryDirectory() as tmpdir:
project_dir = Path(tmpdir) / "test_project"
project_dir.mkdir()
checkpoint_db = project_dir / "checkpoints.db"
checkpoint_db.touch()
# Create a mock checkpoint
with patch('src.cli.main.CheckpointManager') as mock_mgr:
mock_checkpoint = MagicMock()
mock_checkpoint.storyboard_path = str(Path(tmpdir) / "storyboard.json")
mock_mgr.return_value.get_project_checkpoint.return_value = mock_checkpoint
# Create storyboard file
storyboard_file = Path(tmpdir) / "storyboard.json"
storyboard_file.write_text(VALID_STORYBOARD)
result = runner.invoke(app, [
"resume",
"test_project",
"--output", tmpdir
])
# Should attempt to resume (may fail on actual generation)
assert "Resuming project" in result.output or result.exit_code != 0
class TestCLIHelp:
"""Test CLI help messages."""
def test_main_help(self):
"""Test main help message."""
result = runner.invoke(app, ["--help"])
assert result.exit_code == 0
assert "Storyboard to Video Generation Pipeline" in result.output
def test_generate_help(self):
"""Test generate command help."""
result = runner.invoke(app, ["generate", "--help"])
assert result.exit_code == 0
assert "Generate video from storyboard" in result.output
assert "--output" in result.output
assert "--backend" in result.output
assert "--dry-run" in result.output
def test_validate_help(self):
"""Test validate command help."""
result = runner.invoke(app, ["validate", "--help"])
assert result.exit_code == 0
assert "Validate a storyboard file" in result.output
def test_resume_help(self):
"""Test resume command help."""
result = runner.invoke(app, ["resume", "--help"])
assert result.exit_code == 0
assert "Resume a failed or interrupted project" in result.output