1
0

test_bot_streaks.py 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778
  1. """Tests des conversations avec d'autres bots : pas de boucle sans fin. Lancer depuis la racine du projet : python -m unittest"""
  2. import unittest
  3. from datetime import datetime, timedelta, timezone
  4. from unittest import mock
  5. import discord
  6. from bot.discord_bot import BOT_STREAK_RESET, MAX_BOT_REPLIES, BotStreaks, ChatBot
  7. HOME = 1000
  8. CHANNEL_ID = 10
  9. START = datetime(2026, 11, 3, 18, 0, tzinfo=timezone.utc)
  10. class BotStreaksTest(unittest.TestCase):
  11. def test_counts_per_channel(self):
  12. streaks = BotStreaks()
  13. self.assertEqual(streaks.count(1, START), 1)
  14. self.assertEqual(streaks.count(1, START), 2)
  15. self.assertEqual(streaks.count(2, START), 1)
  16. def test_human_resets(self):
  17. streaks = BotStreaks()
  18. streaks.count(1, START)
  19. streaks.human_spoke(1)
  20. self.assertEqual(streaks.count(1, START), 1)
  21. def test_quiet_channel_resets(self):
  22. streaks = BotStreaks()
  23. streaks.count(1, START)
  24. self.assertEqual(streaks.count(1, START + BOT_STREAK_RESET), 2)
  25. self.assertEqual(streaks.count(1, START + 2 * BOT_STREAK_RESET + timedelta(seconds=1)), 1)
  26. class OnMessageTest(unittest.IsolatedAsyncioTestCase):
  27. def setUp(self):
  28. self.bot = mock.Mock()
  29. self.bot.settings.channel_id = CHANNEL_ID
  30. self.bot.home_guild_id.return_value = HOME
  31. self.bot._bot_streaks = BotStreaks()
  32. self.bot.handle_main_channel = mock.AsyncMock()
  33. self.bot.register_members = mock.AsyncMock()
  34. async def receive(self, from_bot: bool, when: datetime = START) -> None:
  35. message = mock.Mock(guild=mock.Mock(id=HOME), webhook_id=None, type=discord.MessageType.reply,
  36. created_at=when)
  37. message.channel.id = CHANNEL_ID
  38. message.author.bot = from_bot
  39. message.mentions = [self.bot.user] # « Répondre » avec ping
  40. await ChatBot.on_message(self.bot, message)
  41. async def test_bot_loop_stopped(self):
  42. # Un bot qui répond à chacun de ses messages : le bot s'arrête après MAX_BOT_REPLIES réponses.
  43. with self.assertLogs("chatbot.discord", "WARNING") as logs:
  44. for _ in range(MAX_BOT_REPLIES + 3):
  45. await self.receive(from_bot=True)
  46. self.assertEqual(self.bot.handle_main_channel.await_count, MAX_BOT_REPLIES)
  47. self.assertEqual(len(logs.records), 1) # un seul avertissement par série
  48. async def test_member_message_restarts(self):
  49. with self.assertLogs("chatbot.discord", "WARNING"):
  50. for _ in range(MAX_BOT_REPLIES + 1):
  51. await self.receive(from_bot=True)
  52. await self.receive(from_bot=False)
  53. await self.receive(from_bot=True)
  54. self.assertEqual(self.bot.handle_main_channel.await_count, MAX_BOT_REPLIES + 2)
  55. async def test_quiet_channel_restarts(self):
  56. with self.assertLogs("chatbot.discord", "WARNING"):
  57. for _ in range(MAX_BOT_REPLIES + 1):
  58. await self.receive(from_bot=True)
  59. await self.receive(from_bot=True, when=START + BOT_STREAK_RESET + timedelta(seconds=1))
  60. self.assertEqual(self.bot.handle_main_channel.await_count, MAX_BOT_REPLIES + 1)
  61. if __name__ == "__main__":
  62. unittest.main()