diff --git a/integration/P/run.py b/integration/P/run.py index eea048b..b421bd7 100644 --- a/integration/P/run.py +++ b/integration/P/run.py @@ -1,22 +1,36 @@ import stick import unittest from test_kolabd import TestKolabDaemon + from test_wap_client_connect import TestWAPClientConnect from test_wap_client_users import TestWAPClientUserAdd from test_wap_client_resources import TestWAPClientResourceAdd from test_wap_client_form_value_select import TestWAPClientFormValueListOptions +from test_wallace_forward import TestWallaceEmailForward +from test_wallace_footer import TestWallaceFooter +from test_wallace_nonascii import TestWallaceNonAscii +from test_wallace_module_resources import TestWallaceModuleResources + if __name__ == '__main__': opts = stick.conf.cli_keywords loader = stick.KolabTestLoader(opts) alltests = unittest.TestSuite() # add tests in order of their dependencies alltests.addTests(loader.loadTestsFromTestCase(TestWAPClientConnect)) alltests.addTests(loader.loadTestsFromTestCase(TestWAPClientFormValueListOptions)) alltests.addTests(loader.loadTestsFromTestCase(TestWAPClientUserAdd)) alltests.addTests(loader.loadTestsFromTestCase(TestWAPClientResourceAdd)) + + # kolabd alltests.addTests(loader.loadTestsFromTestCase(TestKolabDaemon)) + # wallace + alltests.addTests(loader.loadTestsFromTestCase(TestWallaceEmailForward)) + alltests.addTests(loader.loadTestsFromTestCase(TestWallaceFooter)) + alltests.addTests(loader.loadTestsFromTestCase(TestWallaceNonAscii)) + alltests.addTests(loader.loadTestsFromTestCase(TestWallaceModuleResources)) + stick.main(defaultTest='alltests') diff --git a/integration/P/test_kolabd.py b/integration/P/test_kolabd.py index d956dc7..94b7a04 100644 --- a/integration/P/test_kolabd.py +++ b/integration/P/test_kolabd.py @@ -1,205 +1,206 @@ import stick import time import pykolab from pykolab.auth import Auth from pykolab.imap import IMAP conf = pykolab.getConf() class TestKolabDaemon(stick.KolabIntegrationTest): """ Integration tests for kolabd """ user = None jane = None auth = None imap = None @classmethod def setUpClass(self, *args, **kw): self.cleanafter = True + self.user = self.require_user("John", "Doe") self.jane = self.require_user("Jane", "Doe") (local, domain) = self.user['mail'].split('@') self.user.update({ 'local': local, 'domain': domain }) super(TestKolabDaemon, self).setUpClass(*args, **kw) def tearDown(self): if self.auth: self.auth.disconnect() if self.imap: self.imap.disconnect() def test_001_user_recipient_policy(self): self.auth = Auth() self.auth.connect() recipient = self.auth.find_recipient(self.user['mail']) if hasattr(self, 'assertIsInstance'): self.assertIsInstance(recipient, str) self.assertEqual(recipient, "uid=doe,ou=People,dc=example,dc=org") wap_client = stick.webadmin.get_instance() result = wap_client.user_info(recipient) self.assertEqual(result['mail'], 'john.doe@example.org') self.assertEqual(result['alias'], ['doe@example.org', 'j.doe@example.org']) def test_002_user_recipient_policy_duplicate(self): self.auth = Auth() self.auth.connect() recipient = self.auth.find_recipient("%(mail)s" % self.jane) if hasattr(self, 'assertIsInstance'): self.assertIsInstance(recipient, str) self.assertEqual(recipient, self.jane['dn']) wap_client = stick.webadmin.get_instance() result = wap_client.user_info(recipient) self.assertEqual(result['mail'], 'jane.doe@example.org') self.assertEqual(result['alias'], ['doe2@example.org', 'j.doe2@example.org']) def test_003_user_mailbox_created(self): imap = IMAP() imap.connect() folders = imap.lm('user/%(mail)s' % self.user) self.assertEqual(len(folders), 1) def test_004_user_additional_folders_created(self): imap = IMAP() imap.connect() ac_folders = conf.get_raw('kolab', 'autocreate_folders') exec("ac_folders = %s" % (ac_folders)) folders = imap.lm('user/%(local)s/*@%(domain)s' % self.user) self.assertEqual(len(folders), len(ac_folders.keys())) - def test_005_user_folders_metadata_set(self): + def test_005_user_folders_metadata_get(self): imap = IMAP() imap.connect() ac_folders = conf.get_raw('kolab', 'autocreate_folders') exec("ac_folders = %s" % (ac_folders)) folders = [] folders.extend(imap.lm('user/%(mail)s' % self.user)) folders.extend(imap.lm('user/%(local)s/*@%(domain)s' % self.user)) for folder in folders: metadata = imap.get_metadata(folder) self.log("Metadata for %s: %r" % (folder, metadata)) folder_name = '/'.join(folder.split('/')[2:]).split('@')[0] if ac_folders.has_key(folder_name): if ac_folders[folder_name].has_key('annotations'): for _annotation in ac_folders[folder_name]['annotations'].keys(): if _annotation.startswith('/private'): continue _annotation_value = ac_folders[folder_name]['annotations'][_annotation] self.assertTrue(metadata[metadata.keys().pop()].has_key(_annotation)) self.assertEqual(_annotation_value, metadata[metadata.keys().pop()][_annotation]) def test_006_user_subscriptions(self): imap = IMAP() imap.connect(login=False) login = conf.get('cyrus-imap', 'admin_login') password = conf.get('cyrus-imap', 'admin_password') imap.login_plain(login, password, 'john.doe@example.org') folders = imap.lm() self.assertTrue("INBOX" in folders) folders = imap.imap.lsub() self.assertTrue("Calendar" in folders) def test_011_two_johns(self): john2 = stick.add_user("John", "Doe") stick.synchronize() time.sleep(1) self.assertEqual('john.doe2@example.org', john2['mail']) self.auth = Auth() self.auth.connect() max_tries = 20 while max_tries > 0: recipient1 = self.auth.find_recipient(self.user['mail']) recipient2 = self.auth.find_recipient(john2['mail']) if not recipient1 or not recipient2: time.sleep(1) max_tries -= 1 else: break imap = IMAP() imap.connect() folders = imap.lm('user/%(mail)s' % self.user) self.assertEqual(len(folders), 1, "No INBOX found for first John") folders = imap.lm('user/%(mail)s' % john2) self.assertEqual(len(folders), 1, "No INBOX found for second John") def test_021_user_rename(self): """ Rename user "Doe, John" to "Sixpack, Joe" and verify the recipient policy is applied, and the IMAP INBOX folder for the user is renamed. """ self.auth = Auth() self.auth.connect() recipient = self.auth.find_recipient(self.user['mail']) wap_client = stick.webadmin.get_instance() user_info = wap_client.user_info(recipient) if not user_info.has_key('mailhost'): from tests.functional.synchronize import synchronize_once synchronize_once() imap = IMAP() imap.connect() folders = imap.lm('user/%(mail)s' % self.user) self.assertEqual(len(folders), 1) self.auth = Auth() self.auth.connect() recipient = self.auth.find_recipient("%(mail)s" % self.user) user_info = wap_client.user_info(recipient) user_info['uid'] = 'sixpack' user_info['sn'] = 'Sixpack' user_info['givenname'] = 'Joe' user_edit = wap_client.user_edit(recipient, user_info) - time.sleep(2) + time.sleep(4) dn = self.user['dn'].replace('uid=doe', 'uid=sixpack') mail = 'joe.sixpack@%(domain)s' % self.user user_info = wap_client.user_info(dn) if not user_info['mail'] == mail: stick.synchronize() user_info = wap_client.user_info(dn) self.assertEqual(user_info['mail'], mail) folders = imap.lm('user/%(mail)s' % self.user) self.assertEqual(len(folders), 0, "INBOX for john.doe still exists") folders = imap.lm('user/joe.sixpack@%(domain)s' % self.user) self.assertEqual(len(folders), 1, "INBOX for joe.sixpack does not exist") if __name__ == '__main__': stick.main() \ No newline at end of file diff --git a/integration/P/test_wap_client_users.py b/integration/P/test_users.py similarity index 94% copy from integration/P/test_wap_client_users.py copy to integration/P/test_users.py index bb764af..ca91bc6 100644 --- a/integration/P/test_wap_client_users.py +++ b/integration/P/test_users.py @@ -1,177 +1,171 @@ # -*- coding: utf-8 -*- import stick import pykolab import time from pykolab.auth import Auth from pykolab.imap import IMAP conf = pykolab.getConf() -class TestWAPClientUserAdd(stick.KolabIntegrationTest): +class TestWAPUsers(stick.KolabIntegrationTest): user = None auth = None imap = None alvaro = None thomas = None etienne = None @classmethod def setUpClass(self, *args, **kw): self.cleanafter = True self.user = self._get_user_prop(self.require_user("John", "Doe")) self.etienne = self._get_user_prop(self.require_user("Étienne-Nicola", "Méhul", preferredlanguage='fr_FR')) self.alvaro = self._get_user_prop(self.require_user("Álvaro", "Fuentes", preferredlanguage='es_ES')) self.thomas = self._get_user_prop(self.require_user("Thomas", "Brüderli", preferredlanguage='de_CH')) super(TestWAPClientUserAdd, self).setUpClass(*args, **kw) @classmethod def _get_user_prop(self, data): (local, domain) = data['mail'].split('@') data.update({ 'local': local, 'domain': domain }) return data def tearDown(self): if self.auth: self.auth.disconnect() if self.imap: self.imap.disconnect() def test_001_inbox_created(self): self.imap = IMAP() self.imap.connect() folders = self.imap.lm('user/%(mail)s' % self.user) self.assertEqual(len(folders), 1) def test_002_autocreate_folders_created(self): self.imap = IMAP() self.imap.connect() ac_folders_ = conf.get_raw(self.get_conf('kolab', 'primary_domain'), 'autocreate_folders') if not ac_folders_: ac_folders_ = conf.get_raw('kolab', 'autocreate_folders') exec("ac_folders = %s" % (ac_folders_)) folders = self.imap.lm('user/%(local)s/*@%(domain)s' % self.user) - self.log("Autocreate folders: %r" % (ac_folders.keys())) - self.log("IMAP folders: %r" % (folders)) + #self.log("Autocreate folders: %r" % (ac_folders.keys())) + #self.log("IMAP folders: %r" % (folders)) self.assertEqual(len(folders), len(ac_folders.keys())) def test_003_folders_metadata_set(self): self.imap = IMAP() self.imap.connect() ac_folders_ = conf.get_raw(self.get_conf('kolab', 'primary_domain'), 'autocreate_folders') if not ac_folders_: ac_folders_ = conf.get_raw('kolab', 'autocreate_folders') exec("ac_folders = %s" % (ac_folders_)) folders = [] folders.extend(self.imap.lm('user/%(local)s@%(domain)s' % self.user)) folders.extend(self.imap.lm('user/%(local)s/*@%(domain)s' % self.user)) for folder in folders: metadata = self.imap.get_metadata(folder) folder_name = '/'.join(folder.split('/')[2:]).split('@')[0] if ac_folders.has_key(folder_name): if ac_folders[folder_name].has_key('annotations'): for _annotation in ac_folders[folder_name]['annotations'].keys(): if _annotation.startswith('/private/'): continue _annotation_value = ac_folders[folder_name]['annotations'][_annotation] self.assertTrue(metadata[metadata.keys().pop()].has_key(_annotation)) self.assertEqual(_annotation_value, metadata[metadata.keys().pop()][_annotation]) def test_011_fr_FR_inbox_created(self): - time.sleep(2) self.imap = IMAP() self.imap.connect() folders = self.imap.lm('user/%(local)s@%(domain)s' % self.etienne) self.assertEqual(len(folders), 1) - @stick.todo("TODO: unkown API error") def test_012_fr_FR_user_recipient_policy(self): self.auth = Auth() self.auth.connect() recipient = self.auth.find_recipient("%(local)s@%(domain)s" % self.etienne) if hasattr(self, 'assertIsInstance'): self.assertIsInstance(recipient, str) base_dn = self.get_conf('ldap', 'kolab_user_base_dn') self.assertEqual(recipient, "uid=%s,%s" % (self.etienne['uid'], base_dn)) wap_client = stick.webadmin.get_instance() result = wap_client.user_info(recipient) self.log("User fr_FR: %r" % (result)) self.assertEqual(result['mail'], self.etienne['mail']) self.assertEqual(sorted(result['alias']), ['e.mehul@example.org', 'mehul@example.org']) def test_021_es_ES_inbox_created(self): - time.sleep(2) self.imap = IMAP() self.imap.connect() folders = self.imap.lm('user/%(local)s@%(domain)s' % (self.alvaro)) self.assertEqual(len(folders), 1) - @stick.todo("TODO: unkown API error") def test_022_es_ES_user_recipient_policy(self): self.auth = Auth() self.auth.connect() recipient = self.auth.find_recipient("%(local)s@%(domain)s" % (self.alvaro)) if hasattr(self, 'assertIsInstance'): self.assertIsInstance(recipient, str) base_dn = self.get_conf('ldap', 'kolab_user_base_dn') self.assertEqual(recipient, "uid=%s,%s" % (self.alvaro['uid'], base_dn)) wap_client = stick.webadmin.get_instance() result = wap_client.user_info(recipient) self.assertEqual(result['mail'], self.alvaro['mail']) self.assertEqual(sorted(result['alias']), ['a.fuentes@example.org', 'fuentes@example.org']) def test_031_de_CH_inbox_created(self): - time.sleep(2) self.imap = IMAP() self.imap.connect() folders = self.imap.lm('user/%(local)s@%(domain)s' % (self.thomas)) self.assertEqual(len(folders), 1) - @stick.todo("TODO: unkown API error") def test_032_de_CH_user_recipient_policy(self): self.auth = Auth() self.auth.connect() recipient = self.auth.find_recipient("%(local)s@%(domain)s" % (self.thomas)) if hasattr(self, 'assertIsInstance'): self.assertIsInstance(recipient, str) base_dn = self.get_conf('ldap', 'kolab_user_base_dn') self.assertEqual(recipient, "uid=%s,%s" % (self.thomas['uid'], base_dn)) wap_client = stick.webadmin.get_instance() result = wap_client.user_info(recipient) self.assertEqual(result['mail'], self.thomas['mail']) self.assertEqual(sorted(result['alias']), ['bruederli@example.org', 't.bruederli@example.org']) if __name__ == '__main__': stick.main() diff --git a/integration/P/test_wallace_footer.py b/integration/P/test_wallace_footer.py new file mode 100644 index 0000000..d70683c --- /dev/null +++ b/integration/P/test_wallace_footer.py @@ -0,0 +1,296 @@ +import os +import stick +import time +import smtplib +import pykolab + +from pykolab.imap import IMAP +from email import message_from_string +from email.MIMEMultipart import MIMEMultipart +from email.MIMEBase import MIMEBase +from email.MIMEImage import MIMEImage +from email.MIMEText import MIMEText +from email.Utils import formatdate +from email.message import Message + +conf = pykolab.getConf() + +class TestWallaceFooter(stick.KolabIntegrationTest): + """ + Integration tests for wallace + """ + user = None + jane = None + + @classmethod + def setUpClass(self, *args, **kw): + self.user = self.require_user("John", "Doe") + self.jane = self.require_user("Jane", "Doe") + + self.footer = {} + footer_html_file = conf.get('wallace', 'footer_html') + footer_text_file = conf.get('wallace', 'footer_text') + + if os.path.isfile(footer_text_file): + self.footer['plain'] = open(footer_text_file, 'r').read() + else: + self.footer['plain'] = 'Footer added by wallace' + fp = open(footer_text_file, 'w') + fp.write(self.footer['plain']) + fp.close() + + if os.path.isfile(footer_html_file): + self.footer['html'] = open(footer_html_file, 'r').read() + else: + self.footer['html'] = '

