"""Tests for ftp_server module.""" import pytest from unittest.mock import patch, MagicMock @pytest.fixture(autouse=True) def mock_pyftpdlib(): """Mock pyftpdlib modules which are not available on Python 3.12+.""" with patch.dict("sys.modules", { "pyftpdlib": MagicMock(), "pyftpdlib.authorizers": MagicMock(), "pyftpdlib.handlers": MagicMock(), "pyftpdlib.servers": MagicMock(), }): from factsdb.ftp_server import FTPServerManager, get_ftp_server_manager yield class MockConfig: """Lightweight mock Config for FTP tests.""" def __init__(self): self.ftp_server = MagicMock() self.ftp_server.host = "0.0.0.0" self.ftp_server.port = 2121 self.ftp_server.username = "testuser" self.ftp_server.password = "testpass" self.database = MagicMock() class TestFTPServerManager: def test_init(self, mock_pyftpdlib): from factsdb.ftp_server import FTPServerManager mgr = FTPServerManager(MockConfig()) assert mgr.is_running is False assert mgr.onboarded_directories == set() assert mgr.server is None def test_add_onboarded_directory(self, mock_pyftpdlib, tmp_path): from factsdb.ftp_server import FTPServerManager mgr = FTPServerManager(MockConfig()) mgr.add_onboarded_directory(str(tmp_path)) assert str(tmp_path) in mgr.onboarded_directories def test_add_nonexistent_directory(self, mock_pyftpdlib, tmp_path): from factsdb.ftp_server import FTPServerManager mgr = FTPServerManager(MockConfig()) mgr.add_onboarded_directory("/nonexistent/path") assert len(mgr.onboarded_directories) == 0 def test_is_directory_allowed(self, mock_pyftpdlib, tmp_path): from factsdb.ftp_server import FTPServerManager mgr = FTPServerManager(MockConfig()) mgr.add_onboarded_directory(str(tmp_path)) assert mgr.is_directory_allowed(str(tmp_path)) is True assert mgr.is_directory_allowed("/other/path") is False def test_is_directory_subpath(self, mock_pyftpdlib, tmp_path): from factsdb.ftp_server import FTPServerManager mgr = FTPServerManager(MockConfig()) mgr.add_onboarded_directory(str(tmp_path)) sub = tmp_path / "sub" assert mgr.is_directory_allowed(str(sub)) is True def test_get_onboarded_directories(self, mock_pyftpdlib, tmp_path): from factsdb.ftp_server import FTPServerManager mgr = FTPServerManager(MockConfig()) mgr.add_onboarded_directory(str(tmp_path)) dirs = mgr.get_onboarded_directories() assert len(dirs) == 1 assert str(tmp_path) in dirs def test_is_running_attr(self, mock_pyftpdlib): from factsdb.ftp_server import FTPServerManager mgr = FTPServerManager(MockConfig()) assert mgr.is_running is False class TestFTPServerStartStop: def test_start_already_running(self, mock_pyftpdlib): from factsdb.ftp_server import FTPServerManager mgr = FTPServerManager(MockConfig()) mgr.is_running = True mgr.server = MagicMock() mgr.start() assert mgr.is_running is True class TestGetFtpServerManager: def test_singleton(self, mock_pyftpdlib): from factsdb import ftp_server as ftp_mod ftp_mod._ftp_server_manager = None from factsdb.ftp_server import FTPServerManager, get_ftp_server_manager cfg = MockConfig() m1 = get_ftp_server_manager(cfg) m2 = get_ftp_server_manager(cfg) assert m1 is m2 ftp_mod._ftp_server_manager = None