Skip to content

Commit

Permalink
feat: apply character limit to slack text blocks. resolves #15
Browse files Browse the repository at this point in the history
  • Loading branch information
meetbryce committed Sep 6, 2024
1 parent 45f132f commit 9a87b10
Show file tree
Hide file tree
Showing 3 changed files with 72 additions and 15 deletions.
23 changes: 16 additions & 7 deletions ossai/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -203,6 +203,7 @@ def parse_message(msg):
def get_text_and_blocks_for_say(
title: str, run_id: Union[uuid.UUID, None], messages: list
) -> tuple[str, list]:
CHAR_LIMIT = 3000
text = "\n".join(messages)

blocks = [
Expand All @@ -213,15 +214,23 @@ def get_text_and_blocks_for_say(
"text": title,
},
},
{
"type": "section",
"text": {
"type": "mrkdwn",
"text": text,
},
},
]

# Split text into multiple blocks if it exceeds 3000 characters
remaining_text = text
while len(remaining_text) > 0:
chunk = remaining_text[:CHAR_LIMIT]
blocks.append(
{
"type": "section",
"text": {
"type": "mrkdwn",
"text": chunk,
},
}
)
remaining_text = remaining_text[CHAR_LIMIT:]

if run_id is not None:
blocks.append(
{
Expand Down
37 changes: 29 additions & 8 deletions tests/test_handlers.py
Original file line number Diff line number Diff line change
Expand Up @@ -52,8 +52,25 @@ def shortcuts_payload():


@pytest.fixture
def say():
return AsyncMock()
def say(**kwargs):
async def custom_say(**kwargs):
blocks = kwargs.get("blocks", [])
for block in blocks:
if block["type"] == "section" and len(block["text"]["text"]) > 3000:
error_response = {
"ok": False,
"error": "invalid_blocks",
"errors": [
"failed to match all allowed schemas [json-pointer:/blocks/0/text]",
f"must be less than 3001 characters [json-pointer:/blocks/0/text/text]",
],
}
raise SlackApiError(
"The request to the Slack API failed.", response=error_response
)
return {"ok": True, "message": {"ts": "1234567890.123456"}}

return AsyncMock(side_effect=custom_say)


@pytest.mark.asyncio
Expand Down Expand Up @@ -629,10 +646,14 @@ async def test_handler_sandbox_slash_command_happy_path():
say = AsyncMock()
payload = {"user_id": "U123", "channel_id": "C123", "channel_name": "general"}
client = AsyncMock(spec=WebClient)

await handler_sandbox_slash_command(
client, ack, payload, say, user_id="foo123"
)

await handler_sandbox_slash_command(client, ack, payload, say, user_id="foo123")
say.assert_called_once()
assert any("Useful summary of content goes here" in str(block) for block in say.call_args[1]['blocks'])
assert any("This is a test of the /sandbox command." in str(block) for block in say.call_args[1]['blocks'])
assert any(
"Useful summary of content goes here" in str(block)
for block in say.call_args[1]["blocks"]
)
assert any(
"This is a test of the /sandbox command." in str(block)
for block in say.call_args[1]["blocks"]
)
27 changes: 27 additions & 0 deletions tests/test_utils.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import runpy
from unittest.mock import ANY, patch, MagicMock
import time
import uuid
import pytest
from slack_sdk.errors import SlackApiError

Expand Down Expand Up @@ -276,3 +277,29 @@ def test_get_since_timeframe_presets_values(mock_gmtime):
assert (
expected_value == actual["value"]
), f"'{expected_text}': Expected value {expected_value}, got {actual['value']}"


def test_get_text_and_blocks_for_say_block_size():
title = "Test Title"
run_id = uuid.uuid4()

# Create a message that's longer than 3000 characters
long_message = "A" * 4000
messages = [long_message]

_, blocks = utils.get_text_and_blocks_for_say(title, run_id, messages)

# Check that the title is in the first block
assert blocks[0]['text']['text'] == title

# Check that each block's text is no longer than 3000 characters
for block in blocks[1:-1]: # Exclude the first (title) and last (buttons) blocks
assert len(block['text']['text']) <= 3000, f"Block text exceeds 3000 characters: {len(block['text']['text'])}"

# Check that all of the original message is included
combined_text = ''.join(block['text']['text'] for block in blocks[1:-1])
assert combined_text == long_message

# Check that the last block contains the buttons
assert blocks[-1]['type'] == 'actions'
assert len(blocks[-1]['elements']) == 3 # Three buttons

0 comments on commit 9a87b10

Please sign in to comment.