""" Tests for the check-deprecated-db pre-commit hook. Ensures the hook correctly detects usage of deprecated database connection methods that bypass per-user encrypted databases. This prevents user data from being written to shared, unencrypted storage. """ import sys from importlib import import_module from pathlib import Path # Add the pre-commit hooks directory to path HOOKS_DIR = Path(__file__).parent.parent.parent / ".pre-commit-hooks" sys.path.insert(0, str(HOOKS_DIR)) hook_module = import_module("check-deprecated-db") check_file_fn = hook_module.check_file # Build the deprecated DB name dynamically so this test file itself # is not flagged by the check-ldr-db pre-commit hook. _DEPRECATED_DB = "ldr" + ".db" def _write_and_check(tmp_path, code: str, filename: str = "src/module.py"): """Write code to a temp file and run the checker.""" p = tmp_path / filename p.parent.mkdir(parents=True, exist_ok=True) p.write_text(code, encoding="utf-8") return check_file_fn(str(p)) class TestDetectsDeprecatedDbConnection: """Ensures get_db_connection() usage is flagged.""" def test_detects_get_db_connection_call(self, tmp_path): code = "conn = get_db_connection()\ncursor = conn.cursor()\n" issues = _write_and_check(tmp_path, code) assert len(issues) >= 1 assert any("get_db_connection" in i for i in issues) def test_detects_get_db_connection_import(self, tmp_path): code = "from web.models.database import get_db_connection\n" issues = _write_and_check(tmp_path, code) assert len(issues) >= 1 def test_detects_get_db_connection_with_args(self, tmp_path): code = 'conn = get_db_connection("some_path")\n' issues = _write_and_check(tmp_path, code) assert len(issues) >= 1 class TestDetectsRawSessionAccess: """Ensures db_manager.get_session() is flagged (leaks QueuePool FDs).""" def test_detects_raw_get_session(self, tmp_path): code = 'session = db_manager.get_session("user")\n' issues = _write_and_check(tmp_path, code) assert len(issues) >= 1 assert any("get_session" in i for i in issues) def test_allows_noqa_comment(self, tmp_path): code = 'session = db_manager.get_session("user") # noqa: raw-session\n' issues = _write_and_check(tmp_path, code) assert len(issues) == 0 def test_allows_commented_code(self, tmp_path): code = '# session = db_manager.get_session("user")\n' issues = _write_and_check(tmp_path, code) assert len(issues) == 0 class TestDetectsSharedDbAccess: """Ensures direct SQLite connection to shared DB is flagged.""" def test_detects_sqlite_connect_to_shared_db(self, tmp_path): code = f'conn = sqlite3.connect("{_DEPRECATED_DB}")\n' issues = _write_and_check(tmp_path, code) assert len(issues) >= 1 class TestAllowsSafePatterns: """Ensures correct patterns are NOT flagged.""" def test_allows_get_user_db_session(self, tmp_path): code = """ with get_user_db_session(username) as session: results = session.query(Journal).all() """ issues = _write_and_check(tmp_path, code) assert len(issues) == 0 def test_allows_normal_code(self, tmp_path): code = """ def some_function(): data = process_results() return data """ issues = _write_and_check(tmp_path, code) assert len(issues) == 0