Currently, retrieving DMs with a given username requires several actions: first get the current user's ID; list all users and find the ID of the username; then scan all DM conversations and find the one with the current user's ID and the username's ID, to finally retrieve the messages using that conversation ID. This tool abstracts all that in a single call. PS: we'll implement a similar tool for multi-person DM conversations in a subsequent PR.
684 lines
22 KiB
Python
684 lines
22 KiB
Python
import asyncio
|
|
from unittest.mock import AsyncMock, MagicMock, call, patch
|
|
|
|
import pytest
|
|
from arcade.sdk import ToolContext
|
|
from slack_sdk.errors import SlackApiError
|
|
from slack_sdk.web.async_client import AsyncWebClient
|
|
|
|
from arcade_slack.exceptions import PaginationTimeoutError
|
|
from arcade_slack.models import (
|
|
ConversationType,
|
|
ConversationTypeSlackName,
|
|
)
|
|
from arcade_slack.tools.chat import (
|
|
get_members_in_conversation_by_id,
|
|
list_conversations_metadata,
|
|
)
|
|
from arcade_slack.utils import (
|
|
async_paginate,
|
|
convert_conversation_type_to_slack_name,
|
|
filter_conversations_by_user_ids,
|
|
retrieve_conversations_by_user_ids,
|
|
)
|
|
|
|
|
|
@pytest.mark.asyncio
|
|
async def test_async_paginate():
|
|
mock_slack_client = AsyncMock()
|
|
mock_slack_client.conversations_list.return_value = {
|
|
"ok": True,
|
|
"channels": [{"id": "123"}],
|
|
"response_metadata": {"next_cursor": None},
|
|
}
|
|
|
|
results, next_cursor = await async_paginate(
|
|
func=mock_slack_client.conversations_list,
|
|
response_key="channels",
|
|
)
|
|
|
|
assert results == [{"id": "123"}]
|
|
assert next_cursor is None
|
|
|
|
|
|
@pytest.mark.asyncio
|
|
async def test_async_paginate_with_response_error():
|
|
mock_slack_client = AsyncMock()
|
|
mock_slack_client.conversations_list.side_effect = SlackApiError(
|
|
message="slack_error",
|
|
response={"ok": False, "error": "slack_error"},
|
|
)
|
|
|
|
with pytest.raises(SlackApiError) as e:
|
|
await async_paginate(
|
|
func=mock_slack_client.conversations_list,
|
|
response_key="channels",
|
|
)
|
|
assert str(e.value) == "slack_error"
|
|
|
|
|
|
@pytest.mark.asyncio
|
|
async def test_async_paginate_with_custom_pagination_args():
|
|
mock_slack_client = AsyncMock()
|
|
mock_slack_client.conversations_list.return_value = {
|
|
"ok": True,
|
|
"channels": [{"id": "123"}],
|
|
"response_metadata": {"next_cursor": "456"},
|
|
}
|
|
|
|
results, next_cursor = await async_paginate(
|
|
func=mock_slack_client.conversations_list,
|
|
response_key="channels",
|
|
limit=1,
|
|
next_cursor="123",
|
|
hello="world",
|
|
)
|
|
|
|
assert results == [{"id": "123"}]
|
|
assert next_cursor == "456"
|
|
|
|
mock_slack_client.conversations_list.assert_called_once_with(
|
|
hello="world",
|
|
limit=1,
|
|
cursor="123",
|
|
)
|
|
|
|
|
|
@pytest.mark.asyncio
|
|
@pytest.mark.parametrize(
|
|
"test_limit, last_next_cursor, last_expected_limit",
|
|
[(5, "cursor3", 1), (None, None, 2)],
|
|
)
|
|
async def test_async_paginate_large_limit(test_limit, last_next_cursor, last_expected_limit):
|
|
mock_slack_client = AsyncMock(spec=AsyncWebClient)
|
|
mock_slack_client.conversations_list.side_effect = [
|
|
{
|
|
"ok": True,
|
|
"channels": [{"id": "channel1"}, {"id": "channel2"}],
|
|
"response_metadata": {"next_cursor": "cursor1"},
|
|
},
|
|
{
|
|
"ok": True,
|
|
"channels": [{"id": "channel3"}, {"id": "channel4"}],
|
|
"response_metadata": {"next_cursor": "cursor2"},
|
|
},
|
|
{
|
|
"ok": True,
|
|
"channels": [{"id": "channel5"}],
|
|
"response_metadata": {"next_cursor": last_next_cursor},
|
|
},
|
|
]
|
|
|
|
with patch("arcade_slack.utils.MAX_PAGINATION_SIZE_LIMIT", 2):
|
|
results, next_cursor = await async_paginate(
|
|
func=mock_slack_client.conversations_list,
|
|
response_key="channels",
|
|
limit=test_limit,
|
|
hello="world",
|
|
)
|
|
|
|
assert results == [
|
|
{"id": "channel1"},
|
|
{"id": "channel2"},
|
|
{"id": "channel3"},
|
|
{"id": "channel4"},
|
|
{"id": "channel5"},
|
|
]
|
|
assert next_cursor == last_next_cursor
|
|
assert mock_slack_client.conversations_list.call_count == 3
|
|
mock_slack_client.conversations_list.assert_has_calls([
|
|
call(hello="world", limit=2, cursor=None),
|
|
call(hello="world", limit=2, cursor="cursor1"),
|
|
call(hello="world", limit=last_expected_limit, cursor="cursor2"),
|
|
])
|
|
|
|
|
|
@pytest.mark.asyncio
|
|
async def test_async_paginate_large_limit_with_response_error():
|
|
mock_slack_client = AsyncMock()
|
|
mock_slack_client.conversations_list.side_effect = [
|
|
{
|
|
"ok": True,
|
|
"channels": [{"id": "channel1"}, {"id": "channel2"}],
|
|
"response_metadata": {"next_cursor": "cursor1"},
|
|
},
|
|
SlackApiError(message="slack_error", response={"ok": False, "error": "slack_error"}),
|
|
{
|
|
"ok": True,
|
|
"channels": [{"id": "channel5"}],
|
|
"response_metadata": {"next_cursor": "cursor3"},
|
|
},
|
|
]
|
|
|
|
with (
|
|
patch("arcade_slack.utils.MAX_PAGINATION_SIZE_LIMIT", 2),
|
|
pytest.raises(SlackApiError) as e,
|
|
):
|
|
await async_paginate(
|
|
func=mock_slack_client.conversations_list,
|
|
response_key="channels",
|
|
limit=5,
|
|
hello="world",
|
|
)
|
|
assert str(e.value) == "slack_error"
|
|
|
|
assert mock_slack_client.conversations_list.call_count == 2
|
|
mock_slack_client.conversations_list.assert_has_calls([
|
|
call(hello="world", limit=2, cursor=None),
|
|
call(hello="world", limit=2, cursor="cursor1"),
|
|
])
|
|
|
|
|
|
@pytest.mark.asyncio
|
|
async def test_async_paginate_with_timeout():
|
|
# Mock Slack client
|
|
mock_slack_client = AsyncMock()
|
|
|
|
# Simulate a network delay by making the mock function sleep
|
|
async def mock_conversations_list(*args, **kwargs):
|
|
await asyncio.sleep(1) # Sleep for 1 second to simulate delay
|
|
return {
|
|
"ok": True,
|
|
"channels": [{"id": "123"}],
|
|
"response_metadata": {"next_cursor": None},
|
|
}
|
|
|
|
mock_slack_client.conversations_list.side_effect = mock_conversations_list
|
|
|
|
# Set a low timeout to trigger the timeout error quickly during the test
|
|
max_pagination_timeout_seconds = 0.1 # 100 milliseconds
|
|
|
|
with pytest.raises(PaginationTimeoutError) as exc_info:
|
|
await async_paginate(
|
|
func=mock_slack_client.conversations_list,
|
|
response_key="channels",
|
|
max_pagination_timeout_seconds=max_pagination_timeout_seconds,
|
|
)
|
|
|
|
assert (
|
|
str(exc_info.value)
|
|
== f"The pagination process timed out after {max_pagination_timeout_seconds} seconds."
|
|
)
|
|
|
|
|
|
def test_filter_conversations_by_user_ids():
|
|
conversations = [
|
|
{"id": "123", "members": [{"id": "user1"}, {"id": "user2"}, {"id": "user3"}]},
|
|
{"id": "456", "members": [{"id": "user2"}, {"id": "user3"}]},
|
|
]
|
|
response = filter_conversations_by_user_ids(
|
|
conversations=conversations,
|
|
user_ids=["user1", "user2"],
|
|
exact_match=False,
|
|
)
|
|
assert response == [
|
|
{"id": "123", "members": [{"id": "user1"}, {"id": "user2"}, {"id": "user3"}]},
|
|
]
|
|
|
|
|
|
def test_filter_conversations_by_user_ids_empty_response():
|
|
conversations = [
|
|
{"id": "123", "members": [{"id": "user1"}, {"id": "user3"}, {"id": "user4"}]},
|
|
{"id": "456", "members": [{"id": "user2"}, {"id": "user3"}, {"id": "user4"}]},
|
|
]
|
|
response = filter_conversations_by_user_ids(
|
|
conversations=conversations,
|
|
user_ids=["user1", "user2"],
|
|
exact_match=False,
|
|
)
|
|
assert response == []
|
|
|
|
|
|
def test_filter_conversations_by_user_ids_multiple_matches():
|
|
conversations = [
|
|
{"id": "123", "members": [{"id": "user1"}, {"id": "user2"}, {"id": "user3"}]},
|
|
{"id": "456", "members": [{"id": "user2"}, {"id": "user3"}]},
|
|
{
|
|
"id": "789",
|
|
"members": [{"id": "user4"}, {"id": "user1"}, {"id": "user2"}, {"id": "user3"}],
|
|
},
|
|
]
|
|
response = filter_conversations_by_user_ids(
|
|
conversations=conversations,
|
|
user_ids=["user1", "user2"],
|
|
exact_match=False,
|
|
)
|
|
assert response == [
|
|
{"id": "123", "members": [{"id": "user1"}, {"id": "user2"}, {"id": "user3"}]},
|
|
{
|
|
"id": "789",
|
|
"members": [{"id": "user4"}, {"id": "user1"}, {"id": "user2"}, {"id": "user3"}],
|
|
},
|
|
]
|
|
|
|
|
|
def test_filter_conversations_by_user_ids_exact_match():
|
|
conversations = [
|
|
{"id": "123", "members": [{"id": "user1"}, {"id": "user2"}]},
|
|
{"id": "456", "members": [{"id": "user2"}, {"id": "user3"}]},
|
|
]
|
|
response = filter_conversations_by_user_ids(
|
|
conversations=conversations,
|
|
user_ids=["user1", "user2"],
|
|
exact_match=True,
|
|
)
|
|
assert response == [{"id": "123", "members": [{"id": "user1"}, {"id": "user2"}]}]
|
|
|
|
|
|
def test_filter_conversations_by_user_ids_exact_match_empty_response():
|
|
conversations = [
|
|
{"id": "123", "members": [{"id": "user1"}, {"id": "user2"}, {"id": "user3"}]},
|
|
{"id": "456", "members": [{"id": "user2"}, {"id": "user3"}]},
|
|
]
|
|
response = filter_conversations_by_user_ids(
|
|
conversations=conversations,
|
|
user_ids=["user1", "user2"],
|
|
exact_match=True,
|
|
)
|
|
assert response == []
|
|
|
|
|
|
@pytest.mark.asyncio
|
|
@pytest.mark.parametrize(
|
|
"search_user_ids, conversation_types, exact_match, limit, expected_conversation_ids",
|
|
[
|
|
(["U1", "U2"], [ConversationType.DIRECT_MESSAGE], False, 1, ["C1"]),
|
|
(["U1", "U2"], [ConversationType.DIRECT_MESSAGE], True, 1, ["C1"]),
|
|
(["U1", "U2", "U3"], [ConversationType.DIRECT_MESSAGE], False, 1, []),
|
|
(
|
|
["U1", "U2"],
|
|
[ConversationType.DIRECT_MESSAGE, ConversationType.PUBLIC_CHANNEL],
|
|
False,
|
|
10,
|
|
["C1", "C3", "C4"],
|
|
),
|
|
(
|
|
["U1", "U2"],
|
|
[ConversationType.DIRECT_MESSAGE, ConversationType.PUBLIC_CHANNEL],
|
|
True,
|
|
10,
|
|
["C1", "C3"],
|
|
),
|
|
],
|
|
)
|
|
async def test_retrieve_conversations_by_user_ids(
|
|
mock_chat_slack_client,
|
|
mock_users_slack_client,
|
|
search_user_ids,
|
|
conversation_types,
|
|
exact_match,
|
|
limit,
|
|
expected_conversation_ids,
|
|
):
|
|
context = MagicMock(spec=ToolContext)
|
|
context.authorization = MagicMock()
|
|
context.authorization.token = MagicMock()
|
|
|
|
conversation_types_slack_name_str = [
|
|
convert_conversation_type_to_slack_name(conv_type).value
|
|
for conv_type in conversation_types or ConversationType
|
|
]
|
|
|
|
conversations = [
|
|
{
|
|
"conversation": {
|
|
"id": "C1",
|
|
"type": ConversationTypeSlackName.IM.value,
|
|
"name": "im-1",
|
|
"is_channel": False,
|
|
"is_im": True,
|
|
"is_member": True,
|
|
},
|
|
"members": {
|
|
"ok": True,
|
|
"members": ["U1", "U2"],
|
|
"response_metadata": {"next_cursor": None},
|
|
},
|
|
"users": [
|
|
{"ok": True, "user": {"id": "U1", "team_id": "T123", "name": "user1"}},
|
|
{"ok": True, "user": {"id": "U2", "team_id": "T123", "name": "user2"}},
|
|
],
|
|
},
|
|
{
|
|
"conversation": {
|
|
"id": "C2",
|
|
"type": ConversationTypeSlackName.IM.value,
|
|
"name": "im-2",
|
|
"is_channel": False,
|
|
"is_im": True,
|
|
"is_member": True,
|
|
},
|
|
"members": {
|
|
"ok": True,
|
|
"members": ["U2", "U3"],
|
|
"response_metadata": {"next_cursor": None},
|
|
},
|
|
"users": [
|
|
{"ok": True, "user": {"id": "U2", "team_id": "T123", "name": "user2"}},
|
|
{"ok": True, "user": {"id": "U3", "team_id": "T123", "name": "user3"}},
|
|
],
|
|
},
|
|
{
|
|
"conversation": {
|
|
"id": "C3",
|
|
"type": ConversationTypeSlackName.PUBLIC_CHANNEL.value,
|
|
"name": "general",
|
|
"is_channel": True,
|
|
"is_im": False,
|
|
"is_member": True,
|
|
},
|
|
"members": {
|
|
"ok": True,
|
|
"members": ["U1", "U2"],
|
|
"response_metadata": {"next_cursor": None},
|
|
},
|
|
"users": [
|
|
{"ok": True, "user": {"id": "U1", "team_id": "T123", "name": "user1"}},
|
|
{"ok": True, "user": {"id": "U2", "team_id": "T123", "name": "user2"}},
|
|
],
|
|
},
|
|
{
|
|
"conversation": {
|
|
"id": "C4",
|
|
"type": ConversationTypeSlackName.PUBLIC_CHANNEL.value,
|
|
"name": "random",
|
|
"is_channel": True,
|
|
"is_im": False,
|
|
"is_member": True,
|
|
},
|
|
"members": {
|
|
"ok": True,
|
|
"members": ["U1", "U2", "U3", "U4"],
|
|
"response_metadata": {"next_cursor": None},
|
|
},
|
|
"users": [
|
|
{"ok": True, "user": {"id": "U1", "team_id": "T123", "name": "user1"}},
|
|
{"ok": True, "user": {"id": "U2", "team_id": "T123", "name": "user2"}},
|
|
{"ok": True, "user": {"id": "U3", "team_id": "T123", "name": "user3"}},
|
|
{"ok": True, "user": {"id": "U4", "team_id": "T123", "name": "user4"}},
|
|
],
|
|
},
|
|
]
|
|
|
|
conversations_listed = [
|
|
conversation
|
|
for conversation in conversations
|
|
if conversation["conversation"]["type"] in conversation_types_slack_name_str
|
|
]
|
|
|
|
mock_chat_slack_client.conversations_list.return_value = {
|
|
"ok": True,
|
|
"channels": [conversation["conversation"] for conversation in conversations_listed],
|
|
"response_metadata": {"next_cursor": None},
|
|
}
|
|
|
|
mock_chat_slack_client.conversations_members.side_effect = [
|
|
conversation["members"] for conversation in conversations_listed
|
|
]
|
|
|
|
mock_users_slack_client.users_info.side_effect = [
|
|
user for conversation in conversations_listed for user in conversation["users"]
|
|
]
|
|
|
|
conversations_found = await retrieve_conversations_by_user_ids(
|
|
list_conversations_func=list_conversations_metadata,
|
|
get_members_in_conversation_func=get_members_in_conversation_by_id,
|
|
context=context,
|
|
conversation_types=conversation_types,
|
|
user_ids=search_user_ids,
|
|
exact_match=exact_match,
|
|
limit=limit,
|
|
next_cursor=None,
|
|
)
|
|
|
|
assert [conversation["id"] for conversation in conversations_found] == expected_conversation_ids
|
|
|
|
|
|
@pytest.mark.asyncio
|
|
@pytest.mark.parametrize(
|
|
(
|
|
"search_user_ids, conversation_types, exact_match, limit, "
|
|
"expected_conversation_ids, expected_conversations_list_calls"
|
|
),
|
|
[
|
|
(
|
|
["U1", "U2", "U3"],
|
|
[ConversationType.MULTI_PERSON_DIRECT_MESSAGE],
|
|
False,
|
|
None,
|
|
["C1", "C3"],
|
|
2,
|
|
),
|
|
(
|
|
["U1", "U2", "U3"],
|
|
[ConversationType.MULTI_PERSON_DIRECT_MESSAGE],
|
|
True,
|
|
None,
|
|
["C1"],
|
|
2,
|
|
),
|
|
(["U1", "U2", "U99"], [ConversationType.MULTI_PERSON_DIRECT_MESSAGE], False, None, [], 2),
|
|
(
|
|
["U1", "U2"],
|
|
[ConversationType.MULTI_PERSON_DIRECT_MESSAGE, ConversationType.PUBLIC_CHANNEL],
|
|
False,
|
|
None,
|
|
["C1", "C3", "C4", "C6"],
|
|
2,
|
|
),
|
|
(
|
|
["U1", "U2"],
|
|
[ConversationType.MULTI_PERSON_DIRECT_MESSAGE, ConversationType.PUBLIC_CHANNEL],
|
|
False,
|
|
1,
|
|
["C1"],
|
|
2,
|
|
),
|
|
(
|
|
["U1", "U2"],
|
|
[ConversationType.MULTI_PERSON_DIRECT_MESSAGE, ConversationType.PUBLIC_CHANNEL],
|
|
False,
|
|
3,
|
|
["C1", "C3", "C4"],
|
|
2,
|
|
),
|
|
(
|
|
["U1", "U2"],
|
|
[ConversationType.MULTI_PERSON_DIRECT_MESSAGE, ConversationType.PUBLIC_CHANNEL],
|
|
True,
|
|
None,
|
|
["C4"],
|
|
2,
|
|
),
|
|
],
|
|
)
|
|
async def test_retrieve_conversations_by_user_ids_with_pagination(
|
|
mock_chat_slack_client,
|
|
mock_users_slack_client,
|
|
search_user_ids,
|
|
conversation_types,
|
|
exact_match,
|
|
limit,
|
|
expected_conversation_ids,
|
|
expected_conversations_list_calls,
|
|
):
|
|
context = MagicMock(spec=ToolContext)
|
|
context.authorization = MagicMock()
|
|
context.authorization.token = MagicMock()
|
|
|
|
conversation_types_slack_name_str = [
|
|
convert_conversation_type_to_slack_name(conv_type).value
|
|
for conv_type in conversation_types or ConversationType
|
|
]
|
|
|
|
conversations = [
|
|
{
|
|
"conversation": {
|
|
"id": "C1",
|
|
"type": ConversationTypeSlackName.MPIM.value,
|
|
"name": "mpim-1",
|
|
"is_channel": False,
|
|
"is_im": False,
|
|
"is_mpim": True,
|
|
"is_member": True,
|
|
},
|
|
"members": {
|
|
"ok": True,
|
|
"members": ["U1", "U2", "U3"],
|
|
"response_metadata": {"next_cursor": None},
|
|
},
|
|
"users": [
|
|
{"ok": True, "user": {"id": "U1", "team_id": "T123", "name": "user1"}},
|
|
{"ok": True, "user": {"id": "U2", "team_id": "T123", "name": "user2"}},
|
|
{"ok": True, "user": {"id": "U3", "team_id": "T123", "name": "user3"}},
|
|
],
|
|
},
|
|
{
|
|
"conversation": {
|
|
"id": "C2",
|
|
"type": ConversationTypeSlackName.MPIM.value,
|
|
"name": "mpim-2",
|
|
"is_channel": False,
|
|
"is_im": False,
|
|
"is_mpim": True,
|
|
"is_member": True,
|
|
},
|
|
"members": {
|
|
"ok": True,
|
|
"members": ["U2", "U3"],
|
|
"response_metadata": {"next_cursor": None},
|
|
},
|
|
"users": [
|
|
{"ok": True, "user": {"id": "U2", "team_id": "T123", "name": "user2"}},
|
|
{"ok": True, "user": {"id": "U3", "team_id": "T123", "name": "user3"}},
|
|
],
|
|
},
|
|
{
|
|
"conversation": {
|
|
"id": "C3",
|
|
"type": ConversationTypeSlackName.MPIM.value,
|
|
"name": "mpim-3",
|
|
"is_channel": False,
|
|
"is_im": False,
|
|
"is_mpim": True,
|
|
"is_member": True,
|
|
},
|
|
"members": {
|
|
"ok": True,
|
|
"members": ["U1", "U2", "U3", "U4"],
|
|
"response_metadata": {"next_cursor": None},
|
|
},
|
|
"users": [
|
|
{"ok": True, "user": {"id": "U1", "team_id": "T123", "name": "user1"}},
|
|
{"ok": True, "user": {"id": "U2", "team_id": "T123", "name": "user2"}},
|
|
{"ok": True, "user": {"id": "U3", "team_id": "T123", "name": "user3"}},
|
|
{"ok": True, "user": {"id": "U4", "team_id": "T123", "name": "user4"}},
|
|
],
|
|
},
|
|
{
|
|
"conversation": {
|
|
"id": "C4",
|
|
"type": ConversationTypeSlackName.PUBLIC_CHANNEL.value,
|
|
"name": "channel-4",
|
|
"is_channel": True,
|
|
"is_im": False,
|
|
"is_member": True,
|
|
},
|
|
"members": {
|
|
"ok": True,
|
|
"members": ["U1", "U2"],
|
|
"response_metadata": {"next_cursor": None},
|
|
},
|
|
"users": [
|
|
{"ok": True, "user": {"id": "U1", "team_id": "T123", "name": "user1"}},
|
|
{"ok": True, "user": {"id": "U2", "team_id": "T123", "name": "user2"}},
|
|
],
|
|
},
|
|
{
|
|
"conversation": {
|
|
"id": "C5",
|
|
"type": ConversationTypeSlackName.PUBLIC_CHANNEL.value,
|
|
"name": "channel-5",
|
|
"is_channel": True,
|
|
"is_im": False,
|
|
"is_member": True,
|
|
},
|
|
"members": {
|
|
"ok": True,
|
|
"members": ["U2", "U3", "U4"],
|
|
"response_metadata": {"next_cursor": None},
|
|
},
|
|
"users": [
|
|
{"ok": True, "user": {"id": "U2", "team_id": "T123", "name": "user2"}},
|
|
{"ok": True, "user": {"id": "U3", "team_id": "T123", "name": "user3"}},
|
|
{"ok": True, "user": {"id": "U4", "team_id": "T123", "name": "user4"}},
|
|
],
|
|
},
|
|
{
|
|
"conversation": {
|
|
"id": "C6",
|
|
"type": ConversationTypeSlackName.PUBLIC_CHANNEL.value,
|
|
"name": "channel-6",
|
|
"is_channel": True,
|
|
"is_im": False,
|
|
"is_member": True,
|
|
},
|
|
"members": {
|
|
"ok": True,
|
|
"members": ["U1", "U2", "U3", "U4"],
|
|
"response_metadata": {"next_cursor": None},
|
|
},
|
|
"users": [
|
|
{"ok": True, "user": {"id": "U1", "team_id": "T123", "name": "user1"}},
|
|
{"ok": True, "user": {"id": "U2", "team_id": "T123", "name": "user2"}},
|
|
{"ok": True, "user": {"id": "U3", "team_id": "T123", "name": "user3"}},
|
|
{"ok": True, "user": {"id": "U4", "team_id": "T123", "name": "user4"}},
|
|
],
|
|
},
|
|
]
|
|
|
|
conversations_listed = [
|
|
conversation
|
|
for conversation in conversations
|
|
if conversation["conversation"]["type"] in conversation_types_slack_name_str
|
|
]
|
|
|
|
split_size = len(conversations_listed) // 2
|
|
|
|
conversations_listed_1 = conversations_listed[:split_size]
|
|
conversations_listed_2 = conversations_listed[split_size:]
|
|
|
|
mock_chat_slack_client.conversations_list.side_effect = [
|
|
{
|
|
"ok": True,
|
|
"channels": [conversation["conversation"] for conversation in conversations_listed_1],
|
|
"response_metadata": {"next_cursor": "cursor_1"},
|
|
},
|
|
{
|
|
"ok": True,
|
|
"channels": [conversation["conversation"] for conversation in conversations_listed_2],
|
|
"response_metadata": {"next_cursor": None},
|
|
},
|
|
]
|
|
|
|
mock_chat_slack_client.conversations_members.side_effect = [
|
|
conversation["members"] for conversation in conversations_listed
|
|
]
|
|
|
|
mock_users_slack_client.users_info.side_effect = [
|
|
user for conversation in conversations_listed for user in conversation["users"]
|
|
]
|
|
|
|
conversations_found = await retrieve_conversations_by_user_ids(
|
|
list_conversations_func=list_conversations_metadata,
|
|
get_members_in_conversation_func=get_members_in_conversation_by_id,
|
|
context=context,
|
|
conversation_types=conversation_types,
|
|
user_ids=search_user_ids,
|
|
exact_match=exact_match,
|
|
limit=limit,
|
|
next_cursor=None,
|
|
)
|
|
|
|
assert [conversation["id"] for conversation in conversations_found] == expected_conversation_ids
|
|
assert mock_chat_slack_client.conversations_list.call_count == expected_conversations_list_calls
|