288 lines
8.9 KiB
Python
Executable File
288 lines
8.9 KiB
Python
Executable File
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())
|