Skip to content

Commit 1f5d6c4

Browse files
feat: Add tests for opening, closing and changing citations
1 parent 2edb407 commit 1f5d6c4

File tree

2 files changed

+220
-18
lines changed

2 files changed

+220
-18
lines changed

packages/slackBotFunction/app/slack/slack_events.py

Lines changed: 22 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -652,25 +652,9 @@ def open_citation(channel: str, timestamp: str, message: Any, params: Dict[str,
652652
body = body.replace("»", "") # Remove double chevrons
653653

654654
current_id = f"cite_{source_number}".strip()
655-
selected = False
656655

657656
# Reset all button styles, then set the clicked one
658-
for block in blocks:
659-
if block.get("type") == "actions":
660-
for element in block.get("elements", []):
661-
if element.get("type") == "button":
662-
action_id = element.get("action_id")
663-
if action_id == current_id:
664-
# Toggle: if already styled, unselect; else select
665-
if element.get("style") == "primary":
666-
element.pop("style", None)
667-
selected = False
668-
else:
669-
element["style"] = "primary"
670-
selected = True
671-
else:
672-
# Unselect all other buttons
673-
element.pop("style", None)
657+
[selected, blocks] = format_blocks(blocks, current_id)
674658

675659
# If selected, insert citation block before feedback
676660
if selected:
@@ -693,6 +677,27 @@ def open_citation(channel: str, timestamp: str, message: Any, params: Dict[str,
693677
logger.error(f"Error updating message for citation: {e}", extra={"error": traceback.format_exc()})
694678

695679

680+
def format_blocks(blocks: Any, current_id: str):
681+
selected = False
682+
for block in blocks:
683+
if block.get("type") == "actions":
684+
for element in block.get("elements", []):
685+
if element.get("type") == "button":
686+
action_id = element.get("action_id")
687+
if action_id == current_id:
688+
# Toggle: if already styled, unselect; else select
689+
if element.get("style") == "primary":
690+
element.pop("style", None)
691+
selected = False
692+
else:
693+
element["style"] = "primary"
694+
selected = True
695+
else:
696+
# Unselect all other buttons
697+
element.pop("style", None)
698+
return [selected, blocks]
699+
700+
696701
# ================================================================
697702
# Session management
698703
# ================================================================

packages/slackBotFunction/tests/test_slack_events.py

Lines changed: 198 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -406,7 +406,7 @@ def test_citation_creation(
406406

407407
_sourceNumber = "5"
408408
_title = "Some Title Summarising the Document"
409-
_link = "http://example.com"
409+
_link = "https://example.com"
410410
_filename = "example.pdf"
411411
_text_snippet = "This is some example text, maybe something about NHSE"
412412

@@ -866,3 +866,200 @@ def test_process_feedback_event_error(
866866

867867
# assertions
868868
mock_post_error_message.assert_called_once_with(channel="C123", thread_ts="123", client=mock_client)
869+
870+
871+
def test_process_citation_events_update_chat_message_open_citation():
872+
# set up mocks
873+
mock_client = Mock()
874+
mock_client.chat_postMessage.return_value = {"ts": "1234567890.124"}
875+
mock_client.chat_update.return_value = {"ok": True}
876+
877+
# delete and import module to test
878+
if "app.slack.slack_events" in sys.modules:
879+
del sys.modules["app.slack.slack_events"]
880+
from app.slack.slack_events import open_citation
881+
882+
params = {
883+
"ck": "123123",
884+
"ch": "123123",
885+
"mt": "123123.123123",
886+
"tt": "123123.123123",
887+
"source_number": "1",
888+
"title": "Citation Title",
889+
"body": "Citation Body",
890+
"link": "http://example.com",
891+
}
892+
893+
citations = {
894+
"type": "actions",
895+
"block_id": "citation_actions",
896+
"elements": [
897+
{
898+
"type": "button",
899+
"action_id": "cite_1",
900+
"text": {
901+
"type": "plain_text",
902+
"text": "[1] The body of the citation",
903+
"emoji": "true",
904+
},
905+
"style": None, # Set citation as de-active
906+
"value": str(params),
907+
},
908+
],
909+
}
910+
911+
message = {
912+
"blocks": [citations],
913+
}
914+
915+
# perform operation
916+
open_citation("ABC", "123", message, params, mock_client)
917+
918+
# assertions
919+
expected_blocks = [
920+
citations,
921+
{
922+
"type": "section",
923+
"text": {"type": "mrkdwn", "text": "*Citation Title*\n\n> Citation Body"},
924+
"block_id": "citation_block",
925+
},
926+
]
927+
mock_client.chat_update.assert_called()
928+
mock_client.chat_update.assert_called_with(channel="ABC", ts="123", blocks=expected_blocks)
929+
930+
931+
def test_process_citation_events_update_chat_message_close_citation():
932+
# set up mocks
933+
mock_client = Mock()
934+
mock_client.chat_postMessage.return_value = {"ts": "1234567890.124"}
935+
mock_client.chat_update.return_value = {"ok": True}
936+
937+
# delete and import module to test
938+
if "app.slack.slack_events" in sys.modules:
939+
del sys.modules["app.slack.slack_events"]
940+
from app.slack.slack_events import open_citation
941+
942+
params = {
943+
"ck": "123123",
944+
"ch": "123123",
945+
"mt": "123123.123123",
946+
"tt": "123123.123123",
947+
"source_number": "1",
948+
"title": "Citation Title",
949+
"body": "Citation Body",
950+
"link": "http://example.com",
951+
}
952+
953+
citations = {
954+
"type": "actions",
955+
"block_id": "citation_actions",
956+
"elements": [
957+
{
958+
"type": "button",
959+
"action_id": "cite_1",
960+
"text": {
961+
"type": "plain_text",
962+
"text": "[1] The body of the citation",
963+
"emoji": "true",
964+
},
965+
"style": "primary", # Set citation as active
966+
"value": str(params),
967+
},
968+
],
969+
}
970+
971+
citation_body = {
972+
"type": "section",
973+
"text": {"type": "mrkdwn", "text": "*Citation Title*\n\n> Citation Body"},
974+
"block_id": "citation_block",
975+
}
976+
977+
message = {
978+
"blocks": [citations, citation_body],
979+
}
980+
981+
# perform operation
982+
open_citation("ABC", "123", message, params, mock_client)
983+
984+
# assertions
985+
expected_blocks = [
986+
citations,
987+
]
988+
mock_client.chat_update.assert_called()
989+
mock_client.chat_update.assert_called_with(channel="ABC", ts="123", blocks=expected_blocks)
990+
991+
992+
def test_process_citation_events_update_chat_message_change_close_citation():
993+
# set up mocks
994+
mock_client = Mock()
995+
mock_client.chat_postMessage.return_value = {"ts": "1234567890.124"}
996+
mock_client.chat_update.return_value = {"ok": True}
997+
998+
# delete and import module to test
999+
if "app.slack.slack_events" in sys.modules:
1000+
del sys.modules["app.slack.slack_events"]
1001+
from app.slack.slack_events import open_citation
1002+
1003+
params = {
1004+
"ck": "123123",
1005+
"ch": "123123",
1006+
"mt": "123123.123123",
1007+
"tt": "123123.123123",
1008+
"source_number": "2",
1009+
"title": "Second Citation Title",
1010+
"body": "Second Citation Body",
1011+
"link": "http://example.com",
1012+
}
1013+
1014+
citations = {
1015+
"type": "actions",
1016+
"block_id": "citation_actions",
1017+
"elements": [
1018+
{
1019+
"type": "button",
1020+
"action_id": "cite_1",
1021+
"text": {
1022+
"type": "plain_text",
1023+
"text": "[1] The body of the citation",
1024+
"emoji": "true",
1025+
},
1026+
"style": "primary", # Set citation as active
1027+
"value": str(params),
1028+
},
1029+
{
1030+
"type": "button",
1031+
"action_id": "cite_2",
1032+
"text": {
1033+
"type": "plain_text",
1034+
"text": "[2] The body of the citation",
1035+
"emoji": "true",
1036+
},
1037+
"style": None, # Set citation as active
1038+
"value": str(params),
1039+
},
1040+
],
1041+
}
1042+
1043+
first_citation_body = {
1044+
"type": "section",
1045+
"text": {"type": "mrkdwn", "text": "*First Citation Title*\n\n> First Citation Body"},
1046+
"block_id": "citation_block",
1047+
}
1048+
1049+
second_citation_body = {
1050+
"type": "section",
1051+
"text": {"type": "mrkdwn", "text": "*Second Citation Title*\n\n> Second Citation Body"},
1052+
"block_id": "citation_block",
1053+
}
1054+
1055+
message = {
1056+
"blocks": [citations, first_citation_body],
1057+
}
1058+
1059+
# perform operation
1060+
open_citation("ABC", "123", message, params, mock_client)
1061+
1062+
# assertions
1063+
expected_blocks = [citations, second_citation_body]
1064+
mock_client.chat_update.assert_called()
1065+
mock_client.chat_update.assert_called_with(channel="ABC", ts="123", blocks=expected_blocks)

0 commit comments

Comments
 (0)