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
This commit is contained in:
parent
a3ac9cc060
commit
8d22c97320
36 changed files with 5447 additions and 19 deletions
77
frontend/src/__tests__/mocks/handlers.ts
Normal file
77
frontend/src/__tests__/mocks/handlers.ts
Normal file
|
|
@ -0,0 +1,77 @@
|
|||
import { http, HttpResponse } from 'msw';
|
||||
|
||||
export const handlers = [
|
||||
// Health check
|
||||
http.get('/api/status', () => {
|
||||
return HttpResponse.json({ status: 'OK' });
|
||||
}),
|
||||
|
||||
// Get listings
|
||||
http.get('/api/listing', () => {
|
||||
return HttpResponse.json({ listings: [] });
|
||||
}),
|
||||
|
||||
// Get listing GeoJSON
|
||||
http.get('/api/listing_geojson', () => {
|
||||
return HttpResponse.json({
|
||||
type: 'FeatureCollection',
|
||||
features: [],
|
||||
});
|
||||
}),
|
||||
|
||||
// Stream listing GeoJSON
|
||||
http.get('/api/listing_geojson/stream', () => {
|
||||
const lines = [
|
||||
JSON.stringify({ type: 'metadata', batch_size: 50, total_expected: 0, cached: false }),
|
||||
JSON.stringify({ type: 'complete', total: 0 }),
|
||||
].join('\n') + '\n';
|
||||
|
||||
return new HttpResponse(lines, {
|
||||
headers: { 'Content-Type': 'application/x-ndjson' },
|
||||
});
|
||||
}),
|
||||
|
||||
// Refresh listings
|
||||
http.post('/api/refresh_listings', () => {
|
||||
return HttpResponse.json({ task_id: 'test-task-123', message: 'Task started' });
|
||||
}),
|
||||
|
||||
// Task status
|
||||
http.get('/api/task_status', () => {
|
||||
return HttpResponse.json({
|
||||
task_id: 'test-task-123',
|
||||
status: 'PENDING',
|
||||
result: null,
|
||||
progress: null,
|
||||
processed: null,
|
||||
total: null,
|
||||
message: null,
|
||||
error: null,
|
||||
traceback: null,
|
||||
});
|
||||
}),
|
||||
|
||||
// Tasks for user
|
||||
http.get('/api/tasks_for_user', () => {
|
||||
return HttpResponse.json([]);
|
||||
}),
|
||||
|
||||
// Cancel task
|
||||
http.post('/api/cancel_task', () => {
|
||||
return HttpResponse.json({ success: true, message: 'Task cancelled' });
|
||||
}),
|
||||
|
||||
// Clear all tasks
|
||||
http.post('/api/clear_all_tasks', () => {
|
||||
return HttpResponse.json({ success: true, count: 0, message: 'Cleared 0 tasks' });
|
||||
}),
|
||||
|
||||
// Districts
|
||||
http.get('/api/get_districts', () => {
|
||||
return HttpResponse.json({
|
||||
London: 'REGION^87490',
|
||||
Westminster: 'REGION^93980',
|
||||
Camden: 'REGION^93941',
|
||||
});
|
||||
}),
|
||||
];
|
||||
4
frontend/src/__tests__/mocks/server.ts
Normal file
4
frontend/src/__tests__/mocks/server.ts
Normal file
|
|
@ -0,0 +1,4 @@
|
|||
import { setupServer } from 'msw/node';
|
||||
import { handlers } from './handlers';
|
||||
|
||||
export const server = setupServer(...handlers);
|
||||
Loading…
Add table
Add a link
Reference in a new issue