"""POST /companies/discover: persists nothing, returns a proposed profile, rate-limited tightly since it costs a real search + LLM call.""" from __future__ import annotations import json import uuid from unittest.mock import patch import httpx import respx from app.core.rate_limit import limiter def _register_and_login(client) -> dict[str, str]: email = f"user-{uuid.uuid4().hex[:12]}@example.com" client.post( "/api/v1/auth/register", json={"email": email, "password": "correct-horse-1", "display_name": "Test User"}, ) tokens = client.post( "/api/v1/auth/login", json={"email": email, "password": "correct-horse-1"} ).json() return {"Authorization": f"Bearer {tokens['access_token']}"} def _mock_empty_github_sec(): respx.get("https://api.github.com/search/users").mock( return_value=httpx.Response(200, text=json.dumps({"items": []})) ) respx.get("https://www.sec.gov/cgi-bin/browse-edgar").mock( return_value=httpx.Response( 200, text='' ) ) def test_discover_returns_a_profile_without_persisting_a_company(client): headers = _register_and_login(client) with patch("socket.getaddrinfo", return_value=[(2, 1, 6, "", ("93.184.216.34", 0))]): with respx.mock: _mock_empty_github_sec() respx.get("https://acmewidgets.com/robots.txt").mock(return_value=httpx.Response(404)) respx.get("https://acmewidgets.com").mock( return_value=httpx.Response(200, html="Acme Widgets") ) resp = client.post( "/api/v1/companies/discover", json={"name": "Acme Widgets"}, headers=headers, ) assert resp.status_code == 200 body = resp.json() assert body["name"] == "Acme Widgets" assert body["official_website"] == "https://acmewidgets.com" assert "potential_sources" in body assert "sources_consulted" in body companies = client.get("/api/v1/companies", headers=headers).json() assert companies == [] def test_discover_requires_auth(client): resp = client.post("/api/v1/companies/discover", json={"name": "Acme"}) assert resp.status_code in (401, 403) def test_discover_enforces_rate_limit(client): headers = _register_and_login(client) limiter.enabled = True try: with patch("socket.getaddrinfo", return_value=[(2, 1, 6, "", ("93.184.216.34", 0))]): with respx.mock: _mock_empty_github_sec() respx.route(host="acme0.com").mock(return_value=httpx.Response(404)) respx.route(host="acme1.com").mock(return_value=httpx.Response(404)) respx.route(host="acme2.com").mock(return_value=httpx.Response(404)) respx.route(host="acme3.com").mock(return_value=httpx.Response(404)) respx.route(host="acme4.com").mock(return_value=httpx.Response(404)) respx.route(host="acme5.com").mock(return_value=httpx.Response(404)) statuses = [ client.post( "/api/v1/companies/discover", json={"name": f"Acme{i}"}, headers=headers, ).status_code for i in range(6) ] assert 429 in statuses, f"Expected a 429 among {statuses} after 6 rapid discover calls" finally: limiter.enabled = False