232 lines
7.4 KiB
Python
232 lines
7.4 KiB
Python
"""
|
|
Unit tests for TUI widgets
|
|
"""
|
|
|
|
from datetime import datetime
|
|
from unittest.mock import MagicMock, patch
|
|
|
|
import pytest
|
|
|
|
|
|
class TestStatusBar:
|
|
"""Tests for StatusBar widget"""
|
|
|
|
@pytest.fixture
|
|
def mock_app(self):
|
|
"""Mock Textual app"""
|
|
from unittest.mock import MagicMock
|
|
|
|
from textual.app import App
|
|
|
|
# Create a minimal mock app that works with Textual
|
|
app = MagicMock(spec=App)
|
|
app.theme = "default"
|
|
app.VERSION = "1.0.0"
|
|
return app
|
|
|
|
def test_statusbar_initialization(self, mock_app):
|
|
"""Test StatusBar initialization"""
|
|
from youtube_tui.widgets.status_bar import StatusBar
|
|
|
|
# Mock subprocess.run
|
|
with patch("subprocess.run") as mock_run:
|
|
mock_result = MagicMock()
|
|
mock_result.returncode = 0
|
|
mock_result.stdout = "2024.01.01"
|
|
mock_run.return_value = mock_result
|
|
|
|
status_bar = StatusBar(mock_app)
|
|
|
|
assert status_bar.current_screen == "Search"
|
|
assert status_bar.status_message == "Ready"
|
|
assert status_bar.downloading is False
|
|
assert status_bar.yt_dlp_version == "2024.01.01"
|
|
|
|
def test_statusbar_update_version_success(self, mock_app):
|
|
"""Test version update with successful yt-dlp call"""
|
|
from youtube_tui.widgets.status_bar import StatusBar
|
|
|
|
with patch("subprocess.run") as mock_run:
|
|
mock_result = MagicMock()
|
|
mock_result.returncode = 0
|
|
mock_result.stdout = "2024.01.15"
|
|
mock_run.return_value = mock_result
|
|
|
|
status_bar = StatusBar(mock_app)
|
|
status_bar.update_version()
|
|
|
|
assert status_bar.yt_dlp_version == "2024.01.15"
|
|
|
|
def test_statusbar_update_version_not_installed(self, mock_app):
|
|
"""Test version update when yt-dlp not installed"""
|
|
from youtube_tui.widgets.status_bar import StatusBar
|
|
|
|
with patch("subprocess.run") as mock_run:
|
|
mock_result = MagicMock()
|
|
mock_result.returncode = 1
|
|
mock_run.return_value = mock_result
|
|
|
|
status_bar = StatusBar(mock_app)
|
|
status_bar.update_version()
|
|
|
|
assert status_bar.yt_dlp_version == "not installed"
|
|
|
|
def test_statusbar_update_version_error(self, mock_app):
|
|
"""Test version update with error"""
|
|
from youtube_tui.widgets.status_bar import StatusBar
|
|
|
|
with patch("subprocess.run") as mock_run:
|
|
mock_run.side_effect = Exception("Command failed")
|
|
|
|
status_bar = StatusBar(mock_app)
|
|
status_bar.update_version()
|
|
|
|
assert status_bar.yt_dlp_version == "unknown"
|
|
|
|
def test_statusbar_set_screen(self, mock_app):
|
|
"""Test setting screen name"""
|
|
from youtube_tui.widgets.status_bar import StatusBar
|
|
|
|
with patch("subprocess.run"):
|
|
status_bar = StatusBar(mock_app)
|
|
|
|
status_bar.set_screen("Results")
|
|
assert status_bar.current_screen == "Results"
|
|
|
|
def test_statusbar_set_downloading(self, mock_app):
|
|
"""Test setting downloading state"""
|
|
from youtube_tui.widgets.status_bar import StatusBar
|
|
|
|
with patch("subprocess.run"):
|
|
status_bar = StatusBar(mock_app)
|
|
|
|
status_bar.set_downloading(True)
|
|
assert status_bar.downloading is True
|
|
|
|
status_bar.set_downloading(False)
|
|
assert status_bar.downloading is False
|
|
|
|
def test_statusbar_set_status(self, mock_app):
|
|
"""Test setting status message"""
|
|
from youtube_tui.widgets.status_bar import StatusBar
|
|
|
|
with patch("subprocess.run"):
|
|
status_bar = StatusBar(mock_app)
|
|
|
|
status_bar.set_status("Downloading video...")
|
|
assert status_bar.status_message == "Downloading video..."
|
|
|
|
def test_statusbar_render(self, mock_app):
|
|
"""Test status bar rendering"""
|
|
from datetime import datetime
|
|
|
|
from youtube_tui.widgets.status_bar import StatusBar
|
|
|
|
with patch("subprocess.run") as mock_run:
|
|
mock_result = MagicMock()
|
|
mock_result.returncode = 0
|
|
mock_result.stdout = "2024.01.01"
|
|
mock_run.return_value = mock_result
|
|
|
|
status_bar = StatusBar(mock_app)
|
|
status_bar.set_status("Ready")
|
|
|
|
# Mock datetime for consistent testing
|
|
with patch(
|
|
"youtube_tui.widgets.status_bar.datetime"
|
|
) as mock_datetime:
|
|
mock_datetime.now.return_value = datetime(
|
|
2024, 1, 15, 12, 30, 0
|
|
)
|
|
render_result = status_bar.render()
|
|
|
|
render_str = str(render_result)
|
|
assert "Search" in render_str
|
|
assert "2024.01.01" in render_str
|
|
assert "Ready" in render_str
|
|
assert "12:30:00" in render_str
|
|
|
|
def test_statusbar_render_downloading(self, mock_app):
|
|
"""Test status bar rendering with downloading indicator"""
|
|
from youtube_tui.widgets.status_bar import StatusBar
|
|
|
|
with patch("subprocess.run") as mock_run:
|
|
mock_result = MagicMock()
|
|
mock_result.returncode = 0
|
|
mock_result.stdout = "2024.01.01"
|
|
mock_run.return_value = mock_result
|
|
|
|
status_bar = StatusBar(mock_app)
|
|
status_bar.set_downloading(True)
|
|
|
|
with patch(
|
|
"youtube_tui.widgets.status_bar.datetime"
|
|
) as mock_datetime:
|
|
mock_datetime.now.return_value = datetime(
|
|
2024, 1, 15, 12, 30, 0
|
|
)
|
|
render_result = status_bar.render()
|
|
|
|
render_str = str(render_result)
|
|
assert "↓" in render_str # Download indicator
|
|
|
|
|
|
class TestCommandPalette:
|
|
"""Tests for CommandPalette widget"""
|
|
|
|
def test_command_palette_creation(self):
|
|
"""Test CommandPalette initialization"""
|
|
from youtube_tui.widgets.command_palette import CommandPalette
|
|
|
|
palette = CommandPalette()
|
|
assert palette is not None
|
|
|
|
|
|
class TestCustomWidgets:
|
|
"""Tests for custom widget implementations"""
|
|
|
|
def test_static_widget_creation(self):
|
|
"""Test basic Static widget"""
|
|
from textual.widgets import Static
|
|
|
|
widget = Static("Test content")
|
|
assert widget.renderable == "Test content"
|
|
|
|
def test_static_widget_with_rich_markup(self):
|
|
"""Test Static widget with Rich markup"""
|
|
from textual.widgets import Static
|
|
|
|
widget = Static("[bold]Test[/bold] [red]content[/red]")
|
|
# The content should contain the markup
|
|
assert "[bold]" in str(widget.renderable)
|
|
|
|
def test_button_widget_creation(self):
|
|
"""Test Button widget"""
|
|
from textual.widgets import Button
|
|
|
|
button = Button("Click me")
|
|
assert str(button.label) == "Click me"
|
|
|
|
def test_input_widget_creation(self):
|
|
"""Test Input widget"""
|
|
from textual.widgets import Input
|
|
|
|
input_widget = Input(placeholder="Enter text...")
|
|
assert input_widget.placeholder == "Enter text..."
|
|
|
|
def test_data_table_creation(self):
|
|
"""Test DataTable widget"""
|
|
from textual.widgets import DataTable
|
|
|
|
table = DataTable()
|
|
assert table is not None
|
|
|
|
def test_progress_bar_creation(self):
|
|
"""Test ProgressBar widget"""
|
|
from textual.widgets import ProgressBar
|
|
|
|
progress = ProgressBar(total=100)
|
|
progress.progress = 50
|
|
assert progress.total == 100
|
|
assert progress.progress == 50
|