Scriptorium / tests /test_render_api.py
mattkevan's picture
Fix exporter
186f4a4
Raw
History Blame Contribute Delete
4.57 kB
import asyncio
import importlib
import sys
from types import SimpleNamespace
import pytest
import gradio as gr
from fastapi.responses import FileResponse
def test_start_render_api_registers_one_streamed_output() -> None:
sys.modules.pop("app", None)
module = importlib.import_module("app")
with gr.Blocks() as demo:
dependency = gr.api(module.start_render_api, api_name="start_render")
assert dependency.get("outputs")
assert len(dependency["outputs"]) == 1
def test_start_render_api_adds_public_audio_url_to_completed_chapters(monkeypatch) -> None:
sys.modules.pop("app", None)
module = importlib.import_module("app")
class FakeSynthesisService:
def get_job(self, session_id):
return SimpleNamespace(status="idle")
def render(self, **kwargs):
yield {
"type": "chapter_done",
"session_id": kwargs["session_id"],
"chapter_id": "c1",
"duration_seconds": 12,
"overall_progress": 0.5,
"output_path": "/tmp/scriptorium/session-a/renders/001-c1.wav",
"backend": "modal",
"model": "magpie",
}
yield {
"type": "completed",
"session_id": kwargs["session_id"],
"outputs": ["/tmp/scriptorium/session-a/renders/001-c1.wav"],
"backend": "modal",
"model": "magpie",
}
monkeypatch.setattr(module, "synthesis_service", FakeSynthesisService())
monkeypatch.setattr(module, "_selected_book", lambda session_id, selected_ids: {"chapters": [{"id": "c1", "included": True}]})
monkeypatch.setattr(module, "_voice_config_for_backend", lambda voice_config, session_id: voice_config)
monkeypatch.setattr(module.store, "save_json", lambda *args, **kwargs: None)
events = list(
module.start_render_api(
session_id="session-a",
selected_chapter_ids=["c1"],
voice_config={"mode": "auto"},
diffusion_steps=32,
speed=1.0,
)
)
chapter_done = events[0]
assert chapter_done["type"] == "chapter_done"
assert chapter_done["url"] == "/files/session-a/renders/001-c1.wav"
assert chapter_done["backend"] == "modal"
assert chapter_done["model"] == "magpie"
def test_generate_preview_api_exposes_model_and_backend(monkeypatch) -> None:
sys.modules.pop("app", None)
module = importlib.import_module("app")
class FakeSynthesisService:
def generate_preview(self, **kwargs):
output_path = kwargs["output_path"]
output_path.parent.mkdir(parents=True, exist_ok=True)
output_path.write_bytes(b"RIFFpreview")
return {
"duration_seconds": 6,
"sample_rate": 24000,
"backend": "modal",
"model": "magpie",
}
monkeypatch.setattr(module, "synthesis_service", FakeSynthesisService())
monkeypatch.setattr(
module,
"_book_payload",
lambda _session_id: {"chapters": [{"id": "c1", "text": "hello world", "title": "One"}]},
)
monkeypatch.setattr(module, "_voice_config_for_backend", lambda voice_config, session_id: voice_config)
payload = module.generate_preview_api(
session_id="session-a",
chapter_id="c1",
voice_config={"model": "magpie", "backend": "modal", "speaker": "Sofia", "language": "en"},
diffusion_steps=32,
speed=1.0,
)
assert payload["url"] == "/files/session-a/previews/c1.wav"
assert payload["backend"] == "modal"
assert payload["model"] == "magpie"
def test_serve_generated_file_supports_attachment_downloads(tmp_path, monkeypatch) -> None:
sys.modules.pop("app", None)
module = importlib.import_module("app")
session_root = tmp_path / "session-a"
export_path = session_root / "exports" / "reading-room.m4a"
export_path.parent.mkdir(parents=True, exist_ok=True)
export_path.write_bytes(b"m4a")
monkeypatch.setattr(module, "_session_root", lambda _session_id: session_root)
response = asyncio.run(
module.serve_generated_file(
session_id="session-a",
kind="exports",
filename="reading-room.m4a",
download=True,
)
)
assert isinstance(response, FileResponse)
assert "attachment" in response.headers["content-disposition"]
assert "reading-room.m4a" in response.headers["content-disposition"]