Repository: slackapi/python-slack-sdk (python)

Issue:
ActionsBlock elements are not parsed
### Description

In ActionsBlock __init__, elements are simplie copied. 
[Exact bug place](https://github.com/slackapi/python-slack-sdk/blob/4e4524230ed41ef7cd9d637c52f4e86b1ffedad9/slack/web/classes/blocks.py#L241)

For all other Blocks, similar elements are parsed into BlockElement 
[How it parsed for SectionBlock](https://github.com/slackapi/python-slack-sdk/blob/4e4524230ed41ef7cd9d637c52f4e86b1ffedad9/slack/web/classes/blocks.py#L143)
[How it is parsed for ContextBlock](https://github.com/slackapi/python-slack-sdk/blob/4e4524230ed41ef7cd9d637c52f4e86b1ffedad9/slack/web/classes/blocks.py#L269)

To fix this we can deal with it the same way as in ContextBlock -> replace [this line of code](https://github.com/slackapi/python-slack-sdk/blob/4e4524230ed41ef7cd9d637c52f4e86b1ffedad9/slack/web/classes/blocks.py#L241) by 
`self.elements = BlockElement.parse_all(elements)` 

Also the same issue present in current sdk version(3.1.0)
[Link for bug place in 3.1.0](https://github.com/slackapi/python-slack-sdk/blob/5340ee337a2364e84c38d696c107f19c341dd6eb/slack_sdk/models/blocks/blocks.py#L246)
### Reproducible in:

#### The Slack SDK version

slackclient==2.9.3

#### Python runtime version

Python 3.7.0

#### OS info

Ubuntu 20.04.1 LTS

#### Steps to reproduce:

1.Copy example json from slack API docs for ActionsBlock (https://api.slack.com/reference/block-kit/blocks#actions_examples)
2.Create an ActionsBlock  from parsed (to dict) json
3. Check the type of elements attribute from created ActionsBlock object

### Expected result:

Elements should be instances of BlockElement, the same as it is for SectionBlock.accessory

### Actual result:

Elements of ActionsBlock is not parsed


Pull request description:
Fix #903 by parsing in ActionsBlock
## Summary

Fix [issue 903](https://github.com/slackapi/python-slack-sdk/issues/903)

### Category (place an `x` in each of the `[ ]`)

- [ ] **slack_sdk.web.WebClient** (Web API client)
- [ ] **slack_sdk.webhook.WebhookClient** (Incoming Webhook, response_url sender)
- [x] **slack_sdk.models** (UI component builders)
- [ ] **slack_sdk.oauth** (OAuth Flow Utilities)
- [ ] **slack_sdk.rtm.RTMClient** (RTM client)
- [ ] **slack_sdk.signature** (Request Signature Verifier)
- [ ] `/docs-src` (Documents, have you run `./docs.sh`?)
- [ ] `/docs-src-v2` (Documents, have you run `./docs-v2.sh`?)

## Requirements (place an `x` in each `[ ]`)

- [x] I've read and understood the [Contributing Guidelines](https://github.com/slackapi/python-slack-sdk/blob/main/.github/contributing.md) and have done my best effort to follow them.
- [x] I've read and agree to the [Code of Conduct](https://slackhq.github.io/code-of-conduct).
- [x] I've run `python setup.py validate` after making the changes.


Patch:
diff --git a/slack_sdk/models/blocks/blocks.py b/slack_sdk/models/blocks/blocks.py
index 69b45c5..f53794b 100644
--- a/slack_sdk/models/blocks/blocks.py
+++ b/slack_sdk/models/blocks/blocks.py
@@ -243,7 +243,7 @@ class ActionsBlock(Block):
         super().__init__(type=self.type, block_id=block_id)
         show_unknown_key_warning(self, others)
 
-        self.elements = elements
+        self.elements = BlockElement.parse_all(elements)
 
     @JsonValidator(f"elements attribute cannot exceed {elements_max_length} elements")
     def _validate_elements_length(self):


Test patch:
diff --git a/tests/slack_sdk/web/classes/test_blocks.py b/tests/slack_sdk/web/classes/test_blocks.py
index 5f694b6..55b577b 100644
--- a/tests/slack_sdk/web/classes/test_blocks.py
+++ b/tests/slack_sdk/web/classes/test_blocks.py
@@ -13,11 +13,14 @@ from slack_sdk.models.blocks import (
     Block,
     CallBlock,
     ButtonElement,
+    StaticSelectElement,
+    OverflowMenuElement,
     ImageElement,
     LinkButtonElement,
     PlainTextObject,
     MarkdownTextObject,
     HeaderBlock,
+    Option,
 )
 from . import STRING_3001_CHARS
 
@@ -404,6 +407,26 @@ class ActionsBlockTests(unittest.TestCase):
         with self.assertRaises(SlackObjectFormationError):
             ActionsBlock(elements=self.elements * 3).to_dict()
 
+    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())
+
 
 # ----------------------------------------------
 # Context