2023-10-12 19:43:45 +02:00
from typing_extensions import override
2020-02-12 23:48:55 +01:00
from zerver . lib . test_classes import WebhookTestCase
class SlackIncomingHookTests ( WebhookTestCase ) :
2021-02-12 08:20:45 +01:00
STREAM_NAME = " slack_incoming "
2020-02-12 23:48:55 +01:00
URL_TEMPLATE = " /api/v1/external/slack_incoming?&api_key= {api_key} &stream= {stream} "
2021-06-26 09:18:33 +02:00
WEBHOOK_DIR_NAME = " slack_incoming "
2020-02-12 23:48:55 +01:00
def test_message ( self ) - > None :
2024-01-17 15:53:30 +01:00
expected_topic_name = " (no topic) "
2020-02-12 23:48:55 +01:00
expected_message = """
Hello , world .
""" .strip()
2020-08-23 15:49:24 +02:00
self . check_webhook (
2021-02-12 08:19:30 +01:00
" text " ,
2024-01-17 15:53:30 +01:00
expected_topic_name ,
2021-02-12 08:19:30 +01:00
expected_message ,
2020-02-12 23:48:55 +01:00
)
2022-11-29 22:10:34 +01:00
def test_message_formatting ( self ) - > None :
tests = [
( " some *foo* word " , " some **foo** word " ) ,
( " *foo* " , " **foo** " ) ,
( " *foo* *bar* " , " **foo** **bar** " ) ,
( " *foo*a*bar* " , " *foo*a*bar* " ) ,
( " some _foo_ word " , " some *foo* word " ) ,
]
self . subscribe ( self . test_user , self . STREAM_NAME )
for input_value , output_value in tests :
payload = { " text " : input_value }
msg = self . send_webhook_payload (
self . test_user ,
self . url ,
payload ,
content_type = " application/json " ,
)
self . assert_stream_message (
message = msg ,
stream_name = self . STREAM_NAME ,
topic_name = " (no topic) " ,
content = output_value ,
)
2021-07-13 01:26:09 +02:00
def test_null_message ( self ) - > None :
self . check_webhook (
" null_text " ,
expect_noop = True ,
)
2020-02-12 23:48:55 +01:00
def test_message_as_www_urlencoded ( self ) - > None :
2024-01-17 15:53:30 +01:00
expected_topic_name = " devops "
2020-02-12 23:48:55 +01:00
expected_message = """
: zap : chris has started deploying project tag v0 .0 .2 rc10 to staging
""" .strip()
2020-08-23 15:49:24 +02:00
self . check_webhook (
" urlencoded_text " ,
2024-01-17 15:53:30 +01:00
expected_topic_name ,
2020-02-12 23:48:55 +01:00
expected_message ,
python: Use trailing commas consistently.
Automatically generated by the following script, based on the output
of lint with flake8-comma:
import re
import sys
last_filename = None
last_row = None
lines = []
for msg in sys.stdin:
m = re.match(
r"\x1b\[35mflake8 \|\x1b\[0m \x1b\[1;31m(.+):(\d+):(\d+): (\w+)", msg
)
if m:
filename, row_str, col_str, err = m.groups()
row, col = int(row_str), int(col_str)
if filename == last_filename:
assert last_row != row
else:
if last_filename is not None:
with open(last_filename, "w") as f:
f.writelines(lines)
with open(filename) as f:
lines = f.readlines()
last_filename = filename
last_row = row
line = lines[row - 1]
if err in ["C812", "C815"]:
lines[row - 1] = line[: col - 1] + "," + line[col - 1 :]
elif err in ["C819"]:
assert line[col - 2] == ","
lines[row - 1] = line[: col - 2] + line[col - 1 :].lstrip(" ")
if last_filename is not None:
with open(last_filename, "w") as f:
f.writelines(lines)
Signed-off-by: Anders Kaseorg <anders@zulipchat.com>
2020-04-10 05:23:40 +02:00
content_type = " application/x-www-form-urlencoded " ,
2020-02-12 23:48:55 +01:00
)
2022-04-24 09:32:05 +02:00
def test_message_without_payload ( self ) - > None :
self . url = self . build_webhook_url ( )
2022-07-05 21:28:29 +02:00
result = self . client_post ( self . url )
2022-04-24 09:32:05 +02:00
self . assert_json_error ( result , " Missing ' payload ' argument " )
2020-02-12 23:48:55 +01:00
def test_message_with_actions ( self ) - > None :
2024-01-17 15:53:30 +01:00
expected_topic_name = " C1H9RESGL "
2020-02-12 23:48:55 +01:00
expected_message = """
2021-06-24 16:44:49 +02:00
Danny Torrence left the following * review * for your property :
2020-02-12 23:48:55 +01:00
[ Overlook Hotel ] ( https : / / google . com ) \n : star : \n Doors had too many axe holes , guest in room 237 was far too rowdy , whole place felt stuck in the 1920 s .
2022-06-17 01:11:12 +02:00
2020-02-12 23:48:55 +01:00
[ Haunted hotel image ] ( https : / / is5 - ssl . mzstatic . com / image / thumb / Purple3 / v4 / d3 / 72 / 5 c / d3725c8f - c642 - 5 d69 - 1904 - aa36e4297885 / source / 256 x256bb . jpg )
2023-01-04 21:08:26 +01:00
* * Average Rating * *
1.0
2020-02-12 23:48:55 +01:00
""" .strip()
2020-08-23 15:49:24 +02:00
self . check_webhook (
2021-02-12 08:19:30 +01:00
" actions " ,
2024-01-17 15:53:30 +01:00
expected_topic_name ,
2021-02-12 08:19:30 +01:00
expected_message ,
2020-02-12 23:48:55 +01:00
)
def test_message_with_blocks ( self ) - > None :
2024-01-17 15:53:30 +01:00
expected_topic_name = " (no topic) "
2020-02-12 23:48:55 +01:00
expected_message = """
Danny Torrence left the following review for your property :
[ Overlook Hotel ] ( https : / / example . com ) \n : star : \n Doors had too many axe holes , guest in room 237 was far too rowdy , whole place felt stuck in the 1920 s .
2022-06-17 01:11:12 +02:00
2020-02-12 23:48:55 +01:00
[ Haunted hotel image ] ( https : / / is5 - ssl . mzstatic . com / image / thumb / Purple3 / v4 / d3 / 72 / 5 c / d3725c8f - c642 - 5 d69 - 1904 - aa36e4297885 / source / 256 x256bb . jpg )
2023-01-04 21:08:26 +01:00
* * Average Rating * *
1.0
2020-02-12 23:48:55 +01:00
""" .strip()
2020-08-23 15:49:24 +02:00
self . check_webhook (
2021-02-12 08:19:30 +01:00
" blocks " ,
2024-01-17 15:53:30 +01:00
expected_topic_name ,
2021-02-12 08:19:30 +01:00
expected_message ,
2020-02-12 23:48:55 +01:00
)
def test_message_with_attachment ( self ) - > None :
2024-01-17 15:53:30 +01:00
expected_topic_name = " prometheus-alerts "
2020-02-12 23:48:55 +01:00
expected_message = """
2022-06-17 01:11:12 +02:00
## [[FIRING:2] InstanceDown for api-server (env="prod", severity="critical")](https://alertmanager.local//#/alerts?receiver=default)
2020-02-12 23:48:55 +01:00
: chart_with_upwards_trend : * * [ Graph ] ( http : / / generator . local / 1 ) * * : notebook : * * [ Runbook ] ( https : / / runbook . local / 1 ) * *
* * Alert details * * :
* * Alert : * * api - server down - ` critical `
* * Description : * * api - server at 1.2 .3 .4 : 8080 couldn ' t be scraped **Details:**
• * * alertname : * * ` InstanceDown `
• * * env : * * ` prod `
• * * instance : * * ` 1.2 .3 .4 : 8080 `
• * * job : * * ` api - server `
• * * severity : * * ` critical `
* * Alert : * * api - server down - ` critical `
* * Description : * * api - server at 1.2 .3 .4 : 8081 couldn ' t be scraped **Details:**
• * * alertname : * * ` InstanceDown `
• * * env : * * ` prod `
• * * instance : * * ` 1.2 .3 .4 : 8081 `
• * * job : * * ` api - server `
• * * severity : * * ` critical `
""" .strip()
2020-08-23 15:49:24 +02:00
self . check_webhook (
2021-02-12 08:19:30 +01:00
" attachment " ,
2024-01-17 15:53:30 +01:00
expected_topic_name ,
2021-02-12 08:19:30 +01:00
expected_message ,
2020-02-12 23:48:55 +01:00
)
2022-06-17 01:11:12 +02:00
def test_complicated ( self ) - > None :
# Paste the JSON into
# https://api.slack.com/tools/block-kit-builder to see how it
# is rendered in Slack
2024-01-17 15:53:30 +01:00
expected_topic_name = " (no topic) "
2022-06-17 01:11:12 +02:00
expected_message = """
## Hello from TaskBot
Hey there 👋 I ' m TaskBot. I ' m here to help you create and manage tasks in Slack .
There are two ways to quickly create tasks :
* * 1 ️ ⃣ Use the ` / task ` command * * . Type ` / task ` followed by a short description of your tasks and I ' ll ask for a due date (if applicable). Try it out by using the `/task` command in this channel.
* * 2 ️ ⃣ Use the * Create a Task * action . * * If you want to create a task from a message , select ` Create a Task ` in a message ' s context menu. Try it out by selecting the *Create a Task* action for this message (shown below).
[ image1 ] ( https : / / api . slack . com / img / blocks / bkb_template_images / onboardingComplex . jpg )
➕ To start tracking your team ' s tasks, **add me to a channel** and I ' ll introduce myself . I ' m usually added to a team or project channel. Type `/invite @TaskBot` from the channel or pick a channel on the right.
- - - -
[ cute cat ] ( https : / / pbs . twimg . com / profile_images / 625633822235693056 / lNGUneLX_400x400 . jpg )
👀 View all tasks with ` / task list `
❓ Get help at any time with :
- ` / task help ` , or
- type * * help * * in a DM with me
""" .strip()
self . check_webhook (
" complicated " ,
2024-01-17 15:53:30 +01:00
expected_topic_name ,
2022-06-17 01:11:12 +02:00
expected_message ,
)
def test_attachment_blocks ( self ) - > None :
# On https://api.slack.com/tools/block-kit-builder choose
# "Attachment preview" and paste the JSON in.
2024-01-17 15:53:30 +01:00
expected_topic_name = " (no topic) "
2022-06-17 01:11:12 +02:00
expected_message = """
This is a section block with an accessory image .
[ cute cat ] ( https : / / pbs . twimg . com / profile_images / 625633822235693056 / lNGUneLX_400x400 . jpg )
This is a section block with a button .
2023-01-04 21:08:26 +01:00
| | |
| - | - |
| one | two |
| three | four |
| five | |
2022-06-17 01:11:12 +02:00
""" .strip()
self . check_webhook (
" attachment_blocks " ,
2024-01-17 15:53:30 +01:00
expected_topic_name ,
2022-06-17 01:11:12 +02:00
expected_message ,
)
def test_attachment_fields ( self ) - > None :
2024-01-17 15:53:30 +01:00
expected_topic_name = " (no topic) "
2022-06-17 01:11:12 +02:00
expected_message = """
Build bla bla succeeded
* * Requested by * * : Some user
* * Duration * * : 00 : 02 : 03
* * Build pipeline * * : ConsumerAddressModule
2022-11-29 22:11:07 +01:00
* * Title with null value * *
2022-08-16 21:53:31 +02:00
* * Title without value * *
2022-11-29 22:11:07 +01:00
Value with null title
2022-08-16 21:53:31 +02:00
Value without title
2022-06-17 01:11:12 +02:00
""" .strip()
self . check_webhook (
" attachment_fields " ,
2024-01-17 15:53:30 +01:00
expected_topic_name ,
2022-06-17 01:11:12 +02:00
expected_message ,
)
def test_attachment_pieces ( self ) - > None :
2024-01-17 15:53:30 +01:00
expected_topic_name = " (no topic) "
2022-06-17 01:11:12 +02:00
expected_message = """
## Test
[ ] ( https : / / pbs . twimg . com / profile_images / 625633822235693056 / lNGUneLX_400x400 . jpg )
< time : 1655945306 >
""" .strip()
self . check_webhook (
" attachment_pieces " ,
2024-01-17 15:53:30 +01:00
expected_topic_name ,
2022-06-17 01:11:12 +02:00
expected_message ,
)
2023-10-12 19:43:45 +02:00
@override
2020-02-12 23:48:55 +01:00
def get_body ( self , fixture_name : str ) - > str :
if " urlencoded " in fixture_name :
file_type = " txt "
else :
file_type = " json "
return self . webhook_fixture_data ( " slack_incoming " , fixture_name , file_type = file_type )
2022-08-16 21:53:31 +02:00
def test_attachment_pieces_title_null ( self ) - > None :
2024-01-17 15:53:30 +01:00
expected_topic_name = " (no topic) "
2022-08-16 21:53:31 +02:00
expected_message = """
Sample pretext .
Sample text .
[ ] ( https : / / pbs . twimg . com / profile_images / 625633822235693056 / lNGUneLX_400x400 . jpg )
Sample footer .
< time : 1655945306 >
""" .strip()
self . check_webhook (
" attachment_pieces_title_null " ,
2024-01-17 15:53:30 +01:00
expected_topic_name ,
2022-08-16 21:53:31 +02:00
expected_message ,
)
def test_attachment_pieces_image_url_null ( self ) - > None :
2024-01-17 15:53:30 +01:00
expected_topic_name = " (no topic) "
2022-08-16 21:53:31 +02:00
expected_message = """
## [Sample title.](https://www.google.com)
Sample pretext .
Sample text .
Sample footer .
< time : 1655945306 >
""" .strip()
self . check_webhook (
" attachment_pieces_image_url_null " ,
2024-01-17 15:53:30 +01:00
expected_topic_name ,
2022-08-16 21:53:31 +02:00
expected_message ,
)
def test_attachment_pieces_ts_null ( self ) - > None :
2024-01-17 15:53:30 +01:00
expected_topic_name = " (no topic) "
2022-08-16 21:53:31 +02:00
expected_message = """
## [Sample title.](https://www.google.com)
Sample pretext .
Sample text .
[ ] ( https : / / pbs . twimg . com / profile_images / 625633822235693056 / lNGUneLX_400x400 . jpg )
Sample footer .
""" .strip()
self . check_webhook (
" attachment_pieces_ts_null " ,
2024-01-17 15:53:30 +01:00
expected_topic_name ,
2022-08-16 21:53:31 +02:00
expected_message ,
)
def test_attachment_pieces_text_null ( self ) - > None :
2024-01-17 15:53:30 +01:00
expected_topic_name = " (no topic) "
2022-08-16 21:53:31 +02:00
expected_message = """
## [Sample title.](https://www.google.com)
Sample pretext .
[ ] ( https : / / pbs . twimg . com / profile_images / 625633822235693056 / lNGUneLX_400x400 . jpg )
Sample footer .
< time : 1655945306 >
""" .strip()
self . check_webhook (
" attachment_pieces_text_null " ,
2024-01-17 15:53:30 +01:00
expected_topic_name ,
2022-08-16 21:53:31 +02:00
expected_message ,
)
def test_attachment_pieces_pretext_null ( self ) - > None :
2024-01-17 15:53:30 +01:00
expected_topic_name = " (no topic) "
2022-08-16 21:53:31 +02:00
expected_message = """
## [Sample title.](https://www.google.com)
Sample text .
[ ] ( https : / / pbs . twimg . com / profile_images / 625633822235693056 / lNGUneLX_400x400 . jpg )
Sample footer .
< time : 1655945306 >
""" .strip()
self . check_webhook (
" attachment_pieces_pretext_null " ,
2024-01-17 15:53:30 +01:00
expected_topic_name ,
2022-08-16 21:53:31 +02:00
expected_message ,
)
def test_attachment_pieces_footer_null ( self ) - > None :
2024-01-17 15:53:30 +01:00
expected_topic_name = " (no topic) "
2022-08-16 21:53:31 +02:00
expected_message = """
## [Sample title.](https://www.google.com)
Sample pretext .
Sample text .
[ ] ( https : / / pbs . twimg . com / profile_images / 625633822235693056 / lNGUneLX_400x400 . jpg )
< time : 1655945306 >
""" .strip()
self . check_webhook (
" attachment_pieces_footer_null " ,
2024-01-17 15:53:30 +01:00
expected_topic_name ,
2022-08-16 21:53:31 +02:00
expected_message ,
)
def test_attachment_pieces_title_link_null ( self ) - > None :
2024-01-17 15:53:30 +01:00
expected_topic_name = " (no topic) "
2022-08-16 21:53:31 +02:00
expected_message = """
## Sample title.
Sample pretext .
Sample text .
[ ] ( https : / / pbs . twimg . com / profile_images / 625633822235693056 / lNGUneLX_400x400 . jpg )
Sample footer .
< time : 1655945306 >
""" .strip()
self . check_webhook (
" attachment_pieces_title_link_null " ,
2024-01-17 15:53:30 +01:00
expected_topic_name ,
2022-08-16 21:53:31 +02:00
expected_message ,
)
def test_attachment_pieces_all_null ( self ) - > None :
self . check_webhook ( " attachment_pieces_all_null " , expect_noop = True )