1fedd683e0
Stand: agent-06 (Audit-Log), agent-05 (Krankmeldung), agent-07 Phase 1 (Personalnummer), Busylight-Pull-Integration, TOTP/2FA, Abwesenheiten, Zeiterfassung, Kiosk-Grundgerüst. Migrations 0001–0023 deployed auf 192.168.1.137 + .164. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
129 lines
4.1 KiB
Python
129 lines
4.1 KiB
Python
import pytest
|
|
from httpx import AsyncClient
|
|
|
|
pytestmark = pytest.mark.asyncio
|
|
|
|
REGISTER_URL = "/api/v1/auth/register"
|
|
LOGIN_URL = "/api/v1/auth/login"
|
|
REFRESH_URL = "/api/v1/auth/refresh"
|
|
LOGOUT_URL = "/api/v1/auth/logout"
|
|
RESET_URL = "/api/v1/auth/password-reset"
|
|
ME_URL = "/api/v1/auth/me"
|
|
|
|
|
|
async def test_register_success(client: AsyncClient):
|
|
resp = await client.post(REGISTER_URL, json={
|
|
"company_name": "Acme GmbH",
|
|
"first_name": "Erika",
|
|
"last_name": "Muster",
|
|
"email": "erika@acme.de",
|
|
"password": "Secure123",
|
|
})
|
|
assert resp.status_code == 201
|
|
body = resp.json()
|
|
assert "access_token" in body
|
|
assert "refresh_token" in body
|
|
assert body["token_type"] == "bearer"
|
|
|
|
|
|
async def test_register_duplicate_email(client: AsyncClient, registered_user):
|
|
resp = await client.post(REGISTER_URL, json={
|
|
"company_name": "Other GmbH",
|
|
"first_name": "Max",
|
|
"last_name": "Mustermann",
|
|
"email": registered_user["user"]["email"],
|
|
"password": "Secret123",
|
|
})
|
|
assert resp.status_code == 400
|
|
assert "already registered" in resp.json()["detail"]
|
|
|
|
|
|
async def test_register_weak_password(client: AsyncClient):
|
|
resp = await client.post(REGISTER_URL, json={
|
|
"company_name": "Weak Corp",
|
|
"first_name": "A",
|
|
"last_name": "B",
|
|
"email": "weak@corp.de",
|
|
"password": "nouppercase1",
|
|
})
|
|
assert resp.status_code == 422
|
|
|
|
|
|
async def test_login_success(client: AsyncClient, registered_user):
|
|
resp = await client.post(LOGIN_URL, json={
|
|
"email": registered_user["user"]["email"],
|
|
"password": "Secret123",
|
|
})
|
|
assert resp.status_code == 200
|
|
assert "access_token" in resp.json()
|
|
|
|
|
|
async def test_login_wrong_password(client: AsyncClient, registered_user):
|
|
resp = await client.post(LOGIN_URL, json={
|
|
"email": registered_user["user"]["email"],
|
|
"password": "WrongPassword1",
|
|
})
|
|
assert resp.status_code == 401
|
|
|
|
|
|
async def test_login_unknown_email(client: AsyncClient):
|
|
resp = await client.post(LOGIN_URL, json={
|
|
"email": "nobody@nowhere.de",
|
|
"password": "Secret123",
|
|
})
|
|
assert resp.status_code == 401
|
|
|
|
|
|
async def test_me_authenticated(client: AsyncClient, registered_user):
|
|
resp = await client.get(
|
|
ME_URL,
|
|
headers={"Authorization": f"Bearer {registered_user['tokens']['access_token']}"},
|
|
)
|
|
assert resp.status_code == 200
|
|
body = resp.json()
|
|
assert body["email"] == registered_user["user"]["email"]
|
|
assert body["role"] == "COMPANY_ADMIN"
|
|
|
|
|
|
async def test_me_unauthenticated(client: AsyncClient):
|
|
resp = await client.get(ME_URL)
|
|
assert resp.status_code == 401
|
|
|
|
|
|
async def test_token_refresh(client: AsyncClient, registered_user):
|
|
resp = await client.post(REFRESH_URL, json={
|
|
"refresh_token": registered_user["tokens"]["refresh_token"],
|
|
})
|
|
assert resp.status_code == 200
|
|
new_tokens = resp.json()
|
|
assert "access_token" in new_tokens
|
|
# Old refresh token should now be invalid (rotation)
|
|
resp2 = await client.post(REFRESH_URL, json={
|
|
"refresh_token": registered_user["tokens"]["refresh_token"],
|
|
})
|
|
assert resp2.status_code == 401
|
|
|
|
|
|
async def test_logout(client: AsyncClient):
|
|
reg = await client.post(REGISTER_URL, json={
|
|
"company_name": "Logout Corp",
|
|
"first_name": "Hans",
|
|
"last_name": "Logout",
|
|
"email": "hans@logout.de",
|
|
"password": "Secret123",
|
|
})
|
|
tokens = reg.json()
|
|
resp = await client.post(LOGOUT_URL, json={"refresh_token": tokens["refresh_token"]})
|
|
assert resp.status_code == 200
|
|
# Refresh should now fail
|
|
resp2 = await client.post(REFRESH_URL, json={"refresh_token": tokens["refresh_token"]})
|
|
assert resp2.status_code == 401
|
|
|
|
|
|
async def test_password_reset_request(client: AsyncClient, registered_user):
|
|
resp = await client.post(RESET_URL, json={"email": registered_user["user"]["email"]})
|
|
assert resp.status_code == 200
|
|
# Same response for unknown email (anti-enumeration)
|
|
resp2 = await client.post(RESET_URL, json={"email": "nobody@x.de"})
|
|
assert resp2.status_code == 200
|