From f2f8afda7606c6a729b598241c3d545ccae00d8e Mon Sep 17 00:00:00 2001 From: Aimili Date: Thu, 27 Aug 2026 20:43:39 +0800 Subject: [PATCH] fix: clear readiness state on manual disconnect --- tests/test_manager_logic.py | 24 ++++++++++++++++++++++++ vpngate_manager.py | 17 +---------------- 2 files changed, 25 insertions(+), 16 deletions(-) diff --git a/tests/test_manager_logic.py b/tests/test_manager_logic.py index d7dcd8a..78d57c8 100644 --- a/tests/test_manager_logic.py +++ b/tests/test_manager_logic.py @@ -458,6 +458,30 @@ class ManagerLogicTests(unittest.TestCase): ready_state = {**base_state, "proxy_ready": True, "proxy_ok": True} self.assertTrue(manager.connection_ready_for_ui(ready_state)) + def test_manual_disconnect_state_clears_all_readiness_flags(self) -> None: + nodes = self.write_nodes(1) + nodes[0]["active"] = True + manager.write_json(manager.NODES_FILE, nodes) + manager.set_state( + is_connecting=True, + tunnel_ready=True, + proxy_ready=True, + proxy_ok=True, + proxy_ip="198.51.100.20", + ) + + with mock.patch.object(manager, "stop_active_openvpn") as stop_mock: + manager.clear_active_connection_state("手动断开连接") + + stop_mock.assert_called_once_with() + state = manager.get_state() + self.assertFalse(state["is_connecting"]) + self.assertFalse(state["tunnel_ready"]) + self.assertFalse(state["proxy_ready"]) + self.assertFalse(state["proxy_ok"]) + self.assertEqual("-", state["proxy_ip"]) + self.assertFalse(any(node.get("active") for node in manager.read_nodes())) + def test_ui_auth_json_is_written_private(self) -> None: auth_file = manager.DATA_DIR / "ui_auth.json" manager.write_json(auth_file, {"username": "test", "password": "secret"}) diff --git a/vpngate_manager.py b/vpngate_manager.py index 5ac9c47..d2d20f0 100644 --- a/vpngate_manager.py +++ b/vpngate_manager.py @@ -7146,28 +7146,13 @@ class Handler(BaseHTTPRequestHandler): DATA_DIR.mkdir(exist_ok=True, parents=True) write_json(auth_file, ui_cfg) - stop_active_openvpn() - with lock: - nodes = read_nodes() - for item in nodes: - item["active"] = False - write_json(NODES_FILE, nodes) + clear_active_connection_state("手动断开连接") global last_active_ping_time, last_active_latency last_active_ping_time = 0.0 last_active_latency = 0 global consecutive_proxy_failures, last_proxy_failure_node_id consecutive_proxy_failures = 0 last_proxy_failure_node_id = "" - set_state( - active_openvpn_node_id="", - pending_node_id="", - last_check_message="手动断开连接", - active_node_latency="无活动连接", - proxy_ok=False, - proxy_ip="-", - proxy_latency_ms=0, - proxy_error="连接已手动断开", - ) self.send_json({"ok": True}) except Exception as exc: self.send_json({"ok": False, "error": str(exc)}, HTTPStatus.INTERNAL_SERVER_ERROR)