104 lines
3.4 KiB
Python
104 lines
3.4 KiB
Python
from datetime import datetime, timedelta, timezone
|
|
import uuid
|
|
|
|
import pytest
|
|
|
|
from app.core.config import settings
|
|
from app.crud import user as user_crud
|
|
from app.models.user import User, UserStatus
|
|
from app.models.user_login_session import UserLoginSession
|
|
from app.services.user_login_sessions import get_login_summaries, session_id_from_payload
|
|
|
|
|
|
def test_legacy_session_id_is_stable_without_storing_a_token():
|
|
payload = {"sub": "00000000-0000-0000-0000-000000000101", "orig_iat": 1_700_000_000, "client_type": "web"}
|
|
|
|
first = session_id_from_payload(payload)
|
|
second = session_id_from_payload(payload)
|
|
|
|
assert first == second
|
|
assert isinstance(first, uuid.UUID)
|
|
|
|
|
|
@pytest.mark.asyncio
|
|
async def test_login_summary_marks_recent_unended_sessions_online(db_session, monkeypatch):
|
|
now = datetime.now(timezone.utc)
|
|
monkeypatch.setattr(settings, "USER_SESSION_ONLINE_SECONDS", 300)
|
|
user = User(
|
|
id=uuid.uuid4(),
|
|
email="login-summary@example.com",
|
|
password_hash="hash",
|
|
full_name="Login Summary",
|
|
clinical_department="IT",
|
|
status=UserStatus.ACTIVE,
|
|
)
|
|
db_session.add(user)
|
|
db_session.add_all(
|
|
[
|
|
UserLoginSession(
|
|
id=uuid.uuid4(),
|
|
user_id=user.id,
|
|
client_type="desktop",
|
|
login_at=now - timedelta(minutes=10),
|
|
last_seen_at=now - timedelta(seconds=20),
|
|
),
|
|
UserLoginSession(
|
|
id=uuid.uuid4(),
|
|
user_id=user.id,
|
|
client_type="web",
|
|
login_at=now - timedelta(days=1),
|
|
last_seen_at=now - timedelta(days=1),
|
|
ended_at=now - timedelta(days=1),
|
|
end_reason="logout",
|
|
),
|
|
]
|
|
)
|
|
await db_session.commit()
|
|
|
|
summaries = await get_login_summaries(db_session, [user.id])
|
|
|
|
assert summaries[user.id].status == "ONLINE"
|
|
assert summaries[user.id].active_session_count == 1
|
|
assert summaries[user.id].client_type == "desktop"
|
|
|
|
|
|
@pytest.mark.asyncio
|
|
async def test_user_list_filters_online_and_offline_accounts(db_session, monkeypatch):
|
|
now = datetime.now(timezone.utc)
|
|
monkeypatch.setattr(settings, "USER_SESSION_ONLINE_SECONDS", 300)
|
|
online_user = User(
|
|
id=uuid.uuid4(),
|
|
email="online-filter@example.com",
|
|
password_hash="hash",
|
|
full_name="Online Filter",
|
|
clinical_department="IT",
|
|
status=UserStatus.ACTIVE,
|
|
)
|
|
offline_user = User(
|
|
id=uuid.uuid4(),
|
|
email="offline-filter@example.com",
|
|
password_hash="hash",
|
|
full_name="Offline Filter",
|
|
clinical_department="IT",
|
|
status=UserStatus.ACTIVE,
|
|
)
|
|
db_session.add_all([online_user, offline_user])
|
|
db_session.add(
|
|
UserLoginSession(
|
|
id=uuid.uuid4(),
|
|
user_id=online_user.id,
|
|
client_type="web",
|
|
login_at=now - timedelta(minutes=1),
|
|
last_seen_at=now - timedelta(seconds=10),
|
|
)
|
|
)
|
|
await db_session.commit()
|
|
|
|
online = await user_crud.list_users(db_session, login_status="ONLINE")
|
|
offline = await user_crud.list_users(db_session, login_status="OFFLINE")
|
|
|
|
assert online_user.id in {user.id for user in online}
|
|
assert offline_user.id not in {user.id for user in online}
|
|
assert offline_user.id in {user.id for user in offline}
|
|
assert await user_crud.count_users(db_session, login_status="ONLINE") == len(online)
|