def setUp(self) -> None:
        self.common_options = [
            Option.from_single_value("one"),
            Option.from_single_value("two"),
            Option.from_single_value("three"),
        ]

        self.common = OptionGroup(label="an option",
                                  options=self.common_options)
Exemple #2
0
    def setUp(self) -> None:
        self.options = [
            Option.from_single_value("one"),
            Option.from_single_value("two"),
            Option.from_single_value("three"),
        ]

        self.option_group = [
            OptionGroup(label="group_1", options=self.options)
        ]
    def test_with_static_select_element(self):
        self.maxDiff = None

        elem = StaticSelectElement(
            action_id="action-id",
            initial_option=Option(value="option-1", text="Option 1"),
            options=[
                Option(value="option-1", text="Option 1"),
                Option(value="option-2", text="Option 2"),
                Option(value="option-3", text="Option 3"),
            ],
        )
        expected = {
            "action_id":
            "action-id",
            "initial_option": {
                "text": {
                    "emoji": True,
                    "text": "Option 1",
                    "type": "plain_text"
                },
                "value": "option-1",
            },
            "options": [
                {
                    "text": {
                        "emoji": True,
                        "text": "Option 1",
                        "type": "plain_text"
                    },
                    "value": "option-1",
                },
                {
                    "text": {
                        "emoji": True,
                        "text": "Option 2",
                        "type": "plain_text"
                    },
                    "value": "option-2",
                },
                {
                    "text": {
                        "emoji": True,
                        "text": "Option 3",
                        "type": "plain_text"
                    },
                    "value": "option-3",
                },
            ],
            "type":
            "static_select",
        }
        self.assertDictEqual(expected, elem.to_dict())
 def __init__(
     self,
     *,
     type: Optional[str] = None,  # skipcq: PYL-W0622
     value: Optional[str] = None,
     selected_date: Optional[str] = None,
     selected_conversation: Optional[str] = None,
     selected_channel: Optional[str] = None,
     selected_user: Optional[str] = None,
     selected_option: Optional[str] = None,
     selected_conversations: Optional[Sequence[str]] = None,
     selected_channels: Optional[Sequence[str]] = None,
     selected_users: Optional[Sequence[str]] = None,
     selected_options: Optional[Sequence[Union[dict, Option]]] = None,
 ):
     self.type = type
     self.value = value
     self.selected_date = selected_date
     self.selected_conversation = selected_conversation
     self.selected_channel = selected_channel
     self.selected_user = selected_user
     self.selected_option = selected_option
     self.selected_conversations = selected_conversations
     self.selected_channels = selected_channels
     self.selected_users = selected_users
     if selected_options:
         if isinstance(selected_options, dict):
             self.selected_options = [Option(**d) for d in selected_options]
         else:
             self.selected_options = selected_options
Exemple #5
0
def show_multi_options(ack: Ack) -> None:
    ack(option_groups=[
        OptionGroup(
            label=PlainTextObject(text="Group 1"),
            options=[
                Option(text=PlainTextObject(text="Option 1"), value="1-1"),
                Option(text=PlainTextObject(text="Option 2"), value="1-2"),
            ],
        ),
        OptionGroup(
            label=PlainTextObject(text="Group 2"),
            options=[
                Option(text=PlainTextObject(text="Option 1"), value="2-1"),
            ],
        ),
    ])
Exemple #6
0
    def test_json(self):
        option = Option.from_single_value("one")

        self.assertDictEqual(
            ActionExternalSelector(name="select_1",
                                   text="selector_1",
                                   min_query_length=3).to_dict(),
            {
                "name": "select_1",
                "text": "selector_1",
                "min_query_length": 3,
                "type": "select",
                "data_source": "external",
            },
        )

        self.assertDictEqual(
            ActionExternalSelector(name="select_1",
                                   text="selector_1",
                                   selected_option=option).to_dict(),
            {
                "name": "select_1",
                "text": "selector_1",
                "selected_options": [option.to_dict("action")],
                "type": "select",
                "data_source": "external",
            },
        )
