From 66c8859d4e86254e0565ecd6c44b5c21503f6df2 Mon Sep 17 00:00:00 2001 From: Kazuhiro Sera Date: Sat, 8 May 2021 07:04:58 +0900 Subject: [PATCH] Add timepicker block element support (#876) --- slack_sdk/models/blocks/__init__.py | 1 + slack_sdk/models/blocks/block_elements.py | 42 +++++++++++++++++++++ tests/slack_sdk/models/test_elements.py | 46 +++++++++++++++++++++++ 3 files changed, 89 insertions(+) diff --git a/slack_sdk/models/blocks/__init__.py b/slack_sdk/models/blocks/__init__.py index 1944aa5a1..5272c27b2 100644 --- a/slack_sdk/models/blocks/__init__.py +++ b/slack_sdk/models/blocks/__init__.py @@ -23,6 +23,7 @@ from .block_elements import ConversationMultiSelectElement # noqa from .block_elements import ConversationSelectElement # noqa from .block_elements import DatePickerElement # noqa +from .block_elements import TimePickerElement # noqa from .block_elements import ExternalDataMultiSelectElement # noqa from .block_elements import ExternalDataSelectElement # noqa from .block_elements import ImageElement # noqa diff --git a/slack_sdk/models/blocks/block_elements.py b/slack_sdk/models/blocks/block_elements.py index f32897331..4f0489c19 100644 --- a/slack_sdk/models/blocks/block_elements.py +++ b/slack_sdk/models/blocks/block_elements.py @@ -377,6 +377,48 @@ def _validate_initial_date_valid(self): ) +# ------------------------------------------------- +# TimePicker +# ------------------------------------------------- + + +class TimePickerElement(InputInteractiveElement): + type = "timepicker" + + @property + def attributes(self) -> Set[str]: + return super().attributes.union({"initial_time"}) + + def __init__( + self, + *, + action_id: Optional[str] = None, + placeholder: Optional[Union[str, dict, TextObject]] = None, + initial_time: Optional[str] = None, + confirm: Optional[Union[dict, ConfirmObject]] = None, + **others: dict, + ): + """ + An element which allows selection of a time of day. + https://api.slack.com/reference/block-kit/block-elements#timepicker + """ + super().__init__( + type=self.type, + action_id=action_id, + placeholder=TextObject.parse(placeholder, PlainTextObject.type), + confirm=ConfirmObject.parse(confirm), + ) + show_unknown_key_warning(self, others) + + self.initial_time = initial_time + + @JsonValidator("initial_time attribute must be in format 'HH:mm'") + def _validate_initial_time_valid(self): + return self.initial_time is None or re.match( + r"([0-1][0-9]|2[0-3]):([0-5][0-9])", self.initial_time + ) + + # ------------------------------------------------- # Image # ------------------------------------------------- diff --git a/tests/slack_sdk/models/test_elements.py b/tests/slack_sdk/models/test_elements.py index f34584e98..63573c9a4 100644 --- a/tests/slack_sdk/models/test_elements.py +++ b/tests/slack_sdk/models/test_elements.py @@ -4,6 +4,7 @@ from slack_sdk.models.blocks import ( ButtonElement, DatePickerElement, + TimePickerElement, ExternalDataSelectElement, ImageElement, LinkButtonElement, @@ -216,6 +217,51 @@ def test_issue_623(self): elem.to_dict() +# ------------------------------------------------- +# TimePicker +# ------------------------------------------------- + + +class TimePickerElementTests(unittest.TestCase): + def test_document(self): + input = { + "type": "timepicker", + "action_id": "timepicker123", + "initial_time": "11:40", + "placeholder": {"type": "plain_text", "text": "Select a time",}, + } + self.assertDictEqual(input, TimePickerElement(**input).to_dict()) + + def test_json(self): + for hour in range(0, 23): + for minute in range(0, 59): + time = f"{hour:02}:{minute:02}" + self.assertDictEqual( + { + "action_id": "timepicker123", + "initial_time": time, + "placeholder": { + "emoji": True, + "type": "plain_text", + "text": "Select a time", + }, + "type": "timepicker", + }, + TimePickerElement( + action_id="timepicker123", + placeholder="Select a time", + initial_time=time, + ).to_dict(), + ) + + with self.assertRaises(SlackObjectFormationError): + TimePickerElement( + action_id="timepicker123", + placeholder="Select a time", + initial_time="25:00", + ).to_dict() + + # ------------------------------------------------- # Image # -------------------------------------------------