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:
@@ -21,8 +21,6 @@ def mock_plan_repository():
|
||||
return Mock()
|
||||
|
||||
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def regular_user():
|
||||
"""Create regular user for testing."""
|
||||
@@ -60,52 +58,78 @@ class TestAdminUserEndpoints:
|
||||
test_plan: Plan,
|
||||
) -> None:
|
||||
"""Test listing users successfully."""
|
||||
with patch("app.repositories.user.UserRepository.get_all_with_plan") as mock_get_all:
|
||||
with patch(
|
||||
"app.repositories.user.UserRepository.get_all_with_plan_paginated",
|
||||
) as mock_get_all:
|
||||
# Create mock user objects that don't trigger database saves
|
||||
mock_admin = type("User", (), {
|
||||
"id": admin_user.id,
|
||||
"email": admin_user.email,
|
||||
"name": admin_user.name,
|
||||
"picture": None,
|
||||
"role": admin_user.role,
|
||||
"credits": admin_user.credits,
|
||||
"is_active": admin_user.is_active,
|
||||
"created_at": admin_user.created_at,
|
||||
"updated_at": admin_user.updated_at,
|
||||
"plan": type("Plan", (), {
|
||||
"id": test_plan.id,
|
||||
"name": test_plan.name,
|
||||
"max_credits": test_plan.max_credits,
|
||||
})(),
|
||||
})()
|
||||
mock_admin = type(
|
||||
"User",
|
||||
(),
|
||||
{
|
||||
"id": admin_user.id,
|
||||
"email": admin_user.email,
|
||||
"name": admin_user.name,
|
||||
"picture": None,
|
||||
"role": admin_user.role,
|
||||
"credits": admin_user.credits,
|
||||
"is_active": admin_user.is_active,
|
||||
"created_at": admin_user.created_at,
|
||||
"updated_at": admin_user.updated_at,
|
||||
"plan": type(
|
||||
"Plan",
|
||||
(),
|
||||
{
|
||||
"id": test_plan.id,
|
||||
"name": test_plan.name,
|
||||
"max_credits": test_plan.max_credits,
|
||||
},
|
||||
)(),
|
||||
},
|
||||
)()
|
||||
|
||||
mock_regular = type("User", (), {
|
||||
"id": regular_user.id,
|
||||
"email": regular_user.email,
|
||||
"name": regular_user.name,
|
||||
"picture": None,
|
||||
"role": regular_user.role,
|
||||
"credits": regular_user.credits,
|
||||
"is_active": regular_user.is_active,
|
||||
"created_at": regular_user.created_at,
|
||||
"updated_at": regular_user.updated_at,
|
||||
"plan": type("Plan", (), {
|
||||
"id": test_plan.id,
|
||||
"name": test_plan.name,
|
||||
"max_credits": test_plan.max_credits,
|
||||
})(),
|
||||
})()
|
||||
mock_regular = type(
|
||||
"User",
|
||||
(),
|
||||
{
|
||||
"id": regular_user.id,
|
||||
"email": regular_user.email,
|
||||
"name": regular_user.name,
|
||||
"picture": None,
|
||||
"role": regular_user.role,
|
||||
"credits": regular_user.credits,
|
||||
"is_active": regular_user.is_active,
|
||||
"created_at": regular_user.created_at,
|
||||
"updated_at": regular_user.updated_at,
|
||||
"plan": type(
|
||||
"Plan",
|
||||
(),
|
||||
{
|
||||
"id": test_plan.id,
|
||||
"name": test_plan.name,
|
||||
"max_credits": test_plan.max_credits,
|
||||
},
|
||||
)(),
|
||||
},
|
||||
)()
|
||||
|
||||
mock_get_all.return_value = [mock_admin, mock_regular]
|
||||
# Mock returns tuple (users, total_count)
|
||||
mock_get_all.return_value = ([mock_admin, mock_regular], 2)
|
||||
|
||||
response = await authenticated_admin_client.get("/api/v1/admin/users/")
|
||||
|
||||
assert response.status_code == 200
|
||||
data = response.json()
|
||||
assert len(data) == 2
|
||||
assert data[0]["email"] == "admin@example.com"
|
||||
assert data[1]["email"] == "user@example.com"
|
||||
mock_get_all.assert_called_once_with(limit=100, offset=0)
|
||||
assert "users" in data
|
||||
assert "total" in data
|
||||
assert "page" in data
|
||||
assert "limit" in data
|
||||
assert "total_pages" in data
|
||||
assert len(data["users"]) == 2
|
||||
assert data["users"][0]["email"] == "admin@example.com"
|
||||
assert data["users"][1]["email"] == "user@example.com"
|
||||
assert data["total"] == 2
|
||||
assert data["page"] == 1
|
||||
assert data["limit"] == 50
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_list_users_with_pagination(
|
||||
@@ -115,29 +139,55 @@ class TestAdminUserEndpoints:
|
||||
test_plan: Plan,
|
||||
) -> None:
|
||||
"""Test listing users with pagination."""
|
||||
with patch("app.repositories.user.UserRepository.get_all_with_plan") as mock_get_all:
|
||||
mock_admin = type("User", (), {
|
||||
"id": admin_user.id,
|
||||
"email": admin_user.email,
|
||||
"name": admin_user.name,
|
||||
"picture": None,
|
||||
"role": admin_user.role,
|
||||
"credits": admin_user.credits,
|
||||
"is_active": admin_user.is_active,
|
||||
"created_at": admin_user.created_at,
|
||||
"updated_at": admin_user.updated_at,
|
||||
"plan": type("Plan", (), {
|
||||
"id": test_plan.id,
|
||||
"name": test_plan.name,
|
||||
"max_credits": test_plan.max_credits,
|
||||
})(),
|
||||
})()
|
||||
mock_get_all.return_value = [mock_admin]
|
||||
from app.repositories.user import SortOrder, UserSortField, UserStatus
|
||||
|
||||
response = await authenticated_admin_client.get("/api/v1/admin/users/?limit=10&offset=5")
|
||||
with patch(
|
||||
"app.repositories.user.UserRepository.get_all_with_plan_paginated",
|
||||
) as mock_get_all:
|
||||
mock_admin = type(
|
||||
"User",
|
||||
(),
|
||||
{
|
||||
"id": admin_user.id,
|
||||
"email": admin_user.email,
|
||||
"name": admin_user.name,
|
||||
"picture": None,
|
||||
"role": admin_user.role,
|
||||
"credits": admin_user.credits,
|
||||
"is_active": admin_user.is_active,
|
||||
"created_at": admin_user.created_at,
|
||||
"updated_at": admin_user.updated_at,
|
||||
"plan": type(
|
||||
"Plan",
|
||||
(),
|
||||
{
|
||||
"id": test_plan.id,
|
||||
"name": test_plan.name,
|
||||
"max_credits": test_plan.max_credits,
|
||||
},
|
||||
)(),
|
||||
},
|
||||
)()
|
||||
# Mock returns tuple (users, total_count)
|
||||
mock_get_all.return_value = ([mock_admin], 1)
|
||||
|
||||
response = await authenticated_admin_client.get(
|
||||
"/api/v1/admin/users/?page=2&limit=10",
|
||||
)
|
||||
|
||||
assert response.status_code == 200
|
||||
mock_get_all.assert_called_once_with(limit=10, offset=5)
|
||||
data = response.json()
|
||||
assert "users" in data
|
||||
assert data["page"] == 2
|
||||
assert data["limit"] == 10
|
||||
mock_get_all.assert_called_once_with(
|
||||
page=2,
|
||||
limit=10,
|
||||
search=None,
|
||||
sort_by=UserSortField.NAME,
|
||||
sort_order=SortOrder.ASC,
|
||||
status_filter=UserStatus.ALL,
|
||||
)
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_list_users_unauthenticated(self, client: AsyncClient) -> None:
|
||||
@@ -153,7 +203,9 @@ class TestAdminUserEndpoints:
|
||||
regular_user: User,
|
||||
) -> None:
|
||||
"""Test listing users as non-admin user."""
|
||||
with patch("app.core.dependencies.get_current_active_user", return_value=regular_user):
|
||||
with patch(
|
||||
"app.core.dependencies.get_current_active_user", return_value=regular_user,
|
||||
):
|
||||
response = await client.get("/api/v1/admin/users/")
|
||||
|
||||
assert response.status_code == 401
|
||||
@@ -169,24 +221,34 @@ class TestAdminUserEndpoints:
|
||||
"""Test getting specific user successfully."""
|
||||
with (
|
||||
patch("app.core.dependencies.get_admin_user", return_value=admin_user),
|
||||
patch("app.repositories.user.UserRepository.get_by_id_with_plan") as mock_get_by_id,
|
||||
patch(
|
||||
"app.repositories.user.UserRepository.get_by_id_with_plan",
|
||||
) as mock_get_by_id,
|
||||
):
|
||||
mock_user = type("User", (), {
|
||||
"id": regular_user.id,
|
||||
"email": regular_user.email,
|
||||
"name": regular_user.name,
|
||||
"picture": None,
|
||||
"role": regular_user.role,
|
||||
"credits": regular_user.credits,
|
||||
"is_active": regular_user.is_active,
|
||||
"created_at": regular_user.created_at,
|
||||
"updated_at": regular_user.updated_at,
|
||||
"plan": type("Plan", (), {
|
||||
"id": test_plan.id,
|
||||
"name": test_plan.name,
|
||||
"max_credits": test_plan.max_credits,
|
||||
})(),
|
||||
})()
|
||||
mock_user = type(
|
||||
"User",
|
||||
(),
|
||||
{
|
||||
"id": regular_user.id,
|
||||
"email": regular_user.email,
|
||||
"name": regular_user.name,
|
||||
"picture": None,
|
||||
"role": regular_user.role,
|
||||
"credits": regular_user.credits,
|
||||
"is_active": regular_user.is_active,
|
||||
"created_at": regular_user.created_at,
|
||||
"updated_at": regular_user.updated_at,
|
||||
"plan": type(
|
||||
"Plan",
|
||||
(),
|
||||
{
|
||||
"id": test_plan.id,
|
||||
"name": test_plan.name,
|
||||
"max_credits": test_plan.max_credits,
|
||||
},
|
||||
)(),
|
||||
},
|
||||
)()
|
||||
mock_get_by_id.return_value = mock_user
|
||||
|
||||
response = await authenticated_admin_client.get("/api/v1/admin/users/2")
|
||||
@@ -207,7 +269,10 @@ class TestAdminUserEndpoints:
|
||||
"""Test getting non-existent user."""
|
||||
with (
|
||||
patch("app.core.dependencies.get_admin_user", return_value=admin_user),
|
||||
patch("app.repositories.user.UserRepository.get_by_id_with_plan", return_value=None),
|
||||
patch(
|
||||
"app.repositories.user.UserRepository.get_by_id_with_plan",
|
||||
return_value=None,
|
||||
),
|
||||
):
|
||||
response = await authenticated_admin_client.get("/api/v1/admin/users/999")
|
||||
|
||||
@@ -226,43 +291,63 @@ class TestAdminUserEndpoints:
|
||||
"""Test updating user successfully."""
|
||||
with (
|
||||
patch("app.core.dependencies.get_admin_user", return_value=admin_user),
|
||||
patch("app.repositories.user.UserRepository.get_by_id_with_plan") as mock_get_by_id,
|
||||
patch(
|
||||
"app.repositories.user.UserRepository.get_by_id_with_plan",
|
||||
) as mock_get_by_id,
|
||||
patch("app.repositories.user.UserRepository.update") as mock_update,
|
||||
patch("app.repositories.plan.PlanRepository.get_by_id", return_value=test_plan),
|
||||
patch(
|
||||
"app.repositories.plan.PlanRepository.get_by_id", return_value=test_plan,
|
||||
),
|
||||
):
|
||||
mock_user = type("User", (), {
|
||||
"id": regular_user.id,
|
||||
"email": regular_user.email,
|
||||
"name": regular_user.name,
|
||||
"picture": None,
|
||||
"role": regular_user.role,
|
||||
"credits": regular_user.credits,
|
||||
"is_active": regular_user.is_active,
|
||||
"created_at": regular_user.created_at,
|
||||
"updated_at": regular_user.updated_at,
|
||||
"plan": type("Plan", (), {
|
||||
"id": test_plan.id,
|
||||
"name": test_plan.name,
|
||||
"max_credits": test_plan.max_credits,
|
||||
})(),
|
||||
})()
|
||||
mock_user = type(
|
||||
"User",
|
||||
(),
|
||||
{
|
||||
"id": regular_user.id,
|
||||
"email": regular_user.email,
|
||||
"name": regular_user.name,
|
||||
"picture": None,
|
||||
"role": regular_user.role,
|
||||
"credits": regular_user.credits,
|
||||
"is_active": regular_user.is_active,
|
||||
"created_at": regular_user.created_at,
|
||||
"updated_at": regular_user.updated_at,
|
||||
"plan": type(
|
||||
"Plan",
|
||||
(),
|
||||
{
|
||||
"id": test_plan.id,
|
||||
"name": test_plan.name,
|
||||
"max_credits": test_plan.max_credits,
|
||||
},
|
||||
)(),
|
||||
},
|
||||
)()
|
||||
|
||||
updated_mock = type("User", (), {
|
||||
"id": regular_user.id,
|
||||
"email": regular_user.email,
|
||||
"name": "Updated Name",
|
||||
"picture": None,
|
||||
"role": regular_user.role,
|
||||
"credits": 200,
|
||||
"is_active": regular_user.is_active,
|
||||
"created_at": regular_user.created_at,
|
||||
"updated_at": regular_user.updated_at,
|
||||
"plan": type("Plan", (), {
|
||||
"id": test_plan.id,
|
||||
"name": test_plan.name,
|
||||
"max_credits": test_plan.max_credits,
|
||||
})(),
|
||||
})()
|
||||
updated_mock = type(
|
||||
"User",
|
||||
(),
|
||||
{
|
||||
"id": regular_user.id,
|
||||
"email": regular_user.email,
|
||||
"name": "Updated Name",
|
||||
"picture": None,
|
||||
"role": regular_user.role,
|
||||
"credits": 200,
|
||||
"is_active": regular_user.is_active,
|
||||
"created_at": regular_user.created_at,
|
||||
"updated_at": regular_user.updated_at,
|
||||
"plan": type(
|
||||
"Plan",
|
||||
(),
|
||||
{
|
||||
"id": test_plan.id,
|
||||
"name": test_plan.name,
|
||||
"max_credits": test_plan.max_credits,
|
||||
},
|
||||
)(),
|
||||
},
|
||||
)()
|
||||
|
||||
mock_get_by_id.return_value = mock_user
|
||||
mock_update.return_value = updated_mock
|
||||
@@ -271,7 +356,10 @@ class TestAdminUserEndpoints:
|
||||
async def mock_refresh(instance, attributes=None):
|
||||
pass
|
||||
|
||||
with patch("sqlmodel.ext.asyncio.session.AsyncSession.refresh", side_effect=mock_refresh):
|
||||
with patch(
|
||||
"sqlmodel.ext.asyncio.session.AsyncSession.refresh",
|
||||
side_effect=mock_refresh,
|
||||
):
|
||||
response = await authenticated_admin_client.patch(
|
||||
"/api/v1/admin/users/2",
|
||||
json={
|
||||
@@ -295,7 +383,10 @@ class TestAdminUserEndpoints:
|
||||
"""Test updating non-existent user."""
|
||||
with (
|
||||
patch("app.core.dependencies.get_admin_user", return_value=admin_user),
|
||||
patch("app.repositories.user.UserRepository.get_by_id_with_plan", return_value=None),
|
||||
patch(
|
||||
"app.repositories.user.UserRepository.get_by_id_with_plan",
|
||||
return_value=None,
|
||||
),
|
||||
):
|
||||
response = await authenticated_admin_client.patch(
|
||||
"/api/v1/admin/users/999",
|
||||
@@ -316,25 +407,35 @@ class TestAdminUserEndpoints:
|
||||
"""Test updating user with invalid plan."""
|
||||
with (
|
||||
patch("app.core.dependencies.get_admin_user", return_value=admin_user),
|
||||
patch("app.repositories.user.UserRepository.get_by_id_with_plan") as mock_get_by_id,
|
||||
patch(
|
||||
"app.repositories.user.UserRepository.get_by_id_with_plan",
|
||||
) as mock_get_by_id,
|
||||
patch("app.repositories.plan.PlanRepository.get_by_id", return_value=None),
|
||||
):
|
||||
mock_user = type("User", (), {
|
||||
"id": regular_user.id,
|
||||
"email": regular_user.email,
|
||||
"name": regular_user.name,
|
||||
"picture": None,
|
||||
"role": regular_user.role,
|
||||
"credits": regular_user.credits,
|
||||
"is_active": regular_user.is_active,
|
||||
"created_at": regular_user.created_at,
|
||||
"updated_at": regular_user.updated_at,
|
||||
"plan": type("Plan", (), {
|
||||
"id": 1,
|
||||
"name": "Basic",
|
||||
"max_credits": 100,
|
||||
})(),
|
||||
})()
|
||||
mock_user = type(
|
||||
"User",
|
||||
(),
|
||||
{
|
||||
"id": regular_user.id,
|
||||
"email": regular_user.email,
|
||||
"name": regular_user.name,
|
||||
"picture": None,
|
||||
"role": regular_user.role,
|
||||
"credits": regular_user.credits,
|
||||
"is_active": regular_user.is_active,
|
||||
"created_at": regular_user.created_at,
|
||||
"updated_at": regular_user.updated_at,
|
||||
"plan": type(
|
||||
"Plan",
|
||||
(),
|
||||
{
|
||||
"id": 1,
|
||||
"name": "Basic",
|
||||
"max_credits": 100,
|
||||
},
|
||||
)(),
|
||||
},
|
||||
)()
|
||||
mock_get_by_id.return_value = mock_user
|
||||
response = await authenticated_admin_client.patch(
|
||||
"/api/v1/admin/users/2",
|
||||
@@ -356,29 +457,41 @@ class TestAdminUserEndpoints:
|
||||
"""Test disabling user successfully."""
|
||||
with (
|
||||
patch("app.core.dependencies.get_admin_user", return_value=admin_user),
|
||||
patch("app.repositories.user.UserRepository.get_by_id_with_plan") as mock_get_by_id,
|
||||
patch(
|
||||
"app.repositories.user.UserRepository.get_by_id_with_plan",
|
||||
) as mock_get_by_id,
|
||||
patch("app.repositories.user.UserRepository.update") as mock_update,
|
||||
):
|
||||
mock_user = type("User", (), {
|
||||
"id": regular_user.id,
|
||||
"email": regular_user.email,
|
||||
"name": regular_user.name,
|
||||
"picture": None,
|
||||
"role": regular_user.role,
|
||||
"credits": regular_user.credits,
|
||||
"is_active": regular_user.is_active,
|
||||
"created_at": regular_user.created_at,
|
||||
"updated_at": regular_user.updated_at,
|
||||
"plan": type("Plan", (), {
|
||||
"id": test_plan.id,
|
||||
"name": test_plan.name,
|
||||
"max_credits": test_plan.max_credits,
|
||||
})(),
|
||||
})()
|
||||
mock_user = type(
|
||||
"User",
|
||||
(),
|
||||
{
|
||||
"id": regular_user.id,
|
||||
"email": regular_user.email,
|
||||
"name": regular_user.name,
|
||||
"picture": None,
|
||||
"role": regular_user.role,
|
||||
"credits": regular_user.credits,
|
||||
"is_active": regular_user.is_active,
|
||||
"created_at": regular_user.created_at,
|
||||
"updated_at": regular_user.updated_at,
|
||||
"plan": type(
|
||||
"Plan",
|
||||
(),
|
||||
{
|
||||
"id": test_plan.id,
|
||||
"name": test_plan.name,
|
||||
"max_credits": test_plan.max_credits,
|
||||
},
|
||||
)(),
|
||||
},
|
||||
)()
|
||||
mock_get_by_id.return_value = mock_user
|
||||
mock_update.return_value = mock_user
|
||||
|
||||
response = await authenticated_admin_client.post("/api/v1/admin/users/2/disable")
|
||||
response = await authenticated_admin_client.post(
|
||||
"/api/v1/admin/users/2/disable",
|
||||
)
|
||||
|
||||
assert response.status_code == 200
|
||||
data = response.json()
|
||||
@@ -393,9 +506,14 @@ class TestAdminUserEndpoints:
|
||||
"""Test disabling non-existent user."""
|
||||
with (
|
||||
patch("app.core.dependencies.get_admin_user", return_value=admin_user),
|
||||
patch("app.repositories.user.UserRepository.get_by_id_with_plan", return_value=None),
|
||||
patch(
|
||||
"app.repositories.user.UserRepository.get_by_id_with_plan",
|
||||
return_value=None,
|
||||
),
|
||||
):
|
||||
response = await authenticated_admin_client.post("/api/v1/admin/users/999/disable")
|
||||
response = await authenticated_admin_client.post(
|
||||
"/api/v1/admin/users/999/disable",
|
||||
)
|
||||
|
||||
assert response.status_code == 404
|
||||
data = response.json()
|
||||
@@ -421,29 +539,41 @@ class TestAdminUserEndpoints:
|
||||
|
||||
with (
|
||||
patch("app.core.dependencies.get_admin_user", return_value=admin_user),
|
||||
patch("app.repositories.user.UserRepository.get_by_id_with_plan") as mock_get_by_id,
|
||||
patch(
|
||||
"app.repositories.user.UserRepository.get_by_id_with_plan",
|
||||
) as mock_get_by_id,
|
||||
patch("app.repositories.user.UserRepository.update") as mock_update,
|
||||
):
|
||||
mock_disabled_user = type("User", (), {
|
||||
"id": disabled_user.id,
|
||||
"email": disabled_user.email,
|
||||
"name": disabled_user.name,
|
||||
"picture": None,
|
||||
"role": disabled_user.role,
|
||||
"credits": disabled_user.credits,
|
||||
"is_active": disabled_user.is_active,
|
||||
"created_at": disabled_user.created_at,
|
||||
"updated_at": disabled_user.updated_at,
|
||||
"plan": type("Plan", (), {
|
||||
"id": test_plan.id,
|
||||
"name": test_plan.name,
|
||||
"max_credits": test_plan.max_credits,
|
||||
})(),
|
||||
})()
|
||||
mock_disabled_user = type(
|
||||
"User",
|
||||
(),
|
||||
{
|
||||
"id": disabled_user.id,
|
||||
"email": disabled_user.email,
|
||||
"name": disabled_user.name,
|
||||
"picture": None,
|
||||
"role": disabled_user.role,
|
||||
"credits": disabled_user.credits,
|
||||
"is_active": disabled_user.is_active,
|
||||
"created_at": disabled_user.created_at,
|
||||
"updated_at": disabled_user.updated_at,
|
||||
"plan": type(
|
||||
"Plan",
|
||||
(),
|
||||
{
|
||||
"id": test_plan.id,
|
||||
"name": test_plan.name,
|
||||
"max_credits": test_plan.max_credits,
|
||||
},
|
||||
)(),
|
||||
},
|
||||
)()
|
||||
mock_get_by_id.return_value = mock_disabled_user
|
||||
mock_update.return_value = mock_disabled_user
|
||||
|
||||
response = await authenticated_admin_client.post("/api/v1/admin/users/3/enable")
|
||||
response = await authenticated_admin_client.post(
|
||||
"/api/v1/admin/users/3/enable",
|
||||
)
|
||||
|
||||
assert response.status_code == 200
|
||||
data = response.json()
|
||||
@@ -458,9 +588,14 @@ class TestAdminUserEndpoints:
|
||||
"""Test enabling non-existent user."""
|
||||
with (
|
||||
patch("app.core.dependencies.get_admin_user", return_value=admin_user),
|
||||
patch("app.repositories.user.UserRepository.get_by_id_with_plan", return_value=None),
|
||||
patch(
|
||||
"app.repositories.user.UserRepository.get_by_id_with_plan",
|
||||
return_value=None,
|
||||
),
|
||||
):
|
||||
response = await authenticated_admin_client.post("/api/v1/admin/users/999/enable")
|
||||
response = await authenticated_admin_client.post(
|
||||
"/api/v1/admin/users/999/enable",
|
||||
)
|
||||
|
||||
assert response.status_code == 404
|
||||
data = response.json()
|
||||
@@ -479,9 +614,14 @@ class TestAdminUserEndpoints:
|
||||
|
||||
with (
|
||||
patch("app.core.dependencies.get_admin_user", return_value=admin_user),
|
||||
patch("app.repositories.plan.PlanRepository.get_all", return_value=[basic_plan, premium_plan]),
|
||||
patch(
|
||||
"app.repositories.plan.PlanRepository.get_all",
|
||||
return_value=[basic_plan, premium_plan],
|
||||
),
|
||||
):
|
||||
response = await authenticated_admin_client.get("/api/v1/admin/users/plans/list")
|
||||
response = await authenticated_admin_client.get(
|
||||
"/api/v1/admin/users/plans/list",
|
||||
)
|
||||
|
||||
assert response.status_code == 200
|
||||
data = response.json()
|
||||
|
||||
@@ -488,11 +488,17 @@ class TestAuthEndpoints:
|
||||
test_plan: Plan,
|
||||
) -> None:
|
||||
"""Test refresh token success."""
|
||||
with patch("app.services.auth.AuthService.refresh_access_token") as mock_refresh:
|
||||
mock_refresh.return_value = type("TokenResponse", (), {
|
||||
"access_token": "new_access_token",
|
||||
"expires_in": 3600,
|
||||
})()
|
||||
with patch(
|
||||
"app.services.auth.AuthService.refresh_access_token",
|
||||
) as mock_refresh:
|
||||
mock_refresh.return_value = type(
|
||||
"TokenResponse",
|
||||
(),
|
||||
{
|
||||
"access_token": "new_access_token",
|
||||
"expires_in": 3600,
|
||||
},
|
||||
)()
|
||||
|
||||
response = await test_client.post(
|
||||
"/api/v1/auth/refresh",
|
||||
@@ -516,7 +522,9 @@ class TestAuthEndpoints:
|
||||
@pytest.mark.asyncio
|
||||
async def test_refresh_token_service_error(self, test_client: AsyncClient) -> None:
|
||||
"""Test refresh token with service error."""
|
||||
with patch("app.services.auth.AuthService.refresh_access_token") as mock_refresh:
|
||||
with patch(
|
||||
"app.services.auth.AuthService.refresh_access_token",
|
||||
) as mock_refresh:
|
||||
mock_refresh.side_effect = Exception("Database error")
|
||||
|
||||
response = await test_client.post(
|
||||
@@ -528,7 +536,6 @@ class TestAuthEndpoints:
|
||||
data = response.json()
|
||||
assert "Token refresh failed" in data["detail"]
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_exchange_oauth_token_invalid_code(
|
||||
self,
|
||||
@@ -554,7 +561,9 @@ class TestAuthEndpoints:
|
||||
"""Test update profile success."""
|
||||
with (
|
||||
patch("app.services.auth.AuthService.update_user_profile") as mock_update,
|
||||
patch("app.services.auth.AuthService.user_to_response") as mock_user_to_response,
|
||||
patch(
|
||||
"app.services.auth.AuthService.user_to_response",
|
||||
) as mock_user_to_response,
|
||||
):
|
||||
updated_user = User(
|
||||
id=test_user.id,
|
||||
@@ -569,6 +578,7 @@ class TestAuthEndpoints:
|
||||
|
||||
# Mock the user_to_response to return UserResponse format
|
||||
from app.schemas.auth import UserResponse
|
||||
|
||||
mock_user_to_response.return_value = UserResponse(
|
||||
id=test_user.id,
|
||||
email=test_user.email,
|
||||
@@ -598,7 +608,9 @@ class TestAuthEndpoints:
|
||||
assert data["name"] == "Updated Name"
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_update_profile_unauthenticated(self, test_client: AsyncClient) -> None:
|
||||
async def test_update_profile_unauthenticated(
|
||||
self, test_client: AsyncClient,
|
||||
) -> None:
|
||||
"""Test update profile without authentication."""
|
||||
response = await test_client.patch(
|
||||
"/api/v1/auth/me",
|
||||
@@ -632,7 +644,9 @@ class TestAuthEndpoints:
|
||||
assert data["message"] == "Password changed successfully"
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_change_password_unauthenticated(self, test_client: AsyncClient) -> None:
|
||||
async def test_change_password_unauthenticated(
|
||||
self, test_client: AsyncClient,
|
||||
) -> None:
|
||||
"""Test change password without authentication."""
|
||||
response = await test_client.post(
|
||||
"/api/v1/auth/change-password",
|
||||
@@ -652,7 +666,9 @@ class TestAuthEndpoints:
|
||||
auth_cookies: dict[str, str],
|
||||
) -> None:
|
||||
"""Test get user OAuth providers success."""
|
||||
with patch("app.services.auth.AuthService.get_user_oauth_providers") as mock_providers:
|
||||
with patch(
|
||||
"app.services.auth.AuthService.get_user_oauth_providers",
|
||||
) as mock_providers:
|
||||
from datetime import datetime
|
||||
|
||||
from app.models.user_oauth import UserOauth
|
||||
@@ -699,7 +715,9 @@ class TestAuthEndpoints:
|
||||
assert data[2]["display_name"] == "GitHub"
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_get_user_providers_unauthenticated(self, test_client: AsyncClient) -> None:
|
||||
async def test_get_user_providers_unauthenticated(
|
||||
self, test_client: AsyncClient,
|
||||
) -> None:
|
||||
"""Test get user OAuth providers without authentication."""
|
||||
response = await test_client.get("/api/v1/auth/user-providers")
|
||||
|
||||
|
||||
@@ -109,9 +109,15 @@ class TestPlaylistEndpoints:
|
||||
|
||||
assert response.status_code == 200
|
||||
data = response.json()
|
||||
assert len(data) == 2
|
||||
assert "playlists" in data
|
||||
assert "total" in data
|
||||
assert "page" in data
|
||||
assert "limit" in data
|
||||
assert "total_pages" in data
|
||||
assert len(data["playlists"]) == 2
|
||||
assert data["total"] == 2
|
||||
|
||||
playlist_names = {p["name"] for p in data}
|
||||
playlist_names = {p["name"] for p in data["playlists"]}
|
||||
assert "Test Playlist" in playlist_names
|
||||
assert "Main Playlist" in playlist_names
|
||||
|
||||
|
||||
@@ -9,7 +9,7 @@ from httpx import AsyncClient
|
||||
from app.models.user import User
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from app.services.extraction import ExtractionInfo
|
||||
from app.services.extraction import ExtractionInfo, PaginatedExtractionsResponse
|
||||
|
||||
|
||||
class TestSoundEndpoints:
|
||||
@@ -32,6 +32,7 @@ class TestSoundEndpoints:
|
||||
"error": None,
|
||||
"sound_id": None,
|
||||
"user_id": authenticated_user.id,
|
||||
"user_name": authenticated_user.name,
|
||||
"created_at": "2025-08-03T12:00:00Z",
|
||||
"updated_at": "2025-08-03T12:00:00Z",
|
||||
}
|
||||
@@ -111,6 +112,7 @@ class TestSoundEndpoints:
|
||||
"error": None,
|
||||
"sound_id": 42,
|
||||
"user_id": authenticated_user.id,
|
||||
"user_name": authenticated_user.name,
|
||||
"created_at": "2025-08-03T12:00:00Z",
|
||||
"updated_at": "2025-08-03T12:00:00Z",
|
||||
}
|
||||
@@ -154,41 +156,49 @@ class TestSoundEndpoints:
|
||||
authenticated_user: User,
|
||||
) -> None:
|
||||
"""Test getting user extractions."""
|
||||
mock_extractions: list[ExtractionInfo] = [
|
||||
{
|
||||
"id": 1,
|
||||
"url": "https://www.youtube.com/watch?v=dQw4w9WgXcQ",
|
||||
"title": "Never Gonna Give You Up",
|
||||
"service": "youtube",
|
||||
"service_id": "dQw4w9WgXcQ",
|
||||
"status": "completed",
|
||||
"error": None,
|
||||
"sound_id": 42,
|
||||
"user_id": authenticated_user.id,
|
||||
"created_at": "2025-08-03T12:00:00Z",
|
||||
"updated_at": "2025-08-03T12:00:00Z",
|
||||
},
|
||||
{
|
||||
"id": 2,
|
||||
"url": "https://soundcloud.com/example/track",
|
||||
"title": "Example Track",
|
||||
"service": "soundcloud",
|
||||
"service_id": "example-track",
|
||||
"status": "pending",
|
||||
"error": None,
|
||||
"sound_id": None,
|
||||
"user_id": authenticated_user.id,
|
||||
"created_at": "2025-08-03T12:00:00Z",
|
||||
"updated_at": "2025-08-03T12:00:00Z",
|
||||
},
|
||||
]
|
||||
mock_extractions: PaginatedExtractionsResponse = {
|
||||
"extractions": [
|
||||
{
|
||||
"id": 1,
|
||||
"url": "https://www.youtube.com/watch?v=dQw4w9WgXcQ",
|
||||
"title": "Never Gonna Give You Up",
|
||||
"service": "youtube",
|
||||
"service_id": "dQw4w9WgXcQ",
|
||||
"status": "completed",
|
||||
"error": None,
|
||||
"sound_id": 42,
|
||||
"user_id": authenticated_user.id,
|
||||
"user_name": authenticated_user.name,
|
||||
"created_at": "2025-08-03T12:00:00Z",
|
||||
"updated_at": "2025-08-03T12:00:00Z",
|
||||
},
|
||||
{
|
||||
"id": 2,
|
||||
"url": "https://soundcloud.com/example/track",
|
||||
"title": "Example Track",
|
||||
"service": "soundcloud",
|
||||
"service_id": "example-track",
|
||||
"status": "pending",
|
||||
"error": None,
|
||||
"sound_id": None,
|
||||
"user_id": authenticated_user.id,
|
||||
"user_name": authenticated_user.name,
|
||||
"created_at": "2025-08-03T12:00:00Z",
|
||||
"updated_at": "2025-08-03T12:00:00Z",
|
||||
},
|
||||
],
|
||||
"total": 2,
|
||||
"page": 1,
|
||||
"limit": 50,
|
||||
"total_pages": 1,
|
||||
}
|
||||
|
||||
with patch(
|
||||
"app.services.extraction.ExtractionService.get_user_extractions",
|
||||
) as mock_get:
|
||||
mock_get.return_value = mock_extractions
|
||||
|
||||
response = await authenticated_client.get("/api/v1/extractions/")
|
||||
response = await authenticated_client.get("/api/v1/extractions/user")
|
||||
|
||||
assert response.status_code == 200
|
||||
data = response.json()
|
||||
@@ -337,7 +347,9 @@ class TestSoundEndpoints:
|
||||
"""Test getting sounds with authentication."""
|
||||
from app.models.sound import Sound
|
||||
|
||||
with patch("app.repositories.sound.SoundRepository.search_and_sort") as mock_get:
|
||||
with patch(
|
||||
"app.repositories.sound.SoundRepository.search_and_sort",
|
||||
) as mock_get:
|
||||
# Create mock sounds with all required fields
|
||||
mock_sound_1 = Sound(
|
||||
id=1,
|
||||
@@ -383,7 +395,9 @@ class TestSoundEndpoints:
|
||||
"""Test getting sounds with type filtering."""
|
||||
from app.models.sound import Sound
|
||||
|
||||
with patch("app.repositories.sound.SoundRepository.search_and_sort") as mock_get:
|
||||
with patch(
|
||||
"app.repositories.sound.SoundRepository.search_and_sort",
|
||||
) as mock_get:
|
||||
# Create mock sound with all required fields
|
||||
mock_sound = Sound(
|
||||
id=1,
|
||||
|
||||
Reference in New Issue
Block a user