"""Windows manual driver for tests/test_email_service_dictia.py. src/init_db.py imports `fcntl`, which is POSIX-only. On Windows we stub it before src.app gets imported, then run each test_* function and report. Run from the repo root: py -3 tests/_run_email_service_dictia_windows.py This script is local-dev only (not picked up by pytest collection). """ import os import sys import types import traceback # 1) Stub fcntl BEFORE any import of src.* happens. if 'fcntl' not in sys.modules: fcntl_stub = types.ModuleType('fcntl') fcntl_stub.LOCK_EX = 2 fcntl_stub.LOCK_NB = 4 fcntl_stub.LOCK_UN = 8 fcntl_stub.LOCK_SH = 1 fcntl_stub.flock = lambda *_args, **_kw: None fcntl_stub.fcntl = lambda *_args, **_kw: 0 sys.modules['fcntl'] = fcntl_stub # 2) Make repo root importable HERE = os.path.dirname(os.path.abspath(__file__)) REPO = os.path.dirname(HERE) sys.path.insert(0, REPO) # 3) Set test config os.environ.setdefault('SQLALCHEMY_DATABASE_URI', 'sqlite:///:memory:') os.environ.setdefault('SECRET_KEY', 'test-secret-key') os.environ.setdefault('ENABLE_EMAIL_VERIFICATION', 'false') # Avoid sys.exit(1) in src/config/app_config.py legacy validation. os.environ.setdefault('TRANSCRIPTION_BASE_URL', 'http://test-stub') os.environ.setdefault('TRANSCRIPTION_API_KEY', 'test-stub') # Disable rate limits for forgot_password endpoint test. os.environ.setdefault('RATELIMIT_ENABLED', 'false') # Force UTF-8 stdout so src.app's emoji prints don't crash on cp1252 Windows. try: sys.stdout.reconfigure(encoding='utf-8', errors='replace') sys.stderr.reconfigure(encoding='utf-8', errors='replace') except Exception: pass # 4) Import the test module and run every test_* function it defines import importlib.util # noqa: E402 spec = importlib.util.spec_from_file_location( 'test_email_service_dictia', os.path.join(HERE, 'test_email_service_dictia.py'), ) mod = importlib.util.module_from_spec(spec) spec.loader.exec_module(mod) tests = [(name, fn) for name, fn in vars(mod).items() if name.startswith('test_') and callable(fn)] passed = 0 failed = [] for name, fn in tests: try: fn() print(f' PASS {name}') passed += 1 except Exception as e: # noqa: BLE001 print(f' FAIL {name}: {type(e).__name__}: {e}') failed.append((name, traceback.format_exc())) total = len(tests) print() print(f'Result: {passed}/{total} passed, {len(failed)} failed') if failed: print('\n--- Failures ---\n') for name, tb in failed: print(f'### {name}\n{tb}\n') sys.exit(0 if not failed else 1)