diff --git a/tests/test_extract_router.py b/tests/test_extract_router.py new file mode 100644 index 0000000..5866024 --- /dev/null +++ b/tests/test_extract_router.py @@ -0,0 +1,108 @@ +import pytest +from fastapi import FastAPI +from fastapi.testclient import TestClient + + +@pytest.fixture +def client(monkeypatch): + from axon.services.cache import InMemoryCache + + cache = InMemoryCache() + + async def async_cache(): + return cache + + monkeypatch.setattr("axon.routers.extract.get_cache", async_cache) + + async def fake_extract_url(*args, **kwargs): + return "Clean content", "Example", None + + monkeypatch.setattr("axon.routers.extract.extract_url", fake_extract_url) + + from axon.routers.extract import router + + app = FastAPI() + app.include_router(router) + return TestClient(app) + + +def test_extract_returns_clean_content(client): + resp = client.post("/extract", json={"urls": ["https://example.com"]}) + assert resp.status_code == 200 + data = resp.json() + assert data["results"][0]["success"] is True + assert data["results"][0]["title"] == "Example" + assert data["results"][0]["content"] == "Clean content" + + +def test_extract_rejects_unsafe_url(monkeypatch): + from axon.services.cache import InMemoryCache + + cache = InMemoryCache() + + async def async_cache(): + return cache + + monkeypatch.setattr("axon.routers.extract.get_cache", async_cache) + + async def unsafe(*args, **kwargs): + return None, None, "Unsafe or unsupported URL" + + monkeypatch.setattr("axon.routers.extract.extract_url", unsafe) + + from axon.routers.extract import router + + app = FastAPI() + app.include_router(router) + client = TestClient(app) + + resp = client.post("/extract", json={"urls": ["http://127.0.0.1"]}) + assert resp.status_code == 200 + result = resp.json()["results"][0] + assert result["success"] is False + assert "Unsafe" in result["error"] + + +def test_extract_uses_cache(client, monkeypatch): + calls = {"count": 0} + + async def fake_extract(*args, **kwargs): + calls["count"] += 1 + return "Cached content", "Example", None + + monkeypatch.setattr("axon.routers.extract.extract_url", fake_extract) + + payload = {"urls": ["https://example.com/cache"]} + first = client.post("/extract", json=payload) + second = client.post("/extract", json=payload) + + assert first.status_code == 200 + assert second.status_code == 200 + assert calls["count"] == 1 + + +def test_extract_reports_individual_fetch_failure(monkeypatch): + from axon.services.cache import InMemoryCache + + cache = InMemoryCache() + + async def async_cache(): + return cache + + monkeypatch.setattr("axon.routers.extract.get_cache", async_cache) + + async def fail(*args, **kwargs): + raise RuntimeError("boom") + + monkeypatch.setattr("axon.routers.extract.extract_url", fail) + + from axon.routers.extract import router + + app = FastAPI() + app.include_router(router) + client = TestClient(app) + + resp = client.post("/extract", json={"urls": ["https://bad.example"]}) + result = resp.json()["results"][0] + assert result["success"] is False + assert "boom" in result["error"]