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()
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()
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)