NeighbourAid / tests /test_stats_users.py
Parth Kansal
commit
49e9f9d
import pytest
from unittest.mock import AsyncMock, MagicMock
from bson import ObjectId
from app.core.security import create_token
def _token(role="reporter"):
return create_token({"sub": str(ObjectId()), "role": role})
@pytest.mark.asyncio
async def test_stats_public_no_auth_needed(client):
c, db = client
db.alerts.count_documents = AsyncMock(return_value=0)
async def empty_agg(*args, **kwargs):
if False:
yield
db.alerts.aggregate = MagicMock(return_value=empty_agg())
resp = await c.get("/api/stats/")
assert resp.status_code == 200
body = resp.json()
assert "active_alerts" in body
assert "critical_open" in body
assert "last_24h" in body
@pytest.mark.asyncio
async def test_user_me_requires_auth(client):
c, _ = client
resp = await c.get("/api/users/me")
# FastAPI's HTTPBearer returns 403 when the header is missing
assert resp.status_code in (401, 403)
@pytest.mark.asyncio
async def test_update_location_requires_valid_coords(client):
c, db = client
db.users.find_one_and_update = AsyncMock(
return_value={
"_id": ObjectId(),
"name": "x",
"email": "x@x.com",
"role": "reporter",
"location": {"type": "Point", "coordinates": [76.7, 30.7]},
"created_at": "2024-01-01T00:00:00",
}
)
resp = await c.patch(
"/api/users/me/location",
json={"location": {"type": "Point", "coordinates": [999, 999]}},
headers={"Authorization": f"Bearer {_token()}"},
)
# 422 — our validator rejects out-of-range coords
assert resp.status_code == 422
@pytest.mark.asyncio
async def test_news_endpoint_structure(client, monkeypatch):
c, _ = client
# Patch the symbol where it's actually used (imported into the route module).
from app.routes import news as news_route
async def fake_fetch():
return [
{
"source": "Test",
"title": "Fire in city centre",
"link": "https://example.com/a",
"summary": "...",
"published": "",
}
]
monkeypatch.setattr(news_route, "fetch_news", fake_fetch)
resp = await c.get("/api/news/recent")
assert resp.status_code == 200
body = resp.json()
assert body["count"] == 1
assert body["items"][0]["title"] == "Fire in city centre"
@pytest.mark.asyncio
async def test_my_stats_reporter_shape(client):
c, db = client
db.alerts.count_documents = AsyncMock(return_value=3)
resp = await c.get(
"/api/users/me/stats",
headers={"Authorization": f"Bearer {_token('reporter')}"},
)
assert resp.status_code == 200
body = resp.json()
assert body["role"] == "reporter"
assert body["posted"] == 3