wrongmove/tests/unit/test_export_service.py
Viktor Barzin 8d22c97320
Add comprehensive test suite: 219 new tests across backend and frontend
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
2026-02-10 21:59:45 +00:00

87 lines
4.2 KiB
Python

"""Unit tests for services/export_service.py."""
import pytest
from pathlib import Path
from unittest.mock import AsyncMock, patch
from models.listing import QueryParameters, ListingType
from services import export_service
class TestExportToCsv:
async def test_csv_export_calls_exporter(self, listing_repository, tmp_path):
output_path = tmp_path / "output.csv"
with patch("csv_exporter.export_to_csv", new_callable=AsyncMock) as mock_csv:
mock_csv.return_value = None
result = await export_service.export_to_csv(listing_repository, output_path)
mock_csv.assert_called_once()
assert result.success
async def test_csv_export_returns_correct_record_count(self, listing_repository, sample_rent_listings, tmp_path):
await listing_repository.upsert_listings(sample_rent_listings)
output_path = tmp_path / "output.csv"
with patch("csv_exporter.export_to_csv", new_callable=AsyncMock) as mock_csv:
mock_csv.return_value = None
result = await export_service.export_to_csv(listing_repository, output_path)
assert result.record_count == len(sample_rent_listings)
async def test_csv_export_passes_query_parameters(self, listing_repository, tmp_path):
output_path = tmp_path / "output.csv"
params = QueryParameters(listing_type=ListingType.RENT, min_bedrooms=2)
with patch("csv_exporter.export_to_csv", new_callable=AsyncMock) as mock_csv:
mock_csv.return_value = None
result = await export_service.export_to_csv(
listing_repository, output_path, query_parameters=params
)
assert result.success
assert str(output_path) in result.output_path
class TestExportToGeojson:
async def test_geojson_in_memory_returns_data(self, listing_repository):
fake_geojson = {"type": "FeatureCollection", "features": [{"type": "Feature"}]}
with patch("ui_exporter.export_immoweb", new_callable=AsyncMock) as mock_export:
mock_export.return_value = fake_geojson
result = await export_service.export_to_geojson(listing_repository)
assert result.data is not None
assert result.data["type"] == "FeatureCollection"
async def test_geojson_file_export_returns_path(self, listing_repository, tmp_path):
output_path = tmp_path / "output.geojson"
fake_geojson = {"type": "FeatureCollection", "features": []}
with patch("ui_exporter.export_immoweb", new_callable=AsyncMock) as mock_export:
mock_export.return_value = fake_geojson
result = await export_service.export_to_geojson(
listing_repository, output_path=output_path
)
assert result.output_path is not None
assert result.data is None
async def test_geojson_with_filters(self, listing_repository):
params = QueryParameters(listing_type=ListingType.RENT, min_bedrooms=2)
fake_geojson = {"type": "FeatureCollection", "features": []}
with patch("ui_exporter.export_immoweb", new_callable=AsyncMock) as mock_export:
mock_export.return_value = fake_geojson
result = await export_service.export_to_geojson(
listing_repository, query_parameters=params
)
assert result.success
mock_export.assert_called_once()
async def test_geojson_with_limit(self, listing_repository):
fake_geojson = {"type": "FeatureCollection", "features": []}
with patch("ui_exporter.export_immoweb", new_callable=AsyncMock) as mock_export:
mock_export.return_value = fake_geojson
result = await export_service.export_to_geojson(
listing_repository, limit=5
)
assert result.success
_, kwargs = mock_export.call_args
assert kwargs.get("limit") == 5
async def test_geojson_empty_data(self, listing_repository):
fake_geojson = {"type": "FeatureCollection", "features": []}
with patch("ui_exporter.export_immoweb", new_callable=AsyncMock) as mock_export:
mock_export.return_value = fake_geojson
result = await export_service.export_to_geojson(listing_repository)
assert result.record_count == 0