Files
aiturk-hermes-ide/tests/gateway/test_slack_api_human_senders.py
T

95 lines
3.4 KiB
Python

"""Tests for the Slack ``api_human_users`` allowlist.
A message posted through the Web API with a *user* token (``xoxp-``) is
authored by a real person, but it arrives with the posting ``app_id`` and no
``client_msg_id`` — the #35777 app/bot signature — so
``_event_declares_bot_sender`` drops it. ``platforms.slack.extra.api_human_users``
allowlists those *users* (never apps: an app's own ``xoxb`` bot posts carry
the same user+app_id shape).
"""
import sys
from unittest.mock import MagicMock
import pytest
# Mock slack-bolt / slack-sdk the same way test_slack_mention.py does.
def _ensure_slack_mock():
if "slack_bolt" in sys.modules and hasattr(sys.modules["slack_bolt"], "__file__"):
return
slack_bolt = MagicMock()
slack_bolt.async_app.AsyncApp = MagicMock
slack_bolt.adapter.socket_mode.async_handler.AsyncSocketModeHandler = MagicMock
slack_sdk = MagicMock()
slack_sdk.web.async_client.AsyncWebClient = MagicMock
for name, mod in [
("slack_bolt", slack_bolt),
("slack_bolt.async_app", slack_bolt.async_app),
("slack_bolt.adapter", slack_bolt.adapter),
("slack_bolt.adapter.socket_mode", slack_bolt.adapter.socket_mode),
(
"slack_bolt.adapter.socket_mode.async_handler",
slack_bolt.adapter.socket_mode.async_handler,
),
("slack_sdk", slack_sdk),
("slack_sdk.web", slack_sdk.web),
("slack_sdk.web.async_client", slack_sdk.web.async_client),
]:
sys.modules.setdefault(name, mod)
sys.modules.setdefault("aiohttp", MagicMock())
_ensure_slack_mock()
import plugins.platforms.slack.adapter as _slack_mod # noqa: E402
_slack_mod.SLACK_AVAILABLE = True
from plugins.platforms.slack.adapter import SlackAdapter # noqa: E402
from gateway.config import Platform, PlatformConfig # noqa: E402
HUMAN_ID = "U_human"
def _make_adapter(extra=None):
adapter = object.__new__(SlackAdapter)
adapter.platform = Platform.SLACK
adapter.config = PlatformConfig(enabled=True, extra=dict(extra or {}))
return adapter
def _api_post(**overrides):
"""A user-token chat.postMessage as delivered over Socket Mode:
real ``user``, app_id stamp, no ``client_msg_id``."""
event = {"type": "message", "user": HUMAN_ID, "app_id": "A_frontend", "text": "hi"}
event.update(overrides)
return event
@pytest.fixture(autouse=True)
def _clean_env(monkeypatch):
monkeypatch.delenv("SLACK_API_HUMAN_USERS", raising=False)
def test_api_post_is_bot_by_default():
assert _make_adapter()._event_declares_bot_sender(_api_post()) is True
def test_allowlisted_user_api_post_is_human():
adapter = _make_adapter({"api_human_users": ["U_other", HUMAN_ID]})
assert adapter._event_declares_bot_sender(_api_post()) is False
# Same predicate everywhere: no other user, and no user-less app post, rides it.
assert adapter._event_declares_bot_sender(_api_post(user="U_stranger")) is True
assert adapter._event_declares_bot_sender({"app_id": "A_frontend", "text": "hi"}) is True
def test_bot_markers_win_over_allowlist():
"""Allowlisting a user never admits genuine bot posts, so the app's own
``xoxb`` traffic (bot_id / subtype=bot_message) cannot loop back in."""
adapter = _make_adapter({"api_human_users": HUMAN_ID})
assert adapter._event_declares_bot_sender(_api_post(subtype="bot_message")) is True
assert adapter._event_declares_bot_sender(_api_post(bot_id="B_stamp")) is True