"""Owner endpoints: watchlist and alerts flow with X-CA-Owner-Token (auto-created owner).""" from __future__ import annotations import pytest import test_api_support as support client = support.client fixture_data = support.fixture_data OWNER = support.OWNER pytestmark = pytest.mark.asyncio(loop_scope="session") V = "/api/v1" async def test_owner_token_required(client): # type: ignore[no-untyped-def] assert (await client.get(f"{V}/watchlist")).status_code == 401 assert (await client.get(f"{V}/watchlist", headers={"X-CA-Owner-Token": "short"})).status_code == 401 assert (await client.get(f"{V}/alerts")).status_code == 401 async def test_watchlist_flow(client, fixture_data): # type: ignore[no-untyped-def] r = await client.get(f"{V}/watchlist", headers=OWNER) assert r.status_code == 200 and r.headers["cache-control"] == "no-store" assert r.json()["items"] == [] and r.json()["events"] == [] r = await client.post(f"{V}/watchlist", headers=OWNER, json={"company": fixture_data["alpha_slug"]}) assert r.status_code == 201 and r.json()["added"] is True and r.json()["company"]["slug"] == fixture_data["alpha_slug"] again = await client.post(f"{V}/watchlist", headers=OWNER, json={"company": fixture_data["alpha"]}) assert again.status_code == 201 and again.json()["added"] is False assert (await client.post(f"{V}/watchlist", headers=OWNER, json={"company": "nope"})).status_code == 404 body = (await client.get(f"{V}/watchlist", headers=OWNER)).json() assert [c["slug"] for c in body["items"]] == [fixture_data["alpha_slug"]] and body["items"][0]["added_at"] assert {e["company"]["slug"] for e in body["events"]} == {fixture_data["alpha_slug"]} and len(body["events"]) == 3 r = await client.delete(f"{V}/watchlist/{fixture_data['alpha_slug']}", headers=OWNER) assert r.status_code == 200 and r.json()["removed"] is True assert (await client.delete(f"{V}/watchlist/{fixture_data['alpha_slug']}", headers=OWNER)).json()["removed"] is False assert (await client.get(f"{V}/watchlist", headers=OWNER)).json()["items"] == [] async def test_alerts_flow(client, fixture_data): # type: ignore[no-untyped-def] r = await client.post(f"{V}/alerts", headers=OWNER, json={"name": "Pricing moves", "company": fixture_data["alpha_slug"], "condition": {"event_types": ["pricing"], "min_importance": 0.6}, "channel": "web"}) assert r.status_code == 201 alert = r.json() assert alert["condition"] == {"event_types": ["PRICING"], "min_importance": 0.6} and alert["company"]["slug"] == fixture_data["alpha_slug"] assert (await client.post(f"{V}/alerts", headers=OWNER, json={"name": "bad", "condition": {"event_types": ["NOPE"]}})).status_code == 422 assert (await client.post(f"{V}/alerts", headers=OWNER, json={"name": "hook", "channel": "webhook", "condition": {"min_importance": 0.9}})).status_code == 422 assert (await client.post(f"{V}/alerts", headers=OWNER, json={"name": "empty"})).status_code == 422 ok = await client.post(f"{V}/alerts", headers=OWNER, json={"name": "hook", "channel": "webhook", "target": "https://example.org/hook", "condition": {"metrics": {"activity_score": {"gt": 80}}}}) assert ok.status_code == 201 and ok.json()["condition"]["metrics"]["activity_score"] == {"gt": 80.0} items = (await client.get(f"{V}/alerts", headers=OWNER)).json()["items"] assert {a["name"] for a in items} == {"Pricing moves", "hook"} deliveries = await client.get(f"{V}/alerts/deliveries", headers=OWNER) assert deliveries.status_code == 200 and deliveries.json()["items"] == [] for a in items: assert (await client.delete(f"{V}/alerts/{a['id']}", headers=OWNER)).json()["removed"] is True assert (await client.delete(f"{V}/alerts/{items[0]['id']}", headers=OWNER)).status_code == 404 assert (await client.get(f"{V}/alerts", headers=OWNER)).json()["items"] == []