import asyncio import sys import os sys.path.insert(0, "/home/marco/MonicaAgentIA/app") os.environ["TELEGRAM_BOT_TOKEN"] = "test" os.environ["TELEGRAM_CHAT_ID"] = "123" from monica_agent import ( agendamento_command, load_user_profile, save_user_profile, clear_all_data, is_valid_time, time_to_minutes, is_within_schedule, message_handler, ) class FakeMessage: def __init__(self, text): self.text = text self.chat_id = 7889499475 async def reply_text(self, text, **kwargs): print(f"BOT RESPONSE: {text[:400]}") class FakeUpdate: def __init__(self, text): self.message = FakeMessage(text) self.effective_chat = self self.effective_user = self self.effective_message = self.message @property def id(self): return self.message.chat_id @property def username(self): return "test_user" @property def first_name(self): return "Marco" class FakeContext: def __init__(self): self.bot = self async def send_message(self, **kwargs): print(f"BOT SEND: {kwargs.get('text', '')[:400]}") async def test_agendamento_command(): print("=== Testando /agendamento ===") update = FakeUpdate("/agendamento") context = FakeContext() try: await agendamento_command(update, context) print("✅ agendamento_command executou sem erros") except Exception as e: print(f"❌ Erro: {e}") import traceback traceback.print_exc() async def test_agendamento_flow(): print("\n=== Testando fluxo /agendamento ===") profile = load_user_profile() profile["proactive_schedule"] = {} save_user_profile(profile) update = FakeUpdate("/agendamento") context = FakeContext() await agendamento_command(update, context) update = FakeUpdate("1,2,3,4,5") context = FakeContext() handled = await message_handler(update, context) print(f" Após selecionar dias: handled={handled}") update = FakeUpdate("09:00") context = FakeContext() handled = await message_handler(update, context) print(f" Após enviar start time: handled={handled}") update = FakeUpdate("22:00") context = FakeContext() handled = await message_handler(update, context) print(f" Após enviar end time: handled={handled}") profile = load_user_profile() schedule = profile.get("proactive_schedule", {}) print(f" Schedule salvo: {schedule}") if schedule.get("enabled") and schedule.get("days") == [0, 1, 2, 3, 4] and schedule.get("start_time") and schedule.get("end_time"): print("✅ Agendamento salvo corretamente") else: print("❌ Agendamento não foi salvo como esperado") async def test_agendamento_flow_weekend(): print("\n=== Testando fluxo /agendamento (fim de semana) ===") profile = load_user_profile() profile["proactive_schedule"] = {} save_user_profile(profile) update = FakeUpdate("/agendamento") context = FakeContext() await agendamento_command(update, context) update = FakeUpdate("6,7") context = FakeContext() handled = await message_handler(update, context) print(f" Após selecionar dias: handled={handled}") update = FakeUpdate("14:00") context = FakeContext() handled = await message_handler(update, context) print(f" Após enviar start time: handled={handled}") update = FakeUpdate("23:59") context = FakeContext() handled = await message_handler(update, context) print(f" Após enviar end time: handled={handled}") profile = load_user_profile() schedule = profile.get("proactive_schedule", {}) print(f" Schedule salvo: {schedule}") if schedule.get("enabled") and schedule.get("days") == [5, 6] and schedule.get("start_time") and schedule.get("end_time"): print("✅ Agendamento de fim de semana salvo corretamente") else: print("❌ Agendamento de fim de semana não foi salvo como esperado") async def test_agendamento_invalid_days(): print("\n=== Testando dias inválidos ===") profile = load_user_profile() profile["proactive_schedule"] = {} save_user_profile(profile) update = FakeUpdate("/agendamento") context = FakeContext() await agendamento_command(update, context) update = FakeUpdate("9,10") context = FakeContext() handled = await message_handler(update, context) print(f" Após enviar dias inválidos: handled={handled}") profile = load_user_profile() schedule = profile.get("proactive_schedule", {}) if not schedule.get("enabled", False): print("✅ Dias inválidos foram rejeitados corretamente") else: print("❌ Dias inválidos foram aceitos (erro)") async def test_agendamento_invalid_time(): print("\n=== Testando horário inválido ===") profile = load_user_profile() profile["proactive_schedule"] = {} save_user_profile(profile) update = FakeUpdate("/agendamento") context = FakeContext() await agendamento_command(update, context) update = FakeUpdate("1,2,3") context = FakeContext() await message_handler(update, context) update = FakeUpdate("25:00") context = FakeContext() await message_handler(update, context) print(f" Após enviar horário inválido") profile = load_user_profile() schedule = profile.get("proactive_schedule", {}) if not schedule.get("start_time"): print("✅ Horário inválido foi rejeitado corretamente") else: print("❌ Horário inválido foi aceito (erro)") async def test_clear_all_data(): print("\n=== Testando /limpar ===") profile = load_user_profile() profile["name"] = "Marco" profile["proactive_schedule"] = { "enabled": True, "days": [0, 1, 2], "start_time": "08:00", "end_time": "20:00" } save_user_profile(profile) clear_all_data() profile = load_user_profile() if not profile.get("proactive_schedule"): print("✅ /limpar removeu o agendamento") else: print("❌ /limpar não removeu o agendamento") def test_is_valid_time(): print("\n=== Testando is_valid_time ===") cases = [ ("09:00", True), ("23:59", True), ("00:00", True), ("24:00", False), ("12:60", False), ("abc", False), ("", False), (None, False), ] all_ok = True for value, expected in cases: result = is_valid_time(value) status = "✅" if result == expected else "❌" print(f" {status} is_valid_time({value!r}) = {result} (esperado {expected})") if result != expected: all_ok = False return all_ok def test_is_within_schedule(): print("\n=== Testando is_within_schedule ===") from datetime import datetime from unittest.mock import patch base_profile = { "proactive_schedule": { "enabled": True, "days": [0, 1, 2, 3, 4], "start_time": "09:00", "end_time": "17:00" } } test_cases = [ (base_profile, "monday 10:00", True), (base_profile, "monday 08:00", False), (base_profile, "monday 17:00", True), (base_profile, "saturday 10:00", False), (base_profile, "sunday 10:00", False), ({"proactive_schedule": {}}, "monday 10:00", True), ({"proactive_schedule": {"enabled": False}}, "monday 10:00", True), ] all_ok = True for profile, time_str, expected in test_cases: dt_str, time_part = time_str.split(" ", 1) hour, minute = map(int, time_part.split(":")) dt_map = { "monday": "2026-08-24", "tuesday": "2026-08-25", "wednesday": "2026-08-26", "thursday": "2026-08-27", "friday": "2026-08-28", "saturday": "2026-08-29", "sunday": "2026-08-23", } date_str = dt_map.get(dt_str, "2026-08-25") test_dt = datetime.strptime(f"{date_str} {time_part}", "%Y-%m-%d %H:%M") with patch("monica_agent.datetime") as mock_dt: mock_dt.now.return_value = test_dt mock_dt.side_effect = datetime result = is_within_schedule(profile) status = "✅" if result == expected else "❌" print(f" {status} {time_str}: {result} (esperado {expected})") if result != expected: all_ok = False return all_ok async def main(): await test_agendamento_command() await test_agendamento_flow() await test_agendamento_flow_weekend() await test_agendamento_invalid_days() await test_agendamento_invalid_time() await test_clear_all_data() time_ok = test_is_valid_time() schedule_ok = test_is_within_schedule() print("\n=== Todos os testes concluídos ===") if time_ok and schedule_ok: print("✅ Todos os testes de agendamento passaram!") else: print("❌ Alguns testes falharam") if __name__ == "__main__": asyncio.run(main())