from __future__ import annotations import importlib import os import tempfile import unittest from pathlib import Path class LibraryDatabaseTest(unittest.TestCase): def setUp(self) -> None: self.temp = tempfile.TemporaryDirectory() os.environ["LIBRARY_DATA_DIR"] = self.temp.name os.environ.pop("BOOTSTRAP_ADMIN_USERNAME", None) os.environ.pop("BOOTSTRAP_ADMIN_PASSWORD_FILE", None) import library_db self.db = importlib.reload(library_db) self.db.initialize_database() def tearDown(self) -> None: self.temp.cleanup() def test_password_hash_is_salted_and_verifiable(self) -> None: first = self.db.hash_password("safe-password-123") second = self.db.hash_password("safe-password-123") self.assertNotEqual(first, second) self.assertTrue(self.db.verify_password("safe-password-123", first)) self.assertFalse(self.db.verify_password("wrong-password", first)) def test_session_round_trip(self) -> None: with self.db.connect() as connection: cursor = connection.execute( """ INSERT INTO users (username, display_name, password_hash, created_at) VALUES ('tester', '테스터', ?, ?) """, (self.db.hash_password("safe-password-123"), self.db.utc_now()), ) user_id = cursor.lastrowid token, csrf = self.db.create_session(user_id) user = self.db.get_user_for_session(token) self.assertIsNotNone(user) self.assertEqual(user["username"], "tester") self.assertEqual(user["csrf_token"], csrf) self.db.delete_session(token) self.assertIsNone(self.db.get_user_for_session(token)) def test_database_directory_is_private_project_data(self) -> None: self.assertTrue(Path(self.temp.name, "library.sqlite3").is_file()) self.assertTrue(Path(self.temp.name, "midi").is_dir()) if __name__ == "__main__": unittest.main()