Exemple #7
0
 def test_element_parsing(self):
     elements = [
         ButtonElement(text="Click me", action_id="reg_button", value="1"),
         StaticSelectElement(options=[Option(value="SelectOption")]),
         ImageElement(image_url="url", alt_text="alt-text"),
         OverflowMenuElement(
             options=[Option(value="MenuOption1"), Option(value="MenuOption2")]
         ),
     ]
     input = {
         "type": "actions",
         "block_id": "actionblock789",
         "elements": [e.to_dict() for e in elements],
     }
     parsed_elements = ActionsBlock(**input).elements
     self.assertEqual(len(elements), len(parsed_elements))
     for original, parsed in zip(elements, parsed_elements):
         self.assertEqual(type(original), type(parsed))
         self.assertDictEqual(original.to_dict(), parsed.to_dict())
 def test_valid_description_for_attachments(self):
     option = Option(label="label",
                     value="v",
                     description="this is an option")
     # legacy message actions in attachments
     self.assertDictEqual(
         option.to_dict("action"),
         {
             "text": "label",
             "value": "v",
             "description": "this is an option",
         },
     )
     self.assertDictEqual(
         option.to_dict("attachment"),
         {
             "text": "label",
             "value": "v",
             "description": "this is an option",
         },
     )
 def to_dict(self) -> dict:  # skipcq: PYL-W0221
     json = super().to_dict()
     if self.data_source == "external":
         if isinstance(self.value, Option):
             json["selected_options"] = extract_json([self.value], "dialog")
         elif self.value is not None:
             json["selected_options"] = Option.from_single_value(self.value)
     else:
         if isinstance(self.value, Option):
             json["value"] = self.value.value
         elif self.value is not None:
             json["value"] = self.value
     return json
class OptionTests(unittest.TestCase):
    def setUp(self) -> None:
        self.common = Option(label="an option", value="option_1")

    def test_block_style_json(self):
        expected = {
            "text": {
                "type": "plain_text",
                "text": "an option",
                "emoji": True
            },
            "value": "option_1",
        }
        self.assertDictEqual(expected, self.common.to_dict("block"))
        self.assertDictEqual(expected, self.common.to_dict())

    def test_dialog_style_json(self):
        expected = {"label": "an option", "value": "option_1"}
        self.assertDictEqual(expected, self.common.to_dict("dialog"))

    def test_action_style_json(self):
        expected = {"text": "an option", "value": "option_1"}
        self.assertDictEqual(expected, self.common.to_dict("action"))

    def test_from_single_value(self):
        option = Option(label="option_1", value="option_1")
        self.assertDictEqual(
            option.to_dict("text"),
            option.from_single_value("option_1").to_dict("text"),
        )

    def test_label_length(self):
        with self.assertRaises(SlackObjectFormationError):
            Option(label=STRING_301_CHARS, value="option_1").to_dict("text")

    def test_value_length(self):
        with self.assertRaises(SlackObjectFormationError):
            Option(label="option_1", value=STRING_301_CHARS).to_dict("text")
Exemple #11
0
 def test_basic_json_formation(self):
     options = [
         Option.from_single_value("one"),
         Option.from_single_value("two"),
         Option.from_single_value("three"),
     ]
     self.assertDictEqual(
         DialogStaticSelector(name="dialog",
                              label="Dialog",
                              options=options).to_dict(),
         {
             "optional":
             False,
             "label":
             "Dialog",
             "type":
             "select",
             "name":
             "dialog",
             "options": [
                 {
                     "label": "one",
                     "value": "one"
                 },
                 {
                     "label": "two",
                     "value": "two"
                 },
                 {
                     "label": "three",
                     "value": "three"
                 },
             ],
             "data_source":
             "static",
         },
     )
Exemple #12
0
 def test_basic_json_formation(self):
     o = Option.from_single_value("one")
     self.assertDictEqual(
         DialogExternalSelector(
             name="dialog",
             label="Dialog",
             value=o,
             min_query_length=3,
             optional=True,
             placeholder="something",
         ).to_dict(),
         {
             "optional": True,
             "label": "Dialog",
             "type": "select",
             "name": "dialog",
             "min_query_length": 3,
             "placeholder": "something",
             "selected_options": [o.to_dict("dialog")],
             "data_source": "external",
         },
     )
 def test_valid_description_for_blocks(self):
     option = Option(label="label",
                     value="v",
                     description="this is an option")
     self.assertDictEqual(
         option.to_dict(),
         {
             "text": {
                 "type": "plain_text",
                 "text": "label",
                 "emoji": True,
             },
             "value": "v",
             "description": {
                 "type": "plain_text",
                 "text": "this is an option",
                 "emoji": True,
             },
         },
     )
     option = Option(
         # Note that mrkdwn type is not allowed for this (as of April 2021)
         text=PlainTextObject(text="label"),
         value="v",
         description="this is an option",
     )
     self.assertDictEqual(
         option.to_dict(),
         {
             "text": {
                 "type": "plain_text",
                 "text": "label"
             },
             "value": "v",
             "description": {
                 "type": "plain_text",
                 "text": "this is an option",
                 "emoji": True,
             },
         },
     )
 def setUp(self) -> None:
     self.common = Option(label="an option", value="option_1")