' + self.footer['plain'] + '

' + fp = open(footer_html_file, 'w') + fp.write(self.footer['html']) + fp.close() + + self.send_to = self.user['mail'] + self.send_from = self.user['mail'] + + self.message_to = '"Doe, John" <%s>' % (self.send_to) + self.message_from = '"Doe, John" <%s>' % (self.send_from) + + super(TestWallaceFooter, self).setUpClass(*args, **kw) + + def check_message_delivered(self, subject): + mbox = "user/%(mail)s" % self.user + imap = IMAP() + imap.connect() + imap.set_acl(mbox, "cyrus-admin", "lrs") + imap.imap.m.select(mbox) + + found = False + max_tries = 20 + + while not found and max_tries > 0: + max_tries -= 1 + + typ, data = imap.imap.m.search(None, 'ALL') + for num in data[0].split(): + typ, msg = imap.imap.m.fetch(num, '(RFC822)') + _msg = message_from_string(msg[0][1]) + if _msg['Subject'] == subject: + found = True + + time.sleep(1) + + imap.disconnect() + return _msg if found else None + + def html_attachment(self): + html_body = "

This is an HTML attachment

" + html_part = MIMEBase("text", "html") + html_part.add_header("Content-Disposition", "attachment", filename="html_attachment.html") + html_part.set_payload(html_body) + return html_part + + def image_attachment(self): + image_file = '/usr/share/kolab-webadmin/public_html/skins/default/images/logo_kolab.png' + image_part = MIMEImage(open(image_file, 'r').read()) + image_part.add_header("Content-Disposition", "attachment", filename=os.path.basename(image_file)) + return image_part + + def message_standard_params(self, subject, msg): + msg['From'] = self.message_from + msg['To'] = self.message_to + + msg['Subject'] = subject + msg['Date'] = formatdate(localtime=True) + + return msg + + def send_message(self, msg, _to=None, _from=None): + smtp = smtplib.SMTP('localhost', 10026) + + if _to == None: + _to = self.send_to + + if _from == None: + _from = self.send_from + + smtp.sendmail(_from, _to, msg.as_string()) + + def test_000_config_enabled(self): + self.assertIn('footer', conf.get_list('wallace', 'modules')) + + def test_001_inbox_created(self): + imap = IMAP() + imap.connect() + + folders = imap.lm('user/%(mail)s' % (self.user)) + self.assertEqual(len(folders), 1) + + def test_002_send_plaintext(self): + subject = "test_002_send_plaintext" + body = "This is a test message" + msg = MIMEBase("text", "plain") + msg = self.message_standard_params(subject, msg) + + msg.set_payload(body) + + self.send_message(msg) + + received = self.check_message_delivered(subject) + self.assertIsInstance(received, Message) + self.assertIn(self.footer['plain'], str(received)) + + def test_003_send_plaintext_with_attachment(self): + subject = "test_003_send_plaintext_with_attachment" + body = "This is a test message" + msg = MIMEMultipart() + msg = self.message_standard_params(subject, msg) + + msg.attach(MIMEText(body)) + msg.attach(self.image_attachment()) + + self.send_message(msg) + + received = self.check_message_delivered(subject) + self.assertIsInstance(received, Message) + self.assertIn(self.footer['plain'], str(received)) + + def test_004_send_html(self): + subject = "test_004_send_html" + body = "

