Skip to content

Commit 7d861ff

Browse files
committed
more types
1 parent fd6298a commit 7d861ff

File tree

8 files changed

+283
-105
lines changed

8 files changed

+283
-105
lines changed

packages/slackBotFunction/app/services/dynamo.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,9 @@ def store_state_information(item: dict[str, Any], condition: str = None) -> None
5454
)
5555

5656

57-
def update_state_information(key: str, update_expression: str, expression_attribute_values: dict[str, Any]) -> None:
57+
def update_state_information(
58+
key: dict[str, Any], update_expression: str, expression_attribute_values: dict[str, Any]
59+
) -> None:
5860
start_time = time()
5961
table = get_slack_bot_state_table()
6062
is_success = True

packages/slackBotFunction/app/slack/slack_events.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -422,7 +422,7 @@ def get_conversation_session_data(conversation_key: str) -> Dict[str, Any]:
422422
return None
423423

424424

425-
def get_latest_message_ts(conversation_key: str) -> str:
425+
def get_latest_message_ts(conversation_key: str) -> str | None:
426426
"""
427427
Get latest message timestamp from session
428428
"""

packages/slackBotFunction/tests/test_async_processing.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -164,7 +164,7 @@ def test_process_async_slack_event_with_thread_ts(
164164
"event_id": "evt123",
165165
"bot_token": "bot-token",
166166
}
167-
process_async_slack_event(slack_event_data)
167+
process_async_slack_event(slack_event_data=slack_event_data)
168168

169169
# assertions
170170
# Should be called at least once with the correct thread_ts

packages/slackBotFunction/tests/test_handler_utils.py

Lines changed: 108 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
import sys
22
from unittest.mock import Mock, patch
3+
from slack_sdk.errors import SlackApiError
4+
from botocore.exceptions import ClientError
35

46

57
@patch("app.services.dynamo.get_state_information")
@@ -211,3 +213,109 @@ def test_extract_key_and_root(mock_env: Mock):
211213
# assertions
212214
assert key == "dm#D123"
213215
assert root == "456"
216+
217+
218+
@patch("slack_sdk.WebClient")
219+
def test_respond_with_eyes_on_success(mock_webclient: Mock, mock_env: Mock):
220+
"""Test that respond with eyes"""
221+
# set up mocks
222+
mock_client = Mock()
223+
mock_client.reactions_add.return_value = {"success"}
224+
mock_webclient.return_value = mock_client
225+
226+
# delete and import module to test
227+
if "app.utils.handler_utils" in sys.modules:
228+
del sys.modules["app.utils.handler_utils"]
229+
from app.slack.slack_handlers import respond_with_eyes
230+
231+
# perform operation
232+
event = {"channel": "D123", "ts": "456", "channel_type": "im"}
233+
respond_with_eyes("dummy_token", event)
234+
235+
# assertions
236+
# just need to make sure it does not error
237+
238+
239+
@patch("slack_sdk.WebClient")
240+
def test_respond_with_eyes_on_failure(mock_webclient: Mock, mock_env: Mock):
241+
"""Test that respond with eyes"""
242+
# set up mocks
243+
mock_client = Mock()
244+
mock_client.reactions_add.side_effect = SlackApiError("There was a problem", 500)
245+
mock_webclient.return_value = mock_client
246+
247+
# delete and import module to test
248+
if "app.utils.handler_utils" in sys.modules:
249+
del sys.modules["app.utils.handler_utils"]
250+
from app.slack.slack_handlers import respond_with_eyes
251+
252+
# perform operation
253+
event = {"channel": "D123", "ts": "456", "channel_type": "im"}
254+
respond_with_eyes("dummy_token", event)
255+
256+
# assertions
257+
# just need to make sure it does not error
258+
259+
260+
@patch("app.services.dynamo.store_state_information")
261+
def test_is_duplicate_event_returns_true_when_conditional_check_fails(
262+
mock_store_state_information: Mock,
263+
mock_env: Mock,
264+
):
265+
"""Test duplicate event detection with conditional put"""
266+
# set up mocks
267+
error = ClientError(error_response={"Error": {"Code": "ConditionalCheckFailedException"}}, operation_name="PutItem")
268+
mock_store_state_information.side_effect = error
269+
270+
# delete and import module to test
271+
if "app.utils.handler_utils" in sys.modules:
272+
del sys.modules["app.utils.handler_utils"]
273+
from app.utils.handler_utils import is_duplicate_event
274+
275+
# perform operation
276+
result = is_duplicate_event("test-event")
277+
278+
# assertions
279+
assert result is True
280+
281+
282+
@patch("app.services.dynamo.store_state_information")
283+
def test_is_duplicate_event_client_error(
284+
mock_store_state_information: Mock,
285+
mock_env: Mock,
286+
):
287+
"""Test is_duplicate_event handles other ClientError"""
288+
# set up mocks
289+
error = ClientError(error_response={"Error": {"Code": "SomeOtherError"}}, operation_name="PutItem")
290+
mock_store_state_information.side_effect = error
291+
292+
# delete and import module to test
293+
if "app.utils.handler_utils" in sys.modules:
294+
del sys.modules["app.utils.handler_utils"]
295+
from app.utils.handler_utils import is_duplicate_event
296+
297+
# perform operation
298+
result = is_duplicate_event("test-event")
299+
300+
# assertions
301+
assert result is False
302+
303+
304+
@patch("app.services.dynamo.store_state_information")
305+
def test_is_duplicate_event_no_item(
306+
mock_store_state_information: Mock,
307+
mock_env: Mock,
308+
):
309+
"""Test is_duplicate_event when no item exists (successful put)"""
310+
# set up mocks
311+
312+
# delete and import module to test
313+
if "app.utils.handler_utils" in sys.modules:
314+
del sys.modules["app.utils.handler_utils"]
315+
from app.utils.handler_utils import is_duplicate_event
316+
317+
# perform operation
318+
result = is_duplicate_event("test-event")
319+
320+
# assertions
321+
assert result is False

