From 748351b71f26c5d4e6be4f08b952eb18db49e060 Mon Sep 17 00:00:00 2001 From: mARTin-B78 Date: Fri, 4 Sep 2026 09:28:26 +0200 Subject: [PATCH] test: cover casting constraints --- CHANGELOG.md | 2 ++ TODO.md | 2 +- VERSION | 2 +- tests/test_conversation.py | 23 +++++++++++++++++++++++ 4 files changed, 27 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 5a6ffd7..2a74301 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -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 diff --git a/TODO.md b/TODO.md index 4d9dc76..06587f9 100644 --- a/TODO.md +++ b/TODO.md @@ -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. diff --git a/VERSION b/VERSION index 14bee92..ac1df3f 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -1.23.2 +1.23.3 diff --git a/tests/test_conversation.py b/tests/test_conversation.py index a9060ac..81ea182 100644 --- a/tests/test_conversation.py +++ b/tests/test_conversation.py @@ -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