From 33050a8d014ef053def8136f22be28cc852f3cfe Mon Sep 17 00:00:00 2001 From: Voronin Sergei Date: Sun, 31 May 2026 01:35:27 +1200 Subject: [PATCH] Add assistant thread context regression tests --- tests/slack_bolt/app/test_app_assistant.py | 65 ++++++++++++++++++ .../app/test_async_app_assistant.py | 68 +++++++++++++++++++ 2 files changed, 133 insertions(+) create mode 100644 tests/slack_bolt/app/test_app_assistant.py create mode 100644 tests/slack_bolt_async/app/test_async_app_assistant.py diff --git a/tests/slack_bolt/app/test_app_assistant.py b/tests/slack_bolt/app/test_app_assistant.py new file mode 100644 index 000000000..596a569b3 --- /dev/null +++ b/tests/slack_bolt/app/test_app_assistant.py @@ -0,0 +1,65 @@ +from threading import Event + +from slack_bolt import App, Assistant, BoltRequest +from slack_bolt.authorization import AuthorizeResult +from slack_bolt.context.assistant import assistant_utilities +from slack_bolt.context.assistant.thread_context import AssistantThreadContext +from slack_bolt.context.assistant.thread_context_store.store import AssistantThreadContextStore +from slack_sdk import WebClient +from tests.scenario_tests.test_events_assistant import user_message_event_body + + +class RecordingDefaultAssistantThreadContextStore(AssistantThreadContextStore): + def __init__(self, context, seen_bot_user_ids): + self.seen_bot_user_ids = seen_bot_user_ids + self.seen_bot_user_ids.append(context.bot_user_id) + + def find(self, *, channel_id: str, thread_ts: str): + return AssistantThreadContext({"channel_id": "C222", "team_id": "T111"}) + + def save(self, *, channel_id: str, thread_ts: str, context): + pass + + +class TestAppAssistant: + def test_user_message_get_thread_context_store_is_initialized_after_authorize(self, monkeypatch): + seen_bot_user_ids = [] + + def build_store(context): + return RecordingDefaultAssistantThreadContextStore(context, seen_bot_user_ids) + + monkeypatch.setattr( + assistant_utilities, + "DefaultAssistantThreadContextStore", + build_store, + ) + + def authorize(context, enterprise_id, team_id, user_id): + return AuthorizeResult( + enterprise_id=enterprise_id, + team_id=team_id, + bot_user_id="W23456789", + bot_id="B111", + bot_token="xoxb-valid", + ) + + app = App( + client=WebClient(token=None), + authorize=authorize, + process_before_response=True, + ) + assistant = Assistant() + listener_called = Event() + + @assistant.user_message + def handle_user_message(get_thread_context): + assert get_thread_context() == {"channel_id": "C222", "team_id": "T111"} + listener_called.set() + + app.assistant(assistant) + + response = app.dispatch(BoltRequest(body=user_message_event_body, mode="socket_mode")) + + assert response.status == 200 + assert listener_called.is_set() + assert seen_bot_user_ids == ["W23456789"] diff --git a/tests/slack_bolt_async/app/test_async_app_assistant.py b/tests/slack_bolt_async/app/test_async_app_assistant.py new file mode 100644 index 000000000..f7e1cde34 --- /dev/null +++ b/tests/slack_bolt_async/app/test_async_app_assistant.py @@ -0,0 +1,68 @@ +import asyncio + +import pytest +from slack_sdk.web.async_client import AsyncWebClient + +from slack_bolt.async_app import AsyncApp, AsyncAssistant, AsyncBoltRequest +from slack_bolt.authorization import AuthorizeResult +from slack_bolt.context.assistant import async_assistant_utilities +from slack_bolt.context.assistant.thread_context import AssistantThreadContext +from slack_bolt.context.assistant.thread_context_store.async_store import AsyncAssistantThreadContextStore +from tests.scenario_tests_async.test_events_assistant import user_message_event_body + + +class RecordingDefaultAsyncAssistantThreadContextStore(AsyncAssistantThreadContextStore): + def __init__(self, context, seen_bot_user_ids): + self.seen_bot_user_ids = seen_bot_user_ids + self.seen_bot_user_ids.append(context.bot_user_id) + + async def find(self, *, channel_id: str, thread_ts: str): + return AssistantThreadContext({"channel_id": "C222", "team_id": "T111"}) + + async def save(self, *, channel_id: str, thread_ts: str, context): + pass + + +class TestAsyncAppAssistant: + @pytest.mark.asyncio + async def test_user_message_get_thread_context_store_is_initialized_after_authorize(self, monkeypatch): + seen_bot_user_ids = [] + + def build_store(context): + return RecordingDefaultAsyncAssistantThreadContextStore(context, seen_bot_user_ids) + + monkeypatch.setattr( + async_assistant_utilities, + "DefaultAsyncAssistantThreadContextStore", + build_store, + ) + + async def authorize(context, enterprise_id, team_id, user_id): + return AuthorizeResult( + enterprise_id=enterprise_id, + team_id=team_id, + bot_user_id="W23456789", + bot_id="B111", + bot_token="xoxb-valid", + ) + + app = AsyncApp( + client=AsyncWebClient(token=None), + authorize=authorize, + process_before_response=True, + ) + assistant = AsyncAssistant() + listener_called = asyncio.Event() + + @assistant.user_message + async def handle_user_message(get_thread_context): + assert await get_thread_context() == {"channel_id": "C222", "team_id": "T111"} + listener_called.set() + + app.assistant(assistant) + + response = await app.async_dispatch(AsyncBoltRequest(body=user_message_event_body, mode="socket_mode")) + + assert response.status == 200 + assert listener_called.is_set() + assert seen_bot_user_ids == ["W23456789"]