Add unittest for mail contrib; fix some inconsistencies and refactor to better handle errors.

This commit is contained in:
Griatch 2017-02-19 19:24:00 +01:00
parent 23cfd3ba17
commit 108dd35ee7
2 changed files with 106 additions and 62 deletions

View file

@ -7,10 +7,13 @@ A simple Brandymail style @mail system that uses the Msg class from Evennia Core
Installation: Installation:
import MailCommand from this module into the default Player or Character command set 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 import default_cmds
from evennia.utils import create, evtable from evennia.utils import create, evtable, make_iter
from evennia.comms.models import Msg from evennia.comms.models import Msg
@ -56,9 +59,63 @@ class CmdMail(default_cmds.MuxCommand):
lock = "cmd:all()" lock = "cmd:all()"
help_category = "General" 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): def func(self):
subject = "" subject = ""
body = "" body = ""
if self.switches or self.args: if self.switches or self.args:
if "delete" in self.switches: if "delete" in self.switches:
try: try:
@ -66,12 +123,15 @@ class CmdMail(default_cmds.MuxCommand):
self.caller.msg("No Message ID given. Unable to delete.") self.caller.msg("No Message ID given. Unable to delete.")
return return
else: else:
if self.get_all_mail()[int(self.lhs) - 1]: all_mail = self.get_all_mail()
self.get_all_mail()[int(self.lhs) - 1].delete() mind = int(self.lhs) - 1
if all_mail[mind]:
all_mail[mind].delete()
self.caller.msg("Message %s deleted" % self.lhs) self.caller.msg("Message %s deleted" % self.lhs)
else: else:
self.caller.msg("That message does not exist.") raise IndexError
return except IndexError:
self.caller.msg("That message does not exist.")
except ValueError: except ValueError:
self.caller.msg("Usage: @mail/delete <message ID>") self.caller.msg("Usage: @mail/delete <message ID>")
elif "forward" in self.switches: elif "forward" in self.switches:
@ -83,29 +143,33 @@ class CmdMail(default_cmds.MuxCommand):
self.caller.msg("You must define a message to forward.") self.caller.msg("You must define a message to forward.")
return return
else: else:
all_mail = self.get_all_mail()
if "/" in self.rhs: if "/" in self.rhs:
message_number, message = self.rhs.split("/") message_number, message = self.rhs.split("/")
if self.get_all_mail()[int(message_number) - 1]: mind = int(message_number) - 1
old_message = self.get_all_mail()[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, message + "\n---- Original Message ----\n" + old_message.message,
self.caller) self.caller)
self.caller.msg("Message forwarded.") self.caller.msg("Message forwarded.")
else: else:
self.caller.msg("Message does not exist.") raise IndexError
return
else: else:
if self.get_all_mail()[int(self.rhs) - 1]: mind = int(self.rhs) - 1
old_message = self.get_all_mail()[int(self.rhs) - 1] if all_mail[mind]:
self.send_mail(self.lhslist, "FWD: " + old_message.header, 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) "\n---- Original Message ----\n" + old_message.message, self.caller)
self.caller.msg("Message forwarded.") self.caller.msg("Message forwarded.")
old_message.tags.remove("u", category="mail") old_message.tags.remove("u", category="mail")
old_message.tags.add("f", category="mail") old_message.tags.add("f", category="mail")
else: else:
self.caller.msg("Message does not exist.") raise IndexError
return except IndexError:
self.caller.msg("Message does not exixt.")
except ValueError: except ValueError:
self.caller.msg("Usage: @mail/forward <player list>=<#>[/<Message>]") self.caller.msg("Usage: @mail/forward <player list>=<#>[/<Message>]")
elif "reply" in self.switches: elif "reply" in self.switches:
@ -117,29 +181,33 @@ class CmdMail(default_cmds.MuxCommand):
self.caller.msg("You must supply a reply message") self.caller.msg("You must supply a reply message")
return return
else: else:
if self.get_all_mail()[int(self.lhs) - 1]: all_mail = self.get_all_mail()
old_message = self.get_all_mail()[int(self.lhs) - 1] 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.send_mail(old_message.senders, "RE: " + old_message.header,
self.rhs + "\n---- Original Message ----\n" + old_message.message, self.caller) self.rhs + "\n---- Original Message ----\n" + old_message.message, self.caller)
old_message.tags.remove("u", category="mail") old_message.tags.remove("u", category="mail")
old_message.tags.add("r", category="mail") old_message.tags.add("r", category="mail")
return return
else: else:
self.caller.msg("Message does not exist.") raise IndexError
return except IndexError:
self.caller.msg("Message does not exist.")
except ValueError: except ValueError:
self.caller.msg("Usage: @mail/reply <#>=<message>") self.caller.msg("Usage: @mail/reply <#>=<message>")
else: else:
# normal send
if self.rhs: if self.rhs:
if "/" in self.rhs: if "/" in self.rhs:
subject, body = self.rhs.split("/", 1) subject, body = self.rhs.split("/", 1)
else: else:
body = self.rhs 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: else:
try: try:
message = self.get_all_mail()[int(self.lhs) - 1] 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) self.caller.msg("'%s' is not a valid mail id." % self.lhs)
return return
@ -176,47 +244,8 @@ class CmdMail(default_cmds.MuxCommand):
table.reformat_column(4, width=7) table.reformat_column(4, width=7)
self.caller.msg(_HEAD_CHAR * _WIDTH) self.caller.msg(_HEAD_CHAR * _WIDTH)
self.caller.msg(table) self.caller.msg(unicode(table))
self.caller.msg(_HEAD_CHAR * _WIDTH) self.caller.msg(_HEAD_CHAR * _WIDTH)
else: else:
self.caller.msg("Sorry, you don't have any messages. What a pathetic loser!") 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

View file

@ -521,5 +521,20 @@ class TestGenderSub(CommandTest):
# test mail contrib # 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)