fix: 优化清理失效账号执行响应的 success 标志,对 test_account/delete_account 引入外部 API 日志审计,并对账号 ID 进行安全转义

This commit is contained in:
liumangmang
2026-07-02 00:25:24 +08:00
parent 536c0aa3d4
commit 3b23f21ef3
3 changed files with 134 additions and 63 deletions
+34 -8
View File
@@ -56,7 +56,7 @@ def mock_stream(status_code, lines, raise_exc=None):
def test_website_client_test_account_sse_scenarios(monkeypatch):
"""测试 Sub2ApiWebsiteClient.test_account 在各种 SSE 场景下的解析处理。"""
"""测试 Sub2ApiWebsiteClient.test_account 在各种 SSE 场景下的解析处理、ID 转义和 API 日志记录"""
c = Sub2ApiWebsiteClient(
base_url="http://w1",
api_prefix="api/v1",
@@ -64,41 +64,65 @@ def test_website_client_test_account_sse_scenarios(monkeypatch):
auth_config={"token": "t1"},
)
# 1. success=true
log_calls = []
def mock_log(**kwargs):
log_calls.append(kwargs)
monkeypatch.setattr("app.services.website_client.log_external_api_call", mock_log)
# 1. success=true,包含带有斜杠的 ID 校验以测试 URL quote 转义
monkeypatch.setattr(c._client, "stream", mock_stream(200, ["event: test_complete", "data: {\"success\": true}"]))
res = c.test_account("acc1")
res = c.test_account("acc/1")
assert res["status"] == "success"
assert res["cleanup_allowed"] is False
# 验证日志记录和 URL 转义:acc/1 应被转义为 acc%2F1
assert len(log_calls) == 1
assert log_calls[-1]["method"] == "POST"
assert log_calls[-1]["path"] == "/api/v1/accounts/acc%2F1/test"
assert log_calls[-1]["success"] is True
# 2. success=false
monkeypatch.setattr(c._client, "stream", mock_stream(200, ["event: test_complete", "data: {\"success\": false}"]))
res = c.test_account("acc1")
res = c.test_account("acc/1")
assert res["status"] == "failed"
assert res["cleanup_allowed"] is True
assert len(log_calls) == 2
assert log_calls[-1]["success"] is True
# 3. HTTP 404
monkeypatch.setattr(c._client, "stream", mock_stream(404, []))
res = c.test_account("acc1")
res = c.test_account("acc/1")
assert res["status"] == "404"
assert res["cleanup_allowed"] is True
assert len(log_calls) == 3
assert log_calls[-1]["status_code"] == 404
assert log_calls[-1]["success"] is True
# 4. error event
monkeypatch.setattr(c._client, "stream", mock_stream(200, ["event: error", "data: \"internal error\""]))
res = c.test_account("acc1")
res = c.test_account("acc/1")
assert res["status"] == "error"
assert res["cleanup_allowed"] is False
assert len(log_calls) == 4
assert log_calls[-1]["success"] is False
assert log_calls[-1]["error_type"] == "WebsiteError"
# 5. 超时
monkeypatch.setattr(c._client, "stream", mock_stream(200, [], raise_exc=httpx.TimeoutException("Connection timed out")))
res = c.test_account("acc1")
res = c.test_account("acc/1")
assert res["status"] == "timeout"
assert res["cleanup_allowed"] is False
assert len(log_calls) == 5
assert log_calls[-1]["success"] is False
assert log_calls[-1]["error_type"] == "TimeoutException"
# 6. 非法 SSE (没有 test_complete)
monkeypatch.setattr(c._client, "stream", mock_stream(200, ["data: hello world"]))
res = c.test_account("acc1")
res = c.test_account("acc/1")
assert res["status"] == "invalid_sse"
assert res["cleanup_allowed"] is False
assert len(log_calls) == 6
assert log_calls[-1]["success"] is False
assert log_calls[-1]["error_type"] == "WebsiteError"
def test_cleanup_invalid_preview_and_execute(db_session, monkeypatch):
@@ -229,6 +253,8 @@ def test_cleanup_invalid_preview_and_execute(db_session, monkeypatch):
test_calls.clear()
execute_res = execute_cleanup_invalid_accounts(wid=w.id, db=db_session)
assert execute_res.success is True
assert "成功清理 2 个" in execute_res.message
assert "跳过 1 个" in execute_res.message
# 验证是否重新跑了测试
assert "acc-k1" in test_calls