test: cover casting constraints

This commit is contained in:
mARTin-B78 2026-09-04 09:28:26 +02:00
parent c6c9c53489
commit 748351b71f
4 changed files with 27 additions and 2 deletions

View File

@ -46,6 +46,8 @@ Follows [Keep a Changelog](https://keepachangelog.com/en/1.0.0/) · versioned wi
duplicate manifest entries, and top-level declaration collisions before bundling.
- **Provider Boundary Regression Coverage.** Added deterministic tests for STT backend normalization and ComfyUI
workflow submission, prompt injection, polling, seed derivation, and image retrieval.
- **Casting Constraint Coverage.** Added deterministic regression coverage proving casting filters invented voice IDs
and avoids unnecessary duplicate assignments when distinct catalogue voices are available.
- **STT Cancellation Safety.** Queued transcription cancels before consuming the single STT slot, and timed-out
requests keep the device slot held until the underlying worker actually exits.
- **Credential Boundary Review.** Provider credentials are now documented as server-only; only the explicitly

View File

@ -165,7 +165,7 @@ the first block before investing in architecture or polish.
### Automated tests
- [ ] Character parsing and phantom-speaker prevention.
- [ ] Voice-matching constraints.
- [x] Voice-matching constraints reject invented voice IDs and avoid unnecessary duplicate assignments.
- [ ] Profile-completeness counting.
- [x] Rating persistence.
- [x] STT endpoint normalization and backend-response shape handling.

View File

@ -1 +1 @@
1.23.2
1.23.3

View File

@ -19,6 +19,8 @@ from routes.conversation import (
_fallback_attribute_response,
_bundled_comfyui_workflow,
_comfyui_run,
_CastJobRequest,
match_characters_voices,
)
@ -106,6 +108,27 @@ class AttributionParserTests(unittest.TestCase):
self.assertEqual(submitted["2"]["inputs"]["text"], "new prompt")
self.assertNotEqual(submitted["5"]["inputs"]["seed"], 0)
def test_voice_matching_rejects_invented_and_unnecessarily_duplicate_ids(self):
from unittest.mock import patch
class ResponseStub:
status_code = 200
ok = True
text = ""
def raise_for_status(self):
return None
def json(self):
return {"choices": [{"message": {"content": json.dumps({"assignments": [
{"name": "A", "voice_id": "v1", "reason": "match"},
{"name": "B", "voice_id": "invented", "reason": "bad"},
{"name": "C", "voice_id": "v1", "reason": "duplicate"},
]})}}]}
data = {"names": ["A", "B", "C"], "voices": [{"id": "v1", "gender": "F"}, {"id": "v2", "gender": "M"}], "script": "short", "llm_url": "http://llm/v1"}
with patch("routes.conversation.requests.post", return_value=ResponseStub()):
result = __import__("asyncio").run(match_characters_voices(_CastJobRequest(data, {})))
self.assertEqual([item["voice_id"] for item in result["assignments"]], ["v1"])
def test_consistent_image_job_can_be_cancelled(self):
from fastapi.testclient import TestClient
from server import app