X Tutup
Skip to content

Commit a035652

Browse files
committed
Add Sanic tests
1 parent 9d2dfbb commit a035652

File tree

1 file changed

+194
-0
lines changed

1 file changed

+194
-0
lines changed
Lines changed: 194 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,194 @@
1+
import json
2+
import re
3+
from time import time
4+
from urllib.parse import quote
5+
6+
from slack_sdk.signature import SignatureVerifier
7+
from slack_sdk.web.async_client import AsyncWebClient
8+
from sanic import Sanic
9+
from sanic.request import Request
10+
11+
from slack_bolt.adapter.sanic.async_handler import AsyncSlackRequestHandler
12+
from slack_bolt.app.async_app import AsyncApp
13+
from slack_bolt.oauth.async_oauth_settings import AsyncOAuthSettings
14+
from tests.mock_web_api_server import (
15+
setup_mock_web_api_server,
16+
cleanup_mock_web_api_server,
17+
)
18+
from tests.utils import remove_os_env_temporarily, restore_os_env
19+
20+
21+
class TestSanic:
22+
signing_secret = "secret"
23+
valid_token = "xoxb-valid"
24+
mock_api_server_base_url = "http://localhost:8888"
25+
signature_verifier = SignatureVerifier(signing_secret)
26+
web_client = AsyncWebClient(token=valid_token, base_url=mock_api_server_base_url,)
27+
28+
def setup_method(self):
29+
self.old_os_env = remove_os_env_temporarily()
30+
setup_mock_web_api_server(self)
31+
32+
def teardown_method(self):
33+
cleanup_mock_web_api_server(self)
34+
restore_os_env(self.old_os_env)
35+
36+
def generate_signature(self, body: str, timestamp: str):
37+
return self.signature_verifier.generate_signature(
38+
body=body, timestamp=timestamp,
39+
)
40+
41+
def build_headers(self, timestamp: str, body: str):
42+
content_type = (
43+
"application/json"
44+
if body.startswith("{")
45+
else "application/x-www-form-urlencoded"
46+
)
47+
return {
48+
"content-type": content_type,
49+
"x-slack-signature": self.generate_signature(body, timestamp),
50+
"x-slack-request-timestamp": timestamp,
51+
}
52+
53+
def test_events(self):
54+
app = AsyncApp(client=self.web_client, signing_secret=self.signing_secret,)
55+
56+
async def event_handler():
57+
pass
58+
59+
app.event("app_mention")(event_handler)
60+
61+
input = {
62+
"token": "verification_token",
63+
"team_id": "T111",
64+
"enterprise_id": "E111",
65+
"api_app_id": "A111",
66+
"event": {
67+
"client_msg_id": "9cbd4c5b-7ddf-4ede-b479-ad21fca66d63",
68+
"type": "app_mention",
69+
"text": "<@W111> Hi there!",
70+
"user": "W222",
71+
"ts": "1595926230.009600",
72+
"team": "T111",
73+
"channel": "C111",
74+
"event_ts": "1595926230.009600",
75+
},
76+
"type": "event_callback",
77+
"event_id": "Ev111",
78+
"event_time": 1595926230,
79+
"authed_users": ["W111"],
80+
}
81+
timestamp, body = str(int(time())), json.dumps(input)
82+
83+
api = Sanic(name="awesome-slack-app")
84+
app_handler = AsyncSlackRequestHandler(app)
85+
86+
@api.post("/slack/events")
87+
async def endpoint(req: Request):
88+
return await app_handler.handle(req)
89+
90+
_, response = api.test_client.post(
91+
uri="/slack/events", data=body, headers=self.build_headers(timestamp, body),
92+
)
93+
assert response.status_code == 200
94+
assert self.mock_received_requests["/auth.test"] == 1
95+
96+
def test_shortcuts(self):
97+
app = AsyncApp(client=self.web_client, signing_secret=self.signing_secret,)
98+
99+
async def shortcut_handler(ack):
100+
await ack()
101+
102+
app.shortcut("test-shortcut")(shortcut_handler)
103+
104+
input = {
105+
"type": "shortcut",
106+
"token": "verification_token",
107+
"action_ts": "111.111",
108+
"team": {
109+
"id": "T111",
110+
"domain": "workspace-domain",
111+
"enterprise_id": "E111",
112+
"enterprise_name": "Org Name",
113+
},
114+
"user": {"id": "W111", "username": "primary-owner", "team_id": "T111"},
115+
"callback_id": "test-shortcut",
116+
"trigger_id": "111.111.xxxxxx",
117+
}
118+
119+
timestamp, body = str(int(time())), f"payload={quote(json.dumps(input))}"
120+
121+
api = Sanic(name="awesome-slack-app")
122+
app_handler = AsyncSlackRequestHandler(app)
123+
124+
@api.post("/slack/events")
125+
async def endpoint(req: Request):
126+
return await app_handler.handle(req)
127+
128+
_, response = api.test_client.post(
129+
"/slack/events", data=body, headers=self.build_headers(timestamp, body),
130+
)
131+
assert response.status_code == 200
132+
assert self.mock_received_requests["/auth.test"] == 1
133+
134+
def test_commands(self):
135+
app = AsyncApp(client=self.web_client, signing_secret=self.signing_secret,)
136+
137+
async def command_handler(ack):
138+
await ack()
139+
140+
app.command("/hello-world")(command_handler)
141+
142+
input = (
143+
"token=verification_token"
144+
"&team_id=T111"
145+
"&team_domain=test-domain"
146+
"&channel_id=C111"
147+
"&channel_name=random"
148+
"&user_id=W111"
149+
"&user_name=primary-owner"
150+
"&command=%2Fhello-world"
151+
"&text=Hi"
152+
"&enterprise_id=E111"
153+
"&enterprise_name=Org+Name"
154+
"&response_url=https%3A%2F%2Fhooks.slack.com%2Fcommands%2FT111%2F111%2Fxxxxx"
155+
"&trigger_id=111.111.xxx"
156+
)
157+
timestamp, body = str(int(time())), input
158+
159+
api = Sanic(name="awesome-slack-app")
160+
app_handler = AsyncSlackRequestHandler(app)
161+
162+
@api.post("/slack/events")
163+
async def endpoint(req: Request):
164+
return await app_handler.handle(req)
165+
166+
_, response = api.test_client.post(
167+
"/slack/events", data=body, headers=self.build_headers(timestamp, body),
168+
)
169+
assert response.status_code == 200
170+
assert self.mock_received_requests["/auth.test"] == 1
171+
172+
def test_oauth(self):
173+
app = AsyncApp(
174+
client=self.web_client,
175+
signing_secret=self.signing_secret,
176+
oauth_settings=AsyncOAuthSettings(
177+
client_id="111.111",
178+
client_secret="xxx",
179+
scopes=["chat:write", "commands"],
180+
),
181+
)
182+
api = Sanic(name="awesome-slack-app")
183+
app_handler = AsyncSlackRequestHandler(app)
184+
185+
@api.get("/slack/install")
186+
async def endpoint(req: Request):
187+
return await app_handler.handle(req)
188+
189+
_, response = api.test_client.get("/slack/install", allow_redirects=False)
190+
assert response.status_code == 302
191+
assert re.match(
192+
"https://slack.com/oauth/v2/authorize\\?state=[^&]+&client_id=111.111&scope=chat:write,commands&user_scope=",
193+
response.headers["Location"],
194+
)

0 commit comments

Comments
 (0)
X Tutup