Exemple #15
0
 def test_valid_construction(self):
     modal_view = View(
         type="modal",
         callback_id="modal-id",
         title=PlainTextObject(text="Awesome Modal"),
         submit=PlainTextObject(text="Submit"),
         close=PlainTextObject(text="Cancel"),
         blocks=[
             InputBlock(
                 block_id="b-id",
                 label=PlainTextObject(text="Input label"),
                 element=PlainTextInputElement(action_id="a-id"),
             ),
             InputBlock(
                 block_id="cb-id",
                 label=PlainTextObject(text="Label"),
                 element=CheckboxesElement(
                     action_id="a-cb-id",
                     options=[
                         Option(
                             text=PlainTextObject(
                                 text="*this is plain_text text*"),
                             value="v1",
                         ),
                         Option(
                             text=MarkdownTextObject(
                                 text="*this is mrkdwn text*"),
                             value="v2",
                         ),
                     ],
                 ),
             ),
             SectionBlock(
                 block_id="sb-id",
                 text=MarkdownTextObject(
                     text="This is a mrkdwn text section block."),
                 fields=[
                     PlainTextObject(text="*this is plain_text text*",
                                     emoji=True),
                     MarkdownTextObject(text="*this is mrkdwn text*"),
                     PlainTextObject(text="*this is plain_text text*",
                                     emoji=True),
                 ],
             ),
             DividerBlock(),
             SectionBlock(
                 block_id="rb-id",
                 text=MarkdownTextObject(
                     text=
                     "This is a section block with radio button accessory"),
                 accessory=RadioButtonsElement(
                     initial_option=Option(
                         text=PlainTextObject(text="Option 1"),
                         value="option 1",
                         description=PlainTextObject(
                             text="Description for option 1"),
                     ),
                     options=[
                         Option(
                             text=PlainTextObject(text="Option 1"),
                             value="option 1",
                             description=PlainTextObject(
                                 text="Description for option 1"),
                         ),
                         Option(
                             text=PlainTextObject(text="Option 2"),
                             value="option 2",
                             description=PlainTextObject(
                                 text="Description for option 2"),
                         ),
                     ],
                 ),
             ),
         ],
     )
     modal_view.validate_json()
