from __future__ import annotations import unittest from unittest.mock import patch from app.api.routes import detect as detect_route class DetectApiRoutesTestCase(unittest.TestCase): @patch("app.api.routes.detect.create_detect_run_snapshot") @patch("app.api.routes.detect._dispatch_remote_detect_start") @patch("app.api.routes.detect.get_settings_payload") @patch("app.api.routes.detect.get_detect_status") @patch("app.api.routes.detect.send_worker_command") @patch("app.api.routes.detect.start_worker") @patch("app.api.routes.detect.append_detect_job_event") @patch("app.api.routes.detect.create_detect_job_if_needed") def test_start_detect_skips_local_worker_on_overseas_control( self, mock_create_job, mock_append_event, mock_start_worker, mock_send_worker_command, mock_get_detect_status, mock_get_settings_payload, mock_dispatch_remote, mock_create_snapshot, ) -> None: mock_create_job.return_value = { "job_id": 29, "job_code": "sync-overseas-29", "status": "running", "items_pending": 100, "items_claimed": 0, "items_running": 0, "task_mode": "single_step", "step_code": "detect_register", } mock_get_detect_status.return_value = { "worker_mode": "linux-systemd", "worker_online": False, "worker_process_count": 0, "worker_latest_start_time": "", "worker_runtime_message": "not-applicable", "progress": {}, } mock_get_settings_payload.return_value = { "runtime": {"thread_count": 2000}, "proxy_config": {"proxy_enable": True, "allow_direct": False, "proxy_urls": ["a"]}, } mock_dispatch_remote.return_value = { "queued_jobs": [{"node_code": "mainland-controller-01"}], "queued_total": 1, "failed_total": 0, "target_summary": {"controller_nodes": ["mainland-controller-01"], "worker_nodes": ["mainland-worker-01"]}, } with patch.object(detect_route.settings, "node_region", "overseas"), patch.object( detect_route.settings, "node_role", "control" ): response = detect_route.start_detect() self.assertEqual(0, response.code) self.assertIn("海外控制面", response.message) mock_start_worker.assert_not_called() mock_send_worker_command.assert_not_called() mock_dispatch_remote.assert_called_once() mock_create_snapshot.assert_called_once() event_types = [call.kwargs.get("event_type") for call in mock_append_event.call_args_list] self.assertIn("job_dispatch_requested", event_types) self.assertIn("job_dispatch_skipped_local", event_types) if __name__ == "__main__": unittest.main()