Backend (103 tests): - Unit tests for listing_service, export_service, district_service - Regression tests for API response contracts and query parameter validation - Integration tests for API workflows, Redis listing cache, listing processor pipeline, and repository advanced queries - E2E tests for streaming with filters, batching, caching, and task management Frontend (116 tests): - Service tests for apiClient, streamingService, taskService, listingService, healthService - Hook tests for useTaskProgress (WebSocket + polling) - Component tests for PropertyCard, FilterPanel, Header, ListView, TaskProgressDrawer, TaskIndicator, StreamingProgressBar, HealthIndicator - E2E tests for filter-stream-display flow Infrastructure: - Add pytest-xdist and test markers (regression, integration, e2e) - Add conftest fixtures: fake_redis, rent_listing_factory, seeded_repository - Add vitest + testing-library + MSW for frontend testing
75 lines
2.6 KiB
Python
75 lines
2.6 KiB
Python
"""Regression tests for QueryParameters model and API query parsing."""
|
|
|
|
import pytest
|
|
from datetime import datetime, timezone
|
|
from httpx import ASGITransport, AsyncClient
|
|
from unittest.mock import patch
|
|
|
|
from models.listing import QueryParameters, ListingType, FurnishType
|
|
|
|
|
|
pytestmark = pytest.mark.regression
|
|
|
|
|
|
class TestQueryParametersModel:
|
|
def test_defaults_applied(self):
|
|
params = QueryParameters(listing_type=ListingType.RENT)
|
|
assert params.min_bedrooms == 1
|
|
assert params.max_bedrooms == 999
|
|
assert params.listing_type == ListingType.RENT
|
|
|
|
def test_datetime_z_suffix_parsing(self):
|
|
params = QueryParameters(
|
|
listing_type=ListingType.RENT,
|
|
let_date_available_from="2024-01-15T00:00:00Z",
|
|
)
|
|
assert params.let_date_available_from is not None
|
|
assert isinstance(params.let_date_available_from, datetime)
|
|
|
|
def test_datetime_offset_parsing(self):
|
|
params = QueryParameters(
|
|
listing_type=ListingType.RENT,
|
|
let_date_available_from="2024-01-15T00:00:00+00:00",
|
|
)
|
|
assert params.let_date_available_from is not None
|
|
assert isinstance(params.let_date_available_from, datetime)
|
|
|
|
def test_min_price_greater_than_max_raises(self):
|
|
with pytest.raises((ValueError, Exception)):
|
|
QueryParameters(
|
|
listing_type=ListingType.RENT,
|
|
min_price=5000,
|
|
max_price=1000,
|
|
)
|
|
|
|
def test_min_bedrooms_greater_than_max_raises(self):
|
|
with pytest.raises((ValueError, Exception)):
|
|
QueryParameters(
|
|
listing_type=ListingType.RENT,
|
|
min_bedrooms=5,
|
|
max_bedrooms=2,
|
|
)
|
|
|
|
|
|
class TestQueryParametersApiParsing:
|
|
@pytest.mark.asyncio
|
|
async def test_comma_separated_furnish_types(self, async_client):
|
|
response = await async_client.get(
|
|
"/api/listing?listing_type=RENT&furnish_types=furnished,unfurnished"
|
|
)
|
|
# If the endpoint accepts the param, it should return 200
|
|
assert response.status_code == 200
|
|
|
|
@pytest.mark.asyncio
|
|
async def test_comma_separated_district_names(self, async_client):
|
|
response = await async_client.get(
|
|
"/api/listing?listing_type=RENT&district_names=London,Camden"
|
|
)
|
|
assert response.status_code == 200
|
|
|
|
@pytest.mark.asyncio
|
|
async def test_invalid_listing_type_returns_422(self, async_client):
|
|
response = await async_client.get(
|
|
"/api/listing_geojson?listing_type=INVALID_TYPE"
|
|
)
|
|
assert response.status_code == 422
|