fix: 优化清理失效账号执行响应的 success 标志,对 test_account/delete_account 引入外部 API 日志审计,并对账号 ID 进行安全转义
This commit is contained in:
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user