fix: Utils lint fixes
This commit is contained in:
@@ -34,7 +34,7 @@ def get_audio_duration(file_path: Path) -> int:
|
||||
probe = ffmpeg.probe(str(file_path))
|
||||
duration = float(probe["format"]["duration"])
|
||||
return int(duration * 1000) # Convert to milliseconds
|
||||
except Exception as e:
|
||||
except (ffmpeg.Error, KeyError, ValueError, TypeError, Exception) as e:
|
||||
logger.warning("Failed to get duration for %s: %s", file_path, e)
|
||||
return 0
|
||||
|
||||
|
||||
@@ -3,14 +3,14 @@
|
||||
|
||||
def parse_cookies(cookie_header: str) -> dict[str, str]:
|
||||
"""Parse HTTP cookie header into a dictionary."""
|
||||
cookies = {}
|
||||
cookies: dict[str, str] = {}
|
||||
if not cookie_header:
|
||||
return cookies
|
||||
|
||||
for cookie in cookie_header.split(";"):
|
||||
cookie = cookie.strip()
|
||||
if "=" in cookie:
|
||||
name, value = cookie.split("=", 1)
|
||||
for cookie_part in cookie_header.split(";"):
|
||||
cookie_str = cookie_part.strip()
|
||||
if "=" in cookie_str:
|
||||
name, value = cookie_str.split("=", 1)
|
||||
cookies[name.strip()] = value.strip()
|
||||
|
||||
return cookies
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
"""Decorators for credit management and validation."""
|
||||
|
||||
import functools
|
||||
import inspect
|
||||
import types
|
||||
from collections.abc import Awaitable, Callable
|
||||
from typing import Any, TypeVar
|
||||
|
||||
@@ -16,7 +18,7 @@ def requires_credits(
|
||||
user_id_param: str = "user_id",
|
||||
metadata_extractor: Callable[..., dict[str, Any]] | None = None,
|
||||
) -> Callable[[F], F]:
|
||||
"""Decorator to enforce credit requirements for actions.
|
||||
"""Enforce credit requirements for actions.
|
||||
|
||||
Args:
|
||||
action_type: The type of action that requires credits
|
||||
@@ -40,14 +42,13 @@ def requires_credits(
|
||||
"""
|
||||
def decorator(func: F) -> F:
|
||||
@functools.wraps(func)
|
||||
async def wrapper(*args: Any, **kwargs: Any) -> Any:
|
||||
async def wrapper(*args: Any, **kwargs: Any) -> Any: # noqa: ANN401
|
||||
# Extract user ID from parameters
|
||||
user_id = None
|
||||
if user_id_param in kwargs:
|
||||
user_id = kwargs[user_id_param]
|
||||
else:
|
||||
# Try to find user_id in function signature
|
||||
import inspect
|
||||
sig = inspect.signature(func)
|
||||
param_names = list(sig.parameters.keys())
|
||||
if user_id_param in param_names:
|
||||
@@ -74,14 +75,14 @@ def requires_credits(
|
||||
|
||||
# Execute the function
|
||||
success = False
|
||||
result = None
|
||||
try:
|
||||
result = await func(*args, **kwargs)
|
||||
success = bool(result) # Consider function result as success indicator
|
||||
return result
|
||||
except Exception:
|
||||
success = False
|
||||
raise
|
||||
else:
|
||||
return result
|
||||
finally:
|
||||
# Deduct credits based on success
|
||||
await credit_service.deduct_credits(
|
||||
@@ -97,7 +98,7 @@ def validate_credits_only(
|
||||
credit_service_factory: Callable[[], CreditService],
|
||||
user_id_param: str = "user_id",
|
||||
) -> Callable[[F], F]:
|
||||
"""Decorator to only validate credits without deducting them.
|
||||
"""Validate credits without deducting them.
|
||||
|
||||
Useful for checking if a user can perform an action before actual execution.
|
||||
|
||||
@@ -112,14 +113,13 @@ def validate_credits_only(
|
||||
"""
|
||||
def decorator(func: F) -> F:
|
||||
@functools.wraps(func)
|
||||
async def wrapper(*args: Any, **kwargs: Any) -> Any:
|
||||
async def wrapper(*args: Any, **kwargs: Any) -> Any: # noqa: ANN401
|
||||
# Extract user ID from parameters
|
||||
user_id = None
|
||||
if user_id_param in kwargs:
|
||||
user_id = kwargs[user_id_param]
|
||||
else:
|
||||
# Try to find user_id in function signature
|
||||
import inspect
|
||||
sig = inspect.signature(func)
|
||||
param_names = list(sig.parameters.keys())
|
||||
if user_id_param in param_names:
|
||||
@@ -178,7 +178,12 @@ class CreditManager:
|
||||
self.validated = True
|
||||
return self
|
||||
|
||||
async def __aexit__(self, exc_type: type, exc_val: Exception, exc_tb: Any) -> None:
|
||||
async def __aexit__(
|
||||
self,
|
||||
exc_type: type[BaseException] | None,
|
||||
exc_val: BaseException | None,
|
||||
exc_tb: types.TracebackType | None,
|
||||
) -> None:
|
||||
"""Exit context manager - deduct credits based on success."""
|
||||
if self.validated:
|
||||
# If no exception occurred, consider it successful
|
||||
|
||||
@@ -6,6 +6,7 @@ from unittest.mock import AsyncMock, Mock, patch
|
||||
|
||||
import pytest
|
||||
|
||||
from app.models.credit_transaction import CreditTransaction
|
||||
from app.models.sound import Sound
|
||||
from app.models.user import User
|
||||
from app.services.vlc_player import VLCPlayerService, get_vlc_player_service
|
||||
@@ -323,52 +324,51 @@ class TestVLCPlayerService:
|
||||
with patch("app.services.vlc_player.SoundRepository", return_value=mock_sound_repo):
|
||||
with patch("app.services.vlc_player.UserRepository", return_value=mock_user_repo):
|
||||
with patch("app.services.vlc_player.socket_manager") as mock_socket:
|
||||
with patch("app.services.vlc_player.select") as mock_select:
|
||||
# Mock the file path utility
|
||||
with patch("app.services.vlc_player.get_sound_file_path") as mock_get_path:
|
||||
mock_path = Mock()
|
||||
mock_path.exists.return_value = True
|
||||
mock_get_path.return_value = mock_path
|
||||
# Mock the file path utility
|
||||
with patch("app.services.vlc_player.get_sound_file_path") as mock_get_path:
|
||||
mock_path = Mock()
|
||||
mock_path.exists.return_value = True
|
||||
mock_get_path.return_value = mock_path
|
||||
|
||||
# Mock sound repository responses
|
||||
updated_sound = Sound(
|
||||
id=1,
|
||||
type="SDB",
|
||||
name="Test Sound",
|
||||
filename="test.mp3",
|
||||
duration=5000,
|
||||
size=1024,
|
||||
hash="test_hash",
|
||||
play_count=1, # Updated count
|
||||
)
|
||||
mock_sound_repo.get_by_id.return_value = sample_sound
|
||||
mock_sound_repo.update.return_value = updated_sound
|
||||
# Mock sound repository responses
|
||||
updated_sound = Sound(
|
||||
id=1,
|
||||
type="SDB",
|
||||
name="Test Sound",
|
||||
filename="test.mp3",
|
||||
duration=5000,
|
||||
size=1024,
|
||||
hash="test_hash",
|
||||
play_count=1, # Updated count
|
||||
)
|
||||
mock_sound_repo.get_by_id.return_value = sample_sound
|
||||
mock_sound_repo.update.return_value = updated_sound
|
||||
|
||||
# Mock admin user
|
||||
admin_user = User(
|
||||
id=1,
|
||||
email="admin@test.com",
|
||||
name="Admin User",
|
||||
role="admin",
|
||||
)
|
||||
mock_user_repo.get_by_id.return_value = admin_user
|
||||
# Mock admin user
|
||||
admin_user = User(
|
||||
id=1,
|
||||
email="admin@test.com",
|
||||
name="Admin User",
|
||||
role="admin",
|
||||
)
|
||||
mock_user_repo.get_by_id.return_value = admin_user
|
||||
|
||||
# Mock socket broadcast
|
||||
mock_socket.broadcast_to_all = AsyncMock()
|
||||
# Mock socket broadcast
|
||||
mock_socket.broadcast_to_all = AsyncMock()
|
||||
|
||||
result = await vlc_service_with_db.play_sound(sample_sound)
|
||||
result = await vlc_service_with_db.play_sound(sample_sound)
|
||||
|
||||
# Wait a bit for the async task to complete
|
||||
await asyncio.sleep(0.1)
|
||||
# Wait a bit for the async task to complete
|
||||
await asyncio.sleep(0.1)
|
||||
|
||||
assert result is True
|
||||
assert result is True
|
||||
|
||||
# Verify subprocess was called
|
||||
mock_subprocess.assert_called_once()
|
||||
# Verify subprocess was called
|
||||
mock_subprocess.assert_called_once()
|
||||
|
||||
# Note: The async task runs in the background, so we can't easily
|
||||
# verify the database operations in this test without more complex
|
||||
# mocking or using a real async test framework setup
|
||||
# Note: The async task runs in the background, so we can't easily
|
||||
# verify the database operations in this test without more complex
|
||||
# mocking or using a real async test framework setup
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_record_play_count_success(self, vlc_service_with_db):
|
||||
@@ -401,40 +401,39 @@ class TestVLCPlayerService:
|
||||
with patch("app.services.vlc_player.SoundRepository", return_value=mock_sound_repo):
|
||||
with patch("app.services.vlc_player.UserRepository", return_value=mock_user_repo):
|
||||
with patch("app.services.vlc_player.socket_manager") as mock_socket:
|
||||
with patch("app.services.vlc_player.select") as mock_select:
|
||||
# Setup mocks
|
||||
mock_sound_repo.get_by_id.return_value = test_sound
|
||||
mock_user_repo.get_by_id.return_value = admin_user
|
||||
# Setup mocks
|
||||
mock_sound_repo.get_by_id.return_value = test_sound
|
||||
mock_user_repo.get_by_id.return_value = admin_user
|
||||
|
||||
# Mock socket broadcast
|
||||
mock_socket.broadcast_to_all = AsyncMock()
|
||||
# Mock socket broadcast
|
||||
mock_socket.broadcast_to_all = AsyncMock()
|
||||
|
||||
await vlc_service_with_db._record_play_count(1, "Test Sound")
|
||||
await vlc_service_with_db._record_play_count(1, "Test Sound")
|
||||
|
||||
# Verify sound repository calls
|
||||
mock_sound_repo.get_by_id.assert_called_once_with(1)
|
||||
mock_sound_repo.update.assert_called_once_with(
|
||||
test_sound, {"play_count": 1},
|
||||
)
|
||||
# Verify sound repository calls
|
||||
mock_sound_repo.get_by_id.assert_called_once_with(1)
|
||||
mock_sound_repo.update.assert_called_once_with(
|
||||
test_sound, {"play_count": 1},
|
||||
)
|
||||
|
||||
# Verify user repository calls
|
||||
mock_user_repo.get_by_id.assert_called_once_with(1)
|
||||
# Verify user repository calls
|
||||
mock_user_repo.get_by_id.assert_called_once_with(1)
|
||||
|
||||
# Verify session operations
|
||||
mock_session.add.assert_called_once()
|
||||
mock_session.commit.assert_called_once()
|
||||
mock_session.close.assert_called_once()
|
||||
# Verify session operations
|
||||
mock_session.add.assert_called_once()
|
||||
mock_session.commit.assert_called_once()
|
||||
mock_session.close.assert_called_once()
|
||||
|
||||
# Verify socket broadcast
|
||||
mock_socket.broadcast_to_all.assert_called_once_with(
|
||||
"sound_played",
|
||||
{
|
||||
"sound_id": 1,
|
||||
"sound_name": "Test Sound",
|
||||
"user_id": 1,
|
||||
"play_count": 1,
|
||||
},
|
||||
)
|
||||
# Verify socket broadcast
|
||||
mock_socket.broadcast_to_all.assert_called_once_with(
|
||||
"sound_played",
|
||||
{
|
||||
"sound_id": 1,
|
||||
"sound_name": "Test Sound",
|
||||
"user_id": 1,
|
||||
"play_count": 1,
|
||||
},
|
||||
)
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_record_play_count_no_session_factory(self, vlc_service):
|
||||
|
||||
Reference in New Issue
Block a user