dashboard sync app
This commit is contained in:
235
tests/test_sync_dashboard.py
Normal file
235
tests/test_sync_dashboard.py
Normal file
@@ -0,0 +1,235 @@
|
||||
"""Tests for the sync dashboard TUI."""
|
||||
|
||||
import pytest
|
||||
from unittest.mock import MagicMock, patch
|
||||
from datetime import datetime
|
||||
|
||||
from src.cli.sync_dashboard import (
|
||||
SyncDashboard,
|
||||
SyncProgressTracker,
|
||||
TaskStatus,
|
||||
TaskListItem,
|
||||
get_dashboard,
|
||||
get_progress_tracker,
|
||||
)
|
||||
|
||||
|
||||
class TestSyncProgressTracker:
|
||||
"""Tests for the SyncProgressTracker class."""
|
||||
|
||||
def test_init(self):
|
||||
"""Test tracker initialization."""
|
||||
mock_dashboard = MagicMock()
|
||||
tracker = SyncProgressTracker(mock_dashboard)
|
||||
|
||||
assert tracker.dashboard == mock_dashboard
|
||||
|
||||
def test_start_task(self):
|
||||
"""Test starting a new task."""
|
||||
mock_dashboard = MagicMock()
|
||||
tracker = SyncProgressTracker(mock_dashboard)
|
||||
|
||||
tracker.start_task("inbox", 100)
|
||||
|
||||
mock_dashboard.start_task.assert_called_once_with("inbox", 100)
|
||||
|
||||
def test_start_task_default_total(self):
|
||||
"""Test starting a task with default total."""
|
||||
mock_dashboard = MagicMock()
|
||||
tracker = SyncProgressTracker(mock_dashboard)
|
||||
|
||||
tracker.start_task("calendar")
|
||||
|
||||
mock_dashboard.start_task.assert_called_once_with("calendar", 100)
|
||||
|
||||
def test_update_task(self):
|
||||
"""Test updating task progress."""
|
||||
mock_dashboard = MagicMock()
|
||||
tracker = SyncProgressTracker(mock_dashboard)
|
||||
|
||||
tracker.update_task("inbox", 50, "Processing...")
|
||||
|
||||
mock_dashboard.update_task.assert_called_once_with("inbox", 50, "Processing...")
|
||||
|
||||
def test_update_task_without_message(self):
|
||||
"""Test updating task without message."""
|
||||
mock_dashboard = MagicMock()
|
||||
tracker = SyncProgressTracker(mock_dashboard)
|
||||
|
||||
tracker.update_task("inbox", 75)
|
||||
|
||||
mock_dashboard.update_task.assert_called_once_with("inbox", 75, "")
|
||||
|
||||
def test_complete_task(self):
|
||||
"""Test completing a task."""
|
||||
mock_dashboard = MagicMock()
|
||||
tracker = SyncProgressTracker(mock_dashboard)
|
||||
|
||||
tracker.complete_task("inbox", "Done!")
|
||||
|
||||
mock_dashboard.complete_task.assert_called_once_with("inbox", "Done!")
|
||||
|
||||
def test_complete_task_no_message(self):
|
||||
"""Test completing a task without a message."""
|
||||
mock_dashboard = MagicMock()
|
||||
tracker = SyncProgressTracker(mock_dashboard)
|
||||
|
||||
tracker.complete_task("inbox")
|
||||
|
||||
mock_dashboard.complete_task.assert_called_once_with("inbox", "")
|
||||
|
||||
def test_error_task(self):
|
||||
"""Test marking a task as failed."""
|
||||
mock_dashboard = MagicMock()
|
||||
tracker = SyncProgressTracker(mock_dashboard)
|
||||
|
||||
tracker.error_task("inbox", "Connection failed")
|
||||
|
||||
mock_dashboard.error_task.assert_called_once_with("inbox", "Connection failed")
|
||||
|
||||
def test_skip_task(self):
|
||||
"""Test skipping a task."""
|
||||
mock_dashboard = MagicMock()
|
||||
tracker = SyncProgressTracker(mock_dashboard)
|
||||
|
||||
tracker.skip_task("sweep", "Not needed")
|
||||
|
||||
mock_dashboard.skip_task.assert_called_once_with("sweep", "Not needed")
|
||||
|
||||
def test_skip_task_no_reason(self):
|
||||
"""Test skipping a task without a reason."""
|
||||
mock_dashboard = MagicMock()
|
||||
tracker = SyncProgressTracker(mock_dashboard)
|
||||
|
||||
tracker.skip_task("sweep")
|
||||
|
||||
mock_dashboard.skip_task.assert_called_once_with("sweep", "")
|
||||
|
||||
|
||||
class TestTaskListItem:
|
||||
"""Tests for the TaskListItem class."""
|
||||
|
||||
def test_init(self):
|
||||
"""Test TaskListItem initialization."""
|
||||
item = TaskListItem("inbox", "Inbox Sync")
|
||||
|
||||
assert item.task_id == "inbox"
|
||||
assert item.task_name == "Inbox Sync"
|
||||
assert item.status == TaskStatus.PENDING
|
||||
assert item.progress == 0
|
||||
assert item.total == 100
|
||||
|
||||
def test_get_status_icon_pending(self):
|
||||
"""Test status icon for pending."""
|
||||
item = TaskListItem("inbox", "Inbox Sync")
|
||||
assert item._get_status_icon() == "○"
|
||||
|
||||
def test_get_status_icon_running(self):
|
||||
"""Test status icon for running (animated spinner)."""
|
||||
from src.cli.sync_dashboard import SPINNER_FRAMES
|
||||
|
||||
item = TaskListItem("inbox", "Inbox Sync")
|
||||
item.status = TaskStatus.RUNNING
|
||||
# Running uses spinner frames, starts at frame 0
|
||||
assert item._get_status_icon() == SPINNER_FRAMES[0]
|
||||
|
||||
def test_get_status_icon_completed(self):
|
||||
"""Test status icon for completed."""
|
||||
item = TaskListItem("inbox", "Inbox Sync")
|
||||
item.status = TaskStatus.COMPLETED
|
||||
assert item._get_status_icon() == "✓"
|
||||
|
||||
def test_get_status_icon_error(self):
|
||||
"""Test status icon for error."""
|
||||
item = TaskListItem("inbox", "Inbox Sync")
|
||||
item.status = TaskStatus.ERROR
|
||||
assert item._get_status_icon() == "✗"
|
||||
|
||||
def test_get_status_color_pending(self):
|
||||
"""Test status color for pending."""
|
||||
item = TaskListItem("inbox", "Inbox Sync")
|
||||
assert item._get_status_color() == "dim"
|
||||
|
||||
def test_get_status_color_running(self):
|
||||
"""Test status color for running."""
|
||||
item = TaskListItem("inbox", "Inbox Sync")
|
||||
item.status = TaskStatus.RUNNING
|
||||
assert item._get_status_color() == "cyan"
|
||||
|
||||
def test_get_status_color_completed(self):
|
||||
"""Test status color for completed."""
|
||||
item = TaskListItem("inbox", "Inbox Sync")
|
||||
item.status = TaskStatus.COMPLETED
|
||||
assert item._get_status_color() == "bright_white"
|
||||
|
||||
def test_get_status_color_error(self):
|
||||
"""Test status color for error."""
|
||||
item = TaskListItem("inbox", "Inbox Sync")
|
||||
item.status = TaskStatus.ERROR
|
||||
assert item._get_status_color() == "red"
|
||||
|
||||
|
||||
class TestTaskStatus:
|
||||
"""Tests for the TaskStatus constants."""
|
||||
|
||||
def test_status_values(self):
|
||||
"""Test TaskStatus values."""
|
||||
assert TaskStatus.PENDING == "pending"
|
||||
assert TaskStatus.RUNNING == "running"
|
||||
assert TaskStatus.COMPLETED == "completed"
|
||||
assert TaskStatus.ERROR == "error"
|
||||
|
||||
|
||||
class TestSyncDashboard:
|
||||
"""Tests for the SyncDashboard class."""
|
||||
|
||||
def test_bindings_defined(self):
|
||||
"""Test that key bindings are defined."""
|
||||
assert len(SyncDashboard.BINDINGS) > 0
|
||||
|
||||
# Bindings use the Binding class which has a key attribute
|
||||
binding_keys = [b.key for b in SyncDashboard.BINDINGS] # type: ignore
|
||||
assert "q" in binding_keys
|
||||
assert "r" in binding_keys
|
||||
assert "s" in binding_keys # Sync now
|
||||
assert "+" in binding_keys # Increase interval
|
||||
assert "-" in binding_keys # Decrease interval
|
||||
assert "ctrl+c" in binding_keys
|
||||
assert "up" in binding_keys
|
||||
assert "down" in binding_keys
|
||||
|
||||
def test_css_defined(self):
|
||||
"""Test that CSS is defined."""
|
||||
assert SyncDashboard.CSS is not None
|
||||
assert len(SyncDashboard.CSS) > 0
|
||||
assert ".dashboard" in SyncDashboard.CSS
|
||||
assert ".sidebar" in SyncDashboard.CSS
|
||||
assert ".main-panel" in SyncDashboard.CSS
|
||||
|
||||
def test_reactive_selected_task(self):
|
||||
"""Test selected_task reactive attribute is defined."""
|
||||
assert hasattr(SyncDashboard, "selected_task")
|
||||
|
||||
|
||||
class TestGlobalInstances:
|
||||
"""Tests for global dashboard instances."""
|
||||
|
||||
def test_get_dashboard_initial(self):
|
||||
"""Test get_dashboard returns None initially."""
|
||||
# Reset global state
|
||||
import src.cli.sync_dashboard as dashboard_module
|
||||
|
||||
dashboard_module._dashboard_instance = None
|
||||
|
||||
result = get_dashboard()
|
||||
assert result is None
|
||||
|
||||
def test_get_progress_tracker_initial(self):
|
||||
"""Test get_progress_tracker returns None initially."""
|
||||
# Reset global state
|
||||
import src.cli.sync_dashboard as dashboard_module
|
||||
|
||||
dashboard_module._progress_tracker = None
|
||||
|
||||
result = get_progress_tracker()
|
||||
assert result is None
|
||||
Reference in New Issue
Block a user