From b2279363d7e346fcc5c40964e4b30c83613369d4 Mon Sep 17 00:00:00 2001 From: Kazuhiro Sera Date: Tue, 21 Nov 2023 15:49:34 +0900 Subject: [PATCH] Fix #988 app.action listener should accept block_id-only constraints for bolt-js feature parity --- slack_bolt/listener_matcher/builtins.py | 7 +++++-- tests/scenario_tests/test_block_actions.py | 9 +++++++++ tests/scenario_tests_async/test_block_actions.py | 13 +++++++++++++ 3 files changed, 27 insertions(+), 2 deletions(-) diff --git a/slack_bolt/listener_matcher/builtins.py b/slack_bolt/listener_matcher/builtins.py index e19a25121..c6547f919 100644 --- a/slack_bolt/listener_matcher/builtins.py +++ b/slack_bolt/listener_matcher/builtins.py @@ -292,7 +292,7 @@ def func(body: Dict[str, Any]) -> bool: return workflow_step_edit(constraints["callback_id"], asyncio) raise BoltError(f"type: {action_type} is unsupported") - elif "action_id" in constraints: + elif "action_id" in constraints or "block_id" in constraints: # The default value is "block_actions" return block_action(constraints, asyncio) @@ -313,8 +313,11 @@ def _block_action( elif isinstance(constraints, dict): # block_id matching is optional block_id: Optional[Union[str, Pattern]] = constraints.get("block_id") + action_id: Optional[Union[str, Pattern]] = constraints.get("action_id") + if block_id is None and action_id is None: + return False block_id_matched = block_id is None or _matches(block_id, action.get("block_id")) - action_id_matched = _matches(constraints["action_id"], action["action_id"]) + action_id_matched = action_id is None or _matches(action_id, action.get("action_id")) return block_id_matched and action_id_matched diff --git a/tests/scenario_tests/test_block_actions.py b/tests/scenario_tests/test_block_actions.py index 1c555200e..281cc606c 100644 --- a/tests/scenario_tests/test_block_actions.py +++ b/tests/scenario_tests/test_block_actions.py @@ -109,6 +109,15 @@ def test_default_type_no_block_id(self): assert response.status == 200 assert_auth_test_count(self, 1) + def test_default_type_no_action_id(self): + app = App(client=self.web_client, signing_secret=self.signing_secret) + app.action({"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_default_type_and_unmatched_block_id(self): app = App(client=self.web_client, signing_secret=self.signing_secret) app.action({"action_id": "a", "block_id": "bbb"})(simple_listener) diff --git a/tests/scenario_tests_async/test_block_actions.py b/tests/scenario_tests_async/test_block_actions.py index cdbb09c9c..48809722d 100644 --- a/tests/scenario_tests_async/test_block_actions.py +++ b/tests/scenario_tests_async/test_block_actions.py @@ -114,6 +114,19 @@ async def test_default_type_no_block_id(self): assert response.status == 200 await assert_auth_test_count_async(self, 1) + @pytest.mark.asyncio + async def test_default_type_no_action_id(self): + app = AsyncApp( + client=self.web_client, + signing_secret=self.signing_secret, + ) + app.action({"block_id": "b"})(simple_listener) + + request = self.build_valid_request() + response = await app.async_dispatch(request) + assert response.status == 200 + await assert_auth_test_count_async(self, 1) + @pytest.mark.asyncio async def test_default_type_unmatched_block_id(self): app = AsyncApp(