Exemple #16
0
 def test_all_state_values(self):
     # Testing with
     # {"type":"modal","title":{"type":"plain_text","text":"My App","emoji":true},"submit":{"type":"plain_text","text":"Submit","emoji":true},"close":{"type":"plain_text","text":"Cancel","emoji":true},"blocks":[{"type":"input","element":{"type":"plain_text_input"},"label":{"type":"plain_text","text":"Label","emoji":true}},{"type":"input","element":{"type":"plain_text_input","multiline":true},"label":{"type":"plain_text","text":"Label","emoji":true}},{"type":"input","element":{"type":"datepicker","initial_date":"1990-04-28","placeholder":{"type":"plain_text","text":"Select a date","emoji":true}},"label":{"type":"plain_text","text":"Label","emoji":true}},{"type":"input","element":{"type":"users_select","placeholder":{"type":"plain_text","text":"Select a user","emoji":true}},"label":{"type":"plain_text","text":"Label","emoji":true}},{"type":"input","element":{"type":"multi_static_select","placeholder":{"type":"plain_text","text":"Select options","emoji":true},"options":[{"text":{"type":"plain_text","text":"*this is plain_text text*","emoji":true},"value":"value-0"},{"text":{"type":"plain_text","text":"*this is plain_text text*","emoji":true},"value":"value-1"},{"text":{"type":"plain_text","text":"*this is plain_text text*","emoji":true},"value":"value-2"}]},"label":{"type":"plain_text","text":"Label","emoji":true}},{"type":"input","element":{"type":"checkboxes","options":[{"text":{"type":"plain_text","text":"*this is plain_text text*","emoji":true},"value":"value-0"},{"text":{"type":"plain_text","text":"*this is plain_text text*","emoji":true},"value":"value-1"},{"text":{"type":"plain_text","text":"*this is plain_text text*","emoji":true},"value":"value-2"}]},"label":{"type":"plain_text","text":"Label","emoji":true}},{"type":"input","element":{"type":"radio_buttons","initial_option":{"text":{"type":"plain_text","text":"Option 1"},"value":"option 1","description":{"type":"plain_text","text":"Description for option 1"}},"options":[{"text":{"type":"plain_text","text":"Option 1"},"value":"option 1","description":{"type":"plain_text","text":"Description for option 1"}},{"text":{"type":"plain_text","text":"Option 2"},"value":"option 2","description":{"type":"plain_text","text":"Description for option 2"}},{"text":{"type":"plain_text","text":"Option 3"},"value":"option 3","description":{"type":"plain_text","text":"Description for option 3"}}]},"label":{"type":"plain_text","text":"Label","emoji":true}}]}
     expected = {
         "values": {
             "b1": {
                 "a1": {
                     "type": "datepicker",
                     "selected_date": "1990-04-12"
                 }
             },
             "b2": {
                 "a2": {
                     "type": "plain_text_input",
                     "value": "This is a test"
                 }
             },
             # multiline
             "b3": {
                 "a3": {
                     "type": "plain_text_input",
                     "value": "Something wrong\nPlease help me!",
                 }
             },
             "b4": {
                 "a4": {
                     "type": "users_select",
                     "selected_user": "******"
                 }
             },
             "b4-2": {
                 "a4-2": {
                     "type": "multi_users_select",
                     "selected_users": ["U123", "U234"],
                 }
             },
             "b5": {
                 "a5": {
                     "type": "conversations_select",
                     "selected_conversation": "C123",
                 }
             },
             "b5-2": {
                 "a5-2": {
                     "type": "multi_conversations_select",
                     "selected_conversations": ["C123", "C234"],
                 }
             },
             "b6": {
                 "a6": {
                     "type": "channels_select",
                     "selected_channel": "C123"
                 }
             },
             "b6-2": {
                 "a6-2": {
                     "type": "multi_channels_select",
                     "selected_channels": ["C123", "C234"],
                 }
             },
             "b7": {
                 "a7": {
                     "type":
                     "multi_static_select",
                     "selected_options": [
                         {
                             "text": {
                                 "type": "plain_text",
                                 "text": "*this is plain_text text*",
                                 "emoji": True,
                             },
                             "value": "value-0",
                         },
                         {
                             "text": {
                                 "type": "plain_text",
                                 "text": "*this is plain_text text*",
                                 "emoji": True,
                             },
                             "value": "value-1",
                         },
                     ],
                 }
             },
             "b8": {
                 "a8": {
                     "type":
                     "checkboxes",
                     "selected_options": [
                         {
                             "text": {
                                 "type": "plain_text",
                                 "text": "*this is plain_text text*",
                                 "emoji": True,
                             },
                             "value": "value-0",
                         },
                         {
                             "text": {
                                 "type": "plain_text",
                                 "text": "*this is plain_text text*",
                                 "emoji": True,
                             },
                             "value": "value-1",
                         },
                     ],
                 }
             },
             "b9": {
                 "a9": {
                     "type": "radio_buttons",
                     "selected_option": {
                         "text": {
                             "type": "plain_text",
                             "text": "Option 1",
                             "emoji": True,
                         },
                         "value": "option 1",
                         "description": {
                             "type": "plain_text",
                             "text": "Description for option 1",
                             "emoji": True,
                         },
                     },
                 }
             },
         }
     }
     state = ViewState(
         values={
             "b1": {
                 "a1":
                 ViewStateValue(type="datepicker",
                                selected_date="1990-04-12")
             },
             "b2": {
                 "a2":
                 ViewStateValue(type="plain_text_input",
                                value="This is a test")
             },
             "b3": {
                 "a3":
                 ViewStateValue(
                     type="plain_text_input",
                     value="Something wrong\nPlease help me!",
                 )
             },
             "b4": {
                 "a4": ViewStateValue(type="users_select",
                                      selected_user="******")
             },
             "b4-2": {
                 "a4-2":
                 ViewStateValue(type="multi_users_select",
                                selected_users=["U123", "U234"])
             },
             "b5": {
                 "a5":
                 ViewStateValue(type="conversations_select",
                                selected_conversation="C123")
             },
             "b5-2": {
                 "a5-2":
                 ViewStateValue(
                     type="multi_conversations_select",
                     selected_conversations=["C123", "C234"],
                 )
             },
             "b6": {
                 "a6":
                 ViewStateValue(type="channels_select",
                                selected_channel="C123")
             },
             "b6-2": {
                 "a6-2":
                 ViewStateValue(type="multi_channels_select",
                                selected_channels=["C123", "C234"])
             },
             "b7": {
                 "a7":
                 ViewStateValue(
                     type="multi_static_select",
                     selected_options=[
                         Option(
                             text=PlainTextObject(
                                 text="*this is plain_text text*",
                                 emoji=True),
                             value="value-0",
                         ),
                         Option(
                             text=PlainTextObject(
                                 text="*this is plain_text text*",
                                 emoji=True),
                             value="value-1",
                         ),
                     ],
                 )
             },
             "b8": {
                 "a8":
                 ViewStateValue(
                     type="checkboxes",
                     selected_options=[
                         Option(
                             text=PlainTextObject(
                                 text="*this is plain_text text*",
                                 emoji=True),
                             value="value-0",
                         ),
                         Option(
                             text=PlainTextObject(
                                 text="*this is plain_text text*",
                                 emoji=True),
                             value="value-1",
                         ),
                     ],
                 )
             },
             "b9": {
                 "a9":
                 ViewStateValue(
                     type="radio_buttons",
                     selected_option=Option(
                         text=PlainTextObject(text="Option 1", emoji=True),
                         value="option 1",
                         description=PlainTextObject(
                             text="Description for option 1", emoji=True),
                     ),
                 )
             },
         })
     self.assertDictEqual(expected, ViewState(**expected).to_dict())
     self.assertDictEqual(expected, state.to_dict())
