test_chapters.py (3127B)
1 """Testes do gerador de capitulos.""" 2 3 from __future__ import annotations 4 5 import json 6 import os 7 import unittest 8 from types import SimpleNamespace 9 from unittest.mock import MagicMock, patch 10 11 from lazier.core.chapters import build_chapters 12 from lazier.core.config import reset_model_config_cache 13 14 15 class _FakeChoice: 16 def __init__(self, content: str) -> None: 17 self.message = SimpleNamespace(content=content) 18 19 20 class _FakeResponse: 21 def __init__(self, content: str) -> None: 22 self.choices = [_FakeChoice(content)] 23 24 25 def _segments(count: int, step: float = 5.0): 26 """Gera segments simples com timestamps incrementais.""" 27 return [ 28 { 29 "start": i * step, 30 "end": (i + 1) * step, 31 "text": f"trecho {i + 1}", 32 } 33 for i in range(count) 34 ] 35 36 37 class ChaptersTests(unittest.TestCase): 38 def setUp(self) -> None: 39 os.environ["OPENAI_API_KEY"] = "test-key" 40 os.environ.pop("OPENAI_REASONING_EFFORT", None) 41 reset_model_config_cache() 42 43 def tearDown(self) -> None: 44 reset_model_config_cache() 45 46 def test_returns_empty_when_no_segments(self): 47 self.assertEqual(build_chapters([]), []) 48 49 def test_uses_fallback_for_short_audio(self): 50 # Menos que MIN_SEGMENTS_FOR_CHAPTERS (6) -> fallback determinista. 51 result = build_chapters(_segments(3)) 52 self.assertEqual(len(result), 1) 53 self.assertEqual(result[0]["start"], 0.0) 54 self.assertGreater(result[0]["end"], 0.0) 55 self.assertIn("start_hms", result[0]) 56 57 def test_builds_chapters_from_llm_response(self): 58 segments = _segments(20, step=10.0) # 0..200s 59 llm_payload = { 60 "chapters": [ 61 {"title": "Intro", "summary": "Abertura.", "start_index": 0, "end_index": 4}, 62 {"title": "Core", "summary": "Conteudo principal.", "start_index": 5, "end_index": 14}, 63 {"title": "Wrap", "summary": "Fechamento.", "start_index": 15, "end_index": 19}, 64 ] 65 } 66 67 client = MagicMock() 68 client.chat.completions.create.return_value = _FakeResponse(json.dumps(llm_payload)) 69 70 with patch("lazier.core.chapters._ensure_client", return_value=client): 71 chapters = build_chapters(segments, model="gpt-4o-mini") 72 73 self.assertEqual(len(chapters), 3) 74 self.assertEqual(chapters[0]["title"], "Intro") 75 self.assertEqual(chapters[0]["start"], 0.0) 76 self.assertGreaterEqual(chapters[1]["start"], chapters[0]["end"]) 77 self.assertEqual(chapters[2]["title"], "Wrap") 78 79 def test_falls_back_when_llm_fails(self): 80 segments = _segments(10, step=6.0) 81 client = MagicMock() 82 client.chat.completions.create.side_effect = Exception("network down") 83 84 with patch("lazier.core.chapters._ensure_client", return_value=client): 85 chapters = build_chapters(segments) 86 87 self.assertGreaterEqual(len(chapters), 1) 88 self.assertEqual(chapters[0]["start"], 0.0) 89 self.assertEqual(chapters[0]["title"], "Parte 1") 90 91 92 if __name__ == "__main__": 93 unittest.main()