Aniworld/tests/unit/test_auth_models.py
Lukas 17e5a551e1 feat: migrate to Pydantic V2 and implement rate limiting middleware
- Migrate settings.py to Pydantic V2 (SettingsConfigDict, validation_alias)
- Update config models to use @field_validator with @classmethod
- Replace deprecated datetime.utcnow() with datetime.now(timezone.utc)
- Migrate FastAPI app from @app.on_event to lifespan context manager
- Implement comprehensive rate limiting middleware with:
  * Endpoint-specific rate limits (login: 5/min, register: 3/min)
  * IP-based and user-based tracking
  * Authenticated user multiplier (2x limits)
  * Bypass paths for health, docs, static, websocket endpoints
  * Rate limit headers in responses
- Add 13 comprehensive tests for rate limiting (all passing)
- Update instructions.md to mark completed tasks
- Fix asyncio.create_task usage in anime_service.py

All 714 tests passing. No deprecation warnings.
2025-10-23 22:03:15 +02:00

47 lines
1.2 KiB
Python

from datetime import datetime, timedelta, timezone
import pytest
from src.server.models.auth import (
AuthStatus,
LoginRequest,
LoginResponse,
SessionModel,
SetupRequest,
)
def test_login_request_validation():
# password is required
with pytest.raises(ValueError):
LoginRequest(password="")
req = LoginRequest(password="hunter2", remember=True)
assert req.password == "hunter2"
assert req.remember is True
def test_setup_request_requires_min_length():
with pytest.raises(ValueError):
SetupRequest(master_password="short")
good = SetupRequest(master_password="longenoughpassword")
assert good.master_password == "longenoughpassword"
def test_login_response_and_session_model():
expires = datetime.now(timezone.utc) + timedelta(hours=1)
lr = LoginResponse(access_token="tok", expires_at=expires)
assert lr.token_type == "bearer"
assert lr.access_token == "tok"
s = SessionModel(session_id="abc123", user="admin", expires_at=expires)
assert s.session_id == "abc123"
assert s.user == "admin"
def test_auth_status_defaults():
status = AuthStatus(configured=False, authenticated=False)
assert status.configured is False
assert status.authenticated is False