Files
deer-flow/backend/tests/test_slack_channel_connections.py
T
2026-06-10 22:16:47 +08:00

97 lines
3.1 KiB
Python

"""Slack connection tests for user-owned channel bindings."""
from __future__ import annotations
from datetime import UTC, datetime, timedelta
from unittest.mock import AsyncMock, MagicMock
from app.channels.message_bus import MessageBus, OutboundMessage
async def _make_repo(tmp_path):
from deerflow.persistence.channel_connections import ChannelConnectionRepository, ChannelCredentialCipher
from deerflow.persistence.engine import get_session_factory, init_engine
await init_engine("sqlite", url=f"sqlite+aiosqlite:///{tmp_path / 'slack.db'}", sqlite_dir=str(tmp_path))
return ChannelConnectionRepository(
get_session_factory(),
cipher=ChannelCredentialCipher.from_key("slack-secret"),
)
def test_slack_connect_command_binds_socket_mode_identity(tmp_path):
import anyio
from app.channels.slack import SlackChannel
async def go():
repo = await _make_repo(tmp_path)
state = "slack-bind-code"
await repo.create_oauth_state(
owner_user_id="deerflow-user-1",
provider="slack",
state=state,
expires_at=datetime.now(UTC) + timedelta(minutes=5),
)
channel = SlackChannel(
bus=MessageBus(),
config={"bot_token": "xoxb-operator", "app_token": "xapp-operator", "connection_repo": repo},
)
channel._web_client = MagicMock()
handled = await channel._bind_connection_from_connect_code(
event={
"user": "U123",
"channel": "C123",
"ts": "1710000000.000100",
},
team_id="T123",
code=state,
)
connections = await repo.list_connections("deerflow-user-1")
assert handled is True
assert len(connections) == 1
assert connections[0]["provider"] == "slack"
assert connections[0]["external_account_id"] == "U123"
assert connections[0]["workspace_id"] == "T123"
assert connections[0]["metadata"]["channel_id"] == "C123"
channel._web_client.chat_postMessage.assert_called_once()
await repo.close()
anyio.run(go)
def test_slack_send_uses_connection_bot_token_when_connection_id_is_present():
import anyio
from app.channels.slack import SlackChannel
async def go():
repo = AsyncMock()
repo.get_credentials.return_value = {"access_token": "xoxb-connection-token"}
web_client = MagicMock()
web_client_factory = MagicMock(return_value=web_client)
channel = SlackChannel(
bus=MessageBus(),
config={
"connection_repo": repo,
"web_client_factory": web_client_factory,
},
)
msg = OutboundMessage(
channel_name="slack",
chat_id="C123",
thread_id="thread-1",
text="hello",
connection_id="connection-1",
)
await channel.send(msg)
repo.get_credentials.assert_awaited_once_with("connection-1")
web_client_factory.assert_called_once_with(token="xoxb-connection-token")
web_client.chat_postMessage.assert_called_once()
anyio.run(go)