packages/slackBotFunction/tests/test_handlers.py

Lines changed: 48 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,6 @@ def test_handler_async_processing(
3636
):
3737
"""Test Lambda handler function for async processing"""
3838
# set up mocks
39-
mock_process_async_slack_event.return_value = {"statusCode": 200}
4039

4140
# delete and import module to test
4241
if "app.handler" in sys.modules:
@@ -45,11 +44,10 @@ def test_handler_async_processing(
4544

4645
# perform operation
4746
event = {"async_processing": True, "slack_event": {"body": "test event"}}
48-
result = handler(event, lambda_context)
47+
handler(event, lambda_context)
4948

5049
# assertions
5150
mock_process_async_slack_event.assert_called_once()
52-
assert result["statusCode"] == 200
5351

5452

5553
def test_handler_async_processing_missing_slack_event(
@@ -73,3 +71,50 @@ def test_handler_async_processing_missing_slack_event(
7371
assert isinstance(result, dict)
7472
assert "statusCode" in result
7573
assert result["statusCode"] == 400
74+
75+
76+
@patch("app.slack.slack_events.process_pull_request_slack_event")
77+
def test_handler_pull_request_processing(
78+
mock_process_pull_request_slack_event: Mock,
79+
mock_get_parameter: Mock,
80+
mock_slack_app: Mock,
81+
mock_env: Mock,
82+
lambda_context: Mock,
83+
):
84+
"""Test Lambda handler function for pull request processing"""
85+
# set up mocks
86+
87+
# delete and import module to test
88+
if "app.handler" in sys.modules:
89+
del sys.modules["app.handler"]
90+
from app.handler import handler
91+
92+
# perform operation
93+
event = {"pull_request_processing": True, "slack_event": {"body": "test event"}}
94+
handler(event, lambda_context)
95+
96+
# assertions
97+
mock_process_pull_request_slack_event.assert_called_once()
98+
99+
100+
def test_handler_pull_request_processing_missing_slack_event(
101+
mock_slack_app: Mock, mock_env: Mock, mock_get_parameter: Mock, lambda_context: Mock
102+
):
103+
"""Test Lambda handler function for async processing without slack_event data"""
104+
# set up mocks
105+
106+
# delete and import module to test
107+
if "app.handler" in sys.modules:
108+
del sys.modules["app.handler"]
109+
from app.handler import handler
110+
111+
# perform operation
112+
# Test async processing without slack_event - should return 400
113+
event = {"pull_request_processing": True} # Missing slack_event
114+
result = handler(event, lambda_context)
115+
116+
# assertions
117+
# Check that result is a dict with statusCode
118+
assert isinstance(result, dict)
119+
assert "statusCode" in result
120+
assert result["statusCode"] == 400
Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
import sys
2+
from unittest.mock import Mock, patch
3+
4+
5+
@patch("app.utils.handler_utils.is_duplicate_event")
6+
@patch("app.utils.handler_utils.extract_pull_request_id")
7+
def test_process_pull_request_event(mock_extract_pull_request_id: Mock, mock_is_duplicate_event: Mock, mock_env: Mock):
8+
# set up mocks
9+
mock_is_duplicate_event.return_value = False
10+
mock_extract_pull_request_id.return_value = None, "test question"
11+
12+
# delete and import module to test
13+
if "app.slack.slack_events" in sys.modules:
14+
del sys.modules["app.slack.slack_events"]
15+
from app.slack.slack_events import process_pull_request_slack_event
16+
17+
# perform operation
18+
# patching process_async_slack_event here as its in the same module we are testing
19+
with patch("app.slack.slack_events.process_async_slack_event") as mock_process_async_slack_event:
20+
slack_event_data = {
21+
"event": {
22+
"text": "pr: 60 test question",
23+
"user": "U456",
24+
"channel": "C789",
25+
"ts": "1234567890.123",
26+
"thread_ts": "1234567888.111", # Existing thread
27+
},
28+
"event_id": "evt123",
29+
}
30+
process_pull_request_slack_event(slack_event_data)
31+
32+
# assertions
33+
expected_slack_event_data = {
34+
"event": {
35+
"text": "test question",
36+
"user": "U456",
37+
"channel": "C789",
38+
"ts": "1234567890.123",
39+
"thread_ts": "1234567888.111", # Existing thread
40+
},
41+
"event_id": "evt123",
42+
}
43+
mock_process_async_slack_event.assert_called_once_with(slack_event_data=expected_slack_event_data)
44+
45+
46+
@patch("app.utils.handler_utils.is_duplicate_event")
47+
@patch("app.utils.handler_utils.extract_pull_request_id")
48+
def test_process_pull_request_duplicate_event(
49+
mock_extract_pull_request_id: Mock, mock_is_duplicate_event: Mock, mock_env: Mock
50+
):
51+
# set up mocks
52+
mock_is_duplicate_event.return_value = True
53+
54+
# delete and import module to test
55+
if "app.slack.slack_events" in sys.modules:
56+
del sys.modules["app.slack.slack_events"]
57+
from app.slack.slack_events import process_pull_request_slack_event
58+
59+
# perform operation
60+
slack_event_data = {
61+
"event": {
62+
"text": "pr: 60 test question",
63+
"user": "U456",
64+
"channel": "C789",
65+
"ts": "1234567890.123",
66+
"thread_ts": "1234567888.111", # Existing thread
67+
},
68+
"event_id": "evt123",
69+
}
70+
process_pull_request_slack_event(slack_event_data)
71+
72+
# assertions
73+
mock_extract_pull_request_id.assert_not_called()

packages/slackBotFunction/tests/test_state_management.py

Lines changed: 0 additions & 99 deletions
This file was deleted.

0 commit comments

Comments
 (0)