"""Shared test fixtures. Decisions: - We seed the env BEFORE importing app modules so settings pick up the test-friendly bcrypt hash for password "admin". - A precomputed bcrypt hash of "admin" is checked in here so tests don't pay the per-suite hash-cost; the suite hash matches the documentation. """ from __future__ import annotations import os from datetime import date import pytest # Hash of "admin" (cost 12). Tests rely on this exact value to log in. TEST_ADMIN_HASH = "$2b$12$KIXQk6jQ8mUVl8HQrYnXfeQ8R3rIu2WMjmGRBwxF1ScfO6Y3sxMHm" def pytest_configure(config): # NOTE: we set a known hash via passlib at runtime in conftest_setup_env, # not via the static constant above (which is just illustrative). pass @pytest.fixture(scope="session", autouse=True) def _seed_env(): from passlib.hash import bcrypt os.environ.setdefault("AUTH_MODE", "local") os.environ.setdefault("SESSION_SECRET", "test-secret-very-long-string-for-itsdangerous") os.environ.setdefault("ADMIN_USERNAME", "admin") os.environ["ADMIN_PASSWORD_BCRYPT"] = bcrypt.hash("admin") os.environ.setdefault("DEV_AUTH_BYPASS", "false") # Tests hit /api/... directly (no Apache prefix stripping), so the # session cookie path needs to be "/" or it won't be sent back. os.environ.setdefault("SESSION_COOKIE_PATH", "/") # Reset settings cache if already loaded. try: from app.config import get_settings get_settings.cache_clear() except Exception: pass @pytest.fixture def sample_resources(): return [ { "recordId": "rec1", "name": "Bhakti Doshi", "email": "bhakti@oliver.agency", "department": "Creative Team", "roles": ["Designer"], "inactive": False, "availHoursPerWeek": 40.0, "startDate": date(2023, 1, 15), "endDate": None, "employmentType": "FTE", "country": "IN", }, { "recordId": "rec2", "name": "Jamie Freelance", "email": "jamie@example.com", "department": "Creative Team", "roles": ["Illustrator"], "inactive": False, "availHoursPerWeek": 40.0, "startDate": date(2024, 6, 1), "endDate": None, "employmentType": "Freelancer", "country": "UK", }, ] @pytest.fixture def sample_bookings(): return [ { "id": "bk1", "task": "Concept dev", "startDate": date(2026, 5, 4), # Mon "endDate": date(2026, 5, 8), # Fri (same ISO week W19) "resourceName": "Bhakti Doshi", "projectNumber": "P-12345", "projectName": "Acme Spring Launch", "department": "Creative Team", "division": "Production", "hoursSelection": ["Mon", "Tue", "Wed", "Thu", "Fri"], "totalHoursBooked": 38.0, "bookingStatus": "Active", "placeholder": False, }, ] @pytest.fixture def sample_logged(): return [ {"date": date(2026, 5, 4), "employee": "Bhakti Doshi", "project": "Acme", "task": "Design", "hours": 7.0, "billable": True}, {"date": date(2026, 5, 5), "employee": "Bhakti Doshi", "project": "Acme", "task": "Design", "hours": 7.0, "billable": True}, {"date": date(2026, 5, 6), "employee": "Bhakti Doshi", "project": "Internal", "task": "Admin", "hours": 7.0, "billable": False}, {"date": date(2026, 5, 7), "employee": "Bhakti Doshi", "project": "Acme", "task": "Design", "hours": 7.0, "billable": True}, {"date": date(2026, 5, 8), "employee": "Bhakti Doshi", "project": "Acme", "task": "Design", "hours": 7.0, "billable": True}, ]