| from unittest.mock import ANY, MagicMock, patch |
|
|
| import pytest |
|
|
| from app import process |
|
|
|
|
| @pytest.fixture(autouse=True) |
| def reset_app_mocks(): |
| """Replace app module's crew2 imports with mocks before each test.""" |
| import app as _app_mod |
|
|
| _app_mod.run_pipeline = MagicMock( |
| return_value={ |
| "prompt": "A dragon", |
| "result_corroborate": "Evidence 1", |
| "result_opposite": "Counter 1", |
| } |
| ) |
| _app_mod.generate_image = MagicMock(return_value=b"fake_png_bytes") |
| _app_mod.generate_caption = MagicMock( |
| return_value={"caption": "A beautiful narration.", "voice_style": "girl"} |
| ) |
| _app_mod.generate_voice = MagicMock(return_value=b"fake_wav_bytes") |
| _app_mod.transcribe_audio = MagicMock(return_value="transcribed text") |
|
|
| |
| patcher = patch("PIL.Image.open", return_value="fake_image_object") |
| patcher.start() |
| yield |
| patcher.stop() |
|
|
|
|
| class TestProcess: |
| def test_text_input_returns_all_outputs(self): |
| image, audio_path, caption, style = process("test statement", None) |
|
|
| import app as _app_mod |
|
|
| assert image == "fake_image_object" |
| assert isinstance(audio_path, str) |
| assert audio_path.endswith(".wav") |
| assert caption == "A beautiful narration." |
| assert style == "girl" |
|
|
| _app_mod.run_pipeline.assert_called_once_with("test statement", session_id=ANY) |
| _app_mod.transcribe_audio.assert_not_called() |
|
|
| def test_audio_input_transcribes_first(self): |
| process(None, "/path/to/audio.wav") |
|
|
| import app as _app_mod |
|
|
| _app_mod.transcribe_audio.assert_called_once_with("/path/to/audio.wav", session_id=ANY) |
| _app_mod.run_pipeline.assert_called_once_with("transcribed text", session_id=ANY) |
|
|
| def test_empty_text_raises_error(self): |
| with pytest.raises(Exception, match="provide text"): |
| process("", None) |
|
|
| def test_none_input_raises_error(self): |
| with pytest.raises(Exception, match="provide text"): |
| process(None, None) |
|
|
| def test_caption_not_found_fallback(self): |
| import app as _app_mod |
|
|
| _app_mod.generate_caption.return_value = { |
| "caption": None, |
| "voice_style": None, |
| } |
|
|
| image, audio_path, caption, style = process("test", None) |
|
|
| assert caption == "(not found)" |
| assert style == "(not found)" |
|
|
| def test_audio_has_priority_over_text(self): |
| import app as _app_mod |
|
|
| process("ignored text", "/path/to/audio.wav") |
|
|
| _app_mod.transcribe_audio.assert_called_once_with("/path/to/audio.wav", session_id=ANY) |
| _app_mod.run_pipeline.assert_called_once_with("transcribed text", session_id=ANY) |
|
|