Refactor user endpoint tests to include pagination and response structure validation
- Updated tests for listing users to validate pagination and response format. - Changed mock return values to include total count and pagination details. - Refactored user creation mocks for clarity and consistency. - Enhanced assertions to check for presence of pagination fields in responses. - Adjusted test cases for user retrieval and updates to ensure proper handling of user data. - Improved readability by restructuring mock definitions and assertions across various test files.
This commit is contained in:
@@ -454,7 +454,10 @@ class AuthService:
|
||||
return user
|
||||
|
||||
async def change_user_password(
|
||||
self, user: User, current_password: str | None, new_password: str,
|
||||
self,
|
||||
user: User,
|
||||
current_password: str | None,
|
||||
new_password: str,
|
||||
) -> None:
|
||||
"""Change user's password."""
|
||||
# Store user email before any operations to avoid session detachment issues
|
||||
@@ -484,8 +487,11 @@ class AuthService:
|
||||
self.session.add(user)
|
||||
await self.session.commit()
|
||||
|
||||
logger.info("Password %s successfully for user: %s",
|
||||
"changed" if had_existing_password else "set", user_email)
|
||||
logger.info(
|
||||
"Password %s successfully for user: %s",
|
||||
"changed" if had_existing_password else "set",
|
||||
user_email,
|
||||
)
|
||||
|
||||
async def user_to_response(self, user: User) -> UserResponse:
|
||||
"""Convert User model to UserResponse with plan information."""
|
||||
|
||||
@@ -72,9 +72,7 @@ class DashboardService:
|
||||
"play_count": sound["play_count"],
|
||||
"duration": sound["duration"],
|
||||
"created_at": (
|
||||
sound["created_at"].isoformat()
|
||||
if sound["created_at"]
|
||||
else None
|
||||
sound["created_at"].isoformat() if sound["created_at"] else None
|
||||
),
|
||||
}
|
||||
for sound in top_sounds
|
||||
|
||||
@@ -532,7 +532,8 @@ class ExtractionService:
|
||||
"""Add the sound to the user's main playlist."""
|
||||
try:
|
||||
await self.playlist_service._add_sound_to_main_playlist_internal( # noqa: SLF001
|
||||
sound_id, user_id,
|
||||
sound_id,
|
||||
user_id,
|
||||
)
|
||||
logger.info(
|
||||
"Added sound %d to main playlist for user %d",
|
||||
@@ -554,6 +555,10 @@ class ExtractionService:
|
||||
if not extraction:
|
||||
return None
|
||||
|
||||
# Get user information
|
||||
user = await self.user_repo.get_by_id(extraction.user_id)
|
||||
user_name = user.name if user else None
|
||||
|
||||
return {
|
||||
"id": extraction.id or 0, # Should never be None for existing extraction
|
||||
"url": extraction.url,
|
||||
@@ -564,11 +569,12 @@ class ExtractionService:
|
||||
"error": extraction.error,
|
||||
"sound_id": extraction.sound_id,
|
||||
"user_id": extraction.user_id,
|
||||
"user_name": user_name,
|
||||
"created_at": extraction.created_at.isoformat(),
|
||||
"updated_at": extraction.updated_at.isoformat(),
|
||||
}
|
||||
|
||||
async def get_user_extractions(
|
||||
async def get_user_extractions( # noqa: PLR0913
|
||||
self,
|
||||
user_id: int,
|
||||
search: str | None = None,
|
||||
@@ -580,7 +586,10 @@ class ExtractionService:
|
||||
) -> PaginatedExtractionsResponse:
|
||||
"""Get all extractions for a user with filtering, search, and sorting."""
|
||||
offset = (page - 1) * limit
|
||||
extraction_user_tuples, total_count = await self.extraction_repo.get_user_extractions_filtered(
|
||||
(
|
||||
extraction_user_tuples,
|
||||
total_count,
|
||||
) = await self.extraction_repo.get_user_extractions_filtered(
|
||||
user_id=user_id,
|
||||
search=search,
|
||||
sort_by=sort_by,
|
||||
@@ -619,7 +628,7 @@ class ExtractionService:
|
||||
"total_pages": total_pages,
|
||||
}
|
||||
|
||||
async def get_all_extractions(
|
||||
async def get_all_extractions( # noqa: PLR0913
|
||||
self,
|
||||
search: str | None = None,
|
||||
sort_by: str = "created_at",
|
||||
@@ -630,7 +639,10 @@ class ExtractionService:
|
||||
) -> PaginatedExtractionsResponse:
|
||||
"""Get all extractions with filtering, search, and sorting."""
|
||||
offset = (page - 1) * limit
|
||||
extraction_user_tuples, total_count = await self.extraction_repo.get_all_extractions_filtered(
|
||||
(
|
||||
extraction_user_tuples,
|
||||
total_count,
|
||||
) = await self.extraction_repo.get_all_extractions_filtered(
|
||||
search=search,
|
||||
sort_by=sort_by,
|
||||
sort_order=sort_order,
|
||||
|
||||
@@ -49,12 +49,14 @@ class FavoriteService:
|
||||
# Verify user exists
|
||||
user = await user_repo.get_by_id(user_id)
|
||||
if not user:
|
||||
raise ValueError(f"User with ID {user_id} not found")
|
||||
msg = f"User with ID {user_id} not found"
|
||||
raise ValueError(msg)
|
||||
|
||||
# Verify sound exists
|
||||
sound = await sound_repo.get_by_id(sound_id)
|
||||
if not sound:
|
||||
raise ValueError(f"Sound with ID {sound_id} not found")
|
||||
msg = f"Sound with ID {sound_id} not found"
|
||||
raise ValueError(msg)
|
||||
|
||||
# Get data for the event immediately after loading
|
||||
sound_name = sound.name
|
||||
@@ -63,9 +65,8 @@ class FavoriteService:
|
||||
# Check if already favorited
|
||||
existing = await favorite_repo.get_by_user_and_sound(user_id, sound_id)
|
||||
if existing:
|
||||
raise ValueError(
|
||||
f"Sound {sound_id} is already favorited by user {user_id}",
|
||||
)
|
||||
msg = f"Sound {sound_id} is already favorited by user {user_id}"
|
||||
raise ValueError(msg)
|
||||
|
||||
# Create favorite
|
||||
favorite_data = {
|
||||
@@ -120,12 +121,14 @@ class FavoriteService:
|
||||
# Verify user exists
|
||||
user = await user_repo.get_by_id(user_id)
|
||||
if not user:
|
||||
raise ValueError(f"User with ID {user_id} not found")
|
||||
msg = f"User with ID {user_id} not found"
|
||||
raise ValueError(msg)
|
||||
|
||||
# Verify playlist exists
|
||||
playlist = await playlist_repo.get_by_id(playlist_id)
|
||||
if not playlist:
|
||||
raise ValueError(f"Playlist with ID {playlist_id} not found")
|
||||
msg = f"Playlist with ID {playlist_id} not found"
|
||||
raise ValueError(msg)
|
||||
|
||||
# Check if already favorited
|
||||
existing = await favorite_repo.get_by_user_and_playlist(
|
||||
@@ -133,9 +136,8 @@ class FavoriteService:
|
||||
playlist_id,
|
||||
)
|
||||
if existing:
|
||||
raise ValueError(
|
||||
f"Playlist {playlist_id} is already favorited by user {user_id}",
|
||||
)
|
||||
msg = f"Playlist {playlist_id} is already favorited by user {user_id}"
|
||||
raise ValueError(msg)
|
||||
|
||||
# Create favorite
|
||||
favorite_data = {
|
||||
@@ -163,7 +165,8 @@ class FavoriteService:
|
||||
|
||||
favorite = await favorite_repo.get_by_user_and_sound(user_id, sound_id)
|
||||
if not favorite:
|
||||
raise ValueError(f"Sound {sound_id} is not favorited by user {user_id}")
|
||||
msg = f"Sound {sound_id} is not favorited by user {user_id}"
|
||||
raise ValueError(msg)
|
||||
|
||||
# Get user and sound info before deletion for the event
|
||||
user_repo = UserRepository(session)
|
||||
@@ -192,7 +195,8 @@ class FavoriteService:
|
||||
}
|
||||
await socket_manager.broadcast_to_all("sound_favorited", event_data)
|
||||
logger.info(
|
||||
"Broadcasted sound_favorited event for sound %s removal", sound_id,
|
||||
"Broadcasted sound_favorited event for sound %s removal",
|
||||
sound_id,
|
||||
)
|
||||
except Exception:
|
||||
logger.exception(
|
||||
@@ -219,9 +223,8 @@ class FavoriteService:
|
||||
playlist_id,
|
||||
)
|
||||
if not favorite:
|
||||
raise ValueError(
|
||||
f"Playlist {playlist_id} is not favorited by user {user_id}",
|
||||
)
|
||||
msg = f"Playlist {playlist_id} is not favorited by user {user_id}"
|
||||
raise ValueError(msg)
|
||||
|
||||
await favorite_repo.delete(favorite)
|
||||
logger.info(
|
||||
|
||||
@@ -16,6 +16,7 @@ logger = get_logger(__name__)
|
||||
|
||||
class PaginatedPlaylistsResponse(TypedDict):
|
||||
"""Response type for paginated playlists."""
|
||||
|
||||
playlists: list[dict]
|
||||
total: int
|
||||
page: int
|
||||
@@ -286,7 +287,7 @@ class PlaylistService:
|
||||
) -> PaginatedPlaylistsResponse:
|
||||
"""Search and sort playlists with pagination."""
|
||||
offset = (page - 1) * limit
|
||||
|
||||
|
||||
playlists, total_count = await self.playlist_repo.search_and_sort(
|
||||
search_query=search_query,
|
||||
sort_by=sort_by,
|
||||
@@ -299,9 +300,9 @@ class PlaylistService:
|
||||
current_user_id=current_user_id,
|
||||
return_count=True,
|
||||
)
|
||||
|
||||
|
||||
total_pages = (total_count + limit - 1) // limit # Ceiling division
|
||||
|
||||
|
||||
return PaginatedPlaylistsResponse(
|
||||
playlists=playlists,
|
||||
total=total_count,
|
||||
@@ -468,7 +469,9 @@ class PlaylistService:
|
||||
}
|
||||
|
||||
async def add_sound_to_main_playlist(
|
||||
self, sound_id: int, user_id: int, # noqa: ARG002
|
||||
self,
|
||||
sound_id: int, # noqa: ARG002
|
||||
user_id: int, # noqa: ARG002
|
||||
) -> None:
|
||||
"""Add a sound to the global main playlist."""
|
||||
raise HTTPException(
|
||||
@@ -477,7 +480,9 @@ class PlaylistService:
|
||||
)
|
||||
|
||||
async def _add_sound_to_main_playlist_internal(
|
||||
self, sound_id: int, user_id: int,
|
||||
self,
|
||||
sound_id: int,
|
||||
user_id: int,
|
||||
) -> None:
|
||||
"""Add sound to main playlist bypassing restrictions.
|
||||
|
||||
|
||||
Reference in New Issue
Block a user