From f8a23b7ce5d05c5c7b73aefe28850743afa72ada Mon Sep 17 00:00:00 2001 From: shy3130 <415333856@qq.com> Date: Mon, 7 Sep 2026 22:01:12 +0800 Subject: [PATCH] =?UTF-8?q?fix(api):=20quote=5Fservice=20=E7=BC=BA?= =?UTF-8?q?=E5=A4=B1=E6=97=B6=20quote-interval=20=E5=85=9C=E5=BA=95?= =?UTF-8?q?=E8=BF=94=E5=9B=9E=E9=BB=98=E8=AE=A4=E6=A1=A3=E4=BD=8D=20(#261)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit PUT /preferences/quote-interval 的 if not qs 分支错误调用 qs.get_min_interval(),此时 qs 必为 None,触发 AttributeError → 500。 改为返回硬编码默认值 6.0,与 GET 接口兜底写法及 QuoteService.DEFAULT_INTERVAL 保持一致,并新增复现测试。 --- backend/app/api/settings.py | 2 +- backend/tests/test_quote_interval_settings.py | 29 +++++++++++++++++++ 2 files changed, 30 insertions(+), 1 deletion(-) create mode 100644 backend/tests/test_quote_interval_settings.py diff --git a/backend/app/api/settings.py b/backend/app/api/settings.py index 7f31977..bb3af65 100644 --- a/backend/app/api/settings.py +++ b/backend/app/api/settings.py @@ -1486,7 +1486,7 @@ def update_quote_interval(req: QuoteIntervalIn, request: Request) -> dict: """更新行情轮询间隔。按档位自动 clamp。""" qs = getattr(request.app.state, "quote_service", None) if not qs: - return {"interval": req.interval, "min_interval": qs.get_min_interval(), "max_interval": 60.0} + return {"interval": req.interval, "min_interval": 6.0, "max_interval": 60.0} clamped = qs.set_interval(req.interval) return { "interval": clamped, diff --git a/backend/tests/test_quote_interval_settings.py b/backend/tests/test_quote_interval_settings.py new file mode 100644 index 0000000..b717c78 --- /dev/null +++ b/backend/tests/test_quote_interval_settings.py @@ -0,0 +1,29 @@ +"""行情轮询间隔接口: quote_service 缺失时的兜底分支不能抛 AttributeError (issue #261)。""" + +from __future__ import annotations + +from types import SimpleNamespace + +from app.api.settings import QuoteIntervalIn, update_quote_interval + + +def _request_without_quote_service() -> SimpleNamespace: + return SimpleNamespace(app=SimpleNamespace(state=SimpleNamespace(quote_service=None))) + + +def test_update_quote_interval_without_service_returns_defaults(): + result = update_quote_interval( + QuoteIntervalIn(interval=6.0), request=_request_without_quote_service() + ) + + assert result == {"interval": 6.0, "min_interval": 6.0, "max_interval": 60.0} + + +def test_update_quote_interval_without_service_keeps_requested_interval(): + result = update_quote_interval( + QuoteIntervalIn(interval=12.0), request=_request_without_quote_service() + ) + + assert result["interval"] == 12.0 + assert result["min_interval"] == 6.0 + assert result["max_interval"] == 60.0