Files
ai-kefu-admin/tests/test_config_views.py
T
浅念 71e11c317f refactor: config_views 单入口 + 0语义统一 + FakeAI 收敛(清理单#1#2#3)
- #3 六个消费视图 resolver 收拢 app/platform/config_views(单一定义点):
  resolve_email/push/ai_settings ← 各服务文件, resolve_contact_flags/
  context_seed_map ← conversation, name_to_region_extras ← manager
  __init__ 内联取值(or None 语义原样)——函数体逐字搬入,服务层 import 之,
  旧定义删;Phase 3 编辑器/试金石与该模块对接
- #2 限流 0 语义统一: conn_limiter.try_acquire 的 limit 与 chat_rest 的
  rate_limit_per_hour 取值同款——0 或负 = 回退出厂默认(与姊妹键一致),
  原 conn_limiter 0=全拒改为回退;chat_rest 取值抽 _resolve_rate_limit
  纯函数供锚定
- #1 FakeAI 收敛进 conftest(超集: extract/evaluate/eval_calls),四份拷贝
  删(test_lead_email_trigger/test_cc_integration/test_channel_hygiene/
  test_lead_push_wiring——计划记三份,grep 实有四份;push_wiring 经
  evaluate 参数注入原本地固定返回值,断言零改动)

全量 558 passed(554 + 新增 4: 单入口/内联等价/两处 0 语义)

Co-Authored-By: Claude Code <noreply@anthropic.com>
2026-10-13 11:45:42 +08:00

60 lines
2.9 KiB
Python

"""Phase 2 Task 10(清理单 #1/#2/#3): config_views 单入口 + 限流 0 语义统一。
- #3 单入口: 六个配置消费视图(email/push/ai/contact_flags/context_seed_map/
name_to_region_extras)同住 app.platform.config_views 且可调用——服务层与
Phase 3 编辑器/试金石都从这里拿,散在各服务模块的定义已删(单一定义点);
- #2 0 语义: ws_conn_limit 与 rate_limit_per_hour 行为统一——0 或负 =
回退出厂默认(非全拒)。config_validation 已拒 0/负,这里是直写快照/
旧库数据的纵深防御层;
- #1 FakeAI 收敛(conftest 单一定义点,四份拷贝删)的证明 = 既有测试
全绿,无新增断言。
"""
from app.engine.routes.chat_rest import _resolve_rate_limit
from app.engine.services.conn_limiter import ConnectionLimiter
from app.engine.services.rate_limit import DEFAULT_MAX
from app.platform import config_views
def test_config_views_single_entry():
"""一次 import 拿全六个 resolver——单一定义点,散装定义已收拢。"""
names = ("resolve_email_settings", "resolve_push_settings",
"resolve_ai_settings", "resolve_contact_flags",
"context_seed_map", "name_to_region_extras")
for name in names:
assert callable(getattr(config_views, name)), (
f"config_views 缺消费视图 resolver: {name}")
def test_name_to_region_extras_view_keeps_inline_semantics():
"""ConversationManager.__init__ 内联取值的等价迁移: misc 组缺省/空
dict → None(``or None`` 语义原样保留);有扩表 → 原样返回。"""
assert config_views.name_to_region_extras(None) is None
assert config_views.name_to_region_extras({}) is None
assert config_views.name_to_region_extras(
{"misc": {"name_to_region_extras": {}}}) is None
assert config_views.name_to_region_extras(
{"misc": {"name_to_region_extras": {"德意志": "DE"}}}) == {"德意志": "DE"}
def test_conn_limiter_zero_or_negative_limit_falls_back():
"""ws_conn_limit=0/负 → 构造默认(原语义 0=全拒;统一后与姊妹键
rate_limit_per_hour 一致)。"""
lim = ConnectionLimiter(limit=2)
assert lim.try_acquire("t", "1.1.1.1", limit=0) is True # 0 ≠ 全拒
assert lim.try_acquire("t", "1.1.1.1", limit=0) is True
assert lim.try_acquire("t", "1.1.1.1", limit=0) is False # 默认 2 满
assert lim.try_acquire("t", "2.2.2.2", limit=-3) is True # 负数同回退
def test_chat_rest_rate_limit_zero_or_negative_falls_back():
"""rate_limit_per_hour=0/负 → DEFAULT_MAX(chat_rest 取值处与
ws_conn_limit 同款)。"""
assert _resolve_rate_limit(
{"engine": {"rate_limit_per_hour": 0}}) == DEFAULT_MAX
assert _resolve_rate_limit(
{"engine": {"rate_limit_per_hour": -5}}) == DEFAULT_MAX
assert _resolve_rate_limit({}) == DEFAULT_MAX
assert _resolve_rate_limit(None) == DEFAULT_MAX
assert _resolve_rate_limit(
{"engine": {"rate_limit_per_hour": 7}}) == 7