feat(registry): resolve_by_slug 路径模式解析 + TENANT_SLUG_RE 常量上提

Co-Authored-By: Claude Code <noreply@anthropic.com>
This commit is contained in:
浅念
2026-10-19 16:36:13 +08:00
parent 85627901d0
commit e08a675363
2 changed files with 66 additions and 0 deletions
+44
View File
@@ -9,6 +9,7 @@ Windows 纪律:每个建过 engine 的用例结尾 await reg.dispose_all()——
连接不关,文件锁着,tmp_path 清理 PermissionError。
"""
import asyncio
import dataclasses
import json
import shutil
from pathlib import Path
@@ -22,6 +23,7 @@ from app.platform.registry import (
UnknownTenantError,
make_tenant_engine,
)
from app.platform.tenant_source import FileTenantSource
REPO_ROOT = Path(__file__).resolve().parents[1]
SEED_DIR = REPO_ROOT / "seed_profiles"
@@ -296,3 +298,45 @@ async def test_reload_to_disabled_releases_engine(tmp_path):
with pytest.raises(TenantDisabledError):
await reg.resolve("a.example.com")
await reg.dispose_all()
# ---- 路径前缀模式解析(spec 2026-10-19 §5) ----------------------------------
class TestResolveBySlug:
"""resolve_by_slug:/t/<slug>/ 路径模式的 slug 直查——语义与 resolve_site
同款(未知/停用/懒建/reload 竞态取 _ensure_ready 返回值),首站点为默认。"""
async def test_已知_slug_返回租户与首站点(self, tmp_path):
reg = TenantRegistry.load_from_dir(SEED_DIR, data_dir=tmp_path)
rt, site = await reg.resolve_by_slug("jiancai")
assert rt.config.slug == "jiancai"
assert site.slug == rt.config.sites[0].slug # 首站点为默认
await reg.dispose_all()
async def test_未知_slug_UnknownTenantError(self, tmp_path):
reg = TenantRegistry.load_from_dir(SEED_DIR, data_dir=tmp_path)
with pytest.raises(UnknownTenantError):
await reg.resolve_by_slug("no-such")
await reg.dispose_all()
async def test_停用租户_TenantDisabledError(self, tmp_path):
seed = _write_seed(
tmp_path, {"jiancai": _tenant("jiancai", status="disabled")})
reg = TenantRegistry.load_from_dir(seed, data_dir=tmp_path / "data")
with pytest.raises(TenantDisabledError):
await reg.resolve_by_slug("jiancai")
await reg.dispose_all()
async def test_空站点表按未知处理(self, tmp_path):
"""防御分支(spec §5):两源加载期均拒零站点,直装 sites=[] 的
LoadedTenant 绕过源校验覆盖该分支——正常运行不可达,防将来源
语义漂移。"""
seed = _write_seed(tmp_path, {"jiancai": _tenant("jiancai")})
source = FileTenantSource(seed)
lt = dataclasses.replace(source.read_tenant("jiancai"), sites=[])
reg = TenantRegistry(source, data_dir=tmp_path / "data")
reg._install([lt]) # 手工装配(单元测试:直装内部)
with pytest.raises(UnknownTenantError):
await reg.resolve_by_slug("jiancai")
await reg.dispose_all()