spb/company-atlas
Public
Python 66.3%
TypeScript 22.7%
JavaScript 8.6%
HTML 1.4%
CSS 0.7%
1"""Owner endpoints: watchlist and alerts flow with X-CA-Owner-Token (auto-created owner)."""2from __future__ import annotations34import pytest5import test_api_support as support67client = support.client8fixture_data = support.fixture_data9OWNER = support.OWNER1011pytestmark = pytest.mark.asyncio(loop_scope="session")12V = "/api/v1"131415async def test_owner_token_required(client): # type: ignore[no-untyped-def]16 assert (await client.get(f"{V}/watchlist")).status_code == 40117 assert (await client.get(f"{V}/watchlist", headers={"X-CA-Owner-Token": "short"})).status_code == 40118 assert (await client.get(f"{V}/alerts")).status_code == 401192021async def test_watchlist_flow(client, fixture_data): # type: ignore[no-untyped-def]22 r = await client.get(f"{V}/watchlist", headers=OWNER)23 assert r.status_code == 200 and r.headers["cache-control"] == "no-store"24 assert r.json()["items"] == [] and r.json()["events"] == []25 r = await client.post(f"{V}/watchlist", headers=OWNER, json={"company": fixture_data["alpha_slug"]})26 assert r.status_code == 201 and r.json()["added"] is True and r.json()["company"]["slug"] == fixture_data["alpha_slug"]27 again = await client.post(f"{V}/watchlist", headers=OWNER, json={"company": fixture_data["alpha"]})28 assert again.status_code == 201 and again.json()["added"] is False29 assert (await client.post(f"{V}/watchlist", headers=OWNER, json={"company": "nope"})).status_code == 40430 body = (await client.get(f"{V}/watchlist", headers=OWNER)).json()31 assert [c["slug"] for c in body["items"]] == [fixture_data["alpha_slug"]] and body["items"][0]["added_at"]32 assert {e["company"]["slug"] for e in body["events"]} == {fixture_data["alpha_slug"]} and len(body["events"]) == 333 r = await client.delete(f"{V}/watchlist/{fixture_data['alpha_slug']}", headers=OWNER)34 assert r.status_code == 200 and r.json()["removed"] is True35 assert (await client.delete(f"{V}/watchlist/{fixture_data['alpha_slug']}", headers=OWNER)).json()["removed"] is False36 assert (await client.get(f"{V}/watchlist", headers=OWNER)).json()["items"] == []373839async def test_alerts_flow(client, fixture_data): # type: ignore[no-untyped-def]40 r = await client.post(f"{V}/alerts", headers=OWNER, json={"name": "Pricing moves", "company": fixture_data["alpha_slug"],41 "condition": {"event_types": ["pricing"], "min_importance": 0.6}, "channel": "web"})42 assert r.status_code == 20143 alert = r.json()44 assert alert["condition"] == {"event_types": ["PRICING"], "min_importance": 0.6} and alert["company"]["slug"] == fixture_data["alpha_slug"]45 assert (await client.post(f"{V}/alerts", headers=OWNER, json={"name": "bad", "condition": {"event_types": ["NOPE"]}})).status_code == 42246 assert (await client.post(f"{V}/alerts", headers=OWNER, json={"name": "hook", "channel": "webhook", "condition": {"min_importance": 0.9}})).status_code == 42247 assert (await client.post(f"{V}/alerts", headers=OWNER, json={"name": "empty"})).status_code == 42248 ok = await client.post(f"{V}/alerts", headers=OWNER, json={"name": "hook", "channel": "webhook", "target": "https://example.org/hook",49 "condition": {"metrics": {"activity_score": {"gt": 80}}}})50 assert ok.status_code == 201 and ok.json()["condition"]["metrics"]["activity_score"] == {"gt": 80.0}51 items = (await client.get(f"{V}/alerts", headers=OWNER)).json()["items"]52 assert {a["name"] for a in items} == {"Pricing moves", "hook"}53 deliveries = await client.get(f"{V}/alerts/deliveries", headers=OWNER)54 assert deliveries.status_code == 200 and deliveries.json()["items"] == []55 for a in items:56 assert (await client.delete(f"{V}/alerts/{a['id']}", headers=OWNER)).json()["removed"] is True57 assert (await client.delete(f"{V}/alerts/{items[0]['id']}", headers=OWNER)).status_code == 40458 assert (await client.get(f"{V}/alerts", headers=OWNER)).json()["items"] == []59