"""Tests for login attempt auditing (SEC-009).""" from app.models.audit import AuditLog def test_login_failed_creates_audit_entry(client, admin_user, db): response = client.post( "/api/v1/auth/login", data={"username": "admin", "password": "wrong"}, headers={"X-Forwarded-For": "198.51.100.10", "User-Agent": "LoginAuditTest/1.0"}, ) assert response.status_code == 400 log = ( db.query(AuditLog) .filter(AuditLog.action == "LOGIN_FAILED") .order_by(AuditLog.timestamp.desc()) .first() ) assert log is not None assert log.entity_type == "auth" assert log.details["username"] == "admin" assert log.details["reason"] == "invalid_credentials" assert log.ip_address == "198.51.100.10" assert log.user_agent == "LoginAuditTest/1.0" assert log.integrity_hash def test_login_success_creates_audit_entry(client, admin_user, db): client.cookies.clear() response = client.post( "/api/v1/auth/login", data={"username": "admin", "password": "admin123"}, headers={"X-Forwarded-For": "198.51.100.20"}, ) assert response.status_code == 200 log = ( db.query(AuditLog) .filter(AuditLog.action == "LOGIN_SUCCESS") .order_by(AuditLog.timestamp.desc()) .first() ) assert log is not None assert log.user_id == admin_user.id assert log.ip_address == "198.51.100.20" assert log.integrity_hash def test_login_unknown_user_still_audited(client, db): response = client.post( "/api/v1/auth/login", data={"username": "nobody", "password": "password"}, ) assert response.status_code == 400 log = db.query(AuditLog).filter(AuditLog.action == "LOGIN_FAILED").first() assert log is not None assert log.user_id is None