From 18d5ba86764b219fbfdad02e337b12e794953b8f Mon Sep 17 00:00:00 2001 From: say8hi Date: Wed, 8 Apr 2026 16:27:51 +0500 Subject: [PATCH] test(cron): add tests for enabled_toolsets in create_job and run_job --- tests/cron/test_jobs.py | 29 +++++++++++++++++++ tests/cron/test_scheduler.py | 54 ++++++++++++++++++++++++++++++++++++ 2 files changed, 83 insertions(+) diff --git a/tests/cron/test_jobs.py b/tests/cron/test_jobs.py index e0f56b961..6a9185f07 100644 --- a/tests/cron/test_jobs.py +++ b/tests/cron/test_jobs.py @@ -566,6 +566,35 @@ class TestGetDueJobs: assert get_job("oneshot-stale")["next_run_at"] is None +class TestEnabledToolsets: + def test_enabled_toolsets_stored(self, tmp_cron_dir): + job = create_job(prompt="monitor", schedule="every 1h", enabled_toolsets=["web", "terminal"]) + assert job["enabled_toolsets"] == ["web", "terminal"] + + def test_enabled_toolsets_persisted(self, tmp_cron_dir): + job = create_job(prompt="monitor", schedule="every 1h", enabled_toolsets=["web", "file"]) + fetched = get_job(job["id"]) + assert fetched["enabled_toolsets"] == ["web", "file"] + + def test_enabled_toolsets_none_when_omitted(self, tmp_cron_dir): + job = create_job(prompt="monitor", schedule="every 1h") + assert job["enabled_toolsets"] is None + + def test_enabled_toolsets_empty_list_normalizes_to_none(self, tmp_cron_dir): + job = create_job(prompt="monitor", schedule="every 1h", enabled_toolsets=[]) + assert job["enabled_toolsets"] is None + + def test_enabled_toolsets_whitespace_entries_stripped(self, tmp_cron_dir): + job = create_job(prompt="monitor", schedule="every 1h", enabled_toolsets=["web", " ", "file"]) + assert job["enabled_toolsets"] == ["web", "file"] + + def test_enabled_toolsets_updated_via_update_job(self, tmp_cron_dir): + job = create_job(prompt="monitor", schedule="every 1h") + update_job(job["id"], {"enabled_toolsets": ["web", "delegation"]}) + fetched = get_job(job["id"]) + assert fetched["enabled_toolsets"] == ["web", "delegation"] + + class TestSaveJobOutput: def test_creates_output_file(self, tmp_cron_dir): output_file = save_job_output("test123", "# Results\nEverything ok.") diff --git a/tests/cron/test_scheduler.py b/tests/cron/test_scheduler.py index 524490eb0..421d6859d 100644 --- a/tests/cron/test_scheduler.py +++ b/tests/cron/test_scheduler.py @@ -673,6 +673,60 @@ class TestRunJobSessionPersistence: assert call_args[0][1] == "cron_complete" fake_db.close.assert_called_once() + def _make_run_job_patches(self, tmp_path): + """Common patches for run_job tests.""" + fake_db = MagicMock() + return fake_db, [ + patch("cron.scheduler._hermes_home", tmp_path), + patch("cron.scheduler._resolve_origin", return_value=None), + patch("dotenv.load_dotenv"), + patch("hermes_state.SessionDB", return_value=fake_db), + patch( + "hermes_cli.runtime_provider.resolve_runtime_provider", + return_value={ + "api_key": "test-key", + "base_url": "https://example.invalid/v1", + "provider": "openrouter", + "api_mode": "chat_completions", + }, + ), + ] + + def test_run_job_passes_enabled_toolsets_to_agent(self, tmp_path): + job = { + "id": "toolset-job", + "name": "test", + "prompt": "hello", + "enabled_toolsets": ["web", "terminal", "file"], + } + fake_db, patches = self._make_run_job_patches(tmp_path) + with patches[0], patches[1], patches[2], patches[3], patches[4], \ + patch("run_agent.AIAgent") as mock_agent_cls: + mock_agent = MagicMock() + mock_agent.run_conversation.return_value = {"final_response": "ok"} + mock_agent_cls.return_value = mock_agent + run_job(job) + + kwargs = mock_agent_cls.call_args.kwargs + assert kwargs["enabled_toolsets"] == ["web", "terminal", "file"] + + def test_run_job_enabled_toolsets_none_when_not_set(self, tmp_path): + job = { + "id": "no-toolset-job", + "name": "test", + "prompt": "hello", + } + fake_db, patches = self._make_run_job_patches(tmp_path) + with patches[0], patches[1], patches[2], patches[3], patches[4], \ + patch("run_agent.AIAgent") as mock_agent_cls: + mock_agent = MagicMock() + mock_agent.run_conversation.return_value = {"final_response": "ok"} + mock_agent_cls.return_value = mock_agent + run_job(job) + + kwargs = mock_agent_cls.call_args.kwargs + assert kwargs["enabled_toolsets"] is None + def test_run_job_empty_response_returns_empty_not_placeholder(self, tmp_path): """Empty final_response should stay empty for delivery logic (issue #2234).