aboutsummaryrefslogtreecommitdiff
path: root/app/tests
diff options
context:
space:
mode:
authorhistoria <historiavg@proton.me>2026-09-01 03:38:50 -0400
committerhistoria <historiavg@proton.me>2026-09-01 03:38:50 -0400
commitd15adb490b634dd22a65a1c8d7f4ec9fa74816b4 (patch)
tree8fc5da437ceffc22482968cdf7c2591c81a407cc /app/tests
parent058b19e7a65b40b1024a4fdeb2233062ff273cfd (diff)
downloadtts-audiobook-generator-d15adb490b634dd22a65a1c8d7f4ec9fa74816b4.tar.gz
fix: hide speech-to-speech only models from config wizard
Diffstat (limited to 'app/tests')
-rw-r--r--app/tests/test_backends_audiocpp.py25
-rw-r--r--app/tests/test_hub.py12
-rw-r--r--app/tests/test_tts.py7
3 files changed, 38 insertions, 6 deletions
diff --git a/app/tests/test_backends_audiocpp.py b/app/tests/test_backends_audiocpp.py
index 8b1698b..7edb3c9 100644
--- a/app/tests/test_backends_audiocpp.py
+++ b/app/tests/test_backends_audiocpp.py
@@ -385,6 +385,31 @@ class LoadModelCatalogTests(unittest.TestCase):
self.assertNotIn("empty_tts",
[entry["family"] for entry in catalog])
+ def test_skips_speech_to_speech_only_families(self):
+ # PersonaPlex-style specs: categorized "tts" but with a task list
+ # naming no text-synthesis capability — the family cannot narrate
+ # text and every request would fail, so it is never offered for
+ # install (the generic task check, no family names hardcoded).
+ _write_spec(self.checkout, "personaplex", tasks=("s2s",))
+ catalog = make_server.catalog.load_model_catalog(self.checkout)
+ self.assertNotIn("personaplex",
+ [entry["family"] for entry in catalog])
+
+ def test_design_only_family_is_kept(self):
+ # Voice design is a text-synthesis task: a vdes-only spec stays
+ # installable.
+ _write_spec(self.checkout, "designer", tasks=("vdes",))
+ catalog = make_server.catalog.load_model_catalog(self.checkout)
+ self.assertIn("designer", [entry["family"] for entry in catalog])
+
+ def test_taskless_tts_category_fallback_is_kept(self):
+ # A spec without a task list keeps the old category fallback, so
+ # a future/malformed "tts" spec is not silently dropped.
+ _write_spec(self.checkout, "mystery_tts", tasks=())
+ catalog = make_server.catalog.load_model_catalog(self.checkout)
+ self.assertIn("mystery_tts",
+ [entry["family"] for entry in catalog])
+
def test_families_sorted_alphabetically_by_display_name(self):
catalog = make_server.catalog.load_model_catalog(self.checkout)
names = [entry["display_name"].lower() for entry in catalog]
diff --git a/app/tests/test_hub.py b/app/tests/test_hub.py
index 80a97d0..ddd6ec0 100644
--- a/app/tests/test_hub.py
+++ b/app/tests/test_hub.py
@@ -1238,7 +1238,9 @@ class ConvertFlowTests(unittest.TestCase):
self.assertEqual(kwargs["model_ids"], ["alpha"])
self.assertEqual(kwargs["model_voices"], {"alpha": "narrator"})
self.assertEqual(kwargs["run_notice"],
- "skipped non-TTS model(s): plex")
+ "skipped plex — speech-to-speech, not TTS: it "
+ "cannot turn text into audio. Consider deleting "
+ "the model")
def test_all_pick_refuses_when_every_model_is_non_narrating(self):
# With nothing left to generate with after the skip, the All pick
@@ -1260,9 +1262,11 @@ class ConvertFlowTests(unittest.TestCase):
self._field("model_id")["value"] = hub.AUDIOCPP_MODEL_ALL
error = voice_field["validate"]("narrator")
self.assertIsNotNone(error)
- self.assertIn("plex-1", error)
- self.assertIn("plex-2", error)
- self.assertIn("synthesize text", error)
+ self.assertIn("plex-1, plex-2", error)
+ self.assertIn("speech-to-speech, not TTS", error)
+ self.assertIn("cannot turn text into audio", error)
+ self.assertIn("Consider deleting the models", error)
+ self.assertIn("nothing for an 'All' run", error)
def test_all_voice_falls_back_per_capability(self):
# A CustomVoice entry cannot clone: it synthesizes with a built-in
diff --git a/app/tests/test_tts.py b/app/tests/test_tts.py
index 8403913..6c245e5 100644
--- a/app/tests/test_tts.py
+++ b/app/tests/test_tts.py
@@ -1051,7 +1051,9 @@ class AudioCppFamilyDetectionTests(unittest.TestCase):
{"id": "tts-1", "family": "qwen3_tts", "task": "tts"}]})
message = str(ctx.exception)
self.assertIn("personaplex", message)
- self.assertIn("speech-to-speech", message)
+ self.assertIn("speech-to-speech, not TTS", message)
+ self.assertIn("cannot synthesize narration", message)
+ self.assertIn("Consider deleting the model", message)
self.assertIn(_AUDIOCPP_MODEL_ID, message)
self.assertIn("tts-1", message)
@@ -1385,7 +1387,8 @@ class AudioCppDeterministicErrorTests(unittest.TestCase):
def test_speech_to_speech_only_family_is_not_retryable_with_a_hint(self):
exc = self._error("PersonaPlex supports only speech-to-speech sessions")
self.assertIsInstance(exc, NonRetryableTTSError)
- self.assertIn("cannot generate audiobooks", str(exc))
+ self.assertIn("speech-to-speech, not TTS", str(exc))
+ self.assertIn("Consider deleting the model", str(exc))
def test_unresolvable_clone_voice_is_not_retryable_with_a_hint(self):
exc = self._error("Vevo2 requires target_voice or voice speaker audio")