"""Extended tests for scheduler: job execution flow.""" import os import pytest from unittest.mock import patch, MagicMock from factsdb.config import DatabaseConfig, AIEndpointConfig, FTPServerConfig, SchedulerConfig class MockConfig: def __init__(self, db_path=":memory:"): self.database = DatabaseConfig(path=db_path) self.ai_endpoint = AIEndpointConfig(url="http://localhost", auth_token="tok") self.ftp_server = FTPServerConfig(host="0.0.0.0", port=2121, username="u", password="p") self.scheduler = SchedulerConfig(interval_minutes=10) class TestFactExtractionJobExecute: def test_execute_success(self, tmp_path): from factsdb.scheduler import FactExtractionJob from factsdb.database import DatabaseManager from factsdb.file_processor import FileProcessor cfg = MockConfig(db_path=str(tmp_path / "sched.db")) dm = DatabaseManager(cfg.database) fp = FileProcessor() dm.create_table("t1") # Create a test file test_file = tmp_path / "test.txt" test_file.write_text("Apple released the iPhone in 2007") # Mock AI processor mock_ai = MagicMock() mock_ai.extract_facts_from_text.return_value = { "fact": "Test fact", "key_entities": ["Apple"], "key_dates": ["2007"], } job = FactExtractionJob(cfg, dm, fp, mock_ai) job.execute(str(tmp_path), "t1", "", "gpt-oss") facts = dm.get_facts("t1") assert len(facts) == 1 assert facts[0]["fact"] == "Test fact" def test_execute_skip_processed(self, tmp_path): from factsdb.scheduler import FactExtractionJob from factsdb.database import DatabaseManager from factsdb.file_processor import FileProcessor cfg = MockConfig(db_path=str(tmp_path / "sched.db")) dm = DatabaseManager(cfg.database) fp = FileProcessor() dm.create_table("t1") test_file = tmp_path / "test.txt" test_file.write_text("content") dm.mark_file_processed(str(test_file), "t1", True) mock_ai = MagicMock() job = FactExtractionJob(cfg, dm, fp, mock_ai) job.execute(str(tmp_path), "t1", "", "gpt-oss") mock_ai.extract_facts_from_text.assert_not_called() def test_execute_file_error_continues(self, tmp_path): from factsdb.scheduler import FactExtractionJob from factsdb.database import DatabaseManager from factsdb.file_processor import FileProcessor cfg = MockConfig(db_path=str(tmp_path / "sched.db")) dm = DatabaseManager(cfg.database) dm.create_table("t1") fp = FileProcessor() test_file = tmp_path / "test.txt" test_file.write_text("content") mock_ai = MagicMock() mock_ai.extract_facts_from_text.side_effect = Exception("AI error") job = FactExtractionJob(cfg, dm, fp, mock_ai) job.execute(str(tmp_path), "t1", "", "gpt-oss") facts = dm.get_facts("t1") assert len(facts) == 0 class TestSchedulerInitError: def test_scheduler_db_init_error(self, tmp_path, monkeypatch): from factsdb.scheduler import FactExtractionScheduler cfg = MockConfig(db_path=str(tmp_path / "sched.db")) with patch("factsdb.scheduler.AIProcessor"): with patch("factsdb.scheduler.DatabaseManager", side_effect=Exception("db error")): sched = FactExtractionScheduler(cfg) assert sched.db_manager is None class TestSchedulerRunAllJobs: def test_run_all_jobs(self, tmp_path, monkeypatch): from factsdb.scheduler import FactExtractionScheduler from factsdb.database import DatabaseManager cfg = MockConfig(db_path=str(tmp_path / "sched.db")) dm = DatabaseManager(cfg.database) dm.create_table("t1") test_file = tmp_path / "test.txt" test_file.write_text("content") with patch("factsdb.scheduler.AIProcessor") as mock_ai_cls: mock_ai = MagicMock() mock_ai.extract_facts_from_text.return_value = { "fact": "F", "key_entities": [], "key_dates": [], } mock_ai_cls.return_value = mock_ai with patch("factsdb.scheduler.DatabaseManager", return_value=dm): sched = FactExtractionScheduler(cfg) sched.add_job(str(tmp_path), "t1", "", "gpt-oss") sched._run_all_jobs() facts = dm.get_facts("t1") assert len(facts) == 1