Files
audiobook/backend/test_script_endpoint.py
Paul Bailey e2196c592a Implement script generation endpoint (Task 18)
- Added ScriptRequest, ScriptResponse, and ScriptSegment Pydantic models
- Created /api/tts/script POST endpoint in main.py
- Integrated with TTSService to generate script segments using AI
- Added generate_script_segments method to TTSService
- Returns segments with unique IDs for frontend tracking
- Handles errors gracefully when AI segmentation fails
- Falls back to pattern-based segmentation when Ollama unavailable
- Added comprehensive tests for the endpoint
- Validates: Requirements 15.1, 15.2
2025-12-09 11:43:04 +00:00

174 lines
4.8 KiB
Python

"""
Tests for the script generation endpoint.
"""
import pytest
from fastapi.testclient import TestClient
from main import app
client = TestClient(app)
def test_script_endpoint_exists():
"""Test that the /api/tts/script endpoint exists."""
response = client.post(
"/api/tts/script",
json={
"text": "Alice: Hello there!\nBob: Hi Alice!",
"roles": ["Alice", "Bob"]
}
)
# Should not return 404
assert response.status_code != 404
def test_script_generation_with_valid_input():
"""Test script generation with valid text and roles."""
response = client.post(
"/api/tts/script",
json={
"text": "Alice: Hello there!\nBob: Hi Alice, how are you?",
"roles": ["Alice", "Bob", "Narrator"]
}
)
assert response.status_code == 200
data = response.json()
# Check response structure
assert "segments" in data
assert isinstance(data["segments"], list)
assert len(data["segments"]) > 0
# Check each segment has required fields
for segment in data["segments"]:
assert "id" in segment
assert "speaker" in segment
assert "text" in segment
assert isinstance(segment["id"], str)
assert isinstance(segment["speaker"], str)
assert isinstance(segment["text"], str)
assert len(segment["text"]) > 0
def test_script_generation_with_empty_text():
"""Test that empty text returns validation error."""
response = client.post(
"/api/tts/script",
json={
"text": "",
"roles": ["Alice", "Bob"]
}
)
assert response.status_code == 400
data = response.json()
assert "error" in data
assert data["error"] == "ValidationError"
def test_script_generation_with_empty_roles():
"""Test that empty roles list returns validation error."""
response = client.post(
"/api/tts/script",
json={
"text": "Some text here",
"roles": []
}
)
assert response.status_code == 400
data = response.json()
assert "error" in data
assert data["error"] == "ValidationError"
def test_script_generation_missing_text_field():
"""Test that missing text field returns validation error."""
response = client.post(
"/api/tts/script",
json={
"roles": ["Alice", "Bob"]
}
)
# Our error handler converts 422 to 400
assert response.status_code == 400
data = response.json()
assert "error" in data
assert data["error"] == "ValidationError"
def test_script_generation_missing_roles_field():
"""Test that missing roles field returns validation error."""
response = client.post(
"/api/tts/script",
json={
"text": "Some text here"
}
)
# Our error handler converts 422 to 400
assert response.status_code == 400
data = response.json()
assert "error" in data
assert data["error"] == "ValidationError"
def test_script_segments_have_unique_ids():
"""Test that each segment has a unique ID."""
response = client.post(
"/api/tts/script",
json={
"text": "Alice: Hello!\nBob: Hi!\nAlice: How are you?\nBob: Good!",
"roles": ["Alice", "Bob"]
}
)
assert response.status_code == 200
data = response.json()
segment_ids = [seg["id"] for seg in data["segments"]]
# Check all IDs are unique
assert len(segment_ids) == len(set(segment_ids))
def test_script_generation_with_narrator_text():
"""Test script generation with narrative text (no role markers)."""
response = client.post(
"/api/tts/script",
json={
"text": "The sun was setting over the horizon. It was a beautiful evening.",
"roles": ["Narrator"]
}
)
assert response.status_code == 200
data = response.json()
assert len(data["segments"]) > 0
# Should assign to Narrator since no role markers
assert any(seg["speaker"] == "Narrator" for seg in data["segments"])
def test_script_generation_with_mixed_content():
"""Test script generation with both dialogue and narrative."""
response = client.post(
"/api/tts/script",
json={
"text": "The wizard looked into his crystal ball.\nWizard: I see danger approaching.\nThe knight heard the warning.",
"roles": ["Wizard", "Narrator"]
}
)
assert response.status_code == 200
data = response.json()
assert len(data["segments"]) >= 2
speakers = [seg["speaker"] for seg in data["segments"]]
# Should have both Wizard and Narrator
assert "Wizard" in speakers or "Narrator" in speakers
if __name__ == "__main__":
pytest.main([__file__, "-v"])