Complete refactoring in order to use scheduler

This commit is contained in:
Mindiell 2024-04-01 19:27:52 +02:00
parent ed8ae46086
commit b9d2d2378a
49 changed files with 464 additions and 368 deletions

1
.gitignore vendored
View File

@ -2,6 +2,7 @@ venv/
__pycache__/
*.log
users.conf
reviews/
.coverage

View File

@ -1,3 +1,3 @@
# Hebdobot v3
Ce projet est une refonte d'Hebdobot pour l'april en python.
Ce projet est une refonte d'Hebdobot pour l'April en Python.

View File

@ -1,53 +0,0 @@
from dataclasses import dataclass
import time
from bot.hooks import hooks
from bot.review.review import Review
@dataclass
class Answer:
target: str
message: str
class Hebdobot:
def __init__(self, settings, channel, nickname="hebdobot"):
self.settings = settings
self.channel = channel
self.nickname = nickname
self.answers = []
# Gestion de la revue hebdomadaire
self.review = Review()
def on_private_message(self, channel, sender, message):
"""
Tous les messages privés sont ignorés. Si l'utilisateur tente une commande, on
lui signale de le faire plutôt sur le canal public.
"""
self.answers = []
if message[0] == "!":
self.send(sender, "vos commandes dans le salon public")
return self.answers
def on_public_message(self, channel, sender, message):
"""
Tous les messages publics sont pris en compte. On utilise les hooks chargés au
démarrage pour cela.
"""
self.answers = []
if self.review.is_started:
self.review.add_message(sender, message)
for hook in hooks:
if hook.process(self, channel, sender, message):
break
return self.answers
def send(self, target, message):
self.answers.append(Answer(target, message))
if self.review.is_started and target == self.channel:
self.review.add_message(self.nickname, message)

View File

@ -1,44 +0,0 @@
import logger
class Help:
def process(self, bot, channel, sender, message):
"""
Le message est pris en compte si l'utilisateur demande de l'aide.
"""
if message.lower() in ("!aide", "!help", "!aide hebdobot", "!help hebdobot"):
logger.info("!help caught.")
bot.send(
sender,
f"Bienvenue {sender}. Je suis {bot.nickname}, le robot de gestion "
"des revues hebdomadaires de l'April.",
)
bot.send(sender, "Voici les commandes que je comprends :")
bot.send(sender, " ")
bot.send(sender, " !aide,!help : afficher cette aide")
bot.send(
sender,
" !aide commande : afficher l'aide de la commande !commande"
)
bot.send(sender, " !début : commencer une nouvelle revue")
bot.send(sender, " % message  : traiter comme un commentaire")
bot.send(sender, " # titre  : démarrer un sujet individuel")
bot.send(sender, " ## titre  : démarrer un sujet collectif")
bot.send(
sender,
" !oups   : annuler la dernière entrée dans un point de "
"revue",
)
bot.send(sender, " !courant : afficher le sujet en cours")
bot.send(sender, " !fin : terminer la revue en cours")
bot.send(sender, " !stop  : abandonner la revue en cours")
bot.send(sender, " ")
bot.send(
sender,
"Autres commandes : !anniv, !bonjour, !chrono, !date, !hello, "
"!licence, !manquants, !merci, !record, !salut, !stats, !status, "
"!version",
)
return True

View File

5
events/__init__.py Normal file
View File

@ -0,0 +1,5 @@
from .event import Event
events = (
Event(),
)

31
events/event.py Normal file
View File

@ -0,0 +1,31 @@
"""
Script used to...
"""
import time
import settings
SCHEDULER_DELAY = 60
class Event:
def __init__(self):
self.scheduler = None
self.callback = None
self.event_id = 1
self.last_update = time.gmtime()
def init_scheduler(self, scheduler, callback):
self.scheduler = scheduler
self.callback = callback
self.scheduler.execute_every(SCHEDULER_DELAY, self.do_something)
def do_something(self):
now = time.localtime()
# Gestion du rappel avant la revue hebdomadaire
for reminder in settings.CRON_REVIEW_REMINDERS:
if now.tm_hour == reminder[0] and now.tm_min == reminder[1]:
# On calcule le nombre de minutes avant la revue hebdomadaire
minutes = (settings.REVIEW_HOUR[0] - now.tm_hour) * 60
minutes += settings.REVIEW_HOUR[1] - now.tm_min
self.callback(minutes)

View File

@ -1,24 +1,84 @@
import click
"""
Bot IRC permettant de gérer la revue hebdomadaire de l'April.
"""
import time
from ircbot import IrcBot
import settings
from events import events
from hooks import hooks
import logger
from review.review import Review
import settings
@click.command()
@click.option("--version", is_flag=True, help="Display bot version and exit.")
def main(version):
if version:
click.echo(f"Hebdobot {settings.VERSION}")
exit(0)
class HebdoBot(IrcBot):
def __init__(self, settings):
super().__init__(settings)
self.VERSION = "3.0.0"
self.review = Review()
for event in events:
event.init_scheduler(self.reactor.scheduler, self.callback)
logger.info(
"--==============================INIT===="
"======================================--"
)
logger.info(f"Hebdobot {settings.VERSION}")
IrcBot(settings).start()
logger.info(f"Hebdobot {self.VERSION}")
def callback(self, minutes):
"""
Envoi des notification sur IRC et les réseaux sociaux.
"""
if minutes == 15:
# Envoi sur IRC
self.send(
self.channel,
f"Plus que {minutes} minutes avant le début de la revue hebdomdaire.",
)
# Envoi sur Mastodon
# TODO : Gérer mastodon
# ~ mastodon.send(
# ~ "Revue hebdomadaire April à 12h sur notre salon : "
# ~ "http://april.org/salon-irc-de-lapril\nCette revue ne dure qu'une "
# ~ "quinzaine de minutes et permet d'avoir une idée des actions en cours "
# ~ "et à venir.\nVous pouvez aussi juste nous faire un coucou. Et ça met "
# ~ "en appétit :)",
# ~ )
def on_privmsg(self, connection, event):
"""
Tous les messages privés sont ignorés. Si l'utilisateur tente une commande, on
lui signale de le faire plutôt sur le canal public.
"""
target = event.source.nick
message = event.arguments[0]
if message[0] == "!":
self.send(target, "Vos commandes dans le salon public")
def on_pubmsg(self, connection, event):
"""
Tous les messages publics sont pris en compte. On utilise les hooks chargés au
démarrage pour cela.
"""
channel = event.target
sender = event.source.nick
message = event.arguments[0]
if self.review.is_started:
self.review.add_message(sender, message)
for hook in hooks:
if hook.process(self, channel, sender, message):
break
def send(self, target, message):
if self.review.is_started and target == self.channel:
self.review.add_message(self.nickname, message)
super().send(target, message)
if __name__ == "__main__":
main()
HebdoBot(settings).start()

View File