Exemple #17
0
def show_options(ack: Ack) -> None:
    ack(options=[Option(text=PlainTextObject(text="Maru"), value="maru")])
 def test_from_single_value(self):
     option = Option(label="option_1", value="option_1")
     self.assertDictEqual(
         option.to_dict("text"),
         option.from_single_value("option_1").to_dict("text"),
     )
 def test_value_length(self):
     with self.assertRaises(SlackObjectFormationError):
         Option(label="option_1", value=STRING_301_CHARS).to_dict("text")
Exemple #20
0
 def setUp(self) -> None:
     self.selected_opt = Option.from_single_value("U12345")
Exemple #21
0
class StaticSelectElementTests(unittest.TestCase):
    maxDiff = None

    def test_document_options(self):
        input = {
            "action_id":
            "text1234",
            "type":
            "static_select",
            "placeholder": {
                "type": "plain_text",
                "text": "Select an item"
            },
            "options": [
                {
                    "text": {
                        "type": "plain_text",
                        "text": "*this is plain_text text*"
                    },
                    "value": "value-0",
                },
                {
                    "text": {
                        "type": "plain_text",
                        "text": "*this is plain_text text*"
                    },
                    "value": "value-1",
                },
                {
                    "text": {
                        "type": "plain_text",
                        "text": "*this is plain_text text*"
                    },
                    "value": "value-2",
                },
            ],
        }
        self.assertDictEqual(input, StaticSelectElement(**input).to_dict())

    def test_document_option_groups(self):
        input = {
            "action_id":
            "text1234",
            "type":
            "static_select",
            "placeholder": {
                "type": "plain_text",
                "text": "Select an item"
            },
            "option_groups": [
                {
                    "label": {
                        "type": "plain_text",
                        "text": "Group 1"
                    },
                    "options": [
                        {
                            "text": {
                                "type": "plain_text",
                                "text": "*this is plain_text text*",
                            },
                            "value": "value-0",
                        },
                        {
                            "text": {
                                "type": "plain_text",
                                "text": "*this is plain_text text*",
                            },
                            "value": "value-1",
                        },
                        {
                            "text": {
                                "type": "plain_text",
                                "text": "*this is plain_text text*",
                            },
                            "value": "value-2",
                        },
                    ],
                },
                {
                    "label": {
                        "type": "plain_text",
                        "text": "Group 2"
                    },
                    "options": [{
                        "text": {
                            "type": "plain_text",
                            "text": "*this is plain_text text*",
                        },
                        "value": "value-3",
                    }],
                },
            ],
        }
        self.assertDictEqual(input, StaticSelectElement(**input).to_dict())

    option_one = Option.from_single_value("one")
    option_two = Option.from_single_value("two")
    options = [option_one, option_two, Option.from_single_value("three")]

    def test_json(self):
        dict_options = []
        for o in self.options:
            dict_options.append(o.to_dict())

        self.assertDictEqual(
            {
                "placeholder": {
                    "emoji": True,
                    "text": "selectedValue",
                    "type": "plain_text",
                },
                "action_id": "dropdown",
                "options": dict_options,
                "initial_option": self.option_two.to_dict(),
                "type": "static_select",
            },
            StaticSelectElement(
                placeholder="selectedValue",
                action_id="dropdown",
                options=self.options,
                initial_option=self.option_two,
            ).to_dict(),
        )

        self.assertDictEqual(
            {
                "placeholder": {
                    "emoji": True,
                    "text": "selectedValue",
                    "type": "plain_text",
                },
                "action_id":
                "dropdown",
                "options":
                dict_options,
                "confirm":
                ConfirmObject(title="title", text="text").to_dict("block"),
                "type":
                "static_select",
            },
            StaticSelectElement(
                placeholder="selectedValue",
                action_id="dropdown",
                options=self.options,
                confirm=ConfirmObject(title="title", text="text"),
            ).to_dict(),
        )

    def test_options_length(self):
        with self.assertRaises(SlackObjectFormationError):
            StaticSelectElement(
                placeholder="select",
                action_id="selector",
                options=[self.option_one] * 101,
            ).to_dict()
