示例#1
0
def prepare_songs_for_poll(client: WebClient, poll: Poll, request_form: dict,
                           songs: list) -> None:
    """
    Function that create and save poll in storage.
    """
    # If previous steps are good, do ...
    poll.number_of_songs = len(songs)
    poll.storage.data['is_started'] = True

    # As slack message allows having only < 50 songs in the message, so next code
    # seperate all the songs on 30 songs chunks and put each chunk in its message.
    messages = []

    if len(songs) > 30:
        chunks = poll.divide_all_songs_into_chunks([songs])
    else:
        chunks = [songs]

    send_msg_to_chat(client, request_form,
                     "Please, vote for the next song to play 🎶")

    for songs_chunk in chunks:
        message_blocks = poll.create_poll_blocks(songs_chunk)
        response = send_msg_to_chat(client,
                                    request_form,
                                    '',
                                    blocks=message_blocks)
        messages.append({'id': response.get('ts'), 'songs': songs_chunk})

    poll.storage.data['messages'] = messages
    poll.storage.save()
示例#2
0
def start_resume(client: WebClient, poll: Poll, request_form: dict) -> None:
    """
    Function, that is invoked when we run /drop command.
    /drop is valid only for channel admin.
    """
    poll.storage.data = poll.storage.check_for_unfinished_poll() # Get data from unfinished poll  

    send_msg_to_chat(client, request_form, "Please, vote for the next song to play 🎶")
    for message in poll.storage.data['messages']:
        message_blocks = poll.create_poll_blocks(message.get('songs'))
        response = send_msg_to_chat(client, request_form, '', blocks=message_blocks)
        message['id'] = response.get('ts') # Update messages id
def handle_interactivity(client: WebClient, request, poll: Poll) -> None:
    """
    Function, that handles all the bot interactivity.
    """
    
    payload = json.loads(request.form.get('payload'))

    if payload['type'] == 'block_actions':
        # If button was tracked
        user_id = payload['user']['id']
        selected_song_id = payload['actions'][0]['value']
        songs_chunk_with_selected_song = poll.storage.get_songs_chunk_with_selected_song_id(selected_song_id)
        
        poll.update_votes(user_id, selected_song_id)

        channel_id = payload['container']['channel_id']
        message_id = payload['container']['message_ts']

        edit_msg_in_chat(client, channel_id, message_id, '', poll.create_poll_blocks(songs_chunk_with_selected_song))
        poll.storage.save()
示例#4
0
def start_poptop(client: WebClient, poll: Poll, request_form: dict) -> None:
    """
    Function, that is invoked when we run /poptop command.
    """
    channel_id = request_form.get('channel_id')
    selected_song_id = check_poptop_argument(poll, request_form)
    sorted_songs = sort_songs(poll.storage.get_all_songs())
    song = sorted_songs[selected_song_id - 1]
    message = poll.storage.get_message_from_song(song)

    if poll.is_music_upload:
        upload_song(client, request_form, song)
    else:
        send_msg_to_chat(
            client, request_form,
            f'Poptop song {selected_song_id} is {song["artist"]} - {song["title"]}'
        )

    # Reste selected song votes
    song['voted_users'] = []

    edit_msg_in_chat(client, channel_id, message.get('id'), "POPTOP SONG",
                     poll.create_poll_blocks(message.get('songs')))
    poll.storage.save()
