Files
Aletheia/server/audiobook/test_voicestudio_client.py

40 lines
2.2 KiB
Python

import io
import json
from pathlib import Path
import tempfile
import unittest
from unittest.mock import patch
import voicestudio_client as adapter
class VoiceStudioTests(unittest.TestCase):
def test_bounded_parts_preserve_text_order(self):
text = ('Это длинный раздел книги. ' * 2000).strip()
parts = adapter.split_sections([('Глава', text)])
self.assertGreater(len(parts), 20)
self.assertTrue(all(0 < len(part) <= 1600 for _, part in parts))
self.assertEqual(text, ' '.join(part for _, part in parts))
self.assertEqual([], adapter.split_sections([('Пустая', ' ')]))
def test_stream_progress_and_completed_container(self):
with tempfile.TemporaryDirectory() as root:
outputs = Path(root)
audio = b'\x00\x00\x00\x18ftypM4A ' + b'\0' * 128
(outputs / 'result.m4b').write_bytes(audio)
events = [{'type': 'chapter', 'index': 0, 'total': 1},
{'type': 'assembling'},
{'type': 'done', 'output': 'result.m4b', 'duration_s': 1, 'failed_chapters': []}]
stream = io.BytesIO(b''.join(('data: ' + json.dumps(e) + '\n\n').encode() for e in events))
seen = []
with patch('audio_cleanup.remember_output') as remember, patch.object(adapter, 'check_available'), patch.object(adapter, 'OUTPUTS', outputs), patch.object(adapter, 'urlopen', return_value=stream):
adapter.render_audiobook([('Глава', 'Текст')], 'Книга', 'Автор', outputs / 'book.m4a', seen.append, lambda: False)
remember.assert_called_once_with(outputs / 'book.m4a', outputs / 'result.m4b')
self.assertEqual(events, seen)
self.assertEqual(audio, (outputs / 'book.m4a').read_bytes())
def test_failed_chapters_never_become_ready(self):
stream = io.BytesIO(b'data: {"type":"done","failed_chapters":[1]}\n')
with patch.object(adapter, 'check_available'), patch.object(adapter, 'urlopen', return_value=stream):
with self.assertRaises(RuntimeError):
adapter.render_audiobook([('Chapter', 'Text')], 'Book', '', Path('unused.m4a'), lambda event: None, lambda: False)