From 35e2246db5e5a2162713293529cbf132026f1d90 Mon Sep 17 00:00:00 2001 From: Kazuhiro Sera Date: Thu, 27 May 2021 16:34:52 +0900 Subject: [PATCH] Fix #1021 by updating View constructor to convert state as dict to class object (#1022) --- slack_sdk/models/views/__init__.py | 41 +++++++++++---------- tests/data/view_modal_009.json | 2 +- tests/data/view_modal_010.json | 2 +- tests/slack_sdk/models/test_elements.py | 5 ++- tests/slack_sdk/models/test_views.py | 13 +++++++ tests/slack_sdk_fixture/view_modal_009.json | 2 +- tests/slack_sdk_fixture/view_modal_010.json | 2 +- 7 files changed, 43 insertions(+), 24 deletions(-) diff --git a/slack_sdk/models/views/__init__.py b/slack_sdk/models/views/__init__.py index f524fa57c..0b32273ce 100644 --- a/slack_sdk/models/views/__init__.py +++ b/slack_sdk/models/views/__init__.py @@ -73,6 +73,8 @@ def __init__( self.blocks = Block.parse_all(blocks) self.private_metadata = private_metadata self.state = state + if self.state is not None and isinstance(self.state, dict): + self.state = ViewState(**self.state) self.hash = hash self.clear_on_close = clear_on_close self.notify_on_close = notify_on_close @@ -155,29 +157,30 @@ def __init__( ): value_objects: Dict[str, Dict[str, ViewStateValue]] = {} new_state_values = copy.copy(values) - for block_id, actions in new_state_values.items(): - if actions is None: # skipcq: PYL-R1724 - continue - elif isinstance(actions, dict): - new_actions = copy.copy(actions) - for action_id, v in actions.items(): - if isinstance(v, dict): - d = copy.copy(v) - value_object = ViewStateValue(**d) - elif isinstance(v, ViewStateValue): - value_object = v - else: - self._show_warning_about_unknown(v) - continue - new_actions[action_id] = value_object - value_objects[block_id] = new_actions - else: - self._show_warning_about_unknown(v) + if isinstance(new_state_values, dict): # just in case + for block_id, actions in new_state_values.items(): + if actions is None: # skipcq: PYL-R1724 + continue + elif isinstance(actions, dict): + new_actions = copy.copy(actions) + for action_id, v in actions.items(): + if isinstance(v, dict): + d = copy.copy(v) + value_object = ViewStateValue(**d) + elif isinstance(v, ViewStateValue): + value_object = v + else: + self._show_warning_about_unknown(v) + continue + new_actions[action_id] = value_object + value_objects[block_id] = new_actions + else: + self._show_warning_about_unknown(v) self.values = value_objects def to_dict(self, *args) -> Dict[str, Dict[str, Dict[str, dict]]]: # type: ignore self.validate_json() - if self.values: # skipcq: PYL-R1705 + if self.values is not None: dict_values: Dict[str, Dict[str, dict]] = {} for block_id, actions in self.values.items(): if actions: diff --git a/tests/data/view_modal_009.json b/tests/data/view_modal_009.json index c8fe21df1..74640861e 100644 --- a/tests/data/view_modal_009.json +++ b/tests/data/view_modal_009.json @@ -35,7 +35,7 @@ "callback_id": "view_4", "external_id": "some-unique-id", "state": { - "values": [] + "values": {} }, "hash": "1569362015.55b5e41b", "clear_on_close": true, diff --git a/tests/data/view_modal_010.json b/tests/data/view_modal_010.json index 7530e9378..b01739874 100644 --- a/tests/data/view_modal_010.json +++ b/tests/data/view_modal_010.json @@ -30,7 +30,7 @@ "callback_id": "identify_your_modals", "external_id": "some-unique-id", "state": { - "values": [] + "values": {} }, "hash": "156772938.1827394", "clear_on_close": false, diff --git a/tests/slack_sdk/models/test_elements.py b/tests/slack_sdk/models/test_elements.py index 63573c9a4..3b7d600d7 100644 --- a/tests/slack_sdk/models/test_elements.py +++ b/tests/slack_sdk/models/test_elements.py @@ -228,7 +228,10 @@ def test_document(self): "type": "timepicker", "action_id": "timepicker123", "initial_time": "11:40", - "placeholder": {"type": "plain_text", "text": "Select a time",}, + "placeholder": { + "type": "plain_text", + "text": "Select a time", + }, } self.assertDictEqual(input, TimePickerElement(**input).to_dict()) diff --git a/tests/slack_sdk/models/test_views.py b/tests/slack_sdk/models/test_views.py index 11067b9f1..79802625b 100644 --- a/tests/slack_sdk/models/test_views.py +++ b/tests/slack_sdk/models/test_views.py @@ -30,6 +30,7 @@ def setUp(self) -> None: def verify_loaded_view_object(self, file): input = json.load(file) view = View(**input) + self.assertTrue(view.state is None or isinstance(view.state, ViewState)) self.assertDictEqual(input, view.to_dict()) # -------------------------------- @@ -110,6 +111,18 @@ def test_valid_construction(self): ), ), ], + state=ViewState( + values={ + "b1": { + "a1": ViewStateValue(type="plain_text_input", value="Title") + }, + "b2": { + "a2": ViewStateValue( + type="plain_text_input", value="Description" + ) + }, + } + ), ) modal_view.validate_json() diff --git a/tests/slack_sdk_fixture/view_modal_009.json b/tests/slack_sdk_fixture/view_modal_009.json index c8fe21df1..74640861e 100644 --- a/tests/slack_sdk_fixture/view_modal_009.json +++ b/tests/slack_sdk_fixture/view_modal_009.json @@ -35,7 +35,7 @@ "callback_id": "view_4", "external_id": "some-unique-id", "state": { - "values": [] + "values": {} }, "hash": "1569362015.55b5e41b", "clear_on_close": true, diff --git a/tests/slack_sdk_fixture/view_modal_010.json b/tests/slack_sdk_fixture/view_modal_010.json index 7530e9378..b01739874 100644 --- a/tests/slack_sdk_fixture/view_modal_010.json +++ b/tests/slack_sdk_fixture/view_modal_010.json @@ -30,7 +30,7 @@ "callback_id": "identify_your_modals", "external_id": "some-unique-id", "state": { - "values": [] + "values": {} }, "hash": "156772938.1827394", "clear_on_close": false,