def test_uninstallation_and_revokes(self): app = App(client=self.web_client, signing_secret=self.signing_secret) app._client = WebClient(token="uninstalled-revoked", base_url=self.mock_api_server_base_url) @app.event("app_uninstalled") def handler1(say: Say): say(channel="C111", text="What's up?") @app.event("tokens_revoked") def handler2(say: Say): say(channel="C111", text="What's up?") app_uninstalled_body = { "token": "verification_token", "team_id": "T111", "enterprise_id": "E111", "api_app_id": "A111", "event": { "type": "app_uninstalled" }, "type": "event_callback", "event_id": "Ev111", "event_time": 1599616881, } timestamp, body = str(int(time())), json.dumps(app_uninstalled_body) request: BoltRequest = BoltRequest(body=body, headers=self.build_headers( timestamp, body)) response = app.dispatch(request) assert response.status == 200 tokens_revoked_body = { "token": "verification_token", "team_id": "T111", "enterprise_id": "E111", "api_app_id": "A111", "event": { "type": "tokens_revoked", "tokens": { "oauth": ["UXXXXXXXX"], "bot": ["UXXXXXXXX"] }, }, "type": "event_callback", "event_id": "Ev111", "event_time": 1599616881, } timestamp, body = str(int(time())), json.dumps(tokens_revoked_body) request: BoltRequest = BoltRequest(body=body, headers=self.build_headers( timestamp, body)) response = app.dispatch(request) assert response.status == 200 assert_auth_test_count(self, 1) sleep(1) # wait a bit after auto ack() assert self.mock_received_requests["/chat.postMessage"] == 2
def test_commands(self): app = App( client=self.web_client, signing_secret=self.signing_secret, ) def command_handler(ack): ack() app.command("/hello-world")(command_handler) input = ( "token=verification_token" "&team_id=T111" "&team_domain=test-domain" "&channel_id=C111" "&channel_name=random" "&user_id=W111" "&user_name=primary-owner" "&command=%2Fhello-world" "&text=Hi" "&enterprise_id=E111" "&enterprise_name=Org+Name" "&response_url=https%3A%2F%2Fhooks.slack.com%2Fcommands%2FT111%2F111%2Fxxxxx" "&trigger_id=111.111.xxx") timestamp, body = str(int(time())), input request: Request = testing.DummyRequest() request.path = "/slack/events" request.method = "POST" request.body = body.encode("utf-8") request.headers = self.build_headers(timestamp, body) response: Response = SlackRequestHandler(app).handle(request) assert response.status_code == 200 assert_auth_test_count(self, 1)
async def test_events(self): input = { "token": "verification_token", "team_id": "T111", "enterprise_id": "E111", "api_app_id": "A111", "event": { "client_msg_id": "9cbd4c5b-7ddf-4ede-b479-ad21fca66d63", "type": "app_mention", "text": "<@W111> Hi there!", "user": "******", "ts": "1595926230.009600", "team": "T111", "channel": "C111", "event_ts": "1595926230.009600", }, "type": "event_callback", "event_id": "Ev111", "event_time": 1595926230, "authed_users": ["W111"], } timestamp, body = str(int(time())), json.dumps(input) request = HTTPRequest( url=self.get_url("/slack/events"), method="POST", body=body, headers=self.build_headers(timestamp, body), ) response: HTTPResponse = await self.http_client.fetch(request) assert response.code == 200 assert_auth_test_count(self, 1)
def test_message_handler(self): app = App( client=self.web_client, signing_secret=self.signing_secret, ) result = {"call_count": 0} @app.message("Hi there!") def handle_messages(event, logger): logger.info(event) result["call_count"] = result["call_count"] + 1 request = self.build_request(user_message_event_payload) response = app.dispatch(request) assert response.status == 200 request = self.build_request(bot_message_event_payload) response = app.dispatch(request) assert response.status == 200 request = self.build_request(classic_bot_message_event_payload) response = app.dispatch(request) assert response.status == 200 assert_auth_test_count(self, 1) time.sleep(1) # wait a bit after auto ack() assert result["call_count"] == 3
def test_shortcuts(self): input = { "type": "shortcut", "token": "verification_token", "action_ts": "111.111", "team": { "id": "T111", "domain": "workspace-domain", "enterprise_id": "E111", "enterprise_name": "Org Name", }, "user": { "id": "W111", "username": "******", "team_id": "T111" }, "callback_id": "test-shortcut", "trigger_id": "111.111.xxxxxx", } timestamp, body = str(int( time())), f"payload={quote(json.dumps(input))}" with boddle( method="POST", path="/slack/events", body=body, headers=self.build_headers(timestamp, body), ): response_body = slack_events() assert response.status_code == 200 assert response_body == "" assert_auth_test_count(self, 1)
def test_commands(self): input = ( "token=verification_token" "&team_id=T111" "&team_domain=test-domain" "&channel_id=C111" "&channel_name=random" "&user_id=W111" "&user_name=primary-owner" "&command=%2Fhello-world" "&text=Hi" "&enterprise_id=E111" "&enterprise_name=Org+Name" "&response_url=https%3A%2F%2Fhooks.slack.com%2Fcommands%2FT111%2F111%2Fxxxxx" "&trigger_id=111.111.xxx") timestamp, body = str(int(time())), input with boddle( method="POST", path="/slack/events", body=body, headers=self.build_headers(timestamp, body), ): response_body = slack_events() assert response.status_code == 200 assert response_body == "" assert_auth_test_count(self, 1)
def test_events(self): input = { "token": "verification_token", "team_id": "T111", "enterprise_id": "E111", "api_app_id": "A111", "event": { "client_msg_id": "9cbd4c5b-7ddf-4ede-b479-ad21fca66d63", "type": "app_mention", "text": "<@W111> Hi there!", "user": "******", "ts": "1595926230.009600", "team": "T111", "channel": "C111", "event_ts": "1595926230.009600", }, "type": "event_callback", "event_id": "Ev111", "event_time": 1595926230, "authed_users": ["W111"], } timestamp, body = str(int(time())), json.dumps(input) with boddle( method="POST", path="/slack/events", body=body, headers=self.build_headers(timestamp, body), ): response_body = slack_events() assert response.status_code == 200 assert response_body == "" assert_auth_test_count(self, 1)
async def test_commands(self): input = ( "token=verification_token" "&team_id=T111" "&team_domain=test-domain" "&channel_id=C111" "&channel_name=random" "&user_id=W111" "&user_name=primary-owner" "&command=%2Fhello-world" "&text=Hi" "&enterprise_id=E111" "&enterprise_name=Org+Name" "&response_url=https%3A%2F%2Fhooks.slack.com%2Fcommands%2FT111%2F111%2Fxxxxx" "&trigger_id=111.111.xxx") timestamp, body = str(int(time())), input request = HTTPRequest( url=self.get_url("/slack/events"), method="POST", body=body, headers=self.build_headers(timestamp, body), ) response: HTTPResponse = await self.http_client.fetch(request) assert response.code == 200 assert_auth_test_count(self, 1)
async def test_shortcuts(self): input = { "type": "shortcut", "token": "verification_token", "action_ts": "111.111", "team": { "id": "T111", "domain": "workspace-domain", "enterprise_id": "E111", "enterprise_name": "Org Name", }, "user": { "id": "W111", "username": "******", "team_id": "T111" }, "callback_id": "test-shortcut", "trigger_id": "111.111.xxxxxx", } timestamp, body = str(int( time())), f"payload={quote(json.dumps(input))}" request = HTTPRequest( url=self.get_url("/slack/events"), method="POST", body=body, headers=self.build_headers(timestamp, body), ) response: HTTPResponse = await self.http_client.fetch(request) assert response.code == 200 assert_auth_test_count(self, 1)
def test_shortcuts(self): app = App( client=self.web_client, signing_secret=self.signing_secret, ) def shortcut_handler(ack): ack() app.shortcut("test-shortcut")(shortcut_handler) input = { "type": "shortcut", "token": "verification_token", "action_ts": "111.111", "team": { "id": "T111", "domain": "workspace-domain", "enterprise_id": "E111", "enterprise_name": "Org Name", }, "user": { "id": "W111", "username": "******", "team_id": "T111" }, "callback_id": "test-shortcut", "trigger_id": "111.111.xxxxxx", } timestamp, body = str(int( time())), f"payload={quote(json.dumps(input))}" event = { "body": body, "queryStringParameters": {}, "headers": self.build_headers(timestamp, body), "requestContext": { "http": { "method": "POST" } }, "isBase64Encoded": False, } response = SlackRequestHandler(app).handle(event, self.context) assert response["statusCode"] == 200 assert_auth_test_count(self, 1) event = { "body": body, "queryStringParameters": {}, "headers": self.build_headers(timestamp, body), "requestContext": { "httpMethod": "POST" }, "isBase64Encoded": False, } response = SlackRequestHandler(app).handle(event, self.context) assert response["statusCode"] == 200 assert_auth_test_count(self, 1)
def test_handle_callback(self): oauth_flow = OAuthFlow( client=WebClient(base_url=self.mock_api_server_base_url), settings=OAuthSettings( client_id="111.222", client_secret="xxx", scopes=["chat:write", "commands"], installation_store=FileInstallationStore(), state_store=FileOAuthStateStore(expiration_seconds=120), success_url="https://www.example.com/completion", failure_url="https://www.example.com/failure", ), ) state = oauth_flow.issue_new_state(None) req = BoltRequest( body="", query=f"code=foo&state={state}", headers={ "cookie": [f"{oauth_flow.settings.state_cookie_name}={state}"] }, ) resp = oauth_flow.handle_callback(req) assert resp.status == 200 assert "https://www.example.com/completion" in resp.body app = App(signing_secret="signing_secret", oauth_flow=oauth_flow) global_shortcut_body = { "type": "shortcut", "token": "verification_token", "action_ts": "111.111", "team": { "id": "T111", "domain": "workspace-domain", "enterprise_id": "E111", "enterprise_name": "Org Name", }, "user": { "id": "W111", "username": "******", "team_id": "T111" }, "callback_id": "test-shortcut", "trigger_id": "111.111.xxxxxx", } body = f"payload={quote(json.dumps(global_shortcut_body))}" timestamp = str(int(time())) signature_verifier = SignatureVerifier("signing_secret") headers = { "content-type": ["application/x-www-form-urlencoded"], "x-slack-signature": [ signature_verifier.generate_signature(body=body, timestamp=timestamp) ], "x-slack-request-timestamp": [timestamp], } request = BoltRequest(body=body, headers=headers) response = app.dispatch(request) assert response.status == 200 assert_auth_test_count(self, 1)
def test_events(self): app = App( client=self.web_client, signing_secret=self.signing_secret, ) def event_handler(): pass app.event("app_mention")(event_handler) input = { "token": "verification_token", "team_id": "T111", "enterprise_id": "E111", "api_app_id": "A111", "event": { "client_msg_id": "9cbd4c5b-7ddf-4ede-b479-ad21fca66d63", "type": "app_mention", "text": "<@W111> Hi there!", "user": "******", "ts": "1595926230.009600", "team": "T111", "channel": "C111", "event_ts": "1595926230.009600", }, "type": "event_callback", "event_id": "Ev111", "event_time": 1595926230, "authed_users": ["W111"], } timestamp, body = str(int(time())), json.dumps(input) event = { "body": body, "queryStringParameters": {}, "headers": self.build_headers(timestamp, body), "requestContext": { "http": { "method": "POST" } }, "isBase64Encoded": False, } response = SlackRequestHandler(app).handle(event, self.context) assert response["statusCode"] == 200 assert_auth_test_count(self, 1) event = { "body": body, "queryStringParameters": {}, "headers": self.build_headers(timestamp, body), "requestContext": { "httpMethod": "POST" }, "isBase64Encoded": False, } response = SlackRequestHandler(app).handle(event, self.context) assert response["statusCode"] == 200 assert_auth_test_count(self, 1)
def test_default_type(self): app = App(client=self.web_client, signing_secret=self.signing_secret) app.action({"action_id": "a", "block_id": "b"})(simple_listener) request = self.build_valid_request() response = app.dispatch(request) assert response.status == 200 assert_auth_test_count(self, 1)
def test_message(self): app = App( client=self.web_client, signing_secret=self.signing_secret, installation_store=OrgAppInstallationStore(), ) event_payload = { "token": "verification-token", "team_id": "T111", "enterprise_id": "E111", "api_app_id": "A111", "event": { "client_msg_id": "0186b75a-2ad4-4f36-8ccc-18608b0ac5d1", "type": "message", "text": "<@W222>", "user": "******", "ts": "1606810819.000800", "team": "T111", "channel": "C111", "event_ts": "1606810819.000800", "channel_type": "channel", }, "type": "event_callback", "event_id": "Ev111", "event_time": 1606810819, "authed_users": [], "authorizations": [ { "enterprise_id": "E111", "team_id": None, "user_id": "W222", "is_bot": True, "is_enterprise_install": True, } ], "is_ext_shared_channel": False, "event_context": "1-message-T111-C111", } result = Result() @app.event("message") def handle_app_mention(body): assert body == event_payload result.called = True timestamp, body = str(int(time())), json.dumps(event_payload) request: BoltRequest = BoltRequest( body=body, headers=self.build_headers(timestamp, body) ) response = app.dispatch(request) assert response.status == 200 # auth.test API call must be skipped assert_auth_test_count(self, 1) sleep(1) # wait a bit after auto ack() assert result.called is True
def test_events(self): app = App( client=self.web_client, signing_secret=self.signing_secret, ) @app.event("app_mention") def event_handler(): pass input = { "token": "verification_token", "team_id": "T111", "enterprise_id": "E111", "api_app_id": "A111", "event": { "client_msg_id": "9cbd4c5b-7ddf-4ede-b479-ad21fca66d63", "type": "app_mention", "text": "<@W111> Hi there!", "user": "******", "ts": "1595926230.009600", "team": "T111", "channel": "C111", "event_ts": "1595926230.009600", }, "type": "event_callback", "event_id": "Ev111", "event_time": 1595926230, "authed_users": ["W111"], } timestamp, body = str(int(time())), json.dumps(input) chalice_app = Chalice(app_name="bolt-python-chalice") slack_handler = ChaliceSlackRequestHandler(app=app, chalice=chalice_app) @chalice_app.route( "/slack/events", methods=["POST"], content_types=[ "application/x-www-form-urlencoded", "application/json" ], ) def events() -> Response: return slack_handler.handle(chalice_app.current_request) response: Dict[str, Any] = LocalGateway(chalice_app, Config()).handle_request( method="POST", path="/slack/events", body=body, headers=self.build_headers( timestamp, body), ) assert response["statusCode"] == 200 assert_auth_test_count(self, 1)
def test_shortcuts(self): app = App( client=self.web_client, signing_secret=self.signing_secret, ) @app.shortcut("test-shortcut") def shortcut_handler(ack): ack() input = { "type": "shortcut", "token": "verification_token", "action_ts": "111.111", "team": { "id": "T111", "domain": "workspace-domain", "enterprise_id": "E111", "enterprise_name": "Org Name", }, "user": { "id": "W111", "username": "******", "team_id": "T111" }, "callback_id": "test-shortcut", "trigger_id": "111.111.xxxxxx", } timestamp, body = str(int( time())), f"payload={quote(json.dumps(input))}" chalice_app = Chalice(app_name="bolt-python-chalice") slack_handler = ChaliceSlackRequestHandler(app=app, chalice=chalice_app) @chalice_app.route( "/slack/events", methods=["POST"], content_types=[ "application/x-www-form-urlencoded", "application/json" ], ) def events() -> Response: return slack_handler.handle(chalice_app.current_request) response: Dict[str, Any] = LocalGateway(chalice_app, Config()).handle_request( method="POST", path="/slack/events", body=body, headers=self.build_headers( timestamp, body), ) assert response["statusCode"] == 200 assert_auth_test_count(self, 1)
def test_lazy_listeners(self): app = App( client=self.web_client, signing_secret=self.signing_secret, ) def command_handler(ack): ack() def say_it(say): say("Done!") app.command("/hello-world")(ack=command_handler, lazy=[say_it]) input = ( "token=verification_token" "&team_id=T111" "&team_domain=test-domain" "&channel_id=C111" "&channel_name=random" "&user_id=W111" "&user_name=primary-owner" "&command=%2Fhello-world" "&text=Hi" "&enterprise_id=E111" "&enterprise_name=Org+Name" "&response_url=https%3A%2F%2Fhooks.slack.com%2Fcommands%2FT111%2F111%2Fxxxxx" "&trigger_id=111.111.xxx") timestamp, body = str(int(time())), input chalice_app = Chalice(app_name="bolt-python-chalice") slack_handler = ChaliceSlackRequestHandler(app=app, chalice=chalice_app) headers = self.build_headers(timestamp, body) headers["x-slack-bolt-lazy-only"] = "1" headers["x-slack-bolt-lazy-function-name"] = "say_it" request: Request = Request({ "requestContext": { "httpMethod": "NONE", "resourcePath": "/slack/events", }, "multiValueQueryStringParameters": {}, "pathParameters": {}, "context": {}, "stageVariables": None, "isBase64Encoded": False, "body": body, "headers": headers, }) response: Response = slack_handler.handle(request) assert response.status_code == 200 assert_auth_test_count(self, 1) assert self.mock_received_requests["/chat.postMessage"] == 1
def test_success(self): app = App( client=self.web_client, signing_secret=self.signing_secret, ) app.command("/hello-world")(commander) request = self.build_valid_request() response = app.dispatch(request) assert response.status == 200 assert_auth_test_count(self, 1)
def test_regexp_keyword_unmatched(self): app = App( client=self.web_client, signing_secret=self.signing_secret, ) app.message(re.compile("HELLO"))(whats_up) request = self.build_request() response = app.dispatch(request) assert response.status == 404 assert_auth_test_count(self, 1)
def test_no_next_call(self): app = App( client=self.web_client, signing_secret=self.signing_secret, ) app.use(no_next) app.shortcut("test-shortcut")(just_ack) response = app.dispatch(self.build_request()) assert response.status == 404 assert_auth_test_count(self, 1)
def test_success_global(self): app = App( client=self.web_client, signing_secret=self.signing_secret, ) app.shortcut("test-shortcut")(simple_listener) request = self.build_valid_request(global_shortcut_raw_body) response = app.dispatch(request) assert response.status == 200 assert_auth_test_count(self, 1)
def test_success_2(self): app = App( client=self.web_client, signing_secret=self.signing_secret, ) app.block_action("a")(simple_listener) request = self.build_valid_request() response = app.dispatch(request) assert response.status == 200 assert_auth_test_count(self, 1)
def test_success_without_type(self): app = App( client=self.web_client, signing_secret=self.signing_secret, ) app.action("pick_channel_for_fun")(simple_listener) request = self.build_valid_request() response = app.dispatch(request) assert response.status == 200 assert_auth_test_count(self, 1)
def test_commands(self): app = App( client=self.web_client, signing_secret=self.signing_secret, ) def command_handler(ack): ack() app.command("/hello-world")(command_handler) input = ( "token=verification_token" "&team_id=T111" "&team_domain=test-domain" "&channel_id=C111" "&channel_name=random" "&user_id=W111" "&user_name=primary-owner" "&command=%2Fhello-world" "&text=Hi" "&enterprise_id=E111" "&enterprise_name=Org+Name" "&response_url=https%3A%2F%2Fhooks.slack.com%2Fcommands%2FT111%2F111%2Fxxxxx" "&trigger_id=111.111.xxx") timestamp, body = str(int(time())), input event = { "body": body, "queryStringParameters": {}, "headers": self.build_headers(timestamp, body), "requestContext": { "http": { "method": "POST" } }, "isBase64Encoded": False, } response = SlackRequestHandler(app).handle(event, self.context) assert response["statusCode"] == 200 assert_auth_test_count(self, 1) event = { "body": body, "queryStringParameters": {}, "headers": self.build_headers(timestamp, body), "requestContext": { "httpMethod": "POST" }, "isBase64Encoded": False, } response = SlackRequestHandler(app).handle(event, self.context) assert response["statusCode"] == 200 assert_auth_test_count(self, 1)
def test_process_before_response(self): app = App( client=self.web_client, signing_secret=self.signing_secret, process_before_response=True, ) app.view("view-id")(simple_listener) request = self.build_valid_request() response = app.dispatch(request) assert response.status == 200 assert_auth_test_count(self, 1)
def test_self_events(self): app = App( client=self.web_client, signing_secret=self.signing_secret, authorize=authorize, ) event_body = { "token": "verification_token", "team_id": "T_SOURCE", "enterprise_id": "E_SOURCE", "api_app_id": "A111", "event": { "type": "reaction_added", "user": "******", # bot_user_id "item": { "type": "message", "channel": "C111", "ts": "1599529504.000400", }, "reaction": "heart_eyes", "item_user": "******", "event_ts": "1599616881.000800", }, "type": "event_callback", "event_id": "Ev111", "event_time": 1599616881, "authorizations": [ { "enterprise_id": "E_INSTALLED", "team_id": "T_INSTALLED", "user_id": "W111", "is_bot": True, "is_enterprise_install": False, } ], } @app.event("reaction_added") def handle_app_mention(say): say("What's up?") timestamp, body = str(int(time())), json.dumps(event_body) request: BoltRequest = BoltRequest( body=body, headers=self.build_headers(timestamp, body) ) response = app.dispatch(request) assert response.status == 200 assert_auth_test_count(self, 1) sleep(1) # wait a bit after auto ack() # The listener should not be executed assert self.mock_received_requests.get("/chat.postMessage") is None
def test_shortcuts(self): app = App( client=self.web_client, signing_secret=self.signing_secret, ) def shortcut_handler(ack): ack() app.shortcut("test-shortcut")(shortcut_handler) app_handler = SlackRequestHandler(app) input = { "type": "shortcut", "token": "verification_token", "action_ts": "111.111", "team": { "id": "T111", "domain": "workspace-domain", "enterprise_id": "E111", "enterprise_name": "Org Name", }, "user": { "id": "W111", "username": "******", "team_id": "T111" }, "callback_id": "test-shortcut", "trigger_id": "111.111.xxxxxx", } timestamp, body = str(int( time())), f"payload={quote(json.dumps(input))}" async def endpoint(req: Request): return await app_handler.handle(req) api = Starlette( debug=True, routes=[ Route("/slack/events", endpoint=endpoint, methods=["POST"]) ], ) client = TestClient(api) response = client.post( "/slack/events", data=body, headers=self.build_headers(timestamp, body), ) assert response.status_code == 200 assert_auth_test_count(self, 1)
def test_events(self): app = App( client=self.web_client, signing_secret=self.signing_secret, ) def event_handler(): pass app.event("app_mention")(event_handler) app_handler = SlackRequestHandler(app) input = { "token": "verification_token", "team_id": "T111", "enterprise_id": "E111", "api_app_id": "A111", "event": { "client_msg_id": "9cbd4c5b-7ddf-4ede-b479-ad21fca66d63", "type": "app_mention", "text": "<@W111> Hi there!", "user": "******", "ts": "1595926230.009600", "team": "T111", "channel": "C111", "event_ts": "1595926230.009600", }, "type": "event_callback", "event_id": "Ev111", "event_time": 1595926230, "authed_users": ["W111"], } timestamp, body = str(int(time())), json.dumps(input) async def endpoint(req: Request): return await app_handler.handle(req) api = Starlette( debug=True, routes=[ Route("/slack/events", endpoint=endpoint, methods=["POST"]) ], ) client = TestClient(api) response = client.post( "/slack/events", data=body, headers=self.build_headers(timestamp, body), ) assert response.status_code == 200 assert_auth_test_count(self, 1)
def test_user_context_attributes(self): app = App( client=self.web_client, authorize=user_authorize, signing_secret=self.signing_secret, ) app.action("a")(assert_user_context_attributes) request = self.build_valid_request() response = app.dispatch(request) assert response.status == 200 assert response.body == "" assert_auth_test_count(self, 1)
def test_installation_store_bot_only_oauth_flow(self): app = App( client=self.web_client, signing_secret=self.signing_secret, oauth_flow=OAuthFlow(settings=self.oauth_settings_bot_only), ) app.event("app_mention")(self.handle_app_mention) response = app.dispatch(self.build_app_mention_request()) assert response.status == 200 assert_auth_test_count(self, 1) sleep(1) # wait a bit after auto ack() assert self.mock_received_requests["/chat.postMessage"] == 1