Files
2026-04-12 01:06:31 +07:00

186 lines
7.5 KiB
Python

"""
Tests for minimax_cli.py - CLI argument parsing and task dispatch.
"""
import pytest
import sys
from pathlib import Path
from unittest.mock import Mock, patch, MagicMock
sys.path.insert(0, str(Path(__file__).parent.parent))
import minimax_cli as cli
class TestTaskDefaults:
"""Test task-to-model default mapping."""
def test_generate_defaults_to_image_01(self):
assert cli.TASK_DEFAULTS['generate'] == 'image-01'
def test_generate_video_defaults_to_hailuo(self):
assert cli.TASK_DEFAULTS['generate-video'] == 'MiniMax-Hailuo-2.3'
def test_generate_speech_defaults_to_speech_28_hd(self):
assert cli.TASK_DEFAULTS['generate-speech'] == 'speech-2.8-hd'
def test_generate_music_defaults_to_music_25(self):
assert cli.TASK_DEFAULTS['generate-music'] == 'music-2.5'
class TestPrintResult:
"""Test result formatting."""
def test_success_image(self, capsys):
result = {
"status": "success",
"generated_images": ["/path/to/img.png"],
"model": "image-01"
}
cli.print_result(result, "generate")
output = capsys.readouterr().out
assert "success" in output.lower()
assert "/path/to/img.png" in output
assert "image-01" in output
def test_success_video(self, capsys):
result = {
"status": "success",
"generated_video": "/path/to/vid.mp4",
"generation_time": 45.2,
"model": "MiniMax-Hailuo-2.3"
}
cli.print_result(result, "generate-video")
output = capsys.readouterr().out
assert "/path/to/vid.mp4" in output
assert "45.2s" in output
def test_success_audio(self, capsys):
result = {
"status": "success",
"generated_audio": "/path/to/audio.mp3",
"duration_ms": 140000,
"model": "music-2.5"
}
cli.print_result(result, "generate-music")
output = capsys.readouterr().out
assert "/path/to/audio.mp3" in output
assert "140.0s" in output
def test_error_result(self, capsys):
result = {"status": "error", "error": "Rate limit exceeded"}
cli.print_result(result, "generate")
output = capsys.readouterr().out
assert "Rate limit exceeded" in output
def test_unknown_status(self, capsys):
result = {"model": "image-01"}
cli.print_result(result, "generate")
output = capsys.readouterr().out
assert "unknown" in output.lower()
class TestMainCLI:
"""Test CLI main() argument parsing and dispatch."""
@patch('minimax_cli.find_minimax_api_key', return_value=None)
def test_no_api_key_exits(self, mock_key, capsys):
with patch('sys.argv', ['cli', '--task', 'generate', '--prompt', 'x']):
with pytest.raises(SystemExit) as exc_info:
cli.main()
assert exc_info.value.code == 1
@patch('minimax_cli.generate_image')
@patch('minimax_cli.find_minimax_api_key', return_value='test-key')
def test_generate_image_dispatch(self, mock_key, mock_gen):
mock_gen.return_value = {"status": "success", "generated_images": [],
"model": "image-01"}
with patch('sys.argv', ['cli', '--task', 'generate',
'--prompt', 'A cat']):
cli.main()
mock_gen.assert_called_once()
args = mock_gen.call_args
assert args[0][0] == 'test-key'
assert args[0][1] == 'A cat'
@patch('minimax_cli.generate_speech')
@patch('minimax_cli.find_minimax_api_key', return_value='test-key')
def test_generate_speech_dispatch(self, mock_key, mock_gen):
mock_gen.return_value = {"status": "success",
"generated_audio": "/x.mp3",
"model": "speech-2.8-hd"}
with patch('sys.argv', ['cli', '--task', 'generate-speech',
'--text', 'Hello world']):
cli.main()
mock_gen.assert_called_once()
@patch('minimax_cli.generate_speech')
@patch('minimax_cli.find_minimax_api_key', return_value='test-key')
def test_speech_uses_text_or_prompt(self, mock_key, mock_gen):
mock_gen.return_value = {"status": "success",
"generated_audio": "/x.mp3",
"model": "speech-2.8-hd"}
# --prompt should work as fallback for --text
with patch('sys.argv', ['cli', '--task', 'generate-speech',
'--prompt', 'Fallback text']):
cli.main()
call_args = mock_gen.call_args
assert call_args[0][1] == 'Fallback text'
@patch('minimax_cli.generate_music')
@patch('minimax_cli.find_minimax_api_key', return_value='test-key')
def test_generate_music_dispatch(self, mock_key, mock_gen):
mock_gen.return_value = {"status": "success",
"generated_audio": "/x.mp3",
"duration_ms": 60000,
"model": "music-2.5"}
with patch('sys.argv', ['cli', '--task', 'generate-music',
'--lyrics', 'La la la']):
cli.main()
mock_gen.assert_called_once()
@patch('minimax_cli.generate_video')
@patch('minimax_cli.find_minimax_api_key', return_value='test-key')
def test_generate_video_dispatch(self, mock_key, mock_gen):
mock_gen.return_value = {"status": "success",
"generated_video": "/x.mp4",
"generation_time": 30.0,
"model": "MiniMax-Hailuo-2.3"}
with patch('sys.argv', ['cli', '--task', 'generate-video',
'--prompt', 'A dancer']):
cli.main()
mock_gen.assert_called_once()
@patch('minimax_cli.find_minimax_api_key', return_value='test-key')
def test_auto_model_detection(self, mock_key):
with patch('sys.argv', ['cli', '--task', 'generate-speech',
'--text', 'hi']):
with patch('minimax_cli.generate_speech') as mock_gen:
mock_gen.return_value = {"status": "success",
"generated_audio": "/x.mp3",
"model": "speech-2.8-hd"}
cli.main()
# Model should be auto-detected
assert mock_gen.call_args[0][2] == 'speech-2.8-hd'
@patch('minimax_cli.find_minimax_api_key', return_value='test-key')
def test_explicit_model_override(self, mock_key):
with patch('sys.argv', ['cli', '--task', 'generate-speech',
'--text', 'hi', '--model', 'speech-2.8-turbo']):
with patch('minimax_cli.generate_speech') as mock_gen:
mock_gen.return_value = {"status": "success",
"generated_audio": "/x.mp3",
"model": "speech-2.8-turbo"}
cli.main()
assert mock_gen.call_args[0][2] == 'speech-2.8-turbo'
@patch('minimax_cli.generate_image')
@patch('minimax_cli.find_minimax_api_key', return_value='test-key')
def test_exception_exits_with_1(self, mock_key, mock_gen):
mock_gen.side_effect = Exception("API timeout")
with patch('sys.argv', ['cli', '--task', 'generate',
'--prompt', 'test']):
with pytest.raises(SystemExit) as exc_info:
cli.main()
assert exc_info.value.code == 1