Files
timemaster/backend/tests/test_users.py
T
sysops 1fedd683e0 Initial commit – TimeMaster Zeiterfassung & HR-Tool
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>
2026-05-23 20:03:27 +02:00

129 lines
4.3 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import pytest
from httpx import AsyncClient
pytestmark = pytest.mark.asyncio
USERS_URL = "/api/v1/users"
INVITE_URL = "/api/v1/users/invite"
def auth(tokens):
return {"Authorization": f"Bearer {tokens['access_token']}"}
async def test_list_users_as_admin(client: AsyncClient, registered_user):
resp = await client.get(USERS_URL + "/", headers=auth(registered_user["tokens"]))
assert resp.status_code == 200
body = resp.json()
assert "total" in body
assert "items" in body
assert body["total"] >= 1
async def test_list_users_forbidden_for_employee(client: AsyncClient, registered_user):
# Invite an employee first
inv = await client.post(INVITE_URL, headers=auth(registered_user["tokens"]), json={
"email": "employee@test.de",
"first_name": "Anna",
"last_name": "Arbeit",
"role": "EMPLOYEE",
})
assert inv.status_code == 201
# Employee tries to list users should fail
# (We can't log in as employee here without accepting invite;
# so we test the role check via schema validation only)
assert inv.json()["role"] == "EMPLOYEE"
async def test_invite_user(client: AsyncClient, registered_user):
resp = await client.post(INVITE_URL, headers=auth(registered_user["tokens"]), json={
"email": "newcolleague@test.de",
"first_name": "Birgit",
"last_name": "Neu",
"role": "MANAGER",
})
assert resp.status_code == 201
body = resp.json()
assert body["email"] == "newcolleague@test.de"
assert body["role"] == "MANAGER"
assert body["is_active"] is False # not yet accepted
async def test_invite_duplicate_email(client: AsyncClient, registered_user):
await client.post(INVITE_URL, headers=auth(registered_user["tokens"]), json={
"email": "dup@test.de", "first_name": "D", "last_name": "U", "role": "EMPLOYEE",
})
resp = await client.post(INVITE_URL, headers=auth(registered_user["tokens"]), json={
"email": "dup@test.de", "first_name": "D", "last_name": "U", "role": "EMPLOYEE",
})
assert resp.status_code == 400
async def test_get_me(client: AsyncClient, registered_user):
resp = await client.get(USERS_URL + "/me", headers=auth(registered_user["tokens"]))
assert resp.status_code == 200
assert resp.json()["id"] == registered_user["user"]["id"]
async def test_update_user(client: AsyncClient, registered_user):
user_id = registered_user["user"]["id"]
resp = await client.patch(
f"{USERS_URL}/{user_id}",
headers=auth(registered_user["tokens"]),
json={"first_name": "Maximilian"},
)
assert resp.status_code == 200
assert resp.json()["first_name"] == "Maximilian"
async def test_deactivate_and_reactivate(client: AsyncClient, registered_user):
# Invite a second user to deactivate
inv = await client.post(INVITE_URL, headers=auth(registered_user["tokens"]), json={
"email": "temp@test.de", "first_name": "T", "last_name": "Emp", "role": "EMPLOYEE",
})
user_id = inv.json()["id"]
deact = await client.post(
f"{USERS_URL}/{user_id}/deactivate",
headers=auth(registered_user["tokens"]),
)
assert deact.status_code == 200
assert deact.json()["is_active"] is False
react = await client.post(
f"{USERS_URL}/{user_id}/reactivate",
headers=auth(registered_user["tokens"]),
)
assert react.status_code == 200
assert react.json()["is_active"] is True
async def test_cannot_deactivate_self(client: AsyncClient, registered_user):
user_id = registered_user["user"]["id"]
resp = await client.post(
f"{USERS_URL}/{user_id}/deactivate",
headers=auth(registered_user["tokens"]),
)
assert resp.status_code == 400
async def test_set_kiosk_pin(client: AsyncClient, registered_user):
user_id = registered_user["user"]["id"]
resp = await client.post(
f"{USERS_URL}/{user_id}/kiosk-pin",
headers=auth(registered_user["tokens"]),
json={"pin": "1234"},
)
assert resp.status_code == 200
async def test_kiosk_pin_must_be_numeric(client: AsyncClient, registered_user):
user_id = registered_user["user"]["id"]
resp = await client.post(
f"{USERS_URL}/{user_id}/kiosk-pin",
headers=auth(registered_user["tokens"]),
json={"pin": "abcd"},
)
assert resp.status_code == 422