Finish 'get-email' ad-hoc command implementation

Support browsing emails through multiple pages
Handle error in get-email command

darcs-hash:20080307110959-86b55-5657eb6fa1e38bee46cfcc8b7482ffff16963ec6.gz
This commit is contained in:
David Rousselie
2008-03-07 12:09:59 +01:00
parent 392169732f
commit 9f4768a96d
3 changed files with 224 additions and 59 deletions

View File

@@ -27,7 +27,7 @@ from pyxmpp.jabber.dataforms import Form
import jcl.model.account as account import jcl.model.account as account
import jcl.jabber.command as command import jcl.jabber.command as command
from jcl.jabber.command import JCLCommandManager from jcl.jabber.command import JCLCommandManager, CommandError
from jmc.model.account import MailAccount from jmc.model.account import MailAccount
from jmc.jabber.feeder import MailSender from jmc.jabber.feeder import MailSender
@@ -58,8 +58,6 @@ class MailCommandManager(JCLCommandManager):
self.add_actions(command_node, [command.ACTION_NEXT]) self.add_actions(command_node, [command.ACTION_NEXT])
bare_from_jid = info_query.get_from().bare() bare_from_jid = info_query.get_from().bare()
account_name = info_query.get_to().node account_name = info_query.get_to().node
print str(bare_from_jid)
print str(account_name)
_account = account.get_account(bare_from_jid, account_name, _account = account.get_account(bare_from_jid, account_name,
MailAccount) MailAccount)
if _account is not None: if _account is not None:
@@ -122,42 +120,60 @@ class MailCommandManager(JCLCommandManager):
execute_force_check_2 = execute_force_check_1 execute_force_check_2 = execute_force_check_1
def execute_get_email_1(self, info_query, session_context, def execute_get_email(self, info_query, session_context,
command_node, lang_class): command_node, lang_class):
self.__logger.debug("Executing command 'get-email' step 1") self.__logger.debug("Executing command 'get-email' step 1")
self.add_actions(command_node, [command.ACTION_COMPLETE]) if "fetch_more" in session_context \
bare_from_jid = info_query.get_from().bare() and session_context["fetch_more"][-1] == "0":
account_name = info_query.get_to().node return self.execute_get_email_last(info_query, session_context,
_account = account.get_account(bare_from_jid, account_name) command_node, lang_class)
if _account is not None:
result_form = Form(\
xmlnode_or_type="form",
title=lang_class.command_get_email,
instructions=lang_class.command_get_email_1_description)
email_list = _account.get_mail_list_summary()
field = result_form.add_field(name="emails",
field_type="list-multi",
label=lang_class.field_email_subject)
for (email_index, email_subject) in email_list:
field.add_option(label=email_subject, values=[email_index])
result_form.add_field(name="fetch_more",
field_type="boolean",
label=lang_class.field_select_more_emails)
result_form.as_xml(command_node)
return (result_form, [])
else: else:
# TODO Error self.add_actions(command_node, [command.ACTION_COMPLETE])
return (None, []) bare_from_jid = info_query.get_from().bare()
account_name = info_query.get_to().node
_account = account.get_account(bare_from_jid, account_name)
if _account is not None:
result_form = Form(\
xmlnode_or_type="form",
title=lang_class.command_get_email,
instructions=lang_class.command_get_email_1_description)
if not "start_index" in session_context:
session_context["start_index"] = 1
self.__logger.debug("Checking email list summary from index "
+ str(session_context["start_index"]) + " to "
+ str(session_context["start_index"] + 10))
_account.connect()
email_list = _account.get_mail_list_summary(\
start_index=session_context["start_index"],
end_index=session_context["start_index"] + 9)
_account.disconnect()
session_context["start_index"] += 10
field = result_form.add_field(name="emails",
field_type="list-multi",
label=lang_class.field_email_subject)
for (email_index, email_subject) in email_list:
field.add_option(label=email_subject, values=[email_index])
if len(email_list) == 10:
result_form.add_field(name="fetch_more",
field_type="boolean",
label=lang_class.field_select_more_emails)
else:
session_context["fetch_more"] = ["0"]
result_form.as_xml(command_node)
return (result_form, [])
else:
raise CommandError("item-not-found")
def execute_get_email_2(self, info_query, session_context, def execute_get_email_last(self, info_query, session_context,
command_node, lang_class): command_node, lang_class):
self.__logger.debug("Executing command 'get-email' step 2") self.__logger.debug("Executing command 'get-email' last step")
result = [] result = []
mail_sender = MailSender(self.component) mail_sender = MailSender(self.component)
bare_from_jid = info_query.get_from().bare() bare_from_jid = info_query.get_from().bare()
account_name = info_query.get_to().node account_name = info_query.get_to().node
_account = account.get_account(bare_from_jid, account_name) _account = account.get_account(bare_from_jid, account_name)
if _account is not None: if _account is not None:
_account.connect()
for email_index in session_context["emails"]: for email_index in session_context["emails"]:
(email_body, email_from) = _account.get_mail(email_index) (email_body, email_from) = _account.get_mail(email_index)
result.append(\ result.append(\
@@ -166,6 +182,7 @@ class MailCommandManager(JCLCommandManager):
lang_class.mail_subject % (email_from), lang_class.mail_subject % (email_from),
email_body, email_body,
_account)) _account))
_account.disconnect()
result_form = Form(\ result_form = Form(\
xmlnode_or_type="form", xmlnode_or_type="form",
title=lang_class.command_get_email, title=lang_class.command_get_email,

View File

@@ -228,31 +228,51 @@ class MailCommandManagerGetEmailCommand_TestCase(MailCommandManagerTestCase):
def check_step_1(self, result, options="<option label=\"mail 1\">" \ def check_step_1(self, result, options="<option label=\"mail 1\">" \
+ "<value>1</value></option>" \ + "<value>1</value></option>" \
+ "<option label=\"mail 2\">" \ + "<option label=\"mail 2\">" \
+ "<value>2</value></option>"): + "<value>2</value></option>" \
+ "<option label=\"mail 3\">" \
+ "<value>3</value></option>" \
+ "<option label=\"mail 4\">" \
+ "<value>4</value></option>" \
+ "<option label=\"mail 5\">" \
+ "<value>5</value></option>" \
+ "<option label=\"mail 6\">" \
+ "<value>6</value></option>" \
+ "<option label=\"mail 7\">" \
+ "<value>7</value></option>" \
+ "<option label=\"mail 8\">" \
+ "<value>8</value></option>" \
+ "<option label=\"mail 9\">" \
+ "<value>9</value></option>" \
+ "<option label=\"mail 10\">" \
+ "<value>10</value></option>",
last_page=False):
""" """
Check first step result of get-email ad-hoc command Check first step result of get-email ad-hoc command
""" """
result_iq = result[0].xmlnode result_iq = result[0].xmlnode
result_iq.setNs(None) result_iq.setNs(None)
self.assertTrue(jcl.tests.is_xml_equal(\ xml_ref = u"<iq from='account11@" + unicode(self.comp.jid) \
u"<iq from='account11@" + unicode(self.comp.jid) + "' to='test1@test.com' type='result'>" \
+ "' to='test1@test.com' type='result'>" + "<command xmlns='http://jabber.org/protocol/commands'" \
+ "<command xmlns='http://jabber.org/protocol/commands'" + "status='executing'>" \
+ "status='executing'>" + "<actions execute='complete'><complete/></actions>" \
+ "<actions execute='complete'><complete/></actions>" + "<x xmlns='jabber:x:data' type='form'>" \
+ "<x xmlns='jabber:x:data' type='form'>" + "<title>" + Lang.en.command_get_email + "</title>" \
+ "<title>" + Lang.en.command_get_email + "</title>" + "<instructions>" + Lang.en.command_get_email_1_description \
+ "<instructions>" + Lang.en.command_get_email_1_description + "</instructions>" \
+ "</instructions>" + "<field var='emails' type='list-multi' label='" \
+ "<field var='emails' type='list-multi' label='" + Lang.en.field_email_subject + "'>" \
+ Lang.en.field_email_subject + "'>" + options
+ options if not last_page:
+ "</field><field var='fetch_more' type='boolean' label='" xml_ref += "</field><field var='fetch_more' type='boolean' label='" \
+ Lang.en.field_select_more_emails + "'>" + Lang.en.field_select_more_emails + "'>"
+ "</field></x></command></iq>", xml_ref += "</field></x></command></iq>"
result_iq, True)) self.assertTrue(jcl.tests.is_xml_equal(xml_ref, result_iq, True))
session_id = result_iq.children.prop("sessionid") session_id = result_iq.children.prop("sessionid")
self.assertNotEquals(session_id, None) self.assertNotEquals(session_id, None)
self.assertTrue(self.account11.has_connected)
self.assertFalse(self.account11.connected)
self.account11.has_connected = False
return session_id return session_id
def check_email_message(self, result_iq, index): def check_email_message(self, result_iq, index):
@@ -271,7 +291,7 @@ class MailCommandManagerGetEmailCommand_TestCase(MailCommandManagerTestCase):
+ "</addresses>" + "</addresses>"
+ "</message>", + "</message>",
result_iq, True, test_sibling=False)) result_iq, True, test_sibling=False))
def test_execute_get_email(self): def test_execute_get_email(self):
""" """
Test single email retrieval Test single email retrieval
@@ -301,6 +321,8 @@ class MailCommandManagerGetEmailCommand_TestCase(MailCommandManagerTestCase):
info_query, info_query,
"jmc#get-email", "jmc#get-email",
"execute") "execute")
self.assertTrue(self.account11.has_connected)
self.assertFalse(self.account11.connected)
self.assertEquals(len(result), 2) self.assertEquals(len(result), 2)
result_iq = result[0].xmlnode result_iq = result[0].xmlnode
result_iq.setNs(None) result_iq.setNs(None)
@@ -347,6 +369,8 @@ class MailCommandManagerGetEmailCommand_TestCase(MailCommandManagerTestCase):
info_query, info_query,
"jmc#get-email", "jmc#get-email",
"execute") "execute")
self.assertTrue(self.account11.has_connected)
self.assertFalse(self.account11.connected)
self.assertEquals(len(result), 3) self.assertEquals(len(result), 3)
result_iq = result[0].xmlnode result_iq = result[0].xmlnode
result_iq.setNs(None) result_iq.setNs(None)
@@ -395,10 +419,26 @@ class MailCommandManagerGetEmailCommand_TestCase(MailCommandManagerTestCase):
info_query, info_query,
"jmc#get-email", "jmc#get-email",
"execute") "execute")
self.check_step_1(result, options="<option label=\"mail 3\">" \ self.check_step_1(result, options="<option label=\"mail 11\">" \
+ "<value>3</value></option>" \ + "<value>11</value></option>" \
+ "<option label=\"mail 4\">" \ + "<option label=\"mail 12\">" \
+ "<value>4</value></option>") + "<value>12</value></option>" \
+ "<option label=\"mail 13\">" \
+ "<value>13</value></option>" \
+ "<option label=\"mail 14\">" \
+ "<value>14</value></option>" \
+ "<option label=\"mail 15\">" \
+ "<value>15</value></option>" \
+ "<option label=\"mail 16\">" \
+ "<value>16</value></option>" \
+ "<option label=\"mail 17\">" \
+ "<value>17</value></option>" \
+ "<option label=\"mail 18\">" \
+ "<value>18</value></option>" \
+ "<option label=\"mail 19\">" \
+ "<value>19</value></option>" \
+ "<option label=\"mail 20\">" \
+ "<value>20</value></option>")
# Third step # Third step
info_query = jcl.jabber.tests.command.prepare_submit(\ info_query = jcl.jabber.tests.command.prepare_submit(\
@@ -408,7 +448,7 @@ class MailCommandManagerGetEmailCommand_TestCase(MailCommandManagerTestCase):
to_jid="account11@jmc.test.com", to_jid="account11@jmc.test.com",
fields=[Field(field_type="list-multi", fields=[Field(field_type="list-multi",
name="emails", name="emails",
values=["3", "4"]), values=["13", "14"]),
Field(field_type="boolean", Field(field_type="boolean",
name="fetch_more", name="fetch_more",
value=False)], value=False)],
@@ -417,6 +457,8 @@ class MailCommandManagerGetEmailCommand_TestCase(MailCommandManagerTestCase):
info_query, info_query,
"jmc#get-email", "jmc#get-email",
"execute") "execute")
self.assertTrue(self.account11.has_connected)
self.assertFalse(self.account11.connected)
self.assertEquals(len(result), 5) self.assertEquals(len(result), 5)
result_iq = result[0].xmlnode result_iq = result[0].xmlnode
result_iq.setNs(None) result_iq.setNs(None)
@@ -436,9 +478,99 @@ class MailCommandManagerGetEmailCommand_TestCase(MailCommandManagerTestCase):
result_iq = result[2].xmlnode result_iq = result[2].xmlnode
self.check_email_message(result_iq, 2) self.check_email_message(result_iq, 2)
result_iq = result[3].xmlnode result_iq = result[3].xmlnode
self.check_email_message(result_iq, 3) self.check_email_message(result_iq, 13)
result_iq = result[4].xmlnode result_iq = result[4].xmlnode
self.check_email_message(result_iq, 4) self.check_email_message(result_iq, 14)
def test_execute_get_emails_last_page(self):
"""
Test that field fetch_more does not exist if number of emails < 10
"""
class MockIMAPAccount2(MockIMAPAccount):
""" """
def get_mail_list_summary(self, start_index=1, end_index=20):
return [("1", "mail 1"),
("2", "mail 2")]
get_email_func = self.account11.get_mail
MockIMAPAccount2.createTable(ifNotExists=True)
self.account11.destroySelf()
self.account11 = MockIMAPAccount2(user=self.user1,
name="account11",
jid="account11@" + unicode(self.comp.jid))
self.account11.__dict__["get_mail"] = get_email_func
self.info_query.set_from("test1@test.com")
self.info_query.set_to("account11@" + unicode(self.comp.jid))
result = self.command_manager.apply_command_action(\
self.info_query,
"jmc#get-email",
"execute")
session_id = self.check_step_1(result, options="<option label=\"mail 1\">" \
+ "<value>1</value></option>" \
+ "<option label=\"mail 2\">" \
+ "<value>2</value></option>",
last_page=True)
self.assertTrue("fetch_more" in
self.command_manager.sessions[session_id][1])
self.assertEquals(\
self.command_manager.sessions[session_id][1]["fetch_more"][-1],
"0")
# Second step
info_query = jcl.jabber.tests.command.prepare_submit(\
node="jmc#get-email",
session_id=session_id,
from_jid="test1@test.com",
to_jid="account11@jmc.test.com",
fields=[Field(field_type="list-multi",
name="emails",
values=["1"])],
action="complete")
result = self.command_manager.apply_command_action(\
info_query,
"jmc#get-email",
"execute")
self.assertTrue(self.account11.has_connected)
self.assertFalse(self.account11.connected)
self.assertEquals(len(result), 2)
result_iq = result[0].xmlnode
result_iq.setNs(None)
self.assertTrue(jcl.tests.is_xml_equal(\
u"<iq from='account11@" + unicode(self.comp.jid)
+ "' to='test1@test.com' type='result'>"
+ "<command xmlns='http://jabber.org/protocol/commands' "
+ "status='completed'>"
+ "<x xmlns='jabber:x:data' type='form'>"
+ "<title>" + Lang.en.command_get_email + "</title>"
+ "<instructions>" + Lang.en.command_get_email_2_description
% (1) + "</instructions>"
+ "</x></command></iq>",
result_iq, True, test_sibling=False))
result_iq = result[1].xmlnode
self.check_email_message(result_iq, 1)
MockIMAPAccount2.dropTable(ifExists=True)
def test_execute_get_email_error(self):
"""
Test single email retrieval
"""
self.info_query.set_from("test1@test.com")
self.info_query.set_to("unknown@" + unicode(self.comp.jid))
result = self.command_manager.apply_command_action(\
self.info_query,
"jmc#get-email",
"execute")
result_iq = result[0].xmlnode
self.assertTrue(jcl.tests.is_xml_equal(\
u"<iq from='unknown@" + unicode(self.comp.jid)
+ "' to='test1@test.com' type='error' "
+ "xmlns='http://pyxmpp.jabberstudio.org/xmlns/common'>"
+ "<command xmlns='http://jabber.org/protocol/commands' "
+ "node='jmc#get-email' />"
+ "<error type='cancel'>"
+ "<item-not-found xmlns='urn:ietf:params:xml:ns:xmpp-stanzas' />"
+ "</error></iq>",
result_iq, True))
def suite(): def suite():
test_suite = unittest.TestSuite() test_suite = unittest.TestSuite()

