wrongmove/crawler/tests/integration/test_api.py

181 lines
6.6 KiB
Python
Raw Permalink Normal View History

"""Integration tests for API endpoints."""
from unittest.mock import AsyncMock, patch
import pytest
from httpx import AsyncClient
from api.auth import User
class TestStatusEndpoint:
"""Tests for the /api/status endpoint."""
async def test_status_endpoint_returns_ok(
self, async_client: AsyncClient
) -> None:
"""Test that status endpoint returns OK status."""
response = await async_client.get("/api/status")
assert response.status_code == 200
assert response.json() == {"status": "OK"}
class TestListingEndpoint:
"""Tests for the /api/listing endpoint."""
async def test_listing_endpoint_requires_auth(self) -> None:
"""Test that listing endpoint requires authentication."""
from api.app import app
from httpx import ASGITransport, AsyncClient
# Clear any dependency overrides to test auth requirement
app.dependency_overrides.clear()
transport = ASGITransport(app=app)
async with AsyncClient(transport=transport, base_url="http://test") as client:
response = await client.get("/api/listing")
# Should return 401 or 403 without valid auth
assert response.status_code in (401, 403)
async def test_listing_endpoint_with_auth(
self, async_client: AsyncClient
) -> None:
"""Test that listing endpoint works with authentication."""
# Mock the repository to return empty list
with patch(
"api.app.ListingRepository.get_listings",
new_callable=AsyncMock,
return_value=[],
):
response = await async_client.get("/api/listing")
assert response.status_code == 200
data = response.json()
assert "listings" in data
class TestListingGeoJsonEndpoint:
"""Tests for the /api/listing_geojson endpoint."""
async def test_listing_geojson_requires_auth(self) -> None:
"""Test that listing_geojson endpoint requires authentication."""
from api.app import app
from httpx import ASGITransport, AsyncClient
# Clear any dependency overrides to test auth requirement
app.dependency_overrides.clear()
transport = ASGITransport(app=app)
async with AsyncClient(transport=transport, base_url="http://test") as client:
response = await client.get(
"/api/listing_geojson",
params={"listing_type": "RENT"},
)
# Should return 401 or 403 without valid auth
assert response.status_code in (401, 403)
async def test_listing_geojson_with_filters(
self, async_client: AsyncClient
) -> None:
"""Test that listing_geojson accepts filter parameters."""
with patch(
"api.app.export_immoweb",
new_callable=AsyncMock,
return_value={"type": "FeatureCollection", "features": []},
):
response = await async_client.get(
"/api/listing_geojson",
params={
"listing_type": "RENT",
"min_bedrooms": 2,
"max_bedrooms": 3,
"min_price": 1500,
"max_price": 3000,
},
)
assert response.status_code == 200
data = response.json()
assert data["type"] == "FeatureCollection"
class TestGetDistrictsEndpoint:
"""Tests for the /api/get_districts endpoint."""
async def test_get_districts_requires_auth(self) -> None:
"""Test that get_districts endpoint requires authentication."""
from api.app import app
from httpx import ASGITransport, AsyncClient
# Clear any dependency overrides to test auth requirement
app.dependency_overrides.clear()
transport = ASGITransport(app=app)
async with AsyncClient(transport=transport, base_url="http://test") as client:
response = await client.get("/api/get_districts")
# Should return 401 or 403 without valid auth
assert response.status_code in (401, 403)
async def test_get_districts_returns_dict(
self, async_client: AsyncClient
) -> None:
"""Test that get_districts returns a dictionary of districts."""
response = await async_client.get("/api/get_districts")
assert response.status_code == 200
data = response.json()
assert isinstance(data, dict)
# Check some known districts exist
assert "London" in data
assert "Westminster" in data
assert "Camden" in data
async def test_get_districts_values_are_region_ids(
self, async_client: AsyncClient
) -> None:
"""Test that district values are REGION identifiers."""
response = await async_client.get("/api/get_districts")
data = response.json()
# All values should be REGION^... format
for district_name, region_id in data.items():
assert region_id.startswith("REGION^"), (
f"District {district_name} has invalid region ID: {region_id}"
)
class TestRefreshListingsEndpoint:
"""Tests for the /api/refresh_listings endpoint."""
async def test_refresh_listings_requires_auth(self) -> None:
"""Test that refresh_listings endpoint requires authentication."""
from api.app import app
from httpx import ASGITransport, AsyncClient
# Clear any dependency overrides to test auth requirement
app.dependency_overrides.clear()
transport = ASGITransport(app=app)
async with AsyncClient(transport=transport, base_url="http://test") as client:
response = await client.post(
"/api/refresh_listings",
params={"listing_type": "RENT"},
)
# Should return 401 or 403 without valid auth
assert response.status_code in (401, 403)
class TestTaskStatusEndpoint:
"""Tests for the /api/task_status endpoint."""
async def test_task_status_requires_auth(self) -> None:
"""Test that task_status endpoint requires authentication."""
from api.app import app
from httpx import ASGITransport, AsyncClient
# Clear any dependency overrides to test auth requirement
app.dependency_overrides.clear()
transport = ASGITransport(app=app)
async with AsyncClient(transport=transport, base_url="http://test") as client:
response = await client.get(
"/api/task_status",
params={"task_id": "test-task-id"},
)
# Should return 401 or 403 without valid auth
assert response.status_code in (401, 403)