diff --git a/callbacks/echo.py b/callbacks/echo.py index 6d2532d..511fb01 100644 --- a/callbacks/echo.py +++ b/callbacks/echo.py @@ -7,7 +7,7 @@ from behaviours.trigger_payment_reminder import trigger_payment_reminder from db.queries import find_row_by_chat_id, find_all_info_by_chat_id, update_players_on_db, update_teams_on_db, \ is_already_present -from utils.utils import flatten_args, get_sender_name, filter_maybe_placeholders, swap_players, \ +from utils.utils import flatten_args, get_sender_name, exclude_maybe, swap_players, \ format_summary from utils.constants import maybe_placeholder @@ -40,13 +40,13 @@ def echo(update: Update, context: CallbackContext): update_players_on_db(chat_id, sender + maybe_placeholder, "remove") update_players_on_db(chat_id, sender, "add") show_summary = True - reached_target = players and len(filter_maybe_placeholders(players)) + 1 == target + reached_target = players and len(exclude_maybe(players)) + 1 == target else: if not players or len(players) <= target - 1: answer = 'Ok, ' + sender + ', ti aggiungo' update_players_on_db(chat_id, sender, "add") show_summary = True - reached_target = players and len(filter_maybe_placeholders(players)) + 1 == target + reached_target = players and len(exclude_maybe(players)) + 1 == target else: answer = 'Siete già in ' + str(target) show_summary = False @@ -61,13 +61,13 @@ def echo(update: Update, context: CallbackContext): update_players_on_db(chat_id, to_be_added + maybe_placeholder, "remove") update_players_on_db(chat_id, to_be_added, "add") show_summary = True - reached_target = players and len(filter_maybe_placeholders(players)) + 1 == target + reached_target = players and len(exclude_maybe(players)) + 1 == target else: if not players or len(players) <= target - 1: answer = 'Ok, aggiungo ' + to_be_added update_players_on_db(chat_id, to_be_added, "add") show_summary = True - reached_target = players and len(filter_maybe_placeholders(players)) + 1 == target + reached_target = players and len(exclude_maybe(players)) + 1 == target else: answer = 'Siete già in ' + str(target) show_summary = False @@ -156,12 +156,12 @@ def echo(update: Update, context: CallbackContext): elif not is_already_present(chat_id, y): answer = y + " non c'è" else: - error, teams = swap_players(teams, x, y) - if error: - answer = x + " e " + y + " sono nella stessa squadra!" - else: + try: + teams = swap_players(teams, x, y) update_teams_on_db(chat_id, teams) answer = "Perfetto, ho scambiato " + x + " con " + y + except Exception: + answer = x + " e " + y + " sono nella stessa squadra!" context.bot.send_message(chat_id=update.effective_chat.id, parse_mode='markdown', text=escape_markdown(answer)) diff --git a/callbacks/set_number.py b/callbacks/set_number.py index a269af2..ab3eb70 100644 --- a/callbacks/set_number.py +++ b/callbacks/set_number.py @@ -6,7 +6,7 @@ from behaviours.remove_job_if_exists import remove_job_if_exists from behaviours.trigger_payment_reminder import trigger_payment_reminder from db.queries import find_all_info_by_chat_id, update_teams_on_db, update_target_on_db -from utils.utils import get_sender_name, filter_maybe_placeholders, format_summary +from utils.utils import get_sender_name, exclude_maybe, format_summary def set_number(update: Update, context: CallbackContext): chat_id = update.message.chat_id @@ -26,7 +26,7 @@ def set_number(update: Update, context: CallbackContext): if players is None: participants_num = 0 else: - participants_num = len(filter_maybe_placeholders(players)) + participants_num = len(exclude_maybe(players)) if choosen_number_str.isnumeric(): choosen_number = int(choosen_number_str) diff --git a/callbacks/teams.py b/callbacks/teams.py index 6206122..fca6a33 100644 --- a/callbacks/teams.py +++ b/callbacks/teams.py @@ -1,7 +1,7 @@ from telegram import Update from telegram.ext import CallbackContext from db.queries import find_all_info_by_chat_id, update_teams_on_db -from utils.utils import filter_maybe_placeholders, format_teams, generate_teams +from utils.utils import exclude_maybe, format_teams, generate_teams import json def teams(update: Update, context: CallbackContext): @@ -18,7 +18,7 @@ def teams(update: Update, context: CallbackContext): if players is None: participants_num = 0 else: - participants_num = len(filter_maybe_placeholders(players)) + participants_num = len(exclude_maybe(players)) reached_target = players and participants_num == target if teams is not None: diff --git a/test/test_utils.py b/test/test_utils.py index b056b10..83e5cfb 100644 --- a/test/test_utils.py +++ b/test/test_utils.py @@ -1,7 +1,8 @@ import unittest -from unittest.mock import patch +from telegram import Update +from unittest.mock import patch, MagicMock from datetime import datetime -from utils.utils import get_next_weekday, compute_next_wednesday +from utils.utils import get_next_weekday, compute_next_wednesday, get_sender_name, swap_players, generate_teams, flatten_args, exclude_maybe, format_teams, format_summary class TestUtils(unittest.TestCase): @@ -53,5 +54,153 @@ def test_compute_next_wednesday(self, mock_date): mock_date.strftime = datetime.strftime self.assertEqual(compute_next_wednesday(), '17/11/2021') + def test_get_sender_name(self): + mock_update = MagicMock(spec=Update) + mock_update.message.from_user.username = 'JohnDoe' + self.assertEqual(get_sender_name(mock_update), 'johndoe') + + def test_swap_players(self): + # Test case 1: Swap two players from different teams + teams = {'black': ['JohnDoe', 'JaneDoe', 'Alice'], 'white': ['Bob', 'Charlie', 'Eve']} + x = 'JohnDoe' + y = 'Bob' + new_teams = swap_players(teams, x, y) + self.assertEqual(new_teams, '{"black": ["Bob", "JaneDoe", "Alice"], "white": ["JohnDoe", "Charlie", "Eve"]}') + + # Test case 2: Swap two players from the same team + teams = {'black': ['JohnDoe', 'JaneDoe', 'Alice'], 'white': ['Bob', 'Charlie', 'Eve']} + x = 'JohnDoe' + y = 'JaneDoe' + with self.assertRaises(Exception): + swap_players(teams, x, y) + + @patch('utils.utils.random.sample') + def test_generate_teams(self, mock_sample): + players = ['JohnDoe', 'JaneDoe', 'Alice', 'Bob', 'Charlie', 'Eve'] + + # Mock the output of random.sample + mock_sample.return_value = ['JohnDoe', 'JaneDoe', 'Alice'] + + expected_result = '{"black": ["JohnDoe", "JaneDoe", "Alice"], "white": ["Bob", "Charlie", "Eve"]}' + result = generate_teams(players) + self.assertEqual(result, expected_result) + + def test_flatten_args(self): + # Test case 1: Single argument + args = ['Wednesday'] + self.assertEqual(flatten_args(args), 'Wednesday') + + # Test case 2: Multiple arguments + args = ['Wednesday', '01/01/2000'] + self.assertEqual(flatten_args(args), 'Wednesday 01/01/2000') + + # Test case 3: No arguments + args = [] + self.assertEqual(flatten_args(args), '') + + def test_exclude_maybe(self): + # Test case 1: No placeholders + players = ['JohnDoe', 'JaneDoe', 'Alice', 'Bob', 'Charlie', 'Eve'] + self.assertEqual(exclude_maybe(players), players) + + # Test case 2: Placeholders present + players = ['JohnDoe', 'JaneDoe', 'Alice%is%maybe%present', 'Bob', 'Charlie', 'Eve%is%maybe%present'] + self.assertEqual(exclude_maybe(players), ['JohnDoe', 'JaneDoe', 'Bob', 'Charlie']) + + def test_format_teams(self): + # Test case 1: Teams are empty + teams = '{}' + with self.assertRaises(Exception): + format_teams(teams) + + # Test case 2: Teams are not empty + teams = '{"black": ["JohnDoe", "JaneDoe", "Alice"], "white": ["Bob", "Charlie", "Eve"]}' + self.assertEqual(format_teams(teams), '*SQUADRA NERA* \n - JohnDoe\n - JaneDoe\n - Alice\n\n*SQUADRA BIANCA* \n - Bob\n - Charlie\n - Eve\n') + + def test_format_summary(self): + # Test case 1: No players + all_players = [] + day = 'Wednesday' + time = '20:00' + target = 6 + default_message = 'Default message' + pitch = 'Pitch' + expected_output = ( + "*GIORNO*: Wednesday | 20:00\n\n" + "1. ❌\n" + "2. ❌\n" + "3. ❌\n" + "4. ❌\n" + "5. ❌\n" + "6. ❌\n\n" + "Default message\n\n" + "*CAMPO*: \n" + "Pitch" + ) + self.assertEqual(format_summary(all_players, day, time, target, default_message, pitch), expected_output) + + # Test case 2: Full players present + all_players = ['JohnDoe', 'JaneDoe', 'Alice', 'Bob', 'Charlie', 'Eve'] + day = 'Wednesday' + time = '20:00' + target = 6 + default_message = 'Default message' + pitch = 'Pitch' + expected_output = ( + "*GIORNO*: Wednesday | 20:00\n\n" + "1. JohnDoe ✅\n" + "2. JaneDoe ✅\n" + "3. Alice ✅\n" + "4. Bob ✅\n" + "5. Charlie ✅\n" + "6. Eve ✅\n\n" + "Default message\n\n" + "*CAMPO*: \n" + "Pitch" + ) + self.assertEqual(format_summary(all_players, day, time, target, default_message, pitch), expected_output) + + # Test case 3: Some players present + all_players = ['JohnDoe', 'JaneDoe', 'Alice', 'Bob', 'Charlie'] + day = 'Wednesday' + time = '20:00' + target = 6 + default_message = 'Default message' + pitch = 'Pitch' + expected_output = ( + "*GIORNO*: Wednesday | 20:00\n\n" + "1. JohnDoe ✅\n" + "2. JaneDoe ✅\n" + "3. Alice ✅\n" + "4. Bob ✅\n" + "5. Charlie ✅\n" + "6. ❌\n\n" + "Default message\n\n" + "*CAMPO*: \n" + "Pitch" + ) + self.assertEqual(format_summary(all_players, day, time, target, default_message, pitch), expected_output) + + # Test case 4: Some players present, some maybe + all_players = ['JohnDoe', 'JaneDoe', 'Alice%is%maybe%present', 'Bob', 'Charlie%is%maybe%present'] + day = 'Wednesday' + time = '20:00' + target = 6 + default_message = 'Default message' + pitch = 'Pitch' + expected_output = ( + "*GIORNO*: Wednesday | 20:00\n\n" + "1. JohnDoe ✅\n" + "2. JaneDoe ✅\n" + "3. Alice ❓\n" + "4. Bob ✅\n" + "5. Charlie ❓\n" + "6. ❌\n\n" + "Default message\n\n" + "*CAMPO*: \n" + "Pitch" + ) + self.assertEqual(format_summary(all_players, day, time, target, default_message, pitch), expected_output) + if __name__ == '__main__': unittest.main() \ No newline at end of file diff --git a/utils/utils.py b/utils/utils.py index 52ea6ea..c33e0b4 100644 --- a/utils/utils.py +++ b/utils/utils.py @@ -1,12 +1,11 @@ from datetime import datetime, timedelta from dateutil.parser import parse +from telegram import Update from telegram.utils.helpers import escape_markdown from utils.constants import maybe_placeholder import random import json - - def get_next_weekday(startdate: str, weekday: int) -> str: """ Get the next weekday from a given date @@ -42,14 +41,12 @@ def extract_match_time(time): def compute_seconds_from_now(destination_date): return destination_date.timestamp() - datetime.now().timestamp() -def get_sender_name(source): +def get_sender_name(source: Update): return source.message.from_user.username.lower() def swap_players(teams, x, y): - error = False - if (x in teams['black'] and y in teams['black']) or (x in teams['white'] and y in teams['white']): - error = True + raise Exception("Not allowed to swap two players of the same team") temp_black = None temp_white = None @@ -67,7 +64,7 @@ def swap_players(teams, x, y): teams['black'] = temp_black teams['white'] = temp_white - return error, json.dumps(teams) + return json.dumps(teams) def generate_teams(players): black_team = random.sample(players, int(len(players)/2)) @@ -79,21 +76,17 @@ def generate_teams(players): return json.dumps(teams) def flatten_args(args): - res = "" - - for index, arg in enumerate(args): - if index == 0: - res = str(arg) - else: - res = res + " " + str(arg) - - return res + return " ".join(map(str, args)) -def filter_maybe_placeholders(players): +def exclude_maybe(players): return [player for player in players if maybe_placeholder not in player] def format_teams(teams): json_teams = json.loads(teams) + + if json_teams == {}: + raise Exception("Teams are empty") + black_team = json_teams["black"] white_team = json_teams["white"] @@ -109,28 +102,20 @@ def format_teams(teams): return teams_message def format_summary(all_players, day, time, target, default_message, pitch): - player_list = "" - - prefix = "*GIORNO*: " + escape_markdown(day) + " | " + escape_markdown(time) + "\n"\ - if pitch is None: pitch = "Usa il comando /setpitch per inserire la struttura sportiva dove giocherete." - appendix = default_message + \ - "\n"\ - "*CAMPO*: \n"\ - + escape_markdown(pitch) + prefix = f"*GIORNO*: {escape_markdown(day)} | {escape_markdown(time)}\n\n" + appendix = f"{default_message}\n\n*CAMPO*: \n{escape_markdown(pitch)}" - for i in range(0, target): + player_list = "" + for i in range(target): if all_players and i < len(all_players): player = all_players[i] - if player.endswith(maybe_placeholder): - player = player.replace(maybe_placeholder, "") - presence_outcome_icon = "❓" - else: - presence_outcome_icon = "✅" - player_list = player_list + str(i + 1) + ". " + escape_markdown(player) + " " + presence_outcome_icon + "\n" + presence_outcome_icon = "❓" if player.endswith(maybe_placeholder) else "✅" + player = player.replace(maybe_placeholder, "") if presence_outcome_icon == "❓" else player + player_list += f"{i + 1}. {escape_markdown(player)} {presence_outcome_icon}\n" else: - player_list = player_list + str(i + 1) + ". ❌ \n" + player_list += f"{i + 1}. ❌\n" - return prefix + "\n" + player_list + "\n" + appendix + return prefix + player_list + "\n" + appendix