fix: stabilize feishu login setup
maintainer edit: fix the lint failure, report the active config path, fail fast when the registration response lacks a login URL, and cover the new Feishu login writeback path.
This commit is contained in:
@@ -371,6 +371,8 @@ def _begin_registration(domain: str = "feishu") -> dict:
|
|||||||
if not device_code:
|
if not device_code:
|
||||||
raise RuntimeError("Feishu / Lark registration did not return a device_code")
|
raise RuntimeError("Feishu / Lark registration did not return a device_code")
|
||||||
qr_url = res.get("verification_uri_complete", "")
|
qr_url = res.get("verification_uri_complete", "")
|
||||||
|
if not qr_url:
|
||||||
|
raise RuntimeError("Feishu / Lark registration did not return a login URL")
|
||||||
if "?" in qr_url:
|
if "?" in qr_url:
|
||||||
qr_url += "&from=nanobot&tp=nanobot"
|
qr_url += "&from=nanobot&tp=nanobot"
|
||||||
else:
|
else:
|
||||||
@@ -715,7 +717,7 @@ class FeishuChannel(BaseChannel):
|
|||||||
print(f"Domain: {self.config.domain}")
|
print(f"Domain: {self.config.domain}")
|
||||||
|
|
||||||
# Write credentials back to config.json
|
# Write credentials back to config.json
|
||||||
from nanobot.config.loader import load_config, save_config
|
from nanobot.config.loader import get_config_path, load_config, save_config
|
||||||
|
|
||||||
full_config = load_config()
|
full_config = load_config()
|
||||||
feishu_cfg = getattr(full_config.channels, "feishu", None) or {}
|
feishu_cfg = getattr(full_config.channels, "feishu", None) or {}
|
||||||
@@ -727,7 +729,7 @@ class FeishuChannel(BaseChannel):
|
|||||||
setattr(full_config.channels, "feishu", feishu_cfg)
|
setattr(full_config.channels, "feishu", feishu_cfg)
|
||||||
save_config(full_config)
|
save_config(full_config)
|
||||||
|
|
||||||
print(f"\nCredentials saved to ~/.nanobot/config.json (feishu enabled)")
|
print(f"\nCredentials saved to {get_config_path()} (feishu enabled)")
|
||||||
print("Login successful!")
|
print("Login successful!")
|
||||||
return True
|
return True
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,60 @@
|
|||||||
|
import json
|
||||||
|
|
||||||
|
import pytest
|
||||||
|
from typer.testing import CliRunner
|
||||||
|
|
||||||
|
from nanobot.channels import feishu as feishu_module
|
||||||
|
from nanobot.channels.feishu import FeishuChannel
|
||||||
|
from nanobot.cli.commands import app
|
||||||
|
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",
|
||||||
|
"bot_name": None,
|
||||||
|
"bot_open_id": None,
|
||||||
|
},
|
||||||
|
)
|
||||||
|
|
||||||
|
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_channels_login_feishu_requires_default_config_file(monkeypatch, tmp_path):
|
||||||
|
missing_config = tmp_path / "missing.json"
|
||||||
|
monkeypatch.setattr(loader, "get_config_path", lambda: missing_config)
|
||||||
|
|
||||||
|
result = CliRunner().invoke(app, ["channels", "login", "feishu"])
|
||||||
|
|
||||||
|
assert result.exit_code == 1
|
||||||
|
assert "No configuration file found" in result.output
|
||||||
Reference in New Issue
Block a user