maintainer edit: remove nonessential tracking parameters from the Feishu QR login URL after the author confirmed the flow works without them.
93 lines
2.9 KiB
Python
93 lines
2.9 KiB
Python
import json
|
|
|
|
import httpx
|
|
import pytest
|
|
|
|
from nanobot.channels import feishu as feishu_module
|
|
from nanobot.channels.feishu import FeishuChannel
|
|
from nanobot.config import loader
|
|
from nanobot.config.schema import Config
|
|
|
|
|
|
@pytest.mark.asyncio
|
|
async def test_feishu_login_writes_credentials_to_active_config(monkeypatch, tmp_path):
|
|
config_path = tmp_path / "config.json"
|
|
config = Config()
|
|
config.channels.feishu = {"enabled": False, "domain": "feishu"}
|
|
loader.save_config(config, config_path)
|
|
monkeypatch.setattr(loader, "_current_config_path", config_path)
|
|
monkeypatch.setattr(
|
|
feishu_module,
|
|
"qr_register",
|
|
lambda initial_domain="feishu": {
|
|
"app_id": "cli_app",
|
|
"app_secret": "secret",
|
|
"domain": "lark",
|
|
},
|
|
)
|
|
|
|
channel = FeishuChannel({"enabled": False, "domain": "feishu"}, None)
|
|
|
|
assert await channel.login() is True
|
|
data = json.loads(config_path.read_text(encoding="utf-8"))
|
|
assert data["channels"]["feishu"]["appId"] == "cli_app"
|
|
assert data["channels"]["feishu"]["appSecret"] == "secret"
|
|
assert data["channels"]["feishu"]["domain"] == "lark"
|
|
assert data["channels"]["feishu"]["enabled"] is True
|
|
|
|
|
|
def test_begin_registration_requires_login_url(monkeypatch):
|
|
monkeypatch.setattr(
|
|
feishu_module,
|
|
"_post_registration",
|
|
lambda _base_url, _body: {"device_code": "device"},
|
|
)
|
|
|
|
with pytest.raises(RuntimeError, match="login URL"):
|
|
feishu_module._begin_registration()
|
|
|
|
|
|
def test_begin_registration_preserves_login_url(monkeypatch):
|
|
login_url = "https://accounts.feishu.cn/login?device_code=device"
|
|
monkeypatch.setattr(
|
|
feishu_module,
|
|
"_post_registration",
|
|
lambda _base_url, _body: {
|
|
"device_code": "device",
|
|
"verification_uri_complete": login_url,
|
|
},
|
|
)
|
|
|
|
assert feishu_module._begin_registration()["qr_url"] == login_url
|
|
|
|
|
|
def test_qr_register_returns_none_on_network_error(monkeypatch):
|
|
def raise_connect_error(_base_url, _body):
|
|
raise httpx.ConnectError("network down")
|
|
|
|
monkeypatch.setattr(feishu_module, "_post_registration", raise_connect_error)
|
|
|
|
assert feishu_module.qr_register() is None
|
|
|
|
|
|
@pytest.mark.asyncio
|
|
async def test_feishu_login_creates_missing_active_config(monkeypatch, tmp_path):
|
|
missing_config = tmp_path / "missing.json"
|
|
monkeypatch.setattr(loader, "_current_config_path", missing_config)
|
|
monkeypatch.setattr(
|
|
feishu_module,
|
|
"qr_register",
|
|
lambda initial_domain="feishu": {
|
|
"app_id": "cli_app",
|
|
"app_secret": "secret",
|
|
"domain": "feishu",
|
|
},
|
|
)
|
|
|
|
channel = FeishuChannel({}, None)
|
|
|
|
assert await channel.login() is True
|
|
assert missing_config.exists()
|
|
data = json.loads(missing_config.read_text(encoding="utf-8"))
|
|
assert data["channels"]["feishu"]["appId"] == "cli_app"
|