"""微信 Bot 账号隔离回归测试。""" from types import SimpleNamespace import pytest from fastapi import HTTPException from sqlmodel import Session, SQLModel, create_engine from app.auth import feature_permissions, required_permission from app.main import _wechat_account_visible, wechat_bot_reply from app.models import Agent, AppUser, WeChatBotAccount def _user(uid: int, org: int, role: str = "editor"): return AppUser(id=uid, username=f"u{uid}", role=role, organization_id=org, enabled=True) def test_wechat_accounts_use_digital_human_permission_domain(): assert required_permission("POST", "/api/wechat/bot/accounts/connect") == "agents:write" assert required_permission("GET", "/api/wechat/bot/accounts") == "digital_humans:read" assert feature_permissions("POST", "/api/wechat/bot/accounts/connect")[0] == "feature:digital-humans" def test_wechat_account_visibility_is_organization_scoped(): row = WeChatBotAccount(owner_user_id=7, organization_id=10) assert _wechat_account_visible(row, _user(7, 10)) assert not _wechat_account_visible(row, _user(7, 11)) assert not _wechat_account_visible(row, _user(8, 11, "admin")) assert _wechat_account_visible(row, _user(8, 10, "admin")) def test_reply_requires_account_and_never_uses_global_fallback(tmp_path): """没有 account_id 时即使设置了全局环境变量也必须拒绝。""" engine = create_engine(f"sqlite:///{tmp_path / 'wechat.db'}") SQLModel.metadata.create_all(engine) request = SimpleNamespace(headers={}) with Session(engine) as session: with pytest.raises(HTTPException) as exc: wechat_bot_reply({"text": "hello", "conversation_id": "c"}, session, request) assert exc.value.status_code == 422 def test_reply_rejects_disconnected_account_before_agent_lookup(tmp_path): engine = create_engine(f"sqlite:///{tmp_path / 'wechat2.db'}") SQLModel.metadata.create_all(engine) request = SimpleNamespace(headers={}) with Session(engine) as session: owner = _user(1, 1) session.add(owner) session.add(WeChatBotAccount(id=3, owner_user_id=1, organization_id=1, agent_id=9, status="disconnected", bot_secret_hash="x")) session.commit() with pytest.raises(HTTPException) as exc: wechat_bot_reply({"account_id": 3, "text": "hello", "conversation_id": "c"}, session, request) assert exc.value.status_code == 409