"""Tests für agent-11 PR3: geplante Erinnerungen + Notification-Prefs.""" import pytest import pytest_asyncio from datetime import date, timedelta from httpx import AsyncClient @pytest_asyncio.fixture(scope="session", loop_scope="session") async def rem_company(client: AsyncClient): resp = await client.post("/api/v1/auth/register", json={ "company_name": "Reminder AG", "first_name": "Rita", "last_name": "Admin", "email": "admin@reminderag.de", "password": "Secret123", }) assert resp.status_code == 201, resp.text admin_h = {"Authorization": f"Bearer {resp.json()['access_token']}"} inv = await client.post("/api/v1/users/invite", json={ "first_name": "Emil", "last_name": "Employee", "email": "emil@reminderag.de", "role": "EMPLOYEE", "initial_password": "Secret123", }, headers=admin_h) assert inv.status_code == 201, inv.text login = await client.post("/api/v1/auth/login", json={ "email": "emil@reminderag.de", "password": "Secret123", }) emp_h = {"Authorization": f"Bearer {login.json()['access_token']}"} return {"admin": admin_h, "emp": emp_h, "emp_id": inv.json()["id"]} async def _vacation_type(client, headers): types = (await client.get("/api/v1/absence-types/", headers=headers)).json() return next(t for t in types if t["name"] == "Urlaub")["id"] @pytest.mark.asyncio(loop_scope="session") async def test_notification_prefs_list(client: AsyncClient, rem_company): r = await client.get("/api/v1/users/me/notification-prefs", headers=rem_company["admin"]) assert r.status_code == 200, r.text keys = {p["key"] for p in r.json()} assert "pending_approvals" in keys and "carryover_expiry" in keys assert all(p["enabled"] for p in r.json()) # Default: alle an @pytest.mark.asyncio(loop_scope="session") async def test_run_reminders_pending_approvals(client: AsyncClient, rem_company): vt = await _vacation_type(client, rem_company["emp"]) start = date.today() + timedelta(days=(7 - date.today().weekday()) + 70) await client.post("/api/v1/absences/", json={ "type_id": vt, "start_date": str(start), "end_date": str(start + timedelta(days=2)), }, headers=rem_company["emp"]) run = await client.post("/api/v1/companies/me/run-reminders", headers=rem_company["admin"]) assert run.status_code == 200, run.text assert run.json()["sent"]["pending_approvals"] >= 1 @pytest.mark.asyncio(loop_scope="session") async def test_run_reminders_certificate_overdue(client: AsyncClient, rem_company): # Krankmeldung in der Vergangenheit → AU längst fällig, nicht eingegangen past = date.today() - timedelta(days=10) sick = await client.post("/api/v1/absences/quick-sick", json={ "start_date": str(past), "end_date": str(past), }, headers=rem_company["emp"]) assert sick.status_code == 201, sick.text run = await client.post("/api/v1/companies/me/run-reminders", headers=rem_company["admin"]) assert run.json()["sent"]["certificate_overdue"] >= 1 @pytest.mark.asyncio(loop_scope="session") async def test_notification_prefs_disable_suppresses_mail(client: AsyncClient, rem_company): # pending_approvals für den Admin abschalten → keine Digest-Mail mehr patch = await client.patch("/api/v1/users/me/notification-prefs", json={"prefs": {"pending_approvals": False}}, headers=rem_company["admin"]) assert patch.status_code == 200 assert any(p["key"] == "pending_approvals" and p["enabled"] is False for p in patch.json()) run = await client.post("/api/v1/companies/me/run-reminders", headers=rem_company["admin"]) assert run.json()["sent"]["pending_approvals"] == 0 # wieder aktivieren (sauberer Zustand) await client.patch("/api/v1/users/me/notification-prefs", json={"prefs": {"pending_approvals": True}}, headers=rem_company["admin"]) @pytest.mark.asyncio(loop_scope="session") async def test_run_reminders_carryover_expiry(client: AsyncClient, rem_company): # Verfall auf ~7 Tage in der Zukunft konfigurieren target = date.today() + timedelta(days=7) await client.patch("/api/v1/companies/me", json={ "settings": {"carryover_expires_month": target.month, "carryover_expires_day": target.day}, }, headers=rem_company["admin"]) # Resturlaub fürs aktuelle Jahr beim Mitarbeiter setzen yr = date.today().year await client.patch(f"/api/v1/absences/balance/{rem_company['emp_id']}?year={yr}", json={"carried_over": 5}, headers=rem_company["admin"]) run = await client.post("/api/v1/companies/me/run-reminders", headers=rem_company["admin"]) assert run.json()["sent"]["carryover_expiry"] >= 1