From 108dd35ee7bca304077e50145a14f6dbc44b8e92 Mon Sep 17 00:00:00 2001 From: Griatch Date: Sun, 19 Feb 2017 19:24:00 +0100 Subject: [PATCH] Add unittest for mail contrib; fix some inconsistencies and refactor to better handle errors. --- evennia/contrib/mail.py | 151 +++++++++++++++++++++++---------------- evennia/contrib/tests.py | 17 ++++- 2 files changed, 106 insertions(+), 62 deletions(-) diff --git a/evennia/contrib/mail.py b/evennia/contrib/mail.py index 2397632ad2..4482542de2 100644 --- a/evennia/contrib/mail.py +++ b/evennia/contrib/mail.py @@ -7,10 +7,13 @@ A simple Brandymail style @mail system that uses the Msg class from Evennia Core Installation: import MailCommand from this module into the default Player or Character command set + """ +import re +from evennia import ObjectDB, PlayerDB from evennia import default_cmds -from evennia.utils import create, evtable +from evennia.utils import create, evtable, make_iter from evennia.comms.models import Msg @@ -56,9 +59,63 @@ class CmdMail(default_cmds.MuxCommand): lock = "cmd:all()" help_category = "General" + def search_targets(self, namelist): + """ + Search a list of targets of the same type as caller. + + Args: + caller (Object or Player): The type of object to search. + namelist (list): List of strings for objects to search for. + + Returns: + targetlist (list): List of matches, if any. + + """ + nameregex = r"|".join(r"^%s$" % re.escape(name) for name in make_iter(namelist)) + if hasattr(self.caller, "player") and self.caller.player: + matches = list(ObjectDB.objects.filter(db_key__iregex=nameregex)) + else: + matches = list(PlayerDB.objects.filter(username__iregex=nameregex)) + return matches + + def get_all_mail(self): + """ + Returns a list of all the messages where the caller is a recipient. + + Returns: + messages (list): list of Msg objects. + """ + # mail_messages = Msg.objects.get_by_tag(category="mail") + # messages = [] + messages = Msg.objects.get_by_tag(category="mail", raw_queryset=True).filter(db_receivers_players=self.caller) + return messages + + def send_mail(self, recipients, subject, message, caller): + """ + Function for sending new mail. Also useful for sending notifications from objects or systems. + + Args: + recipients (list): list of Player or character objects to receive the newly created mails. + subject (str): The header or subject of the message to be delivered. + message (str): The body of the message being sent. + caller (obj): The object (or Player or Character) that is sending the message. + """ + for recipient in recipients: + recipient.msg("You have received a new @mail from %s" % caller) + new_message = create.create_message(self.caller, message, receivers=recipient, header=subject) + new_message.tags.add("U", category="mail") + + if recipients: + caller.msg("You sent your message.") + return + else: + caller.msg("No valid players found. Cannot send message.") + return + def func(self): subject = "" body = "" + if self.switches or self.args: if "delete" in self.switches: try: @@ -66,12 +123,15 @@ class CmdMail(default_cmds.MuxCommand): self.caller.msg("No Message ID given. Unable to delete.") return else: - if self.get_all_mail()[int(self.lhs) - 1]: - self.get_all_mail()[int(self.lhs) - 1].delete() + all_mail = self.get_all_mail() + mind = int(self.lhs) - 1 + if all_mail[mind]: + all_mail[mind].delete() self.caller.msg("Message %s deleted" % self.lhs) else: - self.caller.msg("That message does not exist.") - return + raise IndexError + except IndexError: + self.caller.msg("That message does not exist.") except ValueError: self.caller.msg("Usage: @mail/delete ") elif "forward" in self.switches: @@ -83,29 +143,33 @@ class CmdMail(default_cmds.MuxCommand): self.caller.msg("You must define a message to forward.") return else: + all_mail = self.get_all_mail() if "/" in self.rhs: message_number, message = self.rhs.split("/") - if self.get_all_mail()[int(message_number) - 1]: - old_message = self.get_all_mail()[int(message_number) - 1] + mind = int(message_number) - 1 - self.send_mail(self.lhslist, "FWD: " + old_message.header, + if all_mail[mind]: + old_message = all_mail[mind] + + self.send_mail(self.search_targets(self.lhslist), "FWD: " + old_message.header, message + "\n---- Original Message ----\n" + old_message.message, self.caller) self.caller.msg("Message forwarded.") else: - self.caller.msg("Message does not exist.") - return + raise IndexError else: - if self.get_all_mail()[int(self.rhs) - 1]: - old_message = self.get_all_mail()[int(self.rhs) - 1] - self.send_mail(self.lhslist, "FWD: " + old_message.header, + mind = int(self.rhs) - 1 + if all_mail[mind]: + old_message = all_mail[mind] + self.send_mail(self.search_targets(self.lhslist), "FWD: " + old_message.header, "\n---- Original Message ----\n" + old_message.message, self.caller) self.caller.msg("Message forwarded.") old_message.tags.remove("u", category="mail") old_message.tags.add("f", category="mail") else: - self.caller.msg("Message does not exist.") - return + raise IndexError + except IndexError: + self.caller.msg("Message does not exixt.") except ValueError: self.caller.msg("Usage: @mail/forward =<#>[/]") elif "reply" in self.switches: @@ -117,29 +181,33 @@ class CmdMail(default_cmds.MuxCommand): self.caller.msg("You must supply a reply message") return else: - if self.get_all_mail()[int(self.lhs) - 1]: - old_message = self.get_all_mail()[int(self.lhs) - 1] + all_mail = self.get_all_mail() + mind = int(self.lhs) - 1 + if all_mail[mind]: + old_message = all_mail[mind] self.send_mail(old_message.senders, "RE: " + old_message.header, self.rhs + "\n---- Original Message ----\n" + old_message.message, self.caller) old_message.tags.remove("u", category="mail") old_message.tags.add("r", category="mail") return else: - self.caller.msg("Message does not exist.") - return + raise IndexError + except IndexError: + self.caller.msg("Message does not exist.") except ValueError: self.caller.msg("Usage: @mail/reply <#>=") else: + # normal send if self.rhs: if "/" in self.rhs: subject, body = self.rhs.split("/", 1) else: body = self.rhs - self.send_mail(self.lhslist, subject, body, self.caller) + self.send_mail(self.search_targets(self.lhslist), subject, body, self.caller) else: try: message = self.get_all_mail()[int(self.lhs) - 1] - except ValueError: + except (ValueError, IndexError): self.caller.msg("'%s' is not a valid mail id." % self.lhs) return @@ -176,47 +244,8 @@ class CmdMail(default_cmds.MuxCommand): table.reformat_column(4, width=7) self.caller.msg(_HEAD_CHAR * _WIDTH) - self.caller.msg(table) + self.caller.msg(unicode(table)) self.caller.msg(_HEAD_CHAR * _WIDTH) else: self.caller.msg("Sorry, you don't have any messages. What a pathetic loser!") - def get_all_mail(self): - """ - Returns a list of all the messages where the caller is a recipient. - - Returns: - messages (list): list of Msg objects. - """ - # mail_messages = Msg.objects.get_by_tag(category="mail") - # messages = [] - messages = Msg.objects.get_by_tag(category="mail", raw_queryset=True).filter(db_receivers_players=self.caller.player) - return messages - - def send_mail(self, recipients, subject, message, caller): - """ - Function for sending new mail. Also useful for sending notifications from objects or systems. - - Args: - recipients (list): list of Player or character objects to receive the newly created mails. - subject (str): The header or subject of the message to be delivered. - message (str): The body of the message being sent. - caller (obj): The object (or Player or Character) that is sending the message. - """ - recobjs = [] - for char in recipients: - - if self.caller.player.search(char) is not None: - recobjs.append(self.caller.player.search(char)) - if recobjs: - for recipient in recobjs: - recipient.msg("You have received a new @mail from %s" % caller) - - new_message = create.create_message(self.caller, message, receivers=recipient, header=subject) - new_message.tags.add("U", category="mail") - - caller.msg("You sent your message.") - return - else: - caller.msg("No valid players found. Cannot send message.") - return diff --git a/evennia/contrib/tests.py b/evennia/contrib/tests.py index 3952b8200f..85bdb5558d 100644 --- a/evennia/contrib/tests.py +++ b/evennia/contrib/tests.py @@ -521,5 +521,20 @@ class TestGenderSub(CommandTest): # test mail contrib -class TestMail(CommandTest): +from evennia.contrib import mail +class TestMail(CommandTest): + def test_mail(self): + self.call(mail.CmdMail(), "2", "'2' is not a valid mail id.", caller=self.player) + self.call(mail.CmdMail(), "", "Sorry, you don't have any messages.", caller=self.player) + self.call(mail.CmdMail(), "Char=Message 1", "You have received a new @mail from Char|You sent your message.", caller=self.char1) + self.call(mail.CmdMail(), "Char=Message 2", "You sent your message.", caller=self.char2) + self.call(mail.CmdMail(), "TestPlayer2=Message 2", + "You have received a new @mail from TestPlayer2(player 2)|You sent your message.", caller=self.player2) + self.call(mail.CmdMail(), "TestPlayer=Message 1", "You sent your message.", caller=self.player2) + self.call(mail.CmdMail(), "TestPlayer=Message 2", "You sent your message.", caller=self.player2) + self.call(mail.CmdMail(), "", "| ID: From: Subject:", caller=self.player) + self.call(mail.CmdMail(), "2", "From: TestPlayer2", caller=self.player) + self.call(mail.CmdMail(), "/forward TestPlayer2 = 1/Forward message", "You sent your message.|Message forwarded.", caller=self.player) + self.call(mail.CmdMail(), "/reply 2=Reply Message2", "You sent your message.", caller=self.player) + self.call(mail.CmdMail(), "/delete 2", "Message 2 deleted", caller=self.player)