This is a test message

" + msg = MIMEBase("text", "html") + msg = self.message_standard_params(subject, msg) + msg.set_payload(body) + + self.send_message(msg) + + received = self.check_message_delivered(subject) + self.assertIsInstance(received, Message) + self.assertIn(self.footer['html'], str(received)) + + def test_005_send_html_with_plaintext_alternative(self): + subject = "test_005_send_html_with_plaintext_alternative" + html_body = "

This is the HTML part

" + plain_body = "This is the plaintext part" + + msg = MIMEMultipart("alternative") + msg = self.message_standard_params(subject, msg) + + html_part = MIMEBase("text", "html") + html_part.set_payload(html_body) + msg.attach(html_part) + + plain_part = MIMEText(plain_body) + msg.attach(plain_part) + + self.send_message(msg) + + received = self.check_message_delivered(subject) + self.assertIsInstance(received, Message) + self.assertIn(self.footer['html'], str(received)) + self.assertIn(self.footer['plain'], str(received)) + + def test_006_send_html_with_attachment(self): + subject = "test_006_send_html_with_attachment" + html_body = "

This is the HTML part

" + plain_body = "This is the plaintext part" + + msg = MIMEMultipart() + msg = self.message_standard_params(subject, msg) + + html_part = MIMEBase("text", "html") + html_part.set_payload(html_body) + msg.attach(html_part) + + msg.attach(self.image_attachment()) + + self.send_message(msg) + + received = self.check_message_delivered(subject) + self.assertIsInstance(received, Message) + self.assertIn(self.footer['html'], str(received)) + + def test_007_send_html_with_plaintext_alternative_and_attachment(self): + subject = "test_007_send_html_with_plaintext_alternative_and_attachment" + html_body = "

