diff options
| author | historia <historiavg@proton.me> | 2026-08-26 19:12:11 -0400 |
|---|---|---|
| committer | historia <historiavg@proton.me> | 2026-08-26 19:12:11 -0400 |
| commit | 5af37bbd575eec89c6ac2fecf2d8c2eda4c1728d (patch) | |
| tree | 4f8fe9b79d339695ca83968e03301b853eb2e2ef /app/tests/test_hub.py | |
| parent | df95e7034df683c38fde67890430ab4c2abfa4ba (diff) | |
| download | tts-audiobook-generator-5af37bbd575eec89c6ac2fecf2d8c2eda4c1728d.tar.gz | |
fix: crash when menu of clone voices is empty
Diffstat (limited to 'app/tests/test_hub.py')
| -rw-r--r-- | app/tests/test_hub.py | 50 |
1 files changed, 50 insertions, 0 deletions
diff --git a/app/tests/test_hub.py b/app/tests/test_hub.py index 6657540..73ef075 100644 --- a/app/tests/test_hub.py +++ b/app/tests/test_hub.py @@ -856,6 +856,56 @@ class ConvertFlowTests(unittest.TestCase): instr = self._field("instructions") self.assertFalse(instr["visible"](fields)) + def test_audiocpp_remote_without_voices_refuses_generate_with_hint(self): + # A clone-capable entry (e.g. Qwen Base) whose server lists no + # voices at all: the Voice picker stays visible but is empty — + # opening it flashes where to configure voices instead of + # crashing — and Generate! refuses with the same hint. + self._patch_remote( + [{"id": "Qwen3-TTS-12Hz-1.7B-Base-GGUF", + "family": "qwen3_tts", "task": "tts"}], + voices=[]) + with patch.object(hub.config, "AUDIOCPP_INSTRUCTIONS", ""): + self._answer_form( + backend="audiocpp-remote", + model_id="Qwen3-TTS-12Hz-1.7B-Base-GGUF", + audiocpp_voice="", instructions="") + self._convert(None, [self._remote("audiocpp", "audio.cpp")]) + fields = self.tui.forms_seen[0][1] + voice_field = self._field("audiocpp_voice") + self.assertTrue(voice_field["visible"](fields)) + self.assertEqual(voice_field["choices"](fields), []) + error = voice_field["validate"]("") + self.assertIsNotNone(error) + self.assertIn(".wav", error) + self.assertIn("server", error) + + def test_audiocpp_local_without_voice_dir_points_at_configure(self): + # The managed entry's server.json has no voice_dir: clone-capable + # models get an empty Voice picker whose hint sends the user to + # Configure backends instead of crashing on menu(). + with tempfile.TemporaryDirectory() as td: + root = Path(td) + (root / "server.json").write_text(json.dumps({ + "models": [{"id": "qwen", "family": "qwen3_tts", + "task": "tts"}], + }), encoding="utf-8") + with patch.object(hub.audiocpp_backend, "find_local_checkout", + return_value=root), \ + patch.object(hub.config, "AUDIOCPP_INSTRUCTIONS", ""): + self._answer_form(backend="audiocpp", model_id="qwen", + audiocpp_voice="", instructions="") + self._convert(None, + [self._ready("audiocpp", "audio.cpp")]) + fields = self.tui.forms_seen[0][1] + voice_field = self._field("audiocpp_voice") + self.assertTrue(voice_field["visible"](fields)) + self.assertEqual(voice_field["choices"](fields), []) + error = voice_field["validate"]("") + self.assertIsNotNone(error) + self.assertIn(".wav", error) + self.assertIn("Configure backends", error) + def test_audiocpp_remote_missing_family_is_clone_capable(self): # A missing family is unknown — not guessed as qwen3_tts — so the # entry is clone-only: it needs a --voice rather than offering a |