@ -1,8 +1,10 @@
from datetime import datetime
import os
import privatebinapi
import logger
from bot.review.stats import ReviewData, ReviewStats
from review.stats import ReviewData, ReviewStats
class FinishReview:
@ -58,7 +60,14 @@ class FinishReview:
stats.save()
# On copie ce texte sur un pad
url = ""
pastebin_url = ""
if bot.settings.PASTEBIN_URL != "":
result = privatebinapi.send(
bot.settings.PASTEBIN_URL,
text=report,
expiration=bot.settings.PASTEBIN_EXPIRATION,
)
pastebin_url = result.full_url
# On sauve le texte dans un fichier
review_path = os.path.join(
@ -74,7 +83,7 @@ class FinishReview:
f"% C'était la {stats.size}e revue hebdomadaire de l'April, la "
f"{stats.year_review(bot.review.year)}e de l'année {bot.review.year}.",
)
bot.send(channel, f"% Compte-rendu de la revue : {url}")
bot.send(channel, f"% Compte-rendu de la revue : {pastebin_url}")
bot.send(channel, "% Durée de la revue : {temps_ecoule} minutes")
bot.send(channel, "% Nombre de personnes participantes : {combien}")
bot.send(

View File

@ -18,4 +18,5 @@ class Hello:
logger.info("!hello caught.")
bot.send(channel, f"{sender}, bonjour \\o/")
return True

39
hooks/help.py Normal file
View File

@ -0,0 +1,39 @@
import time
import logger
class Help:
def process(self, bot, channel, sender, message):
"""
Le message est pris en compte si l'utilisateur demande de l'aide.
"""
if message.lower() in ("!aide", "!help", "!aide hebdobot", "!help hebdobot"):
logger.info("!help caught.")
bot.send_multiple(
sender,
(
f"Bienvenue {sender}. Je suis {bot.nickname}, le robot de gestion "
"des revues hebdomadaires de l'April.",
"Voici les commandes que je comprends :",
" ",
" !aide,!help : afficher cette aide",
" !aide commande : afficher l'aide de la commande !commande",
" !début : commencer une nouvelle revue",
" % message  : traiter comme un commentaire",
" # titre  : démarrer un sujet individuel",
" ## titre  : démarrer un sujet collectif",
" !oups   : annuler la dernière entrée dans un point de "
"revue",
" !courant : afficher le sujet en cours",
" !fin : terminer la revue en cours",
" !stop  : abandonner la revue en cours",
" ",
"Autres commandes : !anniv, !bonjour, !chrono, !date, !hello, "
"!licence, !manquants, !merci, !record, !salut, !stats, !status, "
"!version",
),
)
return True

View File

@ -10,4 +10,3 @@ class InputReview:
logger.info("message during review caught.")
bot.review.add_input(sender, message)
return True

View File

@ -1,7 +1,7 @@
import locale
import logger
from bot.review.stats import ReviewStats
from review.stats import ReviewStats
class Record:

View File

@ -14,11 +14,10 @@ class StartReview:
return True
# TODO: tester l'heure de démarrage de la revue
bot.review.start(sender)
bot.send(sender, f"% Bonjour {sender}, vous êtes responsable de réunion.")
bot.send(sender, "% Pour terminer la réunion, tapez !fin")
# ~ bot.checkReviewAnniversary();
# TODO: bot.checkReviewAnniversary();
bot.send(channel, "% Début de la réunion hebdomadaire")
bot.send(
channel,

View File

@ -1,7 +1,7 @@
import locale
import logger
from bot.review.stats import ReviewStats
from review.stats import ReviewStats
class Stats:

View File

@ -10,7 +10,7 @@ class Status:
logger.info("!status caught.")
bot.send(sender, f"{sender}, voici l'état d'Hebdobot :")
bot.send(sender, f" revue en cours : {bot.review is not None}")
bot.send(sender, f" revue en cours : {bot.review.started}")
if bot.review.is_started:
bot.send(sender, f" animateur revue : {bot.review.owner}")
else:

View File

@ -23,6 +23,7 @@ class StopReview:
)
return True
bot.send(channel, "Abandon de la revue en cours.")
bot.review.cancel()
bot.send(channel, "Abandon de la revue en cours.")
return True

View File

@ -8,6 +8,6 @@ class Version:
"""
if message.lower() == "!version":
logger.info("!version caught.")
bot.send(channel, bot.settings.VERSION)
bot.send(channel, bot.VERSION)
return True

View File

@ -1,14 +1,10 @@
import time
import irc.bot
import irc.strings
from bot.hebdobot import Hebdobot
class IrcBot(irc.bot.SingleServerIRCBot):
def __init__(self, settings):
# Récupération des paramètres
self.settings = settings
self.server = self.settings.IRC_SERVER
self.port = self.settings.IRC_PORT
@ -16,39 +12,23 @@ class IrcBot(irc.bot.SingleServerIRCBot):
self.nickname = self.settings.IRC_NICK
self.password = self.settings.IRC_PASSWORD
self.bot = Hebdobot(self.settings, self.channel, self.nickname)
# Démarrage et connexion à IRC
# Starting Bot
irc.bot.SingleServerIRCBot.__init__(
self, [(self.server, self.port)], self.nickname, self.nickname
)
def on_nicknameinuse(self, connection, event):
# TODO: Re-tester si son propre nom est disponible plus tard.
# TODO: Check again if name is available later
self.nickname = self.nickname + "_"
self.bot.nickname = self.nickname
connection.nick(self.nickname)
def on_welcome(self, connection, event):
connection.join(self.channel)
def on_privmsg(self, connection, event):
channel = event.target
sender = event.source.nick
message = event.arguments[0]
answers = self.bot.on_private_message(channel, sender, message)
for answer in answers:
self.connection.privmsg(answer.target, answer.message)
def on_pubmsg(self, connection, event):
channel = event.target
sender = event.source.nick
message = event.arguments[0]
answers = self.bot.on_public_message(channel, sender, message)
for answer in answers:
self.connection.privmsg(answer.target, answer.message)
def send(self, target, message):
self.connection.privmsg(target, message)
def send_multiple(self, target, messages):
for message in messages:
self.connection.privmsg(target, message)
self.send(target, message)
time.sleep(self.settings.IRC_DELAY)

View File

@ -2,8 +2,8 @@ from datetime import datetime
import locale
from textwrap import fill
from bot.review.topic import Message, Topic
from bot.review.aliases import Aliases
from review.topic import Message, Topic
from review.aliases import Aliases
LENGTH_LINE = 80

View File

@ -4,8 +4,6 @@ import os
BASE_DIR = os.path.abspath(os.path.dirname(__file__))
VERSION = "3.0.0"
# Log File
LOGFILE = os.environ.get("LOGFILE", os.path.join(BASE_DIR, "hebdobot.log"))
LOGLEVEL = os.environ.get("LOGLEVEL", logging.DEBUG)
@ -15,19 +13,28 @@ LOGDATE = os.environ.get("LOGDATE", "%Y-%m-%d %H:%M:%S")
# IRC configuration
IRC_SERVER = os.environ.get("IRC_SERVER", "irc.libera.chat")
IRC_PORT = int(os.environ.get("IRC_PORT", 6667))
IRC_CHANNEL = os.environ.get("IRC_CHANNEL", " #bidibot")
IRC_NICK = os.environ.get("IRC_NICK", " Testbot")
IRC_CHANNEL = os.environ.get("IRC_CHANNEL", " #april")
IRC_NICK = os.environ.get("IRC_NICK", "Testbot")
IRC_PASSWORD = os.environ.get("IRC_PASSWORD", " ")
IRC_DELAY = float(os.environ.get("IRC_DELAY", 0.5)) # Délai entre plusieurs messages
# User Alias
USER_ALIASES = ""
# User aliases
USER_ALIASES = os.environ.get("USER_ALIASES", os.path.join(BASE_DIR, "users.conf"))
# Review
REVIEW_HOUR = (16, 30)
REVIEW_DIRECTORY = os.environ.get("REVIEW_DIRECTORY", os.path.join(BASE_DIR, "reviews"))
REVIEW_PASTEBIN = ""
REVIEW_STATS = os.environ.get("REVIEW_STATS", os.path.join(REVIEW_DIRECTORY, "reviewstats.csv"))
# Pastebin
PASTEBIN_URL = "https://paste.chapril.org/"
# Values : 5min, 10min, 1hour, 1day, 1week, 1month, 1year, never
PASTEBIN_EXPIRATION = "5min"
# Cron
CRON_REVIEW_REMINDERS = [(11, 45)]
CRON_STOP_BOT = [(16, 15)]
# Mastodon
MASTODON_SERVER = ""
MASTODON_NAME = ""

View File

@ -4,8 +4,6 @@ import os
BASE_DIR = os.path.abspath(os.path.dirname(__file__))
VERSION = "3.0.0"
# Log File
LOGFILE = os.environ.get("LOGFILE", os.path.join(BASE_DIR, "hebdobot.log"))
LOGLEVEL = os.environ.get("LOGLEVEL", logging.DEBUG)
@ -16,18 +14,27 @@ LOGDATE = os.environ.get("LOGDATE", "%Y-%m-%d %H:%M:%S")
IRC_SERVER = os.environ.get("IRC_SERVER", "irc.libera.chat")
IRC_PORT = int(os.environ.get("IRC_PORT", 6667))
IRC_CHANNEL = os.environ.get("IRC_CHANNEL", " #testbot")
IRC_NICK = os.environ.get("IRC_NICK", " Testbot")
IRC_NICK = os.environ.get("IRC_NICK", "Hebdobot")
IRC_PASSWORD = os.environ.get("IRC_PASSWORD", " ")
IRC_DELAY = float(os.environ.get("IRC_DELAY", 0.5)) # Délai entre plusieurs messages
IRC_DELAY = float(os.environ.get("IRC_DELAY", 0)) # Délai entre plusieurs messages
# User aliases
USER_ALIASES = os.environ.get("USER_ALIASES", os.path.join(BASE_DIR, "users.conf"))
# Review
REVIEW_HOUR = (16, 30)
REVIEW_DIRECTORY = os.environ.get("REVIEW_DIRECTORY", os.path.join(BASE_DIR, "reviews"))
REVIEW_PASTEBIN = ""
REVIEW_STATS = os.environ.get("REVIEW_STATS", os.path.join(REVIEW_DIRECTORY, "reviewstats.csv"))
# Pastebin
PASTEBIN_URL = ""
# Values : 5min, 10min, 1hour, 1day, 1week, 1month, 1year, never
PASTEBIN_EXPIRATION = "5min"
# Cron
CRON_REVIEW_REMINDERS = [(11, 45)]
CRON_STOP_BOT = [(16, 15)]
# Mastodon
MASTODON_SERVER = ""
MASTODON_NAME = ""

View File

@ -1,5 +1,5 @@
from bot.review.aliases import Aliases
from tests.utils import bot, CHANNEL, OWNER, SENDER
from review.aliases import Aliases
from tests.utils import bot
def test_aliases(bot):

View File

@ -1,7 +1,7 @@
import os
import shutil
from tests.utils import bot, CHANNEL, OWNER, SENDER
from tests.utils import bot, OWNER, SENDER
def setup_function():
@ -9,7 +9,7 @@ def setup_function():
def test_hook_listen_anniv(bot):
bot.on_public_message(CHANNEL, SENDER, "!anniv")
bot.test_public_message(bot.channel, SENDER, "!anniv")
assert len(bot.answers) == 3
assert bot.answers[0].message.startswith("La revue")
assert bot.answers[1].message.startswith("Hebdobot")
@ -17,96 +17,96 @@ def test_hook_listen_anniv(bot):
def test_hook_bad_command(bot):
bot.on_public_message(CHANNEL, SENDER, "!aniv")
bot.test_public_message(bot.channel, SENDER, "!aniv")
assert len(bot.answers) == 1
assert bot.answers[0].message == f"{SENDER}, Yo !"
def test_hook_date(bot):
bot.on_public_message(CHANNEL, SENDER, "!date")
bot.test_public_message(bot.channel, SENDER, "!date")
assert len(bot.answers) == 1
bot.on_public_message(CHANNEL, SENDER, "!time")
bot.test_public_message(bot.channel, SENDER, "!time")
assert len(bot.answers) == 1
bot.on_public_message(CHANNEL, SENDER, "!now")
bot.test_public_message(bot.channel, SENDER, "!now")
assert len(bot.answers) == 1
def test_hook_default(bot):
bot.on_public_message(CHANNEL, SENDER, "some message")
bot.test_public_message(bot.channel, SENDER, "some message")
assert bot.answers == []
def test_hook_hello(bot):
bot.on_public_message(CHANNEL, SENDER, "!salut")
bot.test_public_message(bot.channel, SENDER, "!salut")
assert len(bot.answers) == 1
assert bot.answers[0].message == f"{SENDER}, bonjour \\o/"
bot.on_public_message(CHANNEL, SENDER, "!bonjour")
bot.test_public_message(bot.channel, SENDER, "!bonjour")
assert len(bot.answers) == 1
assert bot.answers[0].message == f"{SENDER}, bonjour \\o/"
bot.on_public_message(CHANNEL, SENDER, "!hello")
bot.test_public_message(bot.channel, SENDER, "!hello")
assert len(bot.answers) == 1
assert bot.answers[0].message == f"{SENDER}, bonjour \\o/"
bot.on_public_message(CHANNEL, SENDER, "bonjour hebdobot")
bot.test_public_message(bot.channel, SENDER, "bonjour hebdobot")
assert len(bot.answers) == 1
assert bot.answers[0].message == f"{SENDER}, bonjour \\o/"
def test_hook_help(bot):
bot.on_public_message(CHANNEL, SENDER, "!help")
bot.test_public_message(bot.channel, SENDER, "!help")
assert len(bot.answers) == 15
bot.on_public_message(CHANNEL, SENDER, "!aide")
bot.test_public_message(bot.channel, SENDER, "!aide")
assert len(bot.answers) == 15
def test_hook_license(bot):
bot.on_public_message(CHANNEL, SENDER, "!license")
bot.test_public_message(bot.channel, SENDER, "!license")
assert len(bot.answers) == 1
assert bot.answers[0].message.startswith("Hebdobot est un logiciel libre")
bot.on_public_message(CHANNEL, SENDER, "!licence")
bot.test_public_message(bot.channel, SENDER, "!licence")
assert len(bot.answers) == 1
assert bot.answers[0].message.startswith("Hebdobot est un logiciel libre")
def test_hook_listen_alexandrie(bot):
bot.on_public_message(CHANNEL, "alexandrie", "!version")
bot.test_public_message(bot.channel, "alexandrie", "!version")
assert bot.answers == []
bot.on_public_message(CHANNEL, SENDER, "!version")
bot.test_public_message(bot.channel, SENDER, "!version")
assert bot.answers != []
def test_hook_record(bot):
bot.on_public_message(CHANNEL, SENDER, "!record")
bot.test_public_message(bot.channel, SENDER, "!record")
assert len(bot.answers) == 1
assert bot.answers[0].message.startswith("Le record de participation")
def test_hook_stats(bot):
bot.on_public_message(CHANNEL, SENDER, "!stats")
bot.test_public_message(bot.channel, SENDER, "!stats")
assert len(bot.answers) == 5
assert bot.answers[0].message.startswith("% Il y a eu ")
def test_hook_stats_with_no_review(bot):
os.remove("tests/reviews/reviewstats.csv")
bot.on_public_message(CHANNEL, SENDER, "!stats")
bot.test_public_message(bot.channel, SENDER, "!stats")
assert len(bot.answers) == 5
assert bot.answers[0].message == "% Il n'y a pas encore eu de revue."
def test_hook_status(bot):
bot.on_public_message(CHANNEL, SENDER, "!status")
bot.test_public_message(bot.channel, SENDER, "!status")
assert len(bot.answers) == 3
assert bot.answers[0].message.startswith(f"{SENDER}, voici l'état")
bot.on_public_message(CHANNEL, SENDER, "!statut")
bot.test_public_message(bot.channel, SENDER, "!statut")
assert len(bot.answers) == 3
assert bot.answers[0].message.startswith(f"{SENDER}, voici l'état")
assert bot.answers[1].message == f" revue en cours : {bot.review is not None}"
assert bot.answers[1].message == f" revue en cours : {bot.review.started}"
assert bot.answers[2].message == " animateur revue : none"
def test_hook_status_started_review(bot):
bot.on_public_message(CHANNEL, OWNER, "!start")
bot.on_public_message(CHANNEL, SENDER, "!statut")
bot.test_public_message(bot.channel, OWNER, "!start")
bot.test_public_message(bot.channel, SENDER, "!statut")
assert len(bot.answers) == 3
assert bot.answers[0].message.startswith(f"{SENDER}, voici l'état")
assert bot.answers[1].message == f" revue en cours : {bot.review is not None}"
@ -114,11 +114,11 @@ def test_hook_status_started_review(bot):
def test_hook_thanks(bot):
bot.on_public_message(CHANNEL, SENDER, "!merci")
bot.test_public_message(bot.channel, SENDER, "!merci")
assert len(bot.answers) == 1
assert bot.answers[0].message == f"{SENDER}, de rien \\o/"
def test_hook_version(bot):
bot.on_public_message(CHANNEL, SENDER, "!version")
bot.test_public_message(bot.channel, SENDER, "!version")
assert len(bot.answers) == 1

View File

@ -1,12 +1,12 @@
from tests.utils import bot, CHANNEL, OWNER, SENDER
from tests.utils import bot, OWNER, SENDER
def test_private_message(bot):
bot.on_private_message(CHANNEL, SENDER, "hello")
bot.test_private_message(bot.channel, SENDER, "hello")
assert len(bot.answers) == 0
def test_private_command(bot):
bot.on_private_message(CHANNEL, SENDER, "!hello")
bot.test_private_message(bot.channel, SENDER, "!hello")
assert len(bot.answers) == 1
assert bot.answers[0].message == "vos commandes dans le salon public"
assert bot.answers[0].message == "Vos commandes dans le salon public"

View File

@ -1,7 +1,7 @@
from datetime import datetime
import shutil
from tests.utils import bot, CHANNEL, OWNER, SENDER
from tests.utils import bot, OWNER, SENDER
def setup_function():
@ -18,10 +18,10 @@ def test_complete_review(bot):
text = ":".join(data[1:]).strip()
messages.append((author, text))
bot.on_public_message(CHANNEL, "lllll", "!start")
bot.test_public_message(bot.channel, "lllll", "!start")
bot.review.start_time = datetime(2023, 12, 1, 12, 0, 0)
for message in messages:
bot.on_public_message(CHANNEL, message[0], message[1])
bot.test_public_message(bot.channel, message[0], message[1])
# compare contents
with open("tests/datas/20231201-log-irc-revue-hebdomadaire.txt") as file_handle:

View File

@ -1,7 +1,7 @@
from datetime import datetime, timedelta
import shutil
from tests.utils import bot, CHANNEL, OWNER, SENDER
from tests.utils import bot, OWNER, SENDER
def setup_function():
@ -17,17 +17,17 @@ def test_review_starting_new(bot):
assert bot.review.ended == False
assert bot.review.start_time is None
assert bot.review.end_time is None
bot.on_public_message(CHANNEL, OWNER, "!start")
bot.test_public_message(bot.channel, OWNER, "!start")
assert len(bot.answers) == 5
assert bot.answers[0].target == OWNER
assert bot.answers[0].message.startswith(f"% Bonjour {OWNER}")
assert bot.answers[1].target == OWNER
assert bot.answers[1].message.startswith("% Pour terminer")
assert bot.answers[2].target == CHANNEL
assert bot.answers[2].target == bot.channel
assert bot.answers[2].message.startswith("% Début de")
assert bot.answers[3].target == CHANNEL
assert bot.answers[3].target == bot.channel
assert bot.answers[3].message.startswith("% rappel")
assert bot.answers[4].target == CHANNEL
assert bot.answers[4].target == bot.channel
assert bot.answers[4].message.startswith("% pour connaître")
assert bot.review.participants == []
assert bot.review.topics == []
@ -40,8 +40,8 @@ def test_review_starting_new(bot):
def test_review_starting_started_review(bot):
bot.on_public_message(CHANNEL, OWNER, "!start")
bot.on_public_message(CHANNEL, OWNER, "!start")
bot.test_public_message(bot.channel, OWNER, "!start")
bot.test_public_message(bot.channel, OWNER, "!start")
assert len(bot.answers) == 1
assert bot.answers[0].message == f"% {OWNER}, une revue est déjà en cours."
assert bot.review.participants == []
@ -55,7 +55,7 @@ def test_review_starting_started_review(bot):
def test_review_ending_not_started_review(bot):
bot.on_public_message(CHANNEL, OWNER, "!fin")
bot.test_public_message(bot.channel, OWNER, "!fin")
assert len(bot.answers) == 1
assert bot.answers[0].message == f"{OWNER}, pas de revue en cours."
assert bot.review.participants == []
@ -69,8 +69,8 @@ def test_review_ending_not_started_review(bot):
def test_review_ending_as_not_owner(bot):
bot.on_public_message(CHANNEL, OWNER, "!start")
bot.on_public_message(CHANNEL, SENDER, "!fin")
bot.test_public_message(bot.channel, OWNER, "!start")
bot.test_public_message(bot.channel, SENDER, "!fin")
assert len(bot.answers) == 1
assert bot.answers[0].message == f"{SENDER}, vous n'êtes pas responsable de la revue."
assert bot.review.participants == []
@ -84,171 +84,171 @@ def test_review_ending_as_not_owner(bot):
def test_review_cancel_last_message_on_collective_topic(bot):
bot.on_public_message(CHANNEL, OWNER, "!start")
bot.on_public_message(CHANNEL, OWNER, "## Collective topic")
bot.on_public_message(CHANNEL, SENDER, "This is my message")
bot.test_public_message(bot.channel, OWNER, "!start")
bot.test_public_message(bot.channel, OWNER, "## Collective topic")
bot.test_public_message(bot.channel, SENDER, "This is my message")
assert len(bot.review.current_topic.messages) == 1
assert bot.review.current_topic.messages[0].text == "This is my message"
bot.on_public_message(CHANNEL, SENDER, "!oups")
bot.test_public_message(bot.channel, SENDER, "!oups")
assert len(bot.review.current_topic.messages) == 0
bot.on_public_message(CHANNEL, SENDER, "This is my message")
bot.test_public_message(bot.channel, SENDER, "This is my message")
assert len(bot.review.current_topic.messages) == 1
assert bot.review.current_topic.messages[0].text == "This is my message"
bot.on_public_message(CHANNEL, SENDER, "!oops")
bot.test_public_message(bot.channel, SENDER, "!oops")
assert len(bot.review.current_topic.messages) == 0
bot.on_public_message(CHANNEL, SENDER, "This is my message")
bot.test_public_message(bot.channel, SENDER, "This is my message")
assert len(bot.review.current_topic.messages) == 1
assert bot.review.current_topic.messages[0].text == "This is my message"
bot.on_public_message(CHANNEL, SENDER, "!cancelprevious")
bot.test_public_message(bot.channel, SENDER, "!cancelprevious")
assert len(bot.review.current_topic.messages) == 0
def test_review_cancel_only_message_on_collective_topic(bot):
bot.on_public_message(CHANNEL, OWNER, "!start")
bot.on_public_message(CHANNEL, OWNER, "## Collective topic")
bot.on_public_message(CHANNEL, OWNER, "This is a message from owner")
bot.on_public_message(CHANNEL, SENDER, "This is a message from sender")
bot.on_public_message(CHANNEL, OWNER, "This is another message from owner")
bot.test_public_message(bot.channel, OWNER, "!start")
bot.test_public_message(bot.channel, OWNER, "## Collective topic")
bot.test_public_message(bot.channel, OWNER, "This is a message from owner")
bot.test_public_message(bot.channel, SENDER, "This is a message from sender")
bot.test_public_message(bot.channel, OWNER, "This is another message from owner")
assert len(bot.review.current_topic.messages) == 3
assert bot.review.current_topic.messages[1].text == "This is a message from sender"
bot.on_public_message(CHANNEL, SENDER, "!oups")
bot.test_public_message(bot.channel, SENDER, "!oups")
assert len(bot.answers) == 1
assert len(bot.review.current_topic.messages) == 2
assert bot.review.current_topic.messages[1].text == "This is another message from owner"
def test_review_cancel_last_message_from_two_on_collective_topic(bot):
bot.on_public_message(CHANNEL, OWNER, "!start")
bot.on_public_message(CHANNEL, OWNER, "## Collective topic")
bot.on_public_message(CHANNEL, OWNER, "This is a message from owner")
bot.on_public_message(CHANNEL, SENDER, "This is a message from sender")
bot.on_public_message(CHANNEL, SENDER, "This is another message from sender")
bot.test_public_message(bot.channel, OWNER, "!start")
bot.test_public_message(bot.channel, OWNER, "## Collective topic")
bot.test_public_message(bot.channel, OWNER, "This is a message from owner")
bot.test_public_message(bot.channel, SENDER, "This is a message from sender")
bot.test_public_message(bot.channel, SENDER, "This is another message from sender")
assert len(bot.review.current_topic.messages) == 3
assert bot.review.current_topic.messages[1].text == "This is a message from sender"
bot.on_public_message(CHANNEL, SENDER, "!oups")
bot.test_public_message(bot.channel, SENDER, "!oups")
assert len(bot.answers) == 1
assert len(bot.review.current_topic.messages) == 2
assert bot.review.current_topic.messages[1].text == "This is a message from sender"
def test_review_cancel_first_message_from_three_on_collective_topic(bot):
bot.on_public_message(CHANNEL, OWNER, "!start")
bot.on_public_message(CHANNEL, OWNER, "## Collective topic")
bot.on_public_message(CHANNEL, SENDER, "This is a message from sender")
bot.on_public_message(CHANNEL, OWNER, "This is a message from owner")
bot.on_public_message(CHANNEL, OWNER, "This is another message from owner")
bot.on_public_message(CHANNEL, OWNER, "This is a third message from owner")
bot.test_public_message(bot.channel, OWNER, "!start")
bot.test_public_message(bot.channel, OWNER, "## Collective topic")
bot.test_public_message(bot.channel, SENDER, "This is a message from sender")
bot.test_public_message(bot.channel, OWNER, "This is a message from owner")
bot.test_public_message(bot.channel, OWNER, "This is another message from owner")
bot.test_public_message(bot.channel, OWNER, "This is a third message from owner")
assert len(bot.review.current_topic.messages) == 4
assert bot.review.current_topic.messages[1].text == "This is a message from owner"
bot.on_public_message(CHANNEL, SENDER, "!oups")
bot.test_public_message(bot.channel, SENDER, "!oups")
assert len(bot.answers) == 1
assert len(bot.review.current_topic.messages) == 3
assert bot.review.current_topic.messages[1].text == "This is another message from owner"
def test_review_cancel_last_message_no_message_on_collective_topic(bot):
bot.on_public_message(CHANNEL, OWNER, "!start")
bot.on_public_message(CHANNEL, OWNER, "## Collective topic")
bot.on_public_message(CHANNEL, OWNER, "This is my message")
bot.test_public_message(bot.channel, OWNER, "!start")
bot.test_public_message(bot.channel, OWNER, "# Individual topic")
bot.test_public_message(bot.channel, OWNER, "This is my message")
assert len(bot.review.current_topic.messages) == 1
assert bot.review.current_topic.messages[0].text == "This is my message"
bot.on_public_message(CHANNEL, SENDER, "!oups")
bot.test_public_message(bot.channel, SENDER, "!oups")
assert len(bot.review.current_topic.messages) == 1
assert bot.review.current_topic.messages[0].text == "This is my message"
def test_review_cancel_last_message_on_individual_topic(bot):
bot.on_public_message(CHANNEL, OWNER, "!start")
bot.on_public_message(CHANNEL, OWNER, "# Individual topic")
bot.on_public_message(CHANNEL, SENDER, "This is my message")
bot.test_public_message(bot.channel, OWNER, "!start")
bot.test_public_message(bot.channel, OWNER, "# Individual topic")
bot.test_public_message(bot.channel, SENDER, "This is my message")
assert len(bot.review.current_topic.messages) == 1
assert bot.review.current_topic.messages[0].text == "This is my message"
bot.on_public_message(CHANNEL, SENDER, "!oups")
bot.test_public_message(bot.channel, SENDER, "!oups")
assert len(bot.review.current_topic.messages) == 0
bot.on_public_message(CHANNEL, SENDER, "This is my message")
bot.test_public_message(bot.channel, SENDER, "This is my message")
assert len(bot.review.current_topic.messages) == 1
assert bot.review.current_topic.messages[0].text == "This is my message"
bot.on_public_message(CHANNEL, SENDER, "!oops")
bot.test_public_message(bot.channel, SENDER, "!oops")
assert len(bot.review.current_topic.messages) == 0
bot.on_public_message(CHANNEL, SENDER, "This is my message")
bot.test_public_message(bot.channel, SENDER, "This is my message")
assert len(bot.review.current_topic.messages) == 1
assert bot.review.current_topic.messages[0].text == "This is my message"
bot.on_public_message(CHANNEL, SENDER, "!cancelprevious")
bot.test_public_message(bot.channel, SENDER, "!cancelprevious")
assert len(bot.review.current_topic.messages) == 0
def test_review_cancel_only_message_on_individual_topic(bot):
bot.on_public_message(CHANNEL, OWNER, "!start")
bot.on_public_message(CHANNEL, OWNER, "# Individual topic")
bot.on_public_message(CHANNEL, OWNER, "This is a message from owner")
bot.on_public_message(CHANNEL, SENDER, "This is a message from sender")
bot.on_public_message(CHANNEL, OWNER, "This is another message from owner")
bot.test_public_message(bot.channel, OWNER, "!start")
bot.test_public_message(bot.channel, OWNER, "# Individual topic")
bot.test_public_message(bot.channel, OWNER, "This is a message from owner")
bot.test_public_message(bot.channel, SENDER, "This is a message from sender")
bot.test_public_message(bot.channel, OWNER, "This is another message from owner")
assert len(bot.review.current_topic.messages) == 3
assert bot.review.current_topic.messages[1].text == "This is a message from sender"
bot.on_public_message(CHANNEL, SENDER, "!oups")
bot.test_public_message(bot.channel, SENDER, "!oups")
assert len(bot.answers) == 1
assert len(bot.review.current_topic.messages) == 2
assert bot.review.current_topic.messages[1].text == "This is another message from owner"
def test_review_cancel_last_message_from_two_on_individual_topic(bot):
bot.on_public_message(CHANNEL, OWNER, "!start")
bot.on_public_message(CHANNEL, OWNER, "# Individual topic")
bot.on_public_message(CHANNEL, OWNER, "This is a message from owner")
bot.on_public_message(CHANNEL, SENDER, "This is a message from sender")
bot.on_public_message(CHANNEL, SENDER, "This is another message from sender")
bot.test_public_message(bot.channel, OWNER, "!start")
bot.test_public_message(bot.channel, OWNER, "# Individual topic")
bot.test_public_message(bot.channel, OWNER, "This is a message from owner")
bot.test_public_message(bot.channel, SENDER, "This is a message from sender")
bot.test_public_message(bot.channel, SENDER, "This is another message from sender")
assert len(bot.review.current_topic.messages) == 3
assert bot.review.current_topic.messages[1].text == "This is a message from sender"
bot.on_public_message(CHANNEL, SENDER, "!oups")
bot.test_public_message(bot.channel, SENDER, "!oups")
assert len(bot.answers) == 1
assert len(bot.review.current_topic.messages) == 2
assert bot.review.current_topic.messages[1].text == "This is a message from sender"
def test_review_cancel_first_message_from_three_on_individual_topic(bot):
bot.on_public_message(CHANNEL, OWNER, "!start")
bot.on_public_message(CHANNEL, OWNER, "# Individual topic")
bot.on_public_message(CHANNEL, SENDER, "This is a message from sender")
bot.on_public_message(CHANNEL, OWNER, "This is a message from owner")
bot.on_public_message(CHANNEL, OWNER, "This is another message from owner")
bot.on_public_message(CHANNEL, OWNER, "This is a third message from owner")
bot.test_public_message(bot.channel, OWNER, "!start")
bot.test_public_message(bot.channel, OWNER, "# Individual topic")
bot.test_public_message(bot.channel, SENDER, "This is a message from sender")
bot.test_public_message(bot.channel, OWNER, "This is a message from owner")
bot.test_public_message(bot.channel, OWNER, "This is another message from owner")
bot.test_public_message(bot.channel, OWNER, "This is a third message from owner")
assert len(bot.review.current_topic.messages) == 4
assert bot.review.current_topic.messages[1].text == "This is a message from owner"
bot.on_public_message(CHANNEL, SENDER, "!oups")
bot.test_public_message(bot.channel, SENDER, "!oups")
assert len(bot.answers) == 1
assert len(bot.review.current_topic.messages) == 3
assert bot.review.current_topic.messages[1].text == "This is another message from owner"
def test_review_cancel_last_message_no_message_on_individual_topic(bot):
bot.on_public_message(CHANNEL, OWNER, "!start")
bot.on_public_message(CHANNEL, OWNER, "# Individual topic")
bot.on_public_message(CHANNEL, OWNER, "This is my message")
bot.test_public_message(bot.channel, OWNER, "!start")
bot.test_public_message(bot.channel, OWNER, "# Individual topic")
bot.test_public_message(bot.channel, OWNER, "This is my message")
assert len(bot.review.current_topic.messages) == 1
assert bot.review.current_topic.messages[0].text == "This is my message"
bot.on_public_message(CHANNEL, SENDER, "!oups")
bot.test_public_message(bot.channel, SENDER, "!oups")
assert len(bot.review.current_topic.messages) == 1
assert bot.review.current_topic.messages[0].text == "This is my message"
def test_review_cancel_last_message_no_review(bot):
bot.on_public_message(CHANNEL, SENDER, "!oups")
bot.test_public_message(bot.channel, SENDER, "!oups")
assert len(bot.answers) == 1
assert bot.answers[0].message == f"{SENDER}, pas de revue en cours."
def test_review_cancel_last_message_no_topic(bot):
bot.on_public_message(CHANNEL, OWNER, "!start")
bot.on_public_message(CHANNEL, SENDER, "!oups")
bot.test_public_message(bot.channel, OWNER, "!start")
bot.test_public_message(bot.channel, SENDER, "!oups")
assert len(bot.answers) == 1
assert bot.answers[0].message == f"{SENDER}, pas de sujet en cours."
def test_review_collective_topic(bot):
bot.on_public_message(CHANNEL, OWNER, "!start")
bot.test_public_message(bot.channel, OWNER, "!start")
assert len(bot.review.topics) == 0
assert bot.review.current_topic is None
bot.on_public_message(CHANNEL, OWNER, "## collective topic")
bot.test_public_message(bot.channel, OWNER, "## collective topic")
assert len(bot.answers) == 4
assert len(bot.review.topics) == 1
assert bot.review.current_topic is not None
@ -256,13 +256,13 @@ def test_review_collective_topic(bot):
def test_review_second_collective_topic(bot):
bot.on_public_message(CHANNEL, OWNER, "!start")
bot.test_public_message(bot.channel, OWNER, "!start")
assert len(bot.review.topics) == 0
assert bot.review.current_topic is None
bot.on_public_message(CHANNEL, OWNER, "## collective topic")
bot.on_public_message(CHANNEL, OWNER, "This is my message")
bot.on_public_message(CHANNEL, SENDER, "This is a message from sender")
bot.on_public_message(CHANNEL, OWNER, "## second collective topic")
bot.test_public_message(bot.channel, OWNER, "## collective topic")
bot.test_public_message(bot.channel, OWNER, "This is my message")
bot.test_public_message(bot.channel, SENDER, "This is a message from sender")
bot.test_public_message(bot.channel, OWNER, "## second collective topic")
assert len(bot.answers) == 6
assert len(bot.review.topics) == 2
assert bot.review.current_topic is not None
@ -270,7 +270,7 @@ def test_review_second_collective_topic(bot):
def test_review_collective_no_review(bot):
bot.on_public_message(CHANNEL, OWNER, "## collective topic")
bot.test_public_message(bot.channel, OWNER, "## collective topic")
assert len(bot.answers) == 0
assert not bot.review.is_started
assert len(bot.review.topics) == 0
@ -278,58 +278,58 @@ def test_review_collective_no_review(bot):
def test_review_collective_topic_not_owner(bot):
bot.on_public_message(CHANNEL, OWNER, "!start")
bot.on_public_message(CHANNEL, SENDER, "## collective topic")
bot.test_public_message(bot.channel, OWNER, "!start")
bot.test_public_message(bot.channel, SENDER, "## collective topic")
assert len(bot.answers) == 1
assert bot.answers[0].message == f"{SENDER}, vous n'êtes pas responsable de la réunion"
def test_review_comment(bot):
bot.on_public_message(CHANNEL, OWNER, "!start")
bot.on_public_message(CHANNEL, SENDER, "% This is a comment")
bot.test_public_message(bot.channel, OWNER, "!start")
bot.test_public_message(bot.channel, SENDER, "% This is a comment")
assert len(bot.answers) == 0
assert bot.review.messages[-1].text == "% This is a comment"
assert bot.review.current_topic is None
def test_review_current_without_review(bot):
bot.on_public_message(CHANNEL, OWNER, "!courant")
bot.test_public_message(bot.channel, OWNER, "!courant")
assert len(bot.answers) == 1
assert bot.answers[0].message == f"{OWNER}, pas de revue en cours."
assert not bot.review.is_started
def test_review_current_without_topic(bot):
bot.on_public_message(CHANNEL, OWNER, "!start")
bot.on_public_message(CHANNEL, OWNER, "!courant")
bot.test_public_message(bot.channel, OWNER, "!start")
bot.test_public_message(bot.channel, OWNER, "!courant")
assert len(bot.answers) == 1
assert bot.answers[0].message == "% Pas de sujet en cours."
assert bot.review.is_started
def test_review_current_with_collective_topic(bot):
bot.on_public_message(CHANNEL, OWNER, "!start")
bot.on_public_message(CHANNEL, OWNER, "## collective topic")
bot.on_public_message(CHANNEL, OWNER, "!courant")
bot.test_public_message(bot.channel, OWNER, "!start")
bot.test_public_message(bot.channel, OWNER, "## collective topic")
bot.test_public_message(bot.channel, OWNER, "!courant")
assert len(bot.answers) == 1
assert bot.review.current_topic.title == "collective topic"
assert bot.answers[0].message == f"% Sujet collectif en cours : {bot.review.current_topic.title}"
def test_review_current_with_individual_topic(bot):
bot.on_public_message(CHANNEL, OWNER, "!start")
bot.on_public_message(CHANNEL, OWNER, "# individual topic")
bot.on_public_message(CHANNEL, OWNER, "!courant")
bot.test_public_message(bot.channel, OWNER, "!start")
bot.test_public_message(bot.channel, OWNER, "# individual topic")
bot.test_public_message(bot.channel, OWNER, "!courant")
assert len(bot.answers) == 1
assert bot.review.current_topic.title == "individual topic"
assert bot.answers[0].message == f"% Sujet individuel en cours : {bot.review.current_topic.title}"
def test_review_individual_topic(bot):
bot.on_public_message(CHANNEL, OWNER, "!start")
bot.test_public_message(bot.channel, OWNER, "!start")
assert len(bot.review.topics) == 0
assert bot.review.current_topic is None
bot.on_public_message(CHANNEL, OWNER, "# individual topic")
bot.test_public_message(bot.channel, OWNER, "# individual topic")
assert len(bot.answers) == 3
assert len(bot.review.topics) == 1
assert bot.review.current_topic is not None
@ -337,13 +337,13 @@ def test_review_individual_topic(bot):
def test_review_second_individual_topic(bot):
bot.on_public_message(CHANNEL, OWNER, "!start")
bot.test_public_message(bot.channel, OWNER, "!start")
assert len(bot.review.topics) == 0
assert bot.review.current_topic is None
bot.on_public_message(CHANNEL, OWNER, "# individual topic")
bot.on_public_message(CHANNEL, OWNER, "This is my message")
bot.on_public_message(CHANNEL, SENDER, "This is a message from sender")
bot.on_public_message(CHANNEL, OWNER, "# second individual topic")
bot.test_public_message(bot.channel, OWNER, "# individual topic")
bot.test_public_message(bot.channel, OWNER, "This is my message")
bot.test_public_message(bot.channel, SENDER, "This is a message from sender")
bot.test_public_message(bot.channel, OWNER, "# second individual topic")
assert len(bot.answers) == 5
assert len(bot.review.topics) == 2
assert bot.review.current_topic is not None
@ -351,7 +351,7 @@ def test_review_second_individual_topic(bot):
def test_review_individual_no_review(bot):
bot.on_public_message(CHANNEL, OWNER, "# individual topic")
bot.test_public_message(bot.channel, OWNER, "# individual topic")
assert len(bot.answers) == 0
assert not bot.review.is_started
assert len(bot.review.topics) == 0
@ -359,20 +359,20 @@ def test_review_individual_no_review(bot):
def test_review_individual_topic_not_owner(bot):
bot.on_public_message(CHANNEL, OWNER, "!start")
bot.on_public_message(CHANNEL, SENDER, "# individual topic")
bot.test_public_message(bot.channel, OWNER, "!start")
bot.test_public_message(bot.channel, SENDER, "# individual topic")
assert len(bot.answers) == 1
assert bot.answers[0].message == f"{SENDER}, vous n'êtes pas responsable de la réunion"
def test_stop_review(bot):
bot.on_public_message(CHANNEL, OWNER, "!start")
bot.test_public_message(bot.channel, OWNER, "!start")
assert bot.review.is_started
assert not bot.review.is_ended
bot.on_public_message(CHANNEL, OWNER, "A messsage")
bot.on_public_message(CHANNEL, OWNER, "## collective topic")
bot.on_public_message(CHANNEL, OWNER, "Another messsage")
bot.on_public_message(CHANNEL, OWNER, "!stop")
bot.test_public_message(bot.channel, OWNER, "A messsage")
bot.test_public_message(bot.channel, OWNER, "## collective topic")
bot.test_public_message(bot.channel, OWNER, "Another messsage")
bot.test_public_message(bot.channel, OWNER, "!stop")
assert not bot.review.is_started
assert not bot.review.is_ended
assert len(bot.review.topics) == 0
@ -382,15 +382,15 @@ def test_stop_review(bot):
def test_stop_review_not_owner(bot):
bot.on_public_message(CHANNEL, OWNER, "!start")
bot.on_public_message(CHANNEL, SENDER, "!stop")
bot.test_public_message(bot.channel, OWNER, "!start")
bot.test_public_message(bot.channel, SENDER, "!stop")
assert bot.review.is_started
assert len(bot.answers) == 1
assert bot.answers[0].message == f"{SENDER}, vous n'êtes pas responsable de la réunion."
def test_stop_review_no_review(bot):
bot.on_public_message(CHANNEL, OWNER, "!stop")
bot.test_public_message(bot.channel, OWNER, "!stop")
assert not bot.review.is_started
assert not bot.review.is_ended
assert len(bot.review.topics) == 0
@ -400,38 +400,38 @@ def test_stop_review_no_review(bot):
def test_missing_no_review(bot):
bot.on_public_message(CHANNEL, OWNER, "!manquants")
bot.test_public_message(bot.channel, OWNER, "!manquants")
assert not bot.review.is_started
assert len(bot.answers) == 1
assert bot.answers[0].message == f"{OWNER}, pas de revue en cours."
def test_missing_no_topic(bot):
bot.on_public_message(CHANNEL, OWNER, "!start")
bot.test_public_message(bot.channel, OWNER, "!start")
assert bot.review.is_started
bot.on_public_message(CHANNEL, OWNER, "!manquants")
bot.test_public_message(bot.channel, OWNER, "!manquants")
assert len(bot.answers) == 1
assert bot.answers[0].message == "% Pas de sujet en cours."
def test_missing_no_one_is_missing(bot):
bot.on_public_message(CHANNEL, OWNER, "!start")
bot.on_public_message(CHANNEL, OWNER, "## collective topic")
bot.on_public_message(CHANNEL, SENDER, "This is my message")
bot.on_public_message(CHANNEL, OWNER, "This is owner message")
bot.on_public_message(CHANNEL, OWNER, "!manquants")
bot.test_public_message(bot.channel, OWNER, "!start")
bot.test_public_message(bot.channel, OWNER, "## collective topic")
bot.test_public_message(bot.channel, SENDER, "This is my message")
bot.test_public_message(bot.channel, OWNER, "This is owner message")
bot.test_public_message(bot.channel, OWNER, "!manquants")
assert len(bot.answers) == 1
assert bot.answers[0].message == "% Tout le monde s'est exprimé sur le sujet courant \\o/"
def test_missing_one_is_missing(bot):
bot.on_public_message(CHANNEL, OWNER, "!start")
bot.on_public_message(CHANNEL, OWNER, "## collective topic")
bot.on_public_message(CHANNEL, SENDER, "This is my message")
bot.on_public_message(CHANNEL, OWNER, "This is owner message")
bot.on_public_message(CHANNEL, OWNER, "## a second collective topic")
bot.on_public_message(CHANNEL, OWNER, "This is the second owner message")
bot.on_public_message(CHANNEL, OWNER, "!manquants")
bot.test_public_message(bot.channel, OWNER, "!start")
bot.test_public_message(bot.channel, OWNER, "## collective topic")
bot.test_public_message(bot.channel, SENDER, "This is my message")
bot.test_public_message(bot.channel, OWNER, "This is owner message")
bot.test_public_message(bot.channel, OWNER, "## a second collective topic")
bot.test_public_message(bot.channel, OWNER, "This is the second owner message")
bot.test_public_message(bot.channel, OWNER, "!manquants")
assert len(bot.answers) == 1
assert bot.answers[0].message == (
"% Personnes participantes ne s'étant pas exprimées sur le "
@ -440,68 +440,68 @@ def test_missing_one_is_missing(bot):
def test_chrono_no_review(bot):
bot.on_public_message(CHANNEL, OWNER, "!chrono")
bot.test_public_message(bot.channel, OWNER, "!chrono")
assert len(bot.answers) == 1
assert bot.answers[0].message == "n/a"
def test_chrono(bot):
bot.on_public_message(CHANNEL, OWNER, "!start")
bot.test_public_message(bot.channel, OWNER, "!start")
bot.review.start_time = datetime.today() - timedelta(seconds=87)
bot.on_public_message(CHANNEL, OWNER, "!chrono")
bot.test_public_message(bot.channel, OWNER, "!chrono")
assert len(bot.answers) == 1
assert bot.answers[0].message == "01:27"
def test_finish_review(bot):
bot.on_public_message(CHANNEL, OWNER, "!start")
bot.on_public_message(CHANNEL, OWNER, "## collective topic")
bot.on_public_message(CHANNEL, OWNER, "Owner message on collective topic")
bot.on_public_message(CHANNEL, SENDER, "Sender message on collective topic")
bot.on_public_message(CHANNEL, OWNER, "# individual topic")
bot.on_public_message(CHANNEL, OWNER, "Owner message on individual topic")
bot.on_public_message(CHANNEL, SENDER, "Sender message on individual topic")
bot.on_public_message(CHANNEL, OWNER, "!fin")
bot.test_public_message(bot.channel, OWNER, "!start")
bot.test_public_message(bot.channel, OWNER, "## collective topic")
bot.test_public_message(bot.channel, OWNER, "Owner message on collective topic")
bot.test_public_message(bot.channel, SENDER, "Sender message on collective topic")
bot.test_public_message(bot.channel, OWNER, "# individual topic")
bot.test_public_message(bot.channel, OWNER, "Owner message on individual topic")
bot.test_public_message(bot.channel, SENDER, "Sender message on individual topic")
bot.test_public_message(bot.channel, OWNER, "!fin")
assert len(bot.answers) == 10
assert bot.answers[-2].message == "% Fin de la revue hebdomadaire"
assert bot.answers[-1].message == "Revue finie."
def test_finish_review_no_review(bot):
bot.on_public_message(CHANNEL, OWNER, "!fin")
bot.test_public_message(bot.channel, OWNER, "!fin")
assert len(bot.answers) == 1
assert bot.answers[0].message == f"{OWNER}, pas de revue en cours."
def test_finish_review_already_finished(bot):
bot.on_public_message(CHANNEL, OWNER, "!start")
bot.on_public_message(CHANNEL, OWNER, "## collective topic")
bot.on_public_message(CHANNEL, OWNER, "Owner message on collective topic")
bot.on_public_message(CHANNEL, SENDER, "Sender message on collective topic")
bot.on_public_message(CHANNEL, OWNER, "# individual topic")
bot.on_public_message(CHANNEL, OWNER, "Owner message on individual topic")
bot.on_public_message(CHANNEL, SENDER, "Sender message on individual topic")
bot.on_public_message(CHANNEL, OWNER, "!fin")
bot.on_public_message(CHANNEL, OWNER, "!fin")
bot.test_public_message(bot.channel, OWNER, "!start")
bot.test_public_message(bot.channel, OWNER, "## collective topic")
bot.test_public_message(bot.channel, OWNER, "Owner message on collective topic")
bot.test_public_message(bot.channel, SENDER, "Sender message on collective topic")
bot.test_public_message(bot.channel, OWNER, "# individual topic")
bot.test_public_message(bot.channel, OWNER, "Owner message on individual topic")
bot.test_public_message(bot.channel, SENDER, "Sender message on individual topic")
bot.test_public_message(bot.channel, OWNER, "!fin")
bot.test_public_message(bot.channel, OWNER, "!fin")
assert len(bot.answers) == 1
assert bot.answers[0].message == "La revue est déjà finie."
def test_finish_review_not_owner(bot):
bot.on_public_message(CHANNEL, OWNER, "!start")
bot.on_public_message(CHANNEL, OWNER, "## collective topic")
bot.on_public_message(CHANNEL, OWNER, "Owner message on collective topic")
bot.on_public_message(CHANNEL, SENDER, "Sender message on collective topic")
bot.on_public_message(CHANNEL, OWNER, "# individual topic")
bot.on_public_message(CHANNEL, OWNER, "Owner message on individual topic")
bot.on_public_message(CHANNEL, SENDER, "Sender message on individual topic")
bot.on_public_message(CHANNEL, SENDER, "!fin")
bot.test_public_message(bot.channel, OWNER, "!start")
bot.test_public_message(bot.channel, OWNER, "## collective topic")
bot.test_public_message(bot.channel, OWNER, "Owner message on collective topic")
bot.test_public_message(bot.channel, SENDER, "Sender message on collective topic")
bot.test_public_message(bot.channel, OWNER, "# individual topic")
bot.test_public_message(bot.channel, OWNER, "Owner message on individual topic")
bot.test_public_message(bot.channel, SENDER, "Sender message on individual topic")
bot.test_public_message(bot.channel, SENDER, "!fin")
assert len(bot.answers) == 1
assert bot.answers[0].message == f"{SENDER}, vous n'êtes pas responsable de la revue."
def test_finish_review_no_participation(bot):
bot.on_public_message(CHANNEL, OWNER, "!start")
bot.on_public_message(CHANNEL, OWNER, "!fin")
bot.test_public_message(bot.channel, OWNER, "!start")
bot.test_public_message(bot.channel, OWNER, "!fin")
assert len(bot.answers) == 1
assert bot.answers[0].message == "Participation nulle détectée. La revue est ignorée."

View File

@ -1,8 +1,8 @@
from tests.utils import bot, CHANNEL, OWNER, SENDER
from tests.utils import bot, OWNER, SENDER
def test_topic_duration_not_ended(bot):
bot.on_public_message(CHANNEL, OWNER, "!start")
bot.on_public_message(CHANNEL, OWNER, "## collective topic")
assert bot.review.current_topic.duration != ""
bot.test_public_message(bot.channel, SENDER, "!start")
bot.test_public_message(bot.channel, SENDER, "## collective topic")
assert bot.review.current_topic.duration != ""

View File

@ -1,13 +1,53 @@
from dataclasses import dataclass
import pytest
from bot.hebdobot import Hebdobot
from hebdobot import HebdoBot
from tests import settings
CHANNEL = "#test_channel"
OWNER = "me"
SENDER = "foobar"
@dataclass
class Answer():
target: str
message: str
@dataclass
class Source():
nick: str
class Event():
def __init__(self, target, nick, message):
self.target = target
self.source = Source(nick)
self.arguments = [message]
def test_privmsg(self, target, message):
self.answers.append(Answer(target, message))
def test_public_message(self, target, sender, message):
self.answers = []
self.on_pubmsg(None, Event(target, sender, message))
def test_private_message(self, target, sender, message):
self.answers = []
self.on_privmsg(None, Event(target, sender, message))
@pytest.fixture
def bot():
return Hebdobot(settings, CHANNEL, nickname="Hebdobot")
HebdoBot.test_public_message = test_public_message
HebdoBot.test_private_message = test_private_message
HebdoBot.test_privmsg = test_privmsg
hebdobot = HebdoBot(settings)
hebdobot.connection.privmsg = hebdobot.test_privmsg
hebdobot.answers = []
return hebdobot

14
users-sample.conf Normal file
View File

@ -0,0 +1,14 @@
#
# Sample Hebdobot user file
#
Christian P. MOMON=cpm__,cpm_screen
Lionel Allorge=liot,liot_
Frédéric Couchet=madix
Isabella Vanni=cioccolisa
Étienne Gonnu=lonugem
Elsa Pottier=eipoca1
François Poulain=Polux__,Polux_,Polux,Polux[2]
Thérèse Godefroy=therese
Magali Garnero=Bookynette
Marie-Odile Morandi=Marie-Odile1,Marie-Odile