Files
LetterFeed/backend/app/tests/test_auth.py
2025-07-19 10:12:11 +02:00

171 lines
6.1 KiB
Python

from unittest.mock import patch
from fastapi.testclient import TestClient
from sqlalchemy.orm import Session
from app.crud.settings import create_or_update_settings
from app.schemas.settings import SettingsCreate
def test_auth_status_disabled(client: TestClient):
"""Test auth status when auth is disabled."""
response = client.get("/auth/status")
assert response.status_code == 200
assert response.json() == {"auth_enabled": False}
def test_auth_status_enabled(client: TestClient, db_session: Session):
"""Test auth status when auth is enabled."""
settings_data = SettingsCreate(
imap_server="test.com",
imap_username="test",
imap_password="password",
auth_username="admin",
auth_password="password",
)
create_or_update_settings(db_session, settings_data)
response = client.get("/auth/status")
assert response.status_code == 200
assert response.json() == {"auth_enabled": True}
def test_login_endpoint(client: TestClient, db_session: Session):
"""Test the /auth/login endpoint directly."""
# Setup auth credentials in the database
settings_data = SettingsCreate(
imap_server="test.com",
imap_username="test",
imap_password="password",
auth_username="admin",
auth_password="password",
)
create_or_update_settings(db_session, settings_data)
# Test with correct credentials
login_data = {"username": "admin", "password": "password"}
response = client.post("/auth/login", data=login_data)
assert response.status_code == 200
json_response = response.json()
assert "access_token" in json_response
assert json_response["token_type"] == "bearer"
# Test with incorrect password
login_data["password"] = "wrongpassword"
response = client.post("/auth/login", data=login_data)
assert response.status_code == 401
# Test with incorrect username
login_data["username"] = "wronguser"
login_data["password"] = "password"
response = client.post("/auth/login", data=login_data)
assert response.status_code == 401
# Test with no credentials
response = client.post("/auth/login")
assert response.status_code == 422 # FastAPI validation error for missing form data
def test_protected_route_no_auth(client: TestClient, db_session: Session):
"""Test accessing a protected route without auth enabled."""
# Health is not protected, newsletters is.
response = client.get("/newsletters")
assert response.status_code == 200
def test_protected_route_with_auth_fail(client: TestClient, db_session: Session):
"""Test accessing a protected route with auth enabled but wrong credentials."""
settings_data = SettingsCreate(
imap_server="test.com",
imap_username="test",
imap_password="password",
auth_username="admin",
auth_password="password",
)
create_or_update_settings(db_session, settings_data)
response = client.get("/newsletters")
assert response.status_code == 401
response = client.get(
"/newsletters", headers={"Authorization": "Bearer wrongtoken"}
)
assert response.status_code == 401
def test_protected_route_with_auth_success(client: TestClient, db_session: Session):
"""Test accessing a protected route with auth enabled and correct credentials."""
settings_data = SettingsCreate(
imap_server="test.com",
imap_username="test",
imap_password="password",
auth_username="admin",
auth_password="password",
)
create_or_update_settings(db_session, settings_data)
# First, log in to get a token
login_data = {"username": "admin", "password": "password"}
response = client.post("/auth/login", data=login_data)
token = response.json()["access_token"]
# Then, use the token to access the protected route
headers = {"Authorization": f"Bearer {token}"}
response = client.get("/newsletters", headers=headers)
assert response.status_code == 200
def test_unprotected_route_with_auth(client: TestClient, db_session: Session):
"""Test that feed endpoint is not protected."""
settings_data = SettingsCreate(
imap_server="test.com",
imap_username="test",
imap_password="password",
auth_username="admin",
auth_password="password",
)
create_or_update_settings(db_session, settings_data)
# Log in to get a token
login_data = {"username": "admin", "password": "password"}
login_response = client.post("/auth/login", data=login_data)
token = login_response.json()["access_token"]
headers = {"Authorization": f"Bearer {token}"}
# Create a newsletter to get a feed from
newsletter_data = {"name": "Test Newsletter", "sender_emails": ["test@test.com"]}
create_response = client.post("/newsletters", json=newsletter_data, headers=headers)
newsletter_id = create_response.json()["id"]
response = client.get(f"/feeds/{newsletter_id}")
assert response.status_code == 200
def test_auth_with_env_vars(client: TestClient):
"""Test authentication using environment variables."""
with patch("app.core.auth.env_settings") as mock_env_settings:
mock_env_settings.auth_username = "env_admin"
mock_env_settings.auth_password = "env_password"
mock_env_settings.secret_key = "test-secret"
mock_env_settings.algorithm = "HS256"
mock_env_settings.access_token_expire_minutes = 30
# Log in to get a token
login_data = {"username": "env_admin", "password": "env_password"}
login_response = client.post("/auth/login", data=login_data)
assert login_response.status_code == 200
token = login_response.json()["access_token"]
headers = {"Authorization": f"Bearer {token}"}
response = client.get("/newsletters", headers=headers)
assert response.status_code == 200
response = client.get(
"/newsletters", headers={"Authorization": "Bearer wrongtoken"}
)
assert response.status_code == 401
response = client.get("/auth/status")
assert response.status_code == 200
assert response.json() == {"auth_enabled": True}