class TestPoll(unittest.TestCase):
    """
    Testing Poll.
    """
    def setUp(self):
        self.poll = Poll()

    def test_get_is_started(self):
        self.poll.storage.data = {'is_started': True}
        self.assertTrue(self.poll.is_started)

    def test_set_is_started(self):
        self.poll.is_started = False
        self.assertFalse(self.poll.is_started)

        with self.assertRaises(TypeError):
            self.poll.is_started = 5

    def test_get_is_music_upload(self):
        self.poll.storage.data = {'is_music_upload': True}
        self.assertTrue(self.poll.is_music_upload)

    def test_set_is_music_upload(self):
        self.poll.is_music_upload = False
        self.assertFalse(self.poll.is_music_upload)

        with self.assertRaises(TypeError):
            self.poll.is_music_upload = 5

    @patch('poll.JsonPollStorage.get_all_songs')
    def test_update_votes(self, mock_func):
        mock_func.return_value = [{
            'value': 1,
            'title': 'Title1',
            'artist': 'Artist1',
            'link': 'Link1',
            'voted_users': []
        }, {
            'value': 2,
            'title': 'Title2',
            'artist': 'Artist2',
            'link': 'Link2',
            'voted_users': []
        }]

        add_user_result = [{
            'value': 1,
            'title': 'Title1',
            'artist': 'Artist1',
            'link': 'Link1',
            'voted_users': ['User1']
        }, {
            'value': 2,
            'title': 'Title2',
            'artist': 'Artist2',
            'link': 'Link2',
            'voted_users': []
        }]

        remove_user_result = [{
            'value': 1,
            'title': 'Title1',
            'artist': 'Artist1',
            'link': 'Link1',
            'voted_users': []
        }, {
            'value': 2,
            'title': 'Title2',
            'artist': 'Artist2',
            'link': 'Link2',
            'voted_users': []
        }]

        self.poll.update_votes('User1', '1')
        self.assertEqual(mock_func.return_value, add_user_result)

        self.poll.update_votes('User1', '1')
        self.assertEqual(mock_func.return_value, remove_user_result)

    def test_divide_all_songs_into_chunks(self):
        start_list = [[1, 2, 3, 4, 5, 6]]
        good_result = [[1, 2], [3, 4], [5, 6]]

        result = self.poll.divide_all_songs_into_chunks(start_list, 2)
        self.assertEqual(result, good_result)

        start_list = [[1, 2, 3, 4, 5]]
        good_result = [[1, 2], [3, 4], [5]]

        result = self.poll.divide_all_songs_into_chunks(start_list, 2)
        self.assertEqual(result, good_result)

    def test_create_poll_block(self):
        good_value_1 = [{
            'value': 1,
            'title': 'Title1',
            'artist': 'Artist1',
            'link': 'Link1',
            'voted_users': []
        }, {
            'value': 2,
            'title': 'Title2',
            'artist': 'Artist2',
            'link': 'Link2',
            'voted_users': [1]
        }]
        good_result_1 = [{
            "type": "section",
            "text": {
                "type": "plain_text",
                "text": "#"
            }
        }, {
            "type": "section",
            "text": {
                "type": "plain_text",
                "text": "1) Artist1 - Title1 ----- 0 votes"
            },
            'accessory': {
                'type': 'button',
                'text': {
                    'type': 'plain_text',
                    'text': 'Vote/Unvote'
                },
                'value': '1'
            }
        }, {
            "type": "section",
            "text": {
                "type": "plain_text",
                "text": "2) Artist2 - Title2 ----- 1 votes"
            },
            'accessory': {
                'type': 'button',
                'text': {
                    'type': 'plain_text',
                    'text': 'Vote/Unvote'
                },
                'value': '2'
            }
        }]

        # Check different indexes
        good_value_2 = [{
            'value': 10,
            'title': 'Title10',
            'artist': 'Artist10',
            'link': 'Link10',
            'voted_users': []
        }, {
            'value': 11,
            'title': 'Title11',
            'artist': 'Artist11',
            'link': 'Link11',
            'voted_users': []
        }]
        good_result_2 = [{
            "type": "section",
            "text": {
                "type": "plain_text",
                "text": "#"
            }
        }, {
            "type": "section",
            "text": {
                "type": "plain_text",
                "text": "10) Artist10 - Title10 ----- 0 votes"
            },
            'accessory': {
                'type': 'button',
                'text': {
                    'type': 'plain_text',
                    'text': 'Vote/Unvote'
                },
                'value': '10'
            }
        }, {
            "type": "section",
            "text": {
                "type": "plain_text",
                "text": "11) Artist11 - Title11 ----- 0 votes"
            },
            'accessory': {
                'type': 'button',
                'text': {
                    'type': 'plain_text',
                    'text': 'Vote/Unvote'
                },
                'value': '11'
            }
        }]

        self.assertEqual(good_result_1,
                         self.poll.create_poll_blocks(good_value_1))
        self.assertEqual(good_result_2,
                         self.poll.create_poll_blocks(good_value_2))

    @patch('poll.JsonPollStorage.get_all_songs')
    def test_find_winner_song(self, mock_func):
        mock_func.return_value = [
            {
                'value': 1,
                'title': 'Title1',
                'artist': 'Artist1',
                'link': 'Link1',
                'voted_users': []
            },
            {
                'value': 2,
                'title': 'Title2',
                'artist': 'Artist2',
                'link': 'Link2',
                'voted_users': [1, 2, 3]  # Winner
            },
            {
                'value': 3,
                'title': 'Title3',
                'artist': 'Artist3',
                'link': 'Link3',
                'voted_users': []
            }
        ]

        correct_winner = {
            'value': 2,
            'title': 'Title2',
            'artist': 'Artist2',
            'link': 'Link2',
            'voted_users': [1, 2, 3]
        }

        winner = self.poll.find_the_winner_song()
        self.assertEqual(correct_winner, winner)