From fd382e3067965686890ad6403b5bfaaeee786d8c Mon Sep 17 00:00:00 2001 From: patrick Date: Mon, 25 May 2026 00:18:00 +0200 Subject: [PATCH] test: FZA tests korrigiert (can_manual_time_entry, TimeEntryWithWarnings, CalDAV race fix) Co-Authored-By: Claude Sonnet 4.6 --- backend/tests/test_fza.py | 33 +++++++++++++++++++++------------ 1 file changed, 21 insertions(+), 12 deletions(-) diff --git a/backend/tests/test_fza.py b/backend/tests/test_fza.py index 2c010c9..55ee4b2 100644 --- a/backend/tests/test_fza.py +++ b/backend/tests/test_fza.py @@ -303,9 +303,15 @@ async def test_fza_cancel_approved_refunds( assert r3.status_code == 200, r3.text assert r3.json()["status"] == "cancelled" - # Rückbuchung prüfen - await db_session.refresh(ob) - taken_after_cancel = float(ob.taken_hours) + # Rückbuchung prüfen – frischen Query statt refresh (vermeidet Race mit CalDAV-Background-Task) + import asyncio + await asyncio.sleep(0.15) # CalDAV fire-and-forget abwarten + await db_session.execute(text("SET LOCAL app.bypass_rls = 'on'")) + ob2 = await db_session.scalar( + select(OvertimeBalance).where(OvertimeBalance.user_id == emp_me["id"]) + .execution_options(populate_existing=True) + ) + taken_after_cancel = float(ob2.taken_hours) assert taken_after_cancel == pytest.approx(0.0, abs=0.1), f"Rückbuchung fehlgeschlagen, got {taken_after_cancel}" @@ -355,20 +361,23 @@ async def test_time_entry_approval_updates_overtime_balance( ): """Nach Genehmigung eines Zeiteintrags wird OvertimeBalance.total_hours neu berechnet.""" emp_me = (await client.get("/api/v1/auth/me", headers=fza_employee_headers)).json() - hr_me = (await client.get("/api/v1/auth/me", headers=fza_hr_headers)).json() - # Eintrag manuell anlegen (10h, 2h Überstunden bei 8h Soll) + # Manuelle Zeiterfassung für diesen User freischalten + emp_id = emp_me["id"] + r = await client.patch(f"/api/v1/users/{emp_id}", json={"can_manual_time_entry": True}, headers=fza_admin_headers) + assert r.status_code == 200, f"Manual entry freischalten fehlgeschlagen: {r.text}" + + # Eintrag manuell anlegen (10h = 2h Überstunden bei 8h Soll-Tag) resp = await client.post("/api/v1/time/entries", json={ "date": "2026-06-01", "start_time": "08:00", "end_time": "18:00", "break_minutes": 0, }, headers=fza_employee_headers) - # Kann 201 oder 200 sein je nach Implementation - assert resp.status_code in (200, 201), resp.text - entry_id = resp.json()["id"] + assert resp.status_code == 201, resp.text + entry_id = resp.json()["entry"]["id"] - # Genehmigen (HR != EMPLOYEE, Self-Approval ist geblockt) + # Genehmigen (HR, kein Self-Approval) r2 = await client.post(f"/api/v1/time/entries/{entry_id}/approve", headers=fza_hr_headers) assert r2.status_code == 200, r2.text @@ -376,7 +385,7 @@ async def test_time_entry_approval_updates_overtime_balance( await db_session.execute(text("SET LOCAL app.bypass_rls = 'on'")) ob = await db_session.scalar( select(OvertimeBalance).where(OvertimeBalance.user_id == emp_me["id"]) + .execution_options(populate_existing=True) ) - if ob: - await db_session.refresh(ob) - assert ob.last_calculated is not None, "last_calculated sollte nach Genehmigung gesetzt sein" + assert ob is not None, "OvertimeBalance wurde nicht angelegt" + assert ob.last_calculated is not None, "last_calculated sollte nach Genehmigung gesetzt sein"