afterhours-shift-manager/tests/slack_bot/test_handler.py
Adam Moussa 9544dd696a
fix(slack-bot): return 400 on malformed request bodies (#254)
Bolt parse_body raises JSONDecodeError for empty or non-JSON form
payload fields, which turned probe POSTs into unhandled Lambda 500s.

Fixes AFTERHOURS-SHIFT-MANAGER-2
2026-09-16 16:37:54 +00:00

76 lines
2.2 KiB
Python

"""Slack-bot Lambda handler: malformed bodies return 400, not 500."""
import json
from types import SimpleNamespace
import pytest
from slack_bolt.request.internals import parse_body
def _context():
return SimpleNamespace(
function_name="afterhours-shift-manager",
invoked_function_arn="arn:aws:lambda:us-east-1:1:function:x",
)
def _event(body, content_type, user_agent="Python-urllib/3.12"):
return {
"version": "2.0",
"routeKey": "POST /slack/events",
"rawPath": "/slack/events",
"headers": {
"content-type": content_type,
"user-agent": user_agent,
},
"requestContext": {"http": {"method": "POST", "path": "/slack/events"}},
"body": body,
"isBase64Encoded": False,
"queryStringParameters": {},
}
def test_parse_body_empty_payload_raises():
with pytest.raises(json.JSONDecodeError):
parse_body("payload=", "application/x-www-form-urlencoded")
def test_parse_body_non_json_payload_raises():
with pytest.raises(json.JSONDecodeError):
parse_body("payload=not-json", "application/x-www-form-urlencoded")
def test_empty_form_payload_returns_400(slackbot_handler):
result = slackbot_handler.handler(
_event("payload=", "application/x-www-form-urlencoded"), _context()
)
assert result["statusCode"] == 400
assert result["body"] == "invalid request"
def test_non_json_form_payload_returns_400(slackbot_handler):
result = slackbot_handler.handler(
_event("payload=not-json", "application/x-www-form-urlencoded"),
_context(),
)
assert result["statusCode"] == 400
assert result["body"] == "invalid request"
def test_payload_substring_without_form_key_is_unsigned(slackbot_handler):
result = slackbot_handler.handler(
_event("hello payload world", "text/plain"), _context()
)
assert result["statusCode"] in (401, 403)
def test_json_events_body_is_unsigned_not_jsondecode(slackbot_handler):
result = slackbot_handler.handler(
_event(
'{"type":"url_verification","challenge":"abc"}',
"application/json",
user_agent="Slackbot 1.0",
),
_context(),
)
assert result["statusCode"] in (401, 403)