By oneor0


2019-01-09 10:20:24 8 Comments

I have the function which builds and return Slack message with text and attachments. How can I refactor this function to make it easier to test? Should I split it into multiple functions?

def build_list_message(team_id, user_id, msg_state=None, chl_state=None):
    if not msg_state:
        msg_state = {}

    if not chl_state:
        chl_state = {}

    resource_type = msg_state.get('resource_type', 'all')
    availability = msg_state.get('resource_availability', 'all')

    pages = Page.objects.none()
    async_tasks = AsyncTask.objects.none()

    if resource_type in ['web_pages', 'all']:
        pages = Page.objects.filter(
            user__team__team_id=team_id).order_by('title')

    if resource_type in ['async_tasks', 'all']:
        async_tasks = AsyncTask.objects.filter(
            user__team__team_id=team_id).order_by('title')

    if availability == 'available':
        pages = pages.filter(available=True)
        async_tasks = async_tasks.filter(available=True)

    elif availability == 'unavailable':
        pages = pages.filter(available=False)
        async_tasks = async_tasks.filter(available=False)

    channel_id = chl_state.get('channel_id')
    if channel_id:
        pages = pages.filter(alert_channel=channel_id)
        async_tasks = async_tasks.filter(alert_channel=channel_id)

    user = SlackUser.retrieve(team_id, user_id)

    attachments = [
        _build_filters(resource_type, availability),
        *[_build_page_item(p, user) for p in pages],
        *[_build_async_task_item(at, user) for at in async_tasks]
    ]

    return {
        'text': "Here's the list of all monitoring resources",
        'attachments': attachments
    }

Here is private functions:

def _build_filters(resource_type, availability):
    resource_types = [
        {"text": "All types", "value": "all"},
        {"text": ":link: Webpages", "value": "web_pages"}
    ]

    availability_choices = [
        {"text": "Available / Unavailable", "value": "all"},
        {"text": ":white_circle: Available", "value": "available"},
        {"text": ":red_circle: Unavaliable", "value": "unavailable"}
    ]

    selected_resource_types = list(filter(
        lambda t: t['value'] == resource_type, resource_types))

    selected_availability_choices = list(filter(
        lambda a: a['value'] == availability, availability_choices))

    return {
        "fallback": "Resource filters",
        "color": "#d2dde1",
        "mrkdwn_in": ["text"],
        "callback_id": "resource_filters",
        "actions": [
            {
                "name": "resource_type",
                "text": "Type",
                "type": "select",
                "options": resource_types,
                "selected_options": selected_resource_types
            },
            {
                "name": "resource_availability",
                "text": "Available",
                "type": "select",
                "options": availability_choices,
                "selected_options": selected_availability_choices
            }
        ]
    }


def _build_page_item(page, user):
    return {
        "fallback": "Page",
        "color": page.status_color,
        "mrkdwn_in": ["fields"],
        "callback_id": 'page_change',
        "fields": [
            {
                "title": page.title,
                "value": f"_Page_ ({page.status})"
            },
            {
                "title": "URL",
                "value": page.url
            }
        ],
        "footer": _build_resource_footer(page),
        "actions": _build_resource_item_actions(page, user)
    }


def _build_async_task_item(async_task, user):
    return {
        "fallback": "Async task",
        "color": async_task.status_color,
        "mrkdwn_in": ["fields"],
        "callback_id": 'async_task_change',
        "fields": [
            {
                "title": async_task.title,
                "value": f"_Async task_ ({async_task.status})"
            },
            {
                "title": "URL",
                "value": async_task.url
            }
        ],
        "footer": _build_resource_footer(async_task),
        "actions": _build_resource_item_actions(async_task, user)
    }

0 comments

Related Questions

Sponsored Content

1 Answered Questions

2 Answered Questions

[SOLVED] Building a Bill of Materials

  • 2017-03-31 21:17:28
  • travBoog
  • 1096 View
  • 4 Score
  • 2 Answer
  • Tags:   python

1 Answered Questions

[SOLVED] Parsing Wikipedia data in Python

1 Answered Questions

[SOLVED] Basic call-and-response Slack bot

  • 2016-06-30 01:17:25
  • Amanda
  • 387 View
  • 2 Score
  • 1 Answer
  • Tags:   python python-2.x

2 Answered Questions

[SOLVED] Web Scraper in Python

1 Answered Questions

[SOLVED] Steganographic message hiding

1 Answered Questions

2 Answered Questions

[SOLVED] Reverse Message Program

  • 2014-10-17 09:40:12
  • AlexDGrattan
  • 1333 View
  • 1 Score
  • 2 Answer
  • Tags:   python strings

2 Answered Questions

[SOLVED] Building SQL query

  • 2014-03-21 21:21:38
  • broinjc
  • 122 View
  • 7 Score
  • 2 Answer
  • Tags:   python django

3 Answered Questions

[SOLVED] Building and getting a form of objects that have multiple properties

  • 2012-05-19 14:29:11
  • Kit Sunde
  • 81 View
  • 2 Score
  • 3 Answer
  • Tags:   python html django

Sponsored Content