feat: Add tests for dashboard service including statistics and date filters
This commit is contained in:
@@ -478,3 +478,227 @@ class TestAuthEndpoints:
|
||||
assert response.status_code == 400
|
||||
data = response.json()
|
||||
assert "Unsupported OAuth provider" in data["detail"]
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_refresh_token_success(
|
||||
self,
|
||||
test_client: AsyncClient,
|
||||
test_user: User,
|
||||
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,
|
||||
})()
|
||||
|
||||
response = await test_client.post(
|
||||
"/api/v1/auth/refresh",
|
||||
cookies={"refresh_token": "valid_refresh_token"}
|
||||
)
|
||||
|
||||
assert response.status_code == 200
|
||||
data = response.json()
|
||||
assert data["message"] == "Token refreshed successfully"
|
||||
mock_refresh.assert_called_once_with("valid_refresh_token")
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_refresh_token_no_token(self, test_client: AsyncClient) -> None:
|
||||
"""Test refresh token without providing refresh token."""
|
||||
response = await test_client.post("/api/v1/auth/refresh")
|
||||
|
||||
assert response.status_code == 401
|
||||
data = response.json()
|
||||
assert "No refresh token provided" in data["detail"]
|
||||
|
||||
@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:
|
||||
mock_refresh.side_effect = Exception("Database error")
|
||||
|
||||
response = await test_client.post(
|
||||
"/api/v1/auth/refresh",
|
||||
cookies={"refresh_token": "valid_refresh_token"}
|
||||
)
|
||||
|
||||
assert response.status_code == 500
|
||||
data = response.json()
|
||||
assert "Token refresh failed" in data["detail"]
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_exchange_oauth_token_invalid_code(
|
||||
self,
|
||||
test_client: AsyncClient,
|
||||
) -> None:
|
||||
"""Test OAuth token exchange with invalid code."""
|
||||
response = await test_client.post(
|
||||
"/api/v1/auth/exchange-oauth-token",
|
||||
json={"code": "invalid_code"}
|
||||
)
|
||||
|
||||
assert response.status_code == 400
|
||||
data = response.json()
|
||||
assert "Invalid or expired OAuth code" in data["detail"]
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_update_profile_success(
|
||||
self,
|
||||
test_client: AsyncClient,
|
||||
test_user: User,
|
||||
auth_cookies: dict[str, str],
|
||||
) -> None:
|
||||
"""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,
|
||||
):
|
||||
updated_user = User(
|
||||
id=test_user.id,
|
||||
email=test_user.email,
|
||||
name="Updated Name",
|
||||
role=test_user.role,
|
||||
credits=test_user.credits,
|
||||
plan_id=test_user.plan_id,
|
||||
is_active=test_user.is_active,
|
||||
)
|
||||
mock_update.return_value = updated_user
|
||||
|
||||
# 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,
|
||||
name="Updated Name",
|
||||
picture=None,
|
||||
role=test_user.role,
|
||||
credits=test_user.credits,
|
||||
is_active=test_user.is_active,
|
||||
plan={
|
||||
"id": test_user.plan_id,
|
||||
"name": "Test Plan",
|
||||
"max_credits": 100,
|
||||
"features": [],
|
||||
},
|
||||
created_at=test_user.created_at,
|
||||
updated_at=test_user.updated_at,
|
||||
)
|
||||
|
||||
response = await test_client.patch(
|
||||
"/api/v1/auth/me",
|
||||
json={"name": "Updated Name"},
|
||||
cookies=auth_cookies
|
||||
)
|
||||
|
||||
assert response.status_code == 200
|
||||
data = response.json()
|
||||
assert data["name"] == "Updated Name"
|
||||
|
||||
@pytest.mark.asyncio
|
||||
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",
|
||||
json={"name": "Updated Name"}
|
||||
)
|
||||
|
||||
assert response.status_code == 401
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_change_password_success(
|
||||
self,
|
||||
test_client: AsyncClient,
|
||||
test_user: User,
|
||||
auth_cookies: dict[str, str],
|
||||
) -> None:
|
||||
"""Test change password success."""
|
||||
with patch("app.services.auth.AuthService.change_user_password") as mock_change:
|
||||
mock_change.return_value = None
|
||||
|
||||
response = await test_client.post(
|
||||
"/api/v1/auth/change-password",
|
||||
json={
|
||||
"current_password": "old_password",
|
||||
"new_password": "new_password"
|
||||
},
|
||||
cookies=auth_cookies
|
||||
)
|
||||
|
||||
assert response.status_code == 200
|
||||
data = response.json()
|
||||
assert data["message"] == "Password changed successfully"
|
||||
|
||||
@pytest.mark.asyncio
|
||||
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",
|
||||
json={
|
||||
"current_password": "old_password",
|
||||
"new_password": "new_password"
|
||||
}
|
||||
)
|
||||
|
||||
assert response.status_code == 401
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_get_user_providers_success(
|
||||
self,
|
||||
test_client: AsyncClient,
|
||||
test_user: User,
|
||||
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:
|
||||
from app.models.user_oauth import UserOauth
|
||||
from datetime import datetime, timezone
|
||||
|
||||
mock_oauth_google = UserOauth(
|
||||
id=1,
|
||||
user_id=test_user.id,
|
||||
provider="google",
|
||||
provider_user_id="google123",
|
||||
email="test@example.com",
|
||||
name="Test User",
|
||||
created_at=datetime.now(timezone.utc),
|
||||
updated_at=datetime.now(timezone.utc),
|
||||
)
|
||||
mock_oauth_github = UserOauth(
|
||||
id=2,
|
||||
user_id=test_user.id,
|
||||
provider="github",
|
||||
provider_user_id="github456",
|
||||
email="test@example.com",
|
||||
name="Test User",
|
||||
created_at=datetime.now(timezone.utc),
|
||||
updated_at=datetime.now(timezone.utc),
|
||||
)
|
||||
mock_providers.return_value = [mock_oauth_google, mock_oauth_github]
|
||||
|
||||
response = await test_client.get(
|
||||
"/api/v1/auth/user-providers",
|
||||
cookies=auth_cookies
|
||||
)
|
||||
|
||||
assert response.status_code == 200
|
||||
data = response.json()
|
||||
assert len(data) == 3 # password + 2 OAuth providers
|
||||
|
||||
# Check password provider (first)
|
||||
assert data[0]["provider"] == "password"
|
||||
assert data[0]["display_name"] == "Password"
|
||||
|
||||
# Check OAuth providers
|
||||
assert data[1]["provider"] == "google"
|
||||
assert data[1]["display_name"] == "Google"
|
||||
assert data[2]["provider"] == "github"
|
||||
assert data[2]["display_name"] == "GitHub"
|
||||
|
||||
@pytest.mark.asyncio
|
||||
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")
|
||||
|
||||
assert response.status_code == 401
|
||||
|
||||
Reference in New Issue
Block a user