This is the HTML part

" + plain_body = "This is the plaintext part" + + msg = MIMEMultipart("mixed") + msg = self.message_standard_params(subject, msg) + + message_part = MIMEMultipart("alternative") + + html_part = MIMEBase("text", "html") + html_part.set_payload(html_body) + message_part.attach(html_part) + + plain_part = MIMEText(plain_body) + message_part.attach(plain_part) + + msg.attach(message_part) + + msg.attach(self.image_attachment()) + + self.send_message(msg) + + received = self.check_message_delivered(subject) + self.assertIsInstance(received, Message) + self.assertIn(self.footer['html'], str(received)) + self.assertIn(self.footer['plain'], str(received)) + + def test_008_send_plaintext_with_html_attachment(self): + subject = "test_008_send_plaintext_with_html_attachment" + body = "This is a plaintext message" + msg = MIMEMultipart() + msg = self.message_standard_params(subject, msg) + + msg.attach(MIMEText(body)) + + msg.attach(self.html_attachment()) + + self.send_message(msg) + + received = self.check_message_delivered(subject) + self.assertIsInstance(received, Message) + self.assertIn(self.footer['plain'], str(received)) + self.assertNotIn(self.footer['html'], str(received)) + + @stick.todo("TODO: test with sievelib installed") + def test_009_send_plaintext_forwarded(self): + subject = "test_009_send_plaintext_forwarded" + body = "This is a plaintext message" + + admin_login = conf.get('cyrus-imap', 'admin_login') + admin_password = conf.get('cyrus-imap', 'admin_password') + + import sievelib.factory + script = sievelib.factory.FiltersSet("test_wallace_test_009_forward") + script.require("copy") + script.addfilter("forward", ["true"], [("redirect", ":copy", self.user['mail'])]) + + import sievelib.managesieve + sieveclient = sievelib.managesieve.Client('localhost', 4190, True) + sieveclient.connect(None, None, True) + sieveclient._plain_authentication(admin_login, admin_password, self.jane['mail']) + sieveclient.authenticated = True + + script_str = script.__str__() + + self.log(script_str) + + sieveclient.putscript("test_wallace_test_009_forward", script_str) + + sieveclient.setactive("test_wallace_test_009_forward") + + msg = MIMEText(body) + msg['From'] = self.message_from + msg['To'] = '"Doe, Jane" <%(mail)s>' % self.jane + + msg['Subject'] = subject + msg['Date'] = formatdate(localtime=True) + + self.send_message(msg, _to=self.jane['mail'], _from=self.user['mail']) + + received = self.check_message_delivered(subject) + self.assertIsInstance(received, Message) + + +if __name__ == '__main__': + stick.main() \ No newline at end of file diff --git a/integration/P/test_wallace_forward.py b/integration/P/test_wallace_forward.py new file mode 100644 index 0000000..d15cb1b --- /dev/null +++ b/integration/P/test_wallace_forward.py @@ -0,0 +1,82 @@ +import stick +import time +import smtplib +import pykolab + +from pykolab.imap import IMAP +from email.MIMEMultipart import MIMEMultipart +from email.MIMEText import MIMEText +from email.Utils import formatdate +from email import message_from_string + +conf = pykolab.getConf() + +class TestWallaceEmailForward(stick.KolabIntegrationTest): + """ + Integration tests for wallace + """ + john = None + jane = None + + @classmethod + def setUpClass(self, *args, **kw): + # define user accounts required for this test + self.john = self.require_user("John", "Doe") + self.jane = self.require_user("Jane", "Doe") + + super(TestWallaceEmailForward, self).setUpClass(*args, **kw) + + def test_001_inbox_created(self): + imap = IMAP() + imap.connect() + + folders = imap.lm('user/%(mail)s' % (self.john)) + imap.disconnect() + + self.assertEqual(len(folders), 1) + + def test_002_send_forwarded_email(self): + smtp = smtplib.SMTP('localhost', 10026) + subject = "%s" % (time.time()) + body = "This is a test message" + + msg = MIMEMultipart() + msg['From'] = '"Doe, Jane" <%(mail)s>' % self.jane + msg['To'] = '"Doe, John" <%(mail)s>' % self.john + msg['Subject'] = subject + msg['Date'] = formatdate(localtime=True) + msg.attach(MIMEText(body)) + + send_to = self.john['mail'] + send_from = self.jane['mail'] + + smtp.sendmail(send_from, send_to, msg.as_string()) + time.sleep(2) + + mbox = "user/%(mail)s" % self.john + + imap = IMAP() + imap.connect() + imap.set_acl(mbox, "cyrus-admin" % self.jane, "lrs") + imap.imap.m.select(mbox) + + found = False + max_tries = 20 + + while not found and max_tries > 0: + max_tries -= 1 + + typ, data = imap.imap.m.search(None, 'ALL') + for num in data[0].split(): + typ, msg = imap.imap.m.fetch(num, '(RFC822)') + _msg = message_from_string(msg[0][1]) + if _msg['Subject'] == subject: + found = True + + time.sleep(1) + + self.assertTrue(found) + + +if __name__ == '__main__': + stick.main() diff --git a/integration/P/test_wallace_module_resources.py b/integration/P/test_wallace_module_resources.py new file mode 100644 index 0000000..bd699b0 --- /dev/null +++ b/integration/P/test_wallace_module_resources.py @@ -0,0 +1,58 @@ +import stick + +from pykolab.auth import Auth +from wallace import module_resources + +class TestWallaceModuleResources(stick.KolabIntegrationTest): + auth = None + audi = None + passat = None + boxter = None + cars = None + + @classmethod + def setUpClass(self, *args, **kw): + self.audi = self.require_resource("car", "Audi A4") + self.passat = self.require_resource("car", "VW Passat") + self.boxter = self.require_resource("car", "Porsche Boxter S", kolabinvitationpolicy='ACT_ACCEPT_AND_NOTIFY') + self.cars = self.require_resource("collection", "Company Cars", kolabinvitationpolicy='ACT_ACCEPT', members=[ + self.audi['dn'], self.passat['dn'], self.boxter['dn'] + ]) + + super(TestWallaceModuleResources, self).setUpClass(*args, **kw) + + def tearDown(self): + if self.auth: + self.auth.disconnect() + + def test_001_resource_created(self): + resource = module_resources.resource_record_from_email_address(self.audi['mail']) + self.assertEqual(len(resource), 1) + self.assertEqual(resource[0], self.audi['dn']) + + collection = module_resources.resource_record_from_email_address(self.cars['mail']) + self.assertEqual(len(collection), 1) + self.assertEqual(collection[0], self.cars['dn']) + + def test_002_resource_collection(self): + self.auth = Auth() + self.auth.connect() + attrs = self.auth.get_entry_attributes(None, self.cars['dn'], ['*']) + self.assertIn('groupofuniquenames', attrs['objectclass']) + self.assertEqual(len(attrs['uniquemember']), 3) + self.assertEqual(attrs['kolabinvitationpolicy'], 'ACT_ACCEPT') + + def test_003_get_resource_records(self): + resource_dns = module_resources.resource_record_from_email_address(self.cars['mail']) + self.assertEqual(resource_dns[0], self.cars['dn']) + + resources = module_resources.get_resource_records(resource_dns) + self.assertEqual(len(resources), 4) + + # check for (inherited) kolabinvitationpolicy values (bitmasks) + self.assertEqual(resources[self.cars['dn']]['kolabinvitationpolicy'], [module_resources.ACT_ACCEPT]) + self.assertEqual(resources[self.audi['dn']]['kolabinvitationpolicy'], [module_resources.ACT_ACCEPT]) + self.assertEqual(resources[self.boxter['dn']]['kolabinvitationpolicy'], [module_resources.ACT_ACCEPT_AND_NOTIFY]) + +if __name__ == '__main__': + stick.main() diff --git a/integration/P/test_wallace_nonascii.py b/integration/P/test_wallace_nonascii.py new file mode 100644 index 0000000..389635a --- /dev/null +++ b/integration/P/test_wallace_nonascii.py @@ -0,0 +1,121 @@ +# *-* encoding: utf-8 *-* + +import stick +import time +import smtplib +import pykolab + +from pykolab.imap import IMAP +from email.MIMEBase import MIMEBase +from email.Utils import formatdate +from email.header import Header +from email.message import Message +from email import message_from_string + +conf = pykolab.getConf() + +class TestWallaceNonAscii(stick.KolabIntegrationTest): + """ + Integration tests for wallace + """ + user = None + nikolaj = None + + @classmethod + def setUpClass(self, *args, **kw): + self.user = self.require_user("John", "Doe") + self.nikolaj = self.require_user("Николай", "Римский-Корсаков", preferredlanguage='ru_RU') + + self.message_to = '"Doe, John" <%s>' % (self.user['mail']) + self.message_from = '"John Doe" <%s>' % (self.user['mail']) + self.sender_nikolaj = u'"Николай Римский-Корсаков" <%s>' % (self.nikolaj['mail']) + + super(TestWallaceNonAscii, self).setUpClass(*args, **kw) + + def check_message_delivered(self, subject, _mbox=None): + mbox = _mbox or "user/%(mail)s" % self.user + + imap = IMAP() + imap.connect() + imap.set_acl(mbox, "cyrus-admin", "lrs") + imap.imap.m.select(mbox) + + found = False + max_tries = 20 + + while not found and max_tries > 0: + max_tries -= 1 + + typ, data = imap.imap.m.search(None, 'ALL') + for num in data[0].split(): + typ, msg = imap.imap.m.fetch(num, '(RFC822)') + _msg = message_from_string(msg[0][1]) + if _msg['Subject'] == subject: + found = True + + time.sleep(1) + + imap.disconnect() + return _msg if found else None + + def message_standard_params(self, subject, msg, _from=None, _to=None): + msg['From'] = Header(_from or self.message_from) + msg['To'] = Header(_to or self.message_to) + msg['Subject'] = subject + msg['Date'] = formatdate(localtime=True) + + return msg + + def send_message(self, msg, _to=None, _from=None): + smtp = smtplib.SMTP('localhost', 10026) + + if _to == None: + _to = self.user['mail'] + + if _from == None: + _from = self.user['mail'] + + smtp.sendmail(_from, _to, msg.as_string()) + + def test_001_send_nonascii_subject(self): + subject = Header(u"test_002_nonascii_subject chwała") + msg = MIMEBase("text", "plain") + msg = self.message_standard_params(subject, msg) + + msg.set_payload("This is a test message") + + self.send_message(msg) + + received = self.check_message_delivered(subject) + self.assertIsInstance(received, Message) + self.assertEqual(received['subject'], str(subject)) + + def test_002_send_nonascii_subject(self): + subject = Header(u"test_002_nonascii_subject Тест") + msg = MIMEBase("text", "plain") + msg = self.message_standard_params(subject, msg) + + msg.set_payload("This is a test message") + + self.send_message(msg) + + received = self.check_message_delivered(subject) + self.assertIsInstance(received, Message) + self.assertEqual(received['subject'], str(subject)) + + @stick.todo("TODO: Recipient header garbled") + def test_003_send_nonascii_addresses(self): + subject = "test_003_nonascii_addresses" + msg = MIMEBase("text", "plain") + msg = self.message_standard_params(subject, msg, _to=self.sender_nikolaj) + msg.set_payload("This is a test message") + + self.send_message(msg, _to=self.sender_nikolaj) + + received = self.check_message_delivered(subject, "user/%(mail)s" % self.nikolaj) + self.assertIsInstance(received, Message) + self.assertIn(self.user['mail'], received['from']) + self.assertIn(self.nikolaj['mail'], received['to']) + +if __name__ == '__main__': + stick.main() diff --git a/integration/P/test_wap_client_users.py b/integration/P/test_wap_client_users.py index bb764af..d2d739a 100644 --- a/integration/P/test_wap_client_users.py +++ b/integration/P/test_wap_client_users.py @@ -1,177 +1,31 @@ -# -*- coding: utf-8 -*- - import stick -import pykolab -import time - from pykolab.auth import Auth -from pykolab.imap import IMAP - -conf = pykolab.getConf() class TestWAPClientUserAdd(stick.KolabIntegrationTest): - user = None - auth = None - imap = None - alvaro = None - thomas = None - etienne = None @classmethod def setUpClass(self, *args, **kw): self.cleanafter = True - self.user = self._get_user_prop(self.require_user("John", "Doe")) - self.etienne = self._get_user_prop(self.require_user("Étienne-Nicola", "Méhul", preferredlanguage='fr_FR')) - self.alvaro = self._get_user_prop(self.require_user("Álvaro", "Fuentes", preferredlanguage='es_ES')) - self.thomas = self._get_user_prop(self.require_user("Thomas", "Brüderli", preferredlanguage='de_CH')) + stick.wipeall() super(TestWAPClientUserAdd, self).setUpClass(*args, **kw) - @classmethod - def _get_user_prop(self, data): - (local, domain) = data['mail'].split('@') - data.update({ 'local': local, 'domain': domain }) - return data - - def tearDown(self): - if self.auth: - self.auth.disconnect() - if self.imap: - self.imap.disconnect() - - def test_001_inbox_created(self): - self.imap = IMAP() - self.imap.connect() - - folders = self.imap.lm('user/%(mail)s' % self.user) - self.assertEqual(len(folders), 1) - - def test_002_autocreate_folders_created(self): - self.imap = IMAP() - self.imap.connect() - - ac_folders_ = conf.get_raw(self.get_conf('kolab', 'primary_domain'), 'autocreate_folders') - if not ac_folders_: - ac_folders_ = conf.get_raw('kolab', 'autocreate_folders') - - exec("ac_folders = %s" % (ac_folders_)) - - folders = self.imap.lm('user/%(local)s/*@%(domain)s' % self.user) - - self.log("Autocreate folders: %r" % (ac_folders.keys())) - self.log("IMAP folders: %r" % (folders)) - - self.assertEqual(len(folders), len(ac_folders.keys())) - - def test_003_folders_metadata_set(self): - self.imap = IMAP() - self.imap.connect() - - ac_folders_ = conf.get_raw(self.get_conf('kolab', 'primary_domain'), 'autocreate_folders') - if not ac_folders_: - ac_folders_ = conf.get_raw('kolab', 'autocreate_folders') - - exec("ac_folders = %s" % (ac_folders_)) - - folders = [] - folders.extend(self.imap.lm('user/%(local)s@%(domain)s' % self.user)) - folders.extend(self.imap.lm('user/%(local)s/*@%(domain)s' % self.user)) - - for folder in folders: - metadata = self.imap.get_metadata(folder) - - folder_name = '/'.join(folder.split('/')[2:]).split('@')[0] - if ac_folders.has_key(folder_name): - if ac_folders[folder_name].has_key('annotations'): - for _annotation in ac_folders[folder_name]['annotations'].keys(): - if _annotation.startswith('/private/'): - continue - - _annotation_value = ac_folders[folder_name]['annotations'][_annotation] - self.assertTrue(metadata[metadata.keys().pop()].has_key(_annotation)) - self.assertEqual(_annotation_value, metadata[metadata.keys().pop()][_annotation]) - + def test_001_user_create(self): + domain = self.get_conf('kolab', 'primary_domain', 'example.org') + user = stick.add_user("John", "Doe") + self.assertEqual(user['mail'], "john.doe@%s" % (domain)) - def test_011_fr_FR_inbox_created(self): - time.sleep(2) - self.imap = IMAP() - self.imap.connect() - - folders = self.imap.lm('user/%(local)s@%(domain)s' % self.etienne) - self.assertEqual(len(folders), 1) - - @stick.todo("TODO: unkown API error") - def test_012_fr_FR_user_recipient_policy(self): - self.auth = Auth() - self.auth.connect() - recipient = self.auth.find_recipient("%(local)s@%(domain)s" % self.etienne) - if hasattr(self, 'assertIsInstance'): - self.assertIsInstance(recipient, str) - - base_dn = self.get_conf('ldap', 'kolab_user_base_dn') - self.assertEqual(recipient, "uid=%s,%s" % (self.etienne['uid'], base_dn)) - - wap_client = stick.webadmin.get_instance() - result = wap_client.user_info(recipient) - self.log("User fr_FR: %r" % (result)) - - self.assertEqual(result['mail'], self.etienne['mail']) - self.assertEqual(sorted(result['alias']), ['e.mehul@example.org', 'mehul@example.org']) - - - def test_021_es_ES_inbox_created(self): - time.sleep(2) - self.imap = IMAP() - self.imap.connect() - - folders = self.imap.lm('user/%(local)s@%(domain)s' % (self.alvaro)) - self.assertEqual(len(folders), 1) - - @stick.todo("TODO: unkown API error") - def test_022_es_ES_user_recipient_policy(self): - self.auth = Auth() - self.auth.connect() - recipient = self.auth.find_recipient("%(local)s@%(domain)s" % (self.alvaro)) - if hasattr(self, 'assertIsInstance'): - self.assertIsInstance(recipient, str) - - base_dn = self.get_conf('ldap', 'kolab_user_base_dn') - self.assertEqual(recipient, "uid=%s,%s" % (self.alvaro['uid'], base_dn)) - - wap_client = stick.webadmin.get_instance() - result = wap_client.user_info(recipient) - - self.assertEqual(result['mail'], self.alvaro['mail']) - self.assertEqual(sorted(result['alias']), ['a.fuentes@example.org', 'fuentes@example.org']) - - - def test_031_de_CH_inbox_created(self): - time.sleep(2) - self.imap = IMAP() - self.imap.connect() - - folders = self.imap.lm('user/%(local)s@%(domain)s' % (self.thomas)) - self.assertEqual(len(folders), 1) - - @stick.todo("TODO: unkown API error") - def test_032_de_CH_user_recipient_policy(self): - self.auth = Auth() - self.auth.connect() - recipient = self.auth.find_recipient("%(local)s@%(domain)s" % (self.thomas)) - if hasattr(self, 'assertIsInstance'): - self.assertIsInstance(recipient, str) - - base_dn = self.get_conf('ldap', 'kolab_user_base_dn') - self.assertEqual(recipient, "uid=%s,%s" % (self.thomas['uid'], base_dn)) + auth = Auth() + auth.connect() + user_dn = auth.find_recipient(user['mail']) + auth.disconnect() wap_client = stick.webadmin.get_instance() - result = wap_client.user_info(recipient) - - self.assertEqual(result['mail'], self.thomas['mail']) - self.assertEqual(sorted(result['alias']), ['bruederli@example.org', 't.bruederli@example.org']) + user_info = wap_client.user_info(user_dn) + self.assertEqual(user_info['uid'], "doe") if __name__ == '__main__': stick.main() diff --git a/integration/WAP/run.py b/integration/WAP/run.py new file mode 100644 index 0000000..1905885 --- /dev/null +++ b/integration/WAP/run.py @@ -0,0 +1,16 @@ +import stick +import unittest + +from test_user_create import TestWAPUserCreate +from test_policy_uid import TestWAPPolicyUid + +if __name__ == '__main__': + opts = stick.conf.cli_keywords + loader = stick.KolabTestLoader(opts) + alltests = unittest.TestSuite() + + # add tests in order of their dependencies + alltests.addTests(loader.loadTestsFromTestCase(TestWAPUserCreate)) + alltests.addTests(loader.loadTestsFromTestCase(TestWAPPolicyUid)) + + stick.main(defaultTest='alltests') diff --git a/integration/WAP/test_policy_uid.py b/integration/WAP/test_policy_uid.py new file mode 100644 index 0000000..471ab9a --- /dev/null +++ b/integration/WAP/test_policy_uid.py @@ -0,0 +1,111 @@ +import stick +import shutil +import pykolab + +from pykolab.auth import Auth +from pykolab.imap import IMAP +from ConfigParser import RawConfigParser + +conf = pykolab.getConf() + +class TestWAPPolicyUid(stick.KolabIntegrationTest): + user = None + config = None + + @classmethod + def setUpClass(self, *args, **kw): + self.cleanafter = True + + shutil.copyfile(conf.config_file, conf.config_file + '.orig') + + self.config = RawConfigParser() + self.config.read(conf.config_file) + + self.user = { + 'sn': 'Doe', + 'givenname': 'John', + 'local': 'john.doe', + 'domain': conf.get('kolab', 'primary_domain') or 'example.org' + } + + stick.wipeall() + super(TestWAPPolicyUid, self).setUpClass(*args, **kw) + + @classmethod + def tearDownClass(self, *args, **kw): + self.log("Restore default config from " + conf.config_file + '.orig') + shutil.move(conf.config_file + '.orig', conf.config_file) + + super(TestWAPPolicyUid, self).tearDownClass(*args, **kw) + + def tearDown(self): + wap_client = stick.webadmin.get_instance() + wap_client.disconnect(True) + + def set_option(self, section, option, value): + self.config.set(section, option, value) + self.write_config() + + def remove_option(self, section, option): + self.config.remove_option(section, option) + self.write_config() + + def write_config(self): + self.log("Update config with [%s].policy_uid = %s" % (self.user['domain'], self.config.get(self.user['domain'], 'policy_uid'))) + + fp = open(conf.config_file, "w") + self.config.write(fp) + fp.close() + + def add_user_info(self): + stick.wipeall() + + user = stick.add_user(self.user['givenname'], self.user['sn']) + stick.synchronize() + + auth = Auth() + auth.connect() + user_dn = auth.find_recipient(user['mail']) + self.log("User DN for %s is %s" % (user['mail'], user_dn)) + auth.disconnect() + + wap_client = stick.webadmin.get_instance() + return wap_client.user_info(user_dn) + + def test_001_default(self): + user_info = self.add_user_info() + self.assertEqual(user_info['uid'], "doe") + + def test_002_givenname_dot_surname(self): + self.set_option(self.user['domain'], 'policy_uid', '%(givenname)s.%(surname)s') + + user_info = self.add_user_info() + self.assertEqual(user_info['uid'], "John.Doe") + + def test_003_givenname_fc_dot_surname(self): + self.set_option(self.user['domain'], 'policy_uid', "'%(givenname)s'[0:1].%(surname)s") + + user_info = self.add_user_info() + self.assertEqual(user_info['uid'], "J.Doe") + + def test_004_givenname(self): + self.set_option(self.user['domain'], 'policy_uid', '%(givenname)s') + + user_info = self.add_user_info() + self.assertEqual(user_info['uid'], "John") + + def test_005_lowercase_givenname(self): + self.set_option(self.user['domain'], 'policy_uid', '%(givenname)s.lower()') + + user_info = self.add_user_info() + self.assertEqual(user_info['uid'], "john") + + @stick.todo("TODO: %(givenname)s.lower().%(surname)s.lower() wongly substituted") + def test_006_lowercase_givenname_surname(self): + self.set_option(self.user['domain'], 'policy_uid', "%(givenname)s.lower().%(surname)s.lower()") + + user_info = self.add_user_info() + self.assertEqual(user_info['uid'], "john.doe") + +if __name__ == '__main__': + stick.main() diff --git a/integration/P/test_wap_client_users.py b/integration/WAP/test_user_create.py similarity index 93% copy from integration/P/test_wap_client_users.py copy to integration/WAP/test_user_create.py index bb764af..fd94a70 100644 --- a/integration/P/test_wap_client_users.py +++ b/integration/WAP/test_user_create.py @@ -1,177 +1,171 @@ # -*- coding: utf-8 -*- import stick import pykolab import time from pykolab.auth import Auth from pykolab.imap import IMAP conf = pykolab.getConf() -class TestWAPClientUserAdd(stick.KolabIntegrationTest): +class TestWAPUserCreate(stick.KolabIntegrationTest): user = None auth = None imap = None alvaro = None thomas = None etienne = None @classmethod def setUpClass(self, *args, **kw): self.cleanafter = True self.user = self._get_user_prop(self.require_user("John", "Doe")) self.etienne = self._get_user_prop(self.require_user("Étienne-Nicola", "Méhul", preferredlanguage='fr_FR')) self.alvaro = self._get_user_prop(self.require_user("Álvaro", "Fuentes", preferredlanguage='es_ES')) self.thomas = self._get_user_prop(self.require_user("Thomas", "Brüderli", preferredlanguage='de_CH')) - super(TestWAPClientUserAdd, self).setUpClass(*args, **kw) + super(TestWAPUserCreate, self).setUpClass(*args, **kw) @classmethod def _get_user_prop(self, data): (local, domain) = data['mail'].split('@') data.update({ 'local': local, 'domain': domain }) return data def tearDown(self): if self.auth: self.auth.disconnect() if self.imap: self.imap.disconnect() def test_001_inbox_created(self): self.imap = IMAP() self.imap.connect() folders = self.imap.lm('user/%(mail)s' % self.user) self.assertEqual(len(folders), 1) def test_002_autocreate_folders_created(self): self.imap = IMAP() self.imap.connect() ac_folders_ = conf.get_raw(self.get_conf('kolab', 'primary_domain'), 'autocreate_folders') if not ac_folders_: ac_folders_ = conf.get_raw('kolab', 'autocreate_folders') exec("ac_folders = %s" % (ac_folders_)) folders = self.imap.lm('user/%(local)s/*@%(domain)s' % self.user) - self.log("Autocreate folders: %r" % (ac_folders.keys())) - self.log("IMAP folders: %r" % (folders)) + #self.log("Autocreate folders: %r" % (ac_folders.keys())) + #self.log("IMAP folders: %r" % (folders)) self.assertEqual(len(folders), len(ac_folders.keys())) def test_003_folders_metadata_set(self): self.imap = IMAP() self.imap.connect() ac_folders_ = conf.get_raw(self.get_conf('kolab', 'primary_domain'), 'autocreate_folders') if not ac_folders_: ac_folders_ = conf.get_raw('kolab', 'autocreate_folders') exec("ac_folders = %s" % (ac_folders_)) folders = [] folders.extend(self.imap.lm('user/%(local)s@%(domain)s' % self.user)) folders.extend(self.imap.lm('user/%(local)s/*@%(domain)s' % self.user)) for folder in folders: metadata = self.imap.get_metadata(folder) folder_name = '/'.join(folder.split('/')[2:]).split('@')[0] if ac_folders.has_key(folder_name): if ac_folders[folder_name].has_key('annotations'): for _annotation in ac_folders[folder_name]['annotations'].keys(): if _annotation.startswith('/private/'): continue _annotation_value = ac_folders[folder_name]['annotations'][_annotation] self.assertTrue(metadata[metadata.keys().pop()].has_key(_annotation)) self.assertEqual(_annotation_value, metadata[metadata.keys().pop()][_annotation]) def test_011_fr_FR_inbox_created(self): - time.sleep(2) self.imap = IMAP() self.imap.connect() folders = self.imap.lm('user/%(local)s@%(domain)s' % self.etienne) self.assertEqual(len(folders), 1) - @stick.todo("TODO: unkown API error") def test_012_fr_FR_user_recipient_policy(self): self.auth = Auth() self.auth.connect() recipient = self.auth.find_recipient("%(local)s@%(domain)s" % self.etienne) if hasattr(self, 'assertIsInstance'): self.assertIsInstance(recipient, str) base_dn = self.get_conf('ldap', 'kolab_user_base_dn') self.assertEqual(recipient, "uid=%s,%s" % (self.etienne['uid'], base_dn)) wap_client = stick.webadmin.get_instance() result = wap_client.user_info(recipient) self.log("User fr_FR: %r" % (result)) self.assertEqual(result['mail'], self.etienne['mail']) self.assertEqual(sorted(result['alias']), ['e.mehul@example.org', 'mehul@example.org']) def test_021_es_ES_inbox_created(self): - time.sleep(2) self.imap = IMAP() self.imap.connect() folders = self.imap.lm('user/%(local)s@%(domain)s' % (self.alvaro)) self.assertEqual(len(folders), 1) - @stick.todo("TODO: unkown API error") def test_022_es_ES_user_recipient_policy(self): self.auth = Auth() self.auth.connect() recipient = self.auth.find_recipient("%(local)s@%(domain)s" % (self.alvaro)) if hasattr(self, 'assertIsInstance'): self.assertIsInstance(recipient, str) base_dn = self.get_conf('ldap', 'kolab_user_base_dn') self.assertEqual(recipient, "uid=%s,%s" % (self.alvaro['uid'], base_dn)) wap_client = stick.webadmin.get_instance() result = wap_client.user_info(recipient) self.assertEqual(result['mail'], self.alvaro['mail']) self.assertEqual(sorted(result['alias']), ['a.fuentes@example.org', 'fuentes@example.org']) def test_031_de_CH_inbox_created(self): - time.sleep(2) self.imap = IMAP() self.imap.connect() folders = self.imap.lm('user/%(local)s@%(domain)s' % (self.thomas)) self.assertEqual(len(folders), 1) - @stick.todo("TODO: unkown API error") def test_032_de_CH_user_recipient_policy(self): self.auth = Auth() self.auth.connect() recipient = self.auth.find_recipient("%(local)s@%(domain)s" % (self.thomas)) if hasattr(self, 'assertIsInstance'): self.assertIsInstance(recipient, str) base_dn = self.get_conf('ldap', 'kolab_user_base_dn') self.assertEqual(recipient, "uid=%s,%s" % (self.thomas['uid'], base_dn)) wap_client = stick.webadmin.get_instance() result = wap_client.user_info(recipient) self.assertEqual(result['mail'], self.thomas['mail']) self.assertEqual(sorted(result['alias']), ['bruederli@example.org', 't.bruederli@example.org']) if __name__ == '__main__': stick.main()