""" Test fixtures and configuration for Flight Radar Web App tests. This module provides reusable fixtures for testing the API. """ import pytest import sqlite3 import os import tempfile from fastapi.testclient import TestClient from typing import Generator # Import the FastAPI app import sys sys.path.insert(0, os.path.dirname(os.path.dirname(__file__))) from api_server import app, rate_limiter, log_buffer from database import get_connection @pytest.fixture(scope="session") def test_db_path() -> Generator[str, None, None]: """Create a temporary database for testing.""" # Create temporary database fd, path = tempfile.mkstemp(suffix=".db") os.close(fd) # Set environment variable to use test database original_db = os.environ.get('DATABASE_PATH') os.environ['DATABASE_PATH'] = path yield path # Cleanup if original_db: os.environ['DATABASE_PATH'] = original_db else: os.environ.pop('DATABASE_PATH', None) try: os.unlink(path) except OSError: pass @pytest.fixture(scope="function") def clean_database(test_db_path): """Provide a clean database for each test.""" # Initialize database with schema conn = sqlite3.connect(test_db_path) conn.execute("PRAGMA foreign_keys = ON") # Enable foreign keys cursor = conn.cursor() # Read and execute schema schema_path = os.path.join(os.path.dirname(os.path.dirname(__file__)), 'database', 'schema.sql') with open(schema_path, 'r') as f: schema_sql = f.read() cursor.executescript(schema_sql) conn.commit() conn.close() yield test_db_path # Clean up all tables after test conn = sqlite3.connect(test_db_path) conn.execute("PRAGMA foreign_keys = ON") # Enable foreign keys for cleanup cursor = conn.cursor() cursor.execute("DELETE FROM routes") cursor.execute("DELETE FROM scans") # Note: flight_searches and flight_results are not in web app schema conn.commit() conn.close() @pytest.fixture(scope="function") def client(clean_database) -> TestClient: """Provide a test client for the FastAPI app.""" # Clear rate limiter for each test rate_limiter.requests.clear() # Clear log buffer for each test log_buffer.clear() with TestClient(app) as test_client: yield test_client @pytest.fixture def sample_scan_data(): """Provide sample scan data for testing.""" return { "origin": "BDS", "country": "DE", "start_date": "2026-04-01", "end_date": "2026-06-30", "seat_class": "economy", "adults": 2 } @pytest.fixture def sample_route_data(): """Provide sample route data for testing.""" return { "scan_id": 1, "destination": "MUC", "destination_name": "Munich Airport", "destination_city": "Munich", "flight_count": 45, "airlines": '["Lufthansa", "Ryanair"]', "min_price": 89.99, "max_price": 299.99, "avg_price": 150.50 } @pytest.fixture def create_test_scan(clean_database, sample_scan_data): """Create a test scan in the database.""" def _create_scan(**kwargs): # Merge with defaults data = {**sample_scan_data, **kwargs} conn = sqlite3.connect(clean_database) conn.execute("PRAGMA foreign_keys = ON") # Enable foreign keys cursor = conn.cursor() cursor.execute(""" INSERT INTO scans (origin, country, start_date, end_date, status, seat_class, adults) VALUES (?, ?, ?, ?, ?, ?, ?) """, ( data['origin'], data['country'], data['start_date'], data['end_date'], data.get('status', 'pending'), data['seat_class'], data['adults'] )) scan_id = cursor.lastrowid conn.commit() conn.close() return scan_id return _create_scan @pytest.fixture def create_test_route(clean_database, sample_route_data): """Create a test route in the database.""" def _create_route(**kwargs): # Merge with defaults data = {**sample_route_data, **kwargs} conn = sqlite3.connect(clean_database) conn.execute("PRAGMA foreign_keys = ON") # Enable foreign keys cursor = conn.cursor() cursor.execute(""" INSERT INTO routes (scan_id, destination, destination_name, destination_city, flight_count, airlines, min_price, max_price, avg_price) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?) """, ( data['scan_id'], data['destination'], data['destination_name'], data['destination_city'], data['flight_count'], data['airlines'], data['min_price'], data['max_price'], data['avg_price'] )) route_id = cursor.lastrowid conn.commit() conn.close() return route_id return _create_route # Marker helpers for categorizing tests def pytest_configure(config): """Configure custom pytest markers.""" config.addinivalue_line("markers", "unit: Unit tests (fast, isolated)") config.addinivalue_line("markers", "integration: Integration tests (slower)") config.addinivalue_line("markers", "slow: Slow tests") config.addinivalue_line("markers", "database: Tests that interact with database") config.addinivalue_line("markers", "api: Tests for API endpoints")