View File

@@ -156,14 +156,30 @@ class MockIMAPAccount(MockMailAccount, IMAPAccount):
return [("1", "mail 1"), return [("1", "mail 1"),
("2", "mail 2")] ("2", "mail 2")]
def get_mail_list_summary(self): def get_mail_list_summary(self, start_index=1, end_index=20):
if self.get_mail_list_summary_called: if self.get_mail_list_summary_called:
return [("3", "mail 3"), return [("11", "mail 11"),
("4", "mail 4")] ("12", "mail 12"),
("13", "mail 13"),
("14", "mail 14"),
("15", "mail 15"),
("16", "mail 16"),
("17", "mail 17"),
("18", "mail 18"),
("19", "mail 19"),
("20", "mail 20")]
else: else:
self.get_mail_list_summary_called = True self.get_mail_list_summary_called = True
return [("1", "mail 1"), return [("1", "mail 1"),
("2", "mail 2")] ("2", "mail 2"),
("3", "mail 3"),
("4", "mail 4"),
("5", "mail 5"),
("6", "mail 6"),
("7", "mail 7"),
("8", "mail 8"),
("9", "mail 9"),
("10", "mail 10")]
class MockPOP3Account(MockMailAccount, POP3Account): class MockPOP3Account(MockMailAccount, POP3Account):