293 lines
9.7 KiB
Python
293 lines
9.7 KiB
Python
"""Tests for dashboard service."""
|
|
|
|
from datetime import UTC, datetime
|
|
from unittest.mock import AsyncMock, Mock, patch
|
|
|
|
import pytest
|
|
|
|
from app.services.dashboard import DashboardService
|
|
|
|
|
|
@pytest.fixture
|
|
def mock_sound_repository():
|
|
"""Mock sound repository."""
|
|
return Mock()
|
|
|
|
|
|
@pytest.fixture
|
|
def mock_user_repository():
|
|
"""Mock user repository."""
|
|
return Mock()
|
|
|
|
|
|
@pytest.fixture
|
|
def dashboard_service(mock_sound_repository, mock_user_repository):
|
|
"""Dashboard service with mocked dependencies."""
|
|
return DashboardService(
|
|
sound_repository=mock_sound_repository,
|
|
user_repository=mock_user_repository,
|
|
)
|
|
|
|
|
|
class TestDashboardService:
|
|
"""Test dashboard service."""
|
|
|
|
@pytest.mark.asyncio
|
|
async def test_init(self, mock_sound_repository, mock_user_repository):
|
|
"""Test dashboard service initialization."""
|
|
service = DashboardService(
|
|
sound_repository=mock_sound_repository,
|
|
user_repository=mock_user_repository,
|
|
)
|
|
assert service.sound_repository == mock_sound_repository
|
|
assert service.user_repository == mock_user_repository
|
|
|
|
@pytest.mark.asyncio
|
|
async def test_get_soundboard_statistics_success(
|
|
self,
|
|
dashboard_service,
|
|
mock_sound_repository,
|
|
):
|
|
"""Test getting soundboard statistics successfully."""
|
|
# Mock repository response
|
|
mock_stats = {
|
|
"count": 25,
|
|
"total_plays": 150,
|
|
"total_duration": 75000,
|
|
"total_size": 1024000,
|
|
}
|
|
mock_sound_repository.get_soundboard_statistics = AsyncMock(
|
|
return_value=mock_stats,
|
|
)
|
|
|
|
result = await dashboard_service.get_soundboard_statistics()
|
|
|
|
assert result == {
|
|
"sound_count": 25,
|
|
"total_play_count": 150,
|
|
"total_duration": 75000,
|
|
"total_size": 1024000,
|
|
}
|
|
mock_sound_repository.get_soundboard_statistics.assert_called_once()
|
|
|
|
@pytest.mark.asyncio
|
|
async def test_get_soundboard_statistics_exception(
|
|
self,
|
|
dashboard_service,
|
|
mock_sound_repository,
|
|
):
|
|
"""Test getting soundboard statistics with exception."""
|
|
mock_sound_repository.get_soundboard_statistics = AsyncMock(
|
|
side_effect=Exception("Database error"),
|
|
)
|
|
|
|
with pytest.raises(Exception, match="Database error"):
|
|
await dashboard_service.get_soundboard_statistics()
|
|
|
|
mock_sound_repository.get_soundboard_statistics.assert_called_once()
|
|
|
|
@pytest.mark.asyncio
|
|
async def test_get_track_statistics_success(
|
|
self,
|
|
dashboard_service,
|
|
mock_sound_repository,
|
|
):
|
|
"""Test getting track statistics successfully."""
|
|
# Mock repository response
|
|
mock_stats = {
|
|
"count": 15,
|
|
"total_plays": 80,
|
|
"total_duration": 45000,
|
|
"total_size": 512000,
|
|
}
|
|
mock_sound_repository.get_track_statistics = AsyncMock(return_value=mock_stats)
|
|
|
|
result = await dashboard_service.get_track_statistics()
|
|
|
|
assert result == {
|
|
"track_count": 15,
|
|
"total_play_count": 80,
|
|
"total_duration": 45000,
|
|
"total_size": 512000,
|
|
}
|
|
mock_sound_repository.get_track_statistics.assert_called_once()
|
|
|
|
@pytest.mark.asyncio
|
|
async def test_get_track_statistics_exception(
|
|
self,
|
|
dashboard_service,
|
|
mock_sound_repository,
|
|
):
|
|
"""Test getting track statistics with exception."""
|
|
mock_sound_repository.get_track_statistics = AsyncMock(
|
|
side_effect=Exception("Database error"),
|
|
)
|
|
|
|
with pytest.raises(Exception, match="Database error"):
|
|
await dashboard_service.get_track_statistics()
|
|
|
|
mock_sound_repository.get_track_statistics.assert_called_once()
|
|
|
|
@pytest.mark.asyncio
|
|
async def test_get_top_sounds_success_all_time(
|
|
self,
|
|
dashboard_service,
|
|
mock_sound_repository,
|
|
):
|
|
"""Test getting top sounds for all time successfully."""
|
|
# Mock repository response
|
|
mock_sounds = [
|
|
{
|
|
"id": 1,
|
|
"name": "Sound 1",
|
|
"type": "SDB",
|
|
"play_count": 100,
|
|
"duration": 5000,
|
|
"created_at": datetime(2023, 1, 1, 12, 0, 0, tzinfo=UTC),
|
|
},
|
|
{
|
|
"id": 2,
|
|
"name": "Sound 2",
|
|
"type": "SDB",
|
|
"play_count": 50,
|
|
"duration": 3000,
|
|
"created_at": None,
|
|
},
|
|
]
|
|
mock_sound_repository.get_top_sounds = AsyncMock(return_value=mock_sounds)
|
|
|
|
result = await dashboard_service.get_top_sounds("SDB", "all_time", 10)
|
|
|
|
assert len(result) == 2
|
|
assert result[0] == {
|
|
"id": 1,
|
|
"name": "Sound 1",
|
|
"type": "SDB",
|
|
"play_count": 100,
|
|
"duration": 5000,
|
|
"created_at": "2023-01-01T12:00:00+00:00",
|
|
}
|
|
assert result[1] == {
|
|
"id": 2,
|
|
"name": "Sound 2",
|
|
"type": "SDB",
|
|
"play_count": 50,
|
|
"duration": 3000,
|
|
"created_at": None,
|
|
}
|
|
|
|
mock_sound_repository.get_top_sounds.assert_called_once_with(
|
|
sound_type="SDB",
|
|
date_filter=None,
|
|
limit=10,
|
|
)
|
|
|
|
@pytest.mark.asyncio
|
|
async def test_get_top_sounds_success_with_period(
|
|
self,
|
|
dashboard_service,
|
|
mock_sound_repository,
|
|
):
|
|
"""Test getting top sounds with specific period."""
|
|
mock_sounds = []
|
|
mock_sound_repository.get_top_sounds = AsyncMock(return_value=mock_sounds)
|
|
|
|
with patch.object(dashboard_service, "_get_date_filter") as mock_date_filter:
|
|
mock_date_filter.return_value = datetime(2023, 1, 1, tzinfo=UTC)
|
|
|
|
result = await dashboard_service.get_top_sounds("EXT", "1_week", 5)
|
|
|
|
assert result == []
|
|
mock_date_filter.assert_called_once_with("1_week")
|
|
mock_sound_repository.get_top_sounds.assert_called_once_with(
|
|
sound_type="EXT",
|
|
date_filter=datetime(2023, 1, 1, tzinfo=UTC),
|
|
limit=5,
|
|
)
|
|
|
|
@pytest.mark.asyncio
|
|
async def test_get_top_sounds_exception(
|
|
self,
|
|
dashboard_service,
|
|
mock_sound_repository,
|
|
):
|
|
"""Test getting top sounds with exception."""
|
|
mock_sound_repository.get_top_sounds = AsyncMock(
|
|
side_effect=Exception("Database error"),
|
|
)
|
|
|
|
with pytest.raises(Exception, match="Database error"):
|
|
await dashboard_service.get_top_sounds("SDB", "all_time", 10)
|
|
|
|
mock_sound_repository.get_top_sounds.assert_called_once()
|
|
|
|
def test_get_date_filter_today(self, dashboard_service):
|
|
"""Test date filter for today."""
|
|
with patch("app.services.dashboard.datetime") as mock_datetime:
|
|
mock_now = datetime(2023, 6, 15, 14, 30, 45, 123456, tzinfo=UTC)
|
|
mock_datetime.now.return_value = mock_now
|
|
mock_datetime.UTC = UTC
|
|
|
|
result = dashboard_service._get_date_filter("today")
|
|
|
|
expected = datetime(2023, 6, 15, 0, 0, 0, 0, tzinfo=UTC)
|
|
assert result == expected
|
|
|
|
def test_get_date_filter_1_day(self, dashboard_service):
|
|
"""Test date filter for 1 day."""
|
|
with patch("app.services.dashboard.datetime") as mock_datetime:
|
|
mock_now = datetime(2023, 6, 15, 14, 30, 45, tzinfo=UTC)
|
|
mock_datetime.now.return_value = mock_now
|
|
mock_datetime.UTC = UTC
|
|
|
|
result = dashboard_service._get_date_filter("1_day")
|
|
|
|
expected = datetime(2023, 6, 14, 14, 30, 45, tzinfo=UTC)
|
|
assert result == expected
|
|
|
|
def test_get_date_filter_1_week(self, dashboard_service):
|
|
"""Test date filter for 1 week."""
|
|
with patch("app.services.dashboard.datetime") as mock_datetime:
|
|
mock_now = datetime(2023, 6, 15, 14, 30, 45, tzinfo=UTC)
|
|
mock_datetime.now.return_value = mock_now
|
|
mock_datetime.UTC = UTC
|
|
|
|
result = dashboard_service._get_date_filter("1_week")
|
|
|
|
expected = datetime(2023, 6, 8, 14, 30, 45, tzinfo=UTC)
|
|
assert result == expected
|
|
|
|
def test_get_date_filter_1_month(self, dashboard_service):
|
|
"""Test date filter for 1 month."""
|
|
with patch("app.services.dashboard.datetime") as mock_datetime:
|
|
mock_now = datetime(2023, 6, 15, 14, 30, 45, tzinfo=UTC)
|
|
mock_datetime.now.return_value = mock_now
|
|
mock_datetime.UTC = UTC
|
|
|
|
result = dashboard_service._get_date_filter("1_month")
|
|
|
|
expected = datetime(2023, 5, 16, 14, 30, 45, tzinfo=UTC)
|
|
assert result == expected
|
|
|
|
def test_get_date_filter_1_year(self, dashboard_service):
|
|
"""Test date filter for 1 year."""
|
|
with patch("app.services.dashboard.datetime") as mock_datetime:
|
|
mock_now = datetime(2023, 6, 15, 14, 30, 45, tzinfo=UTC)
|
|
mock_datetime.now.return_value = mock_now
|
|
mock_datetime.UTC = UTC
|
|
|
|
result = dashboard_service._get_date_filter("1_year")
|
|
|
|
expected = datetime(2022, 6, 15, 14, 30, 45, tzinfo=UTC)
|
|
assert result == expected
|
|
|
|
def test_get_date_filter_all_time(self, dashboard_service):
|
|
"""Test date filter for all time."""
|
|
result = dashboard_service._get_date_filter("all_time")
|
|
assert result is None
|
|
|
|
def test_get_date_filter_unknown_period(self, dashboard_service):
|
|
"""Test date filter for unknown period."""
|
|
result = dashboard_service._get_date_filter("unknown_period")
|
|
assert result is None
|