"""Tests for FR-5 (Activity entity, polymorphic parent).""" from __future__ import annotations from datetime import datetime import pytest from httpx import AsyncClient @pytest.mark.asyncio async def test_create_activity_with_polymorphic_fk( client: AsyncClient, auth_headers: dict[str, str], seed_data: dict ) -> None: deal_id = seed_data["deal_ids"][0] resp = await client.post( "/api/v1/activities/", json={"type": "task", "subject": "Follow up", "deal_id": deal_id}, headers=auth_headers, ) assert resp.status_code == 201, resp.text body = resp.json() assert body["deal_id"] == deal_id @pytest.mark.asyncio async def test_list_activities_filter_overdue(client: AsyncClient, seed_data: dict) -> None: # seed_data inserts 4 overdue activities resp = await client.get("/api/v1/activities/?overdue=true", headers=seed_data["headers"]) assert resp.status_code == 200 body = resp.json() now = datetime.now() # naive: SQLite returns naive datetimes for a in body: if a.get("due_date") and a.get("completed_at") is None: due = a["due_date"] if due.endswith("Z"): due = due.replace("Z", "+00:00") assert datetime.fromisoformat(due) < now @pytest.mark.asyncio async def test_complete_activity(client: AsyncClient, seed_data: dict) -> None: a_id = seed_data["activity_ids"][0] resp = await client.patch( f"/api/v1/activities/{a_id}/complete", json={"outcome": "Resolved via email"}, headers=seed_data["headers"], ) assert resp.status_code == 200, resp.text body = resp.json() assert body["completed_at"] is not None @pytest.mark.asyncio async def test_activity_requires_at_least_one_parent( client: AsyncClient, auth_headers: dict[str, str] ) -> None: resp = await client.post( "/api/v1/activities/", json={"type": "task", "subject": "Orphan task"}, # no account/contact/deal headers=auth_headers, ) assert resp.status_code == 422