74 lines
2.5 KiB
Python
74 lines
2.5 KiB
Python
from sqlalchemy import select
|
|||
|
|
|
||
|
|
from app.models import AuditEvent
|
||
|
|
|
||
|
|
STRONG_PASSWORD = "Kz8#Fj2!Lm9@Qw4$xR"
|
||
|
|
CREDENTIALS = {"email": "alice@example.com", "password": STRONG_PASSWORD}
|
||
|
|
|
||
|
|
|
||
|
|
# слабый пароль не регистрируется;
|
||
|
|
def test_register_weak_password_returns_400(client):
|
||
|
|
resp = client.post(
|
||
|
|
"/auth/register", json={"email": "weak@example.com", "password": "password"}
|
||
|
|
)
|
||
|
|
assert resp.status_code == 400
|
||
|
|
|
||
|
|
|
||
|
|
def test_register_strong_password_returns_token(client):
|
||
|
|
resp = client.post("/auth/register", json=CREDENTIALS)
|
||
|
|
assert resp.status_code == 201
|
||
|
|
body = resp.json()
|
||
|
|
assert body["access_token"]
|
||
|
|
assert body["token_type"] == "bearer"
|
||
|
|
|
||
|
|
|
||
|
|
def test_register_then_login(client):
|
||
|
|
client.post("/auth/register", json=CREDENTIALS)
|
||
|
|
resp = client.post("/auth/login", json=CREDENTIALS)
|
||
|
|
assert resp.status_code == 200
|
||
|
|
assert resp.json()["access_token"]
|
||
|
|
|
||
|
|
|
||
|
|
# логин с неверным паролем возвращает 401 и не раскрывает, какое именно поле неверно;
|
||
|
|
def test_login_wrong_password_returns_401(client):
|
||
|
|
client.post("/auth/register", json=CREDENTIALS)
|
||
|
|
resp = client.post(
|
||
|
|
"/auth/login",
|
||
|
|
json={"email": CREDENTIALS["email"], "password": "completely-wrong"},
|
||
|
|
)
|
||
|
|
assert resp.status_code == 401
|
||
|
|
assert resp.json()["detail"] == "Invalid credentials"
|
||
|
|
|
||
|
|
|
||
|
|
def test_register_duplicate_email_returns_409(client):
|
||
|
|
client.post("/auth/register", json=CREDENTIALS)
|
||
|
|
resp = client.post("/auth/register", json=CREDENTIALS)
|
||
|
|
assert resp.status_code == 409
|
||
|
|
|
||
|
|
|
||
|
|
# `/auth/me` без токена → 401;
|
||
|
|
def test_me_requires_token(client):
|
||
|
|
resp = client.get("/auth/me")
|
||
|
|
assert resp.status_code == 401
|
||
|
|
|
||
|
|
|
||
|
|
def test_me_with_token(client):
|
||
|
|
token = client.post("/auth/register", json=CREDENTIALS).json()["access_token"]
|
||
|
|
resp = client.get("/auth/me", headers={"Authorization": f"Bearer {token}"})
|
||
|
|
assert resp.status_code == 200
|
||
|
|
body = resp.json()
|
||
|
|
assert body["email"] == CREDENTIALS["email"]
|
||
|
|
assert body["is_admin"] is False
|
||
|
|
assert isinstance(body["id"], int)
|
||
|
|
|
||
|
|
|
||
|
|
# после успешного логина в таблице `audit_events` появляется `user.login.success`.
|
||
|
|
def test_successful_login_records_audit_event(client, db_session):
|
||
|
|
client.post("/auth/register", json=CREDENTIALS)
|
||
|
|
client.post("/auth/login", json=CREDENTIALS)
|
||
|
|
event = db_session.scalar(
|
||
|
|
select(AuditEvent).where(AuditEvent.event_type == "user.login.success")
|
||
|
|
)
|
||
|
|
assert event is not None
|
||
|
|
|