class OptionTests(unittest.TestCase):
    def setUp(self) -> None:
        self.common = Option(label="an option", value="option_1")

    def test_block_style_json(self):
        expected = {
            "text": {
                "type": "plain_text",
                "text": "an option",
                "emoji": True
            },
            "value": "option_1",
        }
        self.assertDictEqual(expected, self.common.to_dict("block"))
        self.assertDictEqual(expected, self.common.to_dict())

    def test_dialog_style_json(self):
        expected = {"label": "an option", "value": "option_1"}
        self.assertDictEqual(expected, self.common.to_dict("dialog"))

    def test_action_style_json(self):
        expected = {"text": "an option", "value": "option_1"}
        self.assertDictEqual(expected, self.common.to_dict("action"))

    def test_from_single_value(self):
        option = Option(label="option_1", value="option_1")
        self.assertDictEqual(
            option.to_dict("text"),
            option.from_single_value("option_1").to_dict("text"),
        )

    def test_label_length(self):
        with self.assertRaises(SlackObjectFormationError):
            Option(label=STRING_301_CHARS, value="option_1").to_dict("text")

    def test_value_length(self):
        with self.assertRaises(SlackObjectFormationError):
            Option(label="option_1", value=STRING_301_CHARS).to_dict("text")

    def test_valid_description_for_blocks(self):
        option = Option(label="label",
                        value="v",
                        description="this is an option")
        self.assertDictEqual(
            option.to_dict(),
            {
                "text": {
                    "type": "plain_text",
                    "text": "label",
                    "emoji": True,
                },
                "value": "v",
                "description": {
                    "type": "plain_text",
                    "text": "this is an option",
                    "emoji": True,
                },
            },
        )
        option = Option(
            # Note that mrkdwn type is not allowed for this (as of April 2021)
            text=PlainTextObject(text="label"),
            value="v",
            description="this is an option",
        )
        self.assertDictEqual(
            option.to_dict(),
            {
                "text": {
                    "type": "plain_text",
                    "text": "label"
                },
                "value": "v",
                "description": {
                    "type": "plain_text",
                    "text": "this is an option",
                    "emoji": True,
                },
            },
        )

    def test_valid_description_for_attachments(self):
        option = Option(label="label",
                        value="v",
                        description="this is an option")
        # legacy message actions in attachments
        self.assertDictEqual(
            option.to_dict("action"),
            {
                "text": "label",
                "value": "v",
                "description": "this is an option",
            },
        )
        self.assertDictEqual(
            option.to_dict("attachment"),
            {
                "text": "label",
                "value": "v",
                "description": "this is an option",
            },
        )