| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107 |
- import json
- import threading
- import unittest
- from http.server import ThreadingHTTPServer
- from pathlib import Path
- from urllib import request as urlrequest
- from unittest.mock import patch
- from config import AppConfig
- class StartSsoProxyTests(unittest.TestCase):
- def _post_json(self, url, payload):
- data = json.dumps(payload).encode("utf-8")
- req = urlrequest.Request(url, data=data, method="POST", headers={"Content-Type": "application/json"})
- try:
- with urlrequest.urlopen(req, timeout=5) as resp:
- return resp.status, json.loads(resp.read().decode("utf-8"))
- except urlrequest.HTTPError as exc:
- return exc.code, json.loads(exc.read().decode("utf-8"))
- def test_start_sso_does_not_inherit_global_proxy_by_default(self):
- import server
- cfg = AppConfig(
- proxy_url="http://global.proxy:8080",
- sso_mail_domain="aef.claudeai.life",
- cpa_url="http://cpa.example",
- cpa_management_key="token",
- )
- httpd = ThreadingHTTPServer(("127.0.0.1", 0), server.Handler)
- thread = threading.Thread(target=httpd.serve_forever, daemon=True)
- with patch("server.AppConfig.load", return_value=cfg), patch.object(server.JOB, "start_sso", return_value="") as start_sso:
- thread.start()
- self.addCleanup(thread.join, 2)
- self.addCleanup(httpd.server_close)
- self.addCleanup(httpd.shutdown)
- status, body = self._post_json(
- f"http://127.0.0.1:{httpd.server_address[1]}/api/start-sso",
- {"account_count": 1, "cpa_url": "http://cpa.example", "cpa_management_key": "token"},
- )
- self.assertEqual(status, 200)
- self.assertTrue(body["ok"])
- self.assertEqual(start_sso.call_args.kwargs["proxy_url"], "")
- class DeprecatedFullAutomationTests(unittest.TestCase):
- def _post_json(self, url, payload=None):
- data = json.dumps(payload or {}).encode("utf-8")
- req = urlrequest.Request(url, data=data, method="POST", headers={"Content-Type": "application/json"})
- try:
- with urlrequest.urlopen(req, timeout=5) as resp:
- return resp.status, json.loads(resp.read().decode("utf-8"))
- except urlrequest.HTTPError as exc:
- return exc.code, json.loads(exc.read().decode("utf-8"))
- def _serve(self):
- import server
- httpd = ThreadingHTTPServer(("127.0.0.1", 0), server.Handler)
- thread = threading.Thread(target=httpd.serve_forever, daemon=True)
- thread.start()
- self.addCleanup(thread.join, 2)
- self.addCleanup(httpd.server_close)
- self.addCleanup(httpd.shutdown)
- return httpd
- def test_start_endpoint_is_disabled_for_full_automation(self):
- import server
- httpd = self._serve()
- status, body = self._post_json(f"http://127.0.0.1:{httpd.server_address[1]}/api/start")
- self.assertEqual(status, 410)
- self.assertIn("已停用", body["error"])
- self.assertFalse(hasattr(server.JOB, "start"))
- def test_tasks_api_rejects_full_mode_without_creating_task(self):
- import server
- httpd = self._serve()
- with patch("server.create_task") as create_task:
- status, body = self._post_json(
- f"http://127.0.0.1:{httpd.server_address[1]}/api/tasks",
- {"mode": "full"},
- )
- self.assertEqual(status, 410)
- self.assertIn("full", body["error"])
- create_task.assert_not_called()
- def test_status_does_not_expose_pool_maintainer(self):
- import server
- self.assertNotIn("pool_maintainer", server.JOB.status())
- def test_server_no_longer_starts_pool_maintainer(self):
- server_py = Path(__file__).resolve().parent.joinpath("server.py").read_text(encoding="utf-8")
- self.assertNotIn("start_pool_maintainer", server_py)
- if __name__ == "__main__":
- unittest.main()
|