""" conftest.py - pytest fixtures and configuration """ import os import sys import pytest import uuid from datetime import datetime, date # Add project root to path sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.abspath(__file__)))) # Set test environment variables os.environ.setdefault("DB_HOST", "localhost") os.environ.setdefault("DB_PORT", "5432") os.environ.setdefault("DB_NAME", "app") os.environ.setdefault("DB_USER", "app") os.environ.setdefault("DB_PASS", "app") os.environ.setdefault("JWT_SECRET", "test-secret-key") @pytest.fixture def test_user_uuid(): """Generate a test user UUID.""" return str(uuid.uuid4()) @pytest.fixture def test_routine_uuid(): """Generate a test routine UUID.""" return str(uuid.uuid4()) @pytest.fixture def test_step_uuid(): """Generate a test step UUID.""" return str(uuid.uuid4()) @pytest.fixture def test_session_uuid(): """Generate a test session UUID.""" return str(uuid.uuid4()) @pytest.fixture def test_tag_uuid(): """Generate a test tag UUID.""" return str(uuid.uuid4()) @pytest.fixture def test_template_uuid(): """Generate a test template UUID.""" return str(uuid.uuid4()) @pytest.fixture def sample_routine_data(test_user_uuid): """Sample routine data for testing.""" return { "id": str(uuid.uuid4()), "user_uuid": test_user_uuid, "name": "Test Routine", "description": "A test routine", "icon": "test", "created_at": datetime.now(), } @pytest.fixture def sample_step_data(test_routine_uuid): """Sample step data for testing.""" return { "id": str(uuid.uuid4()), "routine_id": test_routine_uuid, "name": "Test Step", "instructions": "Do something", "step_type": "generic", "duration_minutes": 5, "media_url": "https://example.com/media.mp3", "position": 1, "created_at": datetime.now(), } @pytest.fixture def sample_session_data(test_routine_uuid, test_user_uuid): """Sample session data for testing.""" return { "id": str(uuid.uuid4()), "routine_id": test_routine_uuid, "user_uuid": test_user_uuid, "status": "active", "current_step_index": 0, "created_at": datetime.now(), } @pytest.fixture def sample_tag_data(): """Sample tag data for testing.""" return { "id": str(uuid.uuid4()), "name": "morning", "color": "#FF0000", } @pytest.fixture def sample_template_data(): """Sample template data for testing.""" return { "id": str(uuid.uuid4()), "name": "Morning Routine", "description": "Start your day right", "icon": "sun", "created_by_admin": False, "created_at": datetime.now(), } @pytest.fixture def mock_auth_header(): """Mock authorization header for testing.""" import jwt token = jwt.encode({"sub": str(uuid.uuid4())}, "test-secret-key", algorithm="HS256") return {"Authorization": f"Bearer {token}"} @pytest.fixture def api_base_url(): """Base URL for API tests.""" return os.environ.get("API_URL", "http://localhost:8080") @pytest.fixture def auth_token(test_user_uuid): """Generate a valid auth token for testing.""" import jwt return jwt.encode({"sub": test_user_uuid}, "test-secret-key", algorithm="HS256") @pytest.fixture def auth_headers(auth_token): """Authorization headers with valid token.""" return {"Authorization": f"Bearer {auth_token}", "Content-Type": "application/json"} def pytest_configure(config): """Configure pytest with custom markers.""" config.addinivalue_line("markers", "api: mark test as API test") config.addinivalue_line("markers", "core: mark test as core module test") config.addinivalue_line("markers", "integration: mark test as integration test") config.addinivalue_line("markers", "slow: mark test as slow running") @pytest.fixture def db_helper(): """Fixture that provides a DBHelper instance.""" import sys import os sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.abspath(__file__)))) class DBHelper: def __init__(self): import core.postgres as postgres self.postgres = postgres def create_user(self, data=None): if data is None: data = {} user = { "id": data.get("id", str(uuid.uuid4())), "username": data.get("username", f"testuser_{uuid.uuid4().hex[:8]}"), "password_hashed": data.get("password_hashed", "$2b$12$test"), } return self.postgres.insert("users", user) def create_routine(self, data): return self.postgres.insert("routines", data) def create_step(self, data): return self.postgres.insert("routine_steps", data) def create_session(self, data): return self.postgres.insert("routine_sessions", data) def create_tag(self, data): return self.postgres.insert("routine_tags", data) def create_template(self, data): return self.postgres.insert("routine_templates", data) def create_streak(self, data): return self.postgres.insert("routine_streaks", data) return DBHelper()