Files
TJWaterServerBinary/tests/auth/test_metadata_dependencies.py
T

107 lines
3.0 KiB
Python

from datetime import datetime, timezone
from types import SimpleNamespace
from unittest.mock import AsyncMock
from uuid import uuid4
import pytest
from fastapi import HTTPException
from app.auth import metadata_dependencies
@pytest.fixture
def anyio_backend():
return "asyncio"
def _user(**overrides):
data = {
"id": uuid4(),
"keycloak_id": uuid4(),
"username": "old-name",
"email": "old@example.com",
"role": "user",
"is_active": True,
"is_superuser": False,
"created_at": datetime(2026, 1, 1, tzinfo=timezone.utc),
"updated_at": datetime(2026, 1, 1, tzinfo=timezone.utc),
"last_login_at": None,
}
data.update(overrides)
return SimpleNamespace(**data)
@pytest.mark.anyio
async def test_current_metadata_user_refreshes_keycloak_claim_snapshot():
keycloak_id = uuid4()
user = _user(keycloak_id=keycloak_id)
refreshed = _user(
id=user.id,
keycloak_id=keycloak_id,
username="alice",
email="alice@example.com",
last_login_at=datetime(2026, 6, 12, tzinfo=timezone.utc),
)
repo = SimpleNamespace(
get_user_by_keycloak_id=AsyncMock(return_value=user),
refresh_user_keycloak_snapshot=AsyncMock(return_value=refreshed),
)
response = await metadata_dependencies.get_current_metadata_user(
{
"sub": str(keycloak_id),
"preferred_username": "alice",
"email": "alice@example.com",
},
metadata_repo=repo,
)
assert response.username == "alice"
repo.get_user_by_keycloak_id.assert_awaited_once_with(keycloak_id)
repo.refresh_user_keycloak_snapshot.assert_awaited_once_with(
user,
username="alice",
email="alice@example.com",
)
@pytest.mark.anyio
async def test_current_metadata_user_rejects_invalid_keycloak_sub():
repo = SimpleNamespace(
get_user_by_keycloak_id=AsyncMock(),
refresh_user_keycloak_snapshot=AsyncMock(),
)
with pytest.raises(HTTPException) as exc:
await metadata_dependencies.get_current_metadata_user(
{"sub": "not-a-uuid"},
metadata_repo=repo,
)
assert exc.value.status_code == 401
repo.get_user_by_keycloak_id.assert_not_called()
repo.refresh_user_keycloak_snapshot.assert_not_called()
@pytest.mark.anyio
async def test_current_metadata_user_rejects_username_claim_fallback():
keycloak_id = uuid4()
repo = SimpleNamespace(
get_user_by_keycloak_id=AsyncMock(),
refresh_user_keycloak_snapshot=AsyncMock(),
)
with pytest.raises(HTTPException) as exc:
await metadata_dependencies.get_current_metadata_user(
{
"sub": str(keycloak_id),
"username": "legacy-name",
},
metadata_repo=repo,
)
assert exc.value.status_code == 401
assert exc.value.detail == "Missing preferred_username claim"
repo.get_user_by_keycloak_id.assert_not_called()
repo.refresh_user_keycloak_snapshot.assert_not_called()