From 629f6e76a9c003ef8befdfdf023f2e5b9eadc718 Mon Sep 17 00:00:00 2001 From: Lance stout Date: Mon, 31 May 2010 13:24:14 -0400 Subject: Added implementation and tests for XEP-0085 - Chat State Notifications. Chat states may be set using: msg['chat_state'].active() msg['chat_state'].composing() msg['chat_state'].gone() msg['chat_state'].inactive() msg['chat_state'].paused() Checking a chat state can be done with either: msg['chat_state'].getState() msg['chat_state'].name When a message with a chat state is receieved, the following events may occur: chatstate_active chatstate_composing chatstate_gone chatstate_inactive chatstate_paused where the event data is the message stanza. Note that currently these events are also triggered for messages sent by SleekXMPP, not just those received. --- tests/test_chatstates.py | 47 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 47 insertions(+) create mode 100644 tests/test_chatstates.py (limited to 'tests') diff --git a/tests/test_chatstates.py b/tests/test_chatstates.py new file mode 100644 index 00000000..8878e318 --- /dev/null +++ b/tests/test_chatstates.py @@ -0,0 +1,47 @@ +import unittest +from xml.etree import cElementTree as ET +from sleekxmpp.xmlstream.matcher.stanzapath import StanzaPath +from . import xmlcompare + +import sleekxmpp.plugins.xep_0085 as cs + +def stanzaPlugin(stanza, plugin): + stanza.plugin_attrib_map[plugin.plugin_attrib] = plugin + stanza.plugin_tag_map["{%s}%s" % (plugin.namespace, plugin.name)] = plugin + +class testchatstates(unittest.TestCase): + + def setUp(self): + self.cs = cs + stanzaPlugin(self.cs.Message, self.cs.Active) + stanzaPlugin(self.cs.Message, self.cs.Composing) + stanzaPlugin(self.cs.Message, self.cs.Gone) + stanzaPlugin(self.cs.Message, self.cs.Inactive) + stanzaPlugin(self.cs.Message, self.cs.Paused) + + def try2Methods(self, xmlstring, msg): + msg2 = self.cs.Message(None, self.cs.ET.fromstring(xmlstring)) + self.failUnless(xmlstring == str(msg) == str(msg2), + "Two methods for creating stanza don't match") + + def testCreateChatState(self): + """Testing creating chat states.""" + xmlstring = """<%s xmlns="http://jabber.org/protocol/chatstates" />""" + + msg = self.cs.Message() + msg['chat_state'].active() + self.try2Methods(xmlstring % 'active', msg) + + msg['chat_state'].composing() + self.try2Methods(xmlstring % 'composing', msg) + + msg['chat_state'].gone() + self.try2Methods(xmlstring % 'gone', msg) + + msg['chat_state'].inactive() + self.try2Methods(xmlstring % 'inactive', msg) + + msg['chat_state'].paused() + self.try2Methods(xmlstring % 'paused', msg) + +suite = unittest.TestLoader().loadTestsFromTestCase(testchatstates) -- cgit v1.2.3 From 646a609c0b4e19203b4e2190df9b58fbe40c43fb Mon Sep 17 00:00:00 2001 From: Lance Stout Date: Tue, 22 Jun 2010 23:09:50 -0400 Subject: Added plugin and tests for XEP-0033, Extended Stanza Addresses. XEP-0033 can be useful for interacting with XMPP<->Email gateways. --- tests/test_addresses.py | 83 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 83 insertions(+) create mode 100644 tests/test_addresses.py (limited to 'tests') diff --git a/tests/test_addresses.py b/tests/test_addresses.py new file mode 100644 index 00000000..eb57537a --- /dev/null +++ b/tests/test_addresses.py @@ -0,0 +1,83 @@ +import unittest +from xml.etree import cElementTree as ET +from sleekxmpp.xmlstream.matcher.stanzapath import StanzaPath +from . import xmlcompare + +import sleekxmpp.plugins.xep_0033 as addr + + +def stanzaPlugin(stanza, plugin): + stanza.plugin_attrib_map[plugin.plugin_attrib] = plugin + stanza.plugin_tag_map["{%s}%s" % (plugin.namespace, plugin.name)] = plugin + + +class testaddresses(unittest.TestCase): + def setUp(self): + self.addr = addr + stanzaPlugin(self.addr.Message, self.addr.Addresses) + + def try2Methods(self, xmlstring, msg): + msg2 = self.addr.Message(None, self.addr.ET.fromstring(xmlstring)) + self.failUnless(xmlstring == str(msg) == str(msg2), + """Three methods for creating stanza don't match:\n%s\n%s\n%s""" % (xmlstring, str(msg), str(msg2))) + + def testAddAddress(self): + """Testing adding extended stanza address.""" + xmlstring = """
""" + + msg = self.addr.Message() + msg['addresses'].addAddress(atype='to', jid='to@header1.org') + self.try2Methods(xmlstring, msg) + + xmlstring = """
""" + + msg = self.addr.Message() + msg['addresses'].addAddress(atype='replyto', jid='replyto@header1.org', desc='Reply address') + self.try2Methods(xmlstring, msg) + + def testAddAddresses(self): + """Testing adding multiple extended stanza addresses.""" + + xmlstring = """
""" + + msg = self.addr.Message() + msg['addresses'].setAddresses([{'type':'replyto', 'jid':'replyto@header1.org', 'desc':'Reply address'}, + {'type':'cc', 'jid':'cc@header2.org'}, + {'type':'bcc', 'jid':'bcc@header2.org'}]) + self.try2Methods(xmlstring, msg) + + msg = self.addr.Message() + msg['addresses']['replyto'] = [{'jid':'replyto@header1.org', 'desc':'Reply address'}] + msg['addresses']['cc'] = [{'jid':'cc@header2.org'}] + msg['addresses']['bcc'] = [{'jid':'bcc@header2.org'}] + self.try2Methods(xmlstring, msg) + + def testAddURI(self): + """Testing adding URI attribute to extended stanza address.""" + + xmlstring = """
""" + msg = self.addr.Message() + addr = msg['addresses'].addAddress(atype='to', jid='to@header1.org', node='foo') + self.try2Methods(xmlstring, msg) + + xmlstring = """
""" + addr['uri'] = 'mailto:to@header2.org' + self.try2Methods(xmlstring, msg) + + def testDelivered(self): + """Testing delivered attribute of extended stanza addresses.""" + + xmlstring = """
""" + + msg = self.addr.Message() + addr = msg['addresses'].addAddress(jid='to@header1.org', atype='to') + self.try2Methods(xmlstring % '', msg) + + addr['delivered'] = True + self.try2Methods(xmlstring % 'delivered="true" ', msg) + + addr['delivered'] = False + self.try2Methods(xmlstring % '', msg) + + +suite = unittest.TestLoader().loadTestsFromTestCase(testaddresses) -- cgit v1.2.3 From 5c76d969f79936ce56828dba2c5ab59214feec12 Mon Sep 17 00:00:00 2001 From: Lance Stout Date: Sun, 27 Jun 2010 17:33:43 -0400 Subject: Added a new SleekTest class that provides useful methods for test cases. Can now use: (where self is a SleekTest instance) self.stanzaPlugin(stanza, plugin) self.Message() \ self.Iq() > Just like basexmpp.Message(), etc. self.Presence() / self.checkMessage(msg, xmlstring) self.checkIq(iq, xmlstring) self.checkPresence(pres, xmlstring) <- Not implemented yet, but stub is there. The check* methods also accept a use_values keyword argument that defaults to True. When this value is True, an additional test is executed by creating a stanza using getValues() and setValues(). Since some stanza objects can override these two methods, disabling this test is sometimes required. --- tests/sleektest.py | 159 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 159 insertions(+) create mode 100644 tests/sleektest.py (limited to 'tests') diff --git a/tests/sleektest.py b/tests/sleektest.py new file mode 100644 index 00000000..eed52ec2 --- /dev/null +++ b/tests/sleektest.py @@ -0,0 +1,159 @@ +""" + SleekXMPP: The Sleek XMPP Library + Copyright (C) 2010 Nathanael C. Fritz, Lance J.T. Stout + This file is part of SleekXMPP. + + See the file license.txt for copying permission. +""" + +import unittest +from xml.etree import cElementTree as ET +from sleekxmpp import Message, Iq +from sleekxmpp.stanza.presence import Presence +from sleekxmpp.xmlstream.matcher.stanzapath import StanzaPath + + +class SleekTest(unittest.TestCase): + """ + A SleekXMPP specific TestCase class that provides + methods for comparing message, iq, and presence stanzas. + """ + + def stanzaPlugin(self, stanza, plugin): + """ + Associate a stanza object as a plugin for another stanza. + """ + tag = "{%s}%s" % (plugin.namespace, plugin.name) + stanza.plugin_attrib_map[plugin.plugin_attrib] = plugin + stanza.plugin_tag_map[tag] = plugin + + def Message(self, *args, **kwargs): + """Create a message stanza.""" + return Message(None, *args, **kwargs) + + def Iq(self, *args, **kwargs): + """Create an iq stanza.""" + return Iq(None, *args, **kwargs) + + def Presence(self, *args, **kwargs): + """Create a presence stanza.""" + return Presence(None, *args, **kwargs) + + def checkMessage(self, msg, xml_string, use_values=True): + """ + Create and compare several message stanza objects to a + correct XML string. + + If use_values is False, the test using getValues() and + setValues() will not be used. + """ + + debug = "Given Stanza:\n%s\n" % ET.tostring(msg.xml) + + xml = ET.fromstring(xml_string) + xml.tag = '{jabber:client}message' + debug += "XML String:\n%s\n" % ET.tostring(xml) + + msg2 = self.Message(xml) + debug += "Constructed Stanza:\n%s\n" % ET.tostring(msg2.xml) + + if use_values: + # Ugly, but need to make sure the type attribute is set. + msg['type'] = msg['type'] + if xml.attrib.get('type', None) is None: + xml.attrib['type'] = 'normal' + + values = msg2.getValues() + msg3 = self.Message() + msg3.setValues(values) + + debug += "Second Constructed Stanza:\n%s\n" % ET.tostring(msg3.xml) + debug = "Three methods for creating stanza do not match:\n" + debug + self.failUnless(self.compare([xml, msg.xml, + msg2.xml, msg3.xml]), + debug) + else: + debug = "Two methods for creating stanza do not match:\n" + debug + self.failUnless(self.compare([xml, msg.xml, msg2.xml]), debug) + + def checkIq(self, iq, xml_string, use_values=True): + """ + Create and compare several iq stanza objects to a + correct XML string. + + If use_values is False, the test using getValues() and + setValues() will not be used. + """ + debug = "Given Stanza:\n%s\n" % ET.tostring(iq.xml) + + xml = ET.fromstring(xml_string) + xml.tag = '{jabber:client}iq' + debug += "XML String:\n%s\n" % ET.tostring(xml) + + iq2 = self.Iq(xml) + debug += "Constructed Stanza:\n%s\n" % ET.tostring(iq2.xml) + + if use_values: + values = iq.getValues() + iq3 = self.Iq() + iq3.setValues(values) + + debug += "Second Constructed Stanza:\n%s\n" % ET.tostring(iq3.xml) + debug = "Three methods for creating stanza do not match:\n" + debug + self.failUnless(self.compare([xml, iq.xml, iq2.xml, iq3.xml]), + debug) + else: + debug = "Two methods for creating stanza do not match:\n" + debug + self.failUnless(self.compare([xml, iq.xml, iq2.xml]), debug) + + def checkPresence(self, pres, xml_string, use_values=True): + """ + Create and compare several presence stanza objects to a + correct XML string. + + If use_values is False, the test using getValues() and + setValues() will not be used. + """ + pass + + def compare(self, xml1, xml2=None): + """ + Compare XML objects. + + If given a list of XML objects, then + all of the elements in the list will be + compared. + """ + + # Compare multiple objects + if type(xml1) is list: + xmls = xml1 + xml1 = xmls[0] + for xml in xmls[1:]: + xml2 = xml + if not self.compare(xml1, xml2): + return False + return True + + # Step 1: Check tags + if xml1.tag != xml2.tag: + print xml1.tag, xml2.tag + return False + + # Step 2: Check attributes + if xml1.attrib != xml2.attrib: + return False + + # Step 3: Recursively check children + for child in xml1: + child2s = xml2.findall("%s" % child.tag) + if child2s is None: + return False + for child2 in child2s: + if self.compare(child, child2): + break + else: + return False + + # Everything matches + return True -- cgit v1.2.3 From 7f8179d91e4f8ae3d58448e57f2e350ed6269fd0 Mon Sep 17 00:00:00 2001 From: Lance Stout Date: Sun, 27 Jun 2010 17:40:06 -0400 Subject: Refactored unit tests for XEP-0030, XEP-0033, and XEP-0085 to use the new SleekTest class. --- tests/test_addresses.py | 129 ++++++++++++++++++++++++++++------------------- tests/test_chatstates.py | 59 ++++++++++------------ tests/test_disco.py | 113 ++++++++++++++++++++++++----------------- 3 files changed, 173 insertions(+), 128 deletions(-) (limited to 'tests') diff --git a/tests/test_addresses.py b/tests/test_addresses.py index eb57537a..2718bb19 100644 --- a/tests/test_addresses.py +++ b/tests/test_addresses.py @@ -1,83 +1,110 @@ -import unittest -from xml.etree import cElementTree as ET -from sleekxmpp.xmlstream.matcher.stanzapath import StanzaPath -from . import xmlcompare +from sleektest import * +import sleekxmpp.plugins.xep_0033 as xep_0033 -import sleekxmpp.plugins.xep_0033 as addr +class TestAddresses(SleekTest): -def stanzaPlugin(stanza, plugin): - stanza.plugin_attrib_map[plugin.plugin_attrib] = plugin - stanza.plugin_tag_map["{%s}%s" % (plugin.namespace, plugin.name)] = plugin - - -class testaddresses(unittest.TestCase): def setUp(self): - self.addr = addr - stanzaPlugin(self.addr.Message, self.addr.Addresses) - - def try2Methods(self, xmlstring, msg): - msg2 = self.addr.Message(None, self.addr.ET.fromstring(xmlstring)) - self.failUnless(xmlstring == str(msg) == str(msg2), - """Three methods for creating stanza don't match:\n%s\n%s\n%s""" % (xmlstring, str(msg), str(msg2))) + self.stanzaPlugin(Message, xep_0033.Addresses) def testAddAddress(self): """Testing adding extended stanza address.""" - xmlstring = """
""" - - msg = self.addr.Message() + msg = self.Message() msg['addresses'].addAddress(atype='to', jid='to@header1.org') - self.try2Methods(xmlstring, msg) - - xmlstring = """
""" - - msg = self.addr.Message() - msg['addresses'].addAddress(atype='replyto', jid='replyto@header1.org', desc='Reply address') - self.try2Methods(xmlstring, msg) + self.checkMessage(msg, """ + + +
+ + + """) + + msg = self.Message() + msg['addresses'].addAddress(atype='replyto', + jid='replyto@header1.org', + desc='Reply address') + self.checkMessage(msg, """ + + +
+ + + """) def testAddAddresses(self): """Testing adding multiple extended stanza addresses.""" - xmlstring = """
""" - - msg = self.addr.Message() - msg['addresses'].setAddresses([{'type':'replyto', 'jid':'replyto@header1.org', 'desc':'Reply address'}, - {'type':'cc', 'jid':'cc@header2.org'}, - {'type':'bcc', 'jid':'bcc@header2.org'}]) - self.try2Methods(xmlstring, msg) - - msg = self.addr.Message() - msg['addresses']['replyto'] = [{'jid':'replyto@header1.org', 'desc':'Reply address'}] + xmlstring = """ + + +
+
+
+ + + """ + + msg = self.Message() + msg['addresses'].setAddresses([{'type':'replyto', + 'jid':'replyto@header1.org', + 'desc':'Reply address'}, + {'type':'cc', + 'jid':'cc@header2.org'}, + {'type':'bcc', + 'jid':'bcc@header2.org'}]) + self.checkMessage(msg, xmlstring) + + msg = self.Message() + msg['addresses']['replyto'] = [{'jid':'replyto@header1.org', + 'desc':'Reply address'}] msg['addresses']['cc'] = [{'jid':'cc@header2.org'}] msg['addresses']['bcc'] = [{'jid':'bcc@header2.org'}] - self.try2Methods(xmlstring, msg) + self.checkMessage(msg, xmlstring) def testAddURI(self): """Testing adding URI attribute to extended stanza address.""" - xmlstring = """
""" - msg = self.addr.Message() - addr = msg['addresses'].addAddress(atype='to', jid='to@header1.org', node='foo') - self.try2Methods(xmlstring, msg) + msg = self.Message() + addr = msg['addresses'].addAddress(atype='to', + jid='to@header1.org', + node='foo') + self.checkMessage(msg, """ + + +
+ + + """) - xmlstring = """
""" addr['uri'] = 'mailto:to@header2.org' - self.try2Methods(xmlstring, msg) + self.checkMessage(msg, """ + + +
+ + + """) def testDelivered(self): """Testing delivered attribute of extended stanza addresses.""" - xmlstring = """
""" + xmlstring = """ + + +
+ + + """ - msg = self.addr.Message() + msg = self.Message() addr = msg['addresses'].addAddress(jid='to@header1.org', atype='to') - self.try2Methods(xmlstring % '', msg) + self.checkMessage(msg, xmlstring % '') addr['delivered'] = True - self.try2Methods(xmlstring % 'delivered="true" ', msg) + self.checkMessage(msg, xmlstring % 'delivered="true"') addr['delivered'] = False - self.try2Methods(xmlstring % '', msg) + self.checkMessage(msg, xmlstring % '') -suite = unittest.TestLoader().loadTestsFromTestCase(testaddresses) +suite = unittest.TestLoader().loadTestsFromTestCase(TestAddresses) diff --git a/tests/test_chatstates.py b/tests/test_chatstates.py index 8878e318..1e585be4 100644 --- a/tests/test_chatstates.py +++ b/tests/test_chatstates.py @@ -1,47 +1,44 @@ -import unittest -from xml.etree import cElementTree as ET -from sleekxmpp.xmlstream.matcher.stanzapath import StanzaPath -from . import xmlcompare +from sleektest import * +import sleekxmpp.plugins.xep_0085 as xep_0085 -import sleekxmpp.plugins.xep_0085 as cs - -def stanzaPlugin(stanza, plugin): - stanza.plugin_attrib_map[plugin.plugin_attrib] = plugin - stanza.plugin_tag_map["{%s}%s" % (plugin.namespace, plugin.name)] = plugin - -class testchatstates(unittest.TestCase): +class TestChatStates(SleekTest): def setUp(self): - self.cs = cs - stanzaPlugin(self.cs.Message, self.cs.Active) - stanzaPlugin(self.cs.Message, self.cs.Composing) - stanzaPlugin(self.cs.Message, self.cs.Gone) - stanzaPlugin(self.cs.Message, self.cs.Inactive) - stanzaPlugin(self.cs.Message, self.cs.Paused) - - def try2Methods(self, xmlstring, msg): - msg2 = self.cs.Message(None, self.cs.ET.fromstring(xmlstring)) - self.failUnless(xmlstring == str(msg) == str(msg2), - "Two methods for creating stanza don't match") + self.stanzaPlugin(Message, xep_0085.Active) + self.stanzaPlugin(Message, xep_0085.Composing) + self.stanzaPlugin(Message, xep_0085.Gone) + self.stanzaPlugin(Message, xep_0085.Inactive) + self.stanzaPlugin(Message, xep_0085.Paused) def testCreateChatState(self): """Testing creating chat states.""" - xmlstring = """<%s xmlns="http://jabber.org/protocol/chatstates" />""" - - msg = self.cs.Message() + + xmlstring = """ + + <%s xmlns="http://jabber.org/protocol/chatstates" /> + + """ + + msg = self.Message() msg['chat_state'].active() - self.try2Methods(xmlstring % 'active', msg) + self.checkMessage(msg, xmlstring % 'active', + use_values=False) msg['chat_state'].composing() - self.try2Methods(xmlstring % 'composing', msg) + self.checkMessage(msg, xmlstring % 'composing', + use_values=False) + msg['chat_state'].gone() - self.try2Methods(xmlstring % 'gone', msg) + self.checkMessage(msg, xmlstring % 'gone', + use_values=False) msg['chat_state'].inactive() - self.try2Methods(xmlstring % 'inactive', msg) + self.checkMessage(msg, xmlstring % 'inactive', + use_values=False) msg['chat_state'].paused() - self.try2Methods(xmlstring % 'paused', msg) + self.checkMessage(msg, xmlstring % 'paused', + use_values=False) -suite = unittest.TestLoader().loadTestsFromTestCase(testchatstates) +suite = unittest.TestLoader().loadTestsFromTestCase(TestChatStates) diff --git a/tests/test_disco.py b/tests/test_disco.py index bbe285a6..6daad13e 100644 --- a/tests/test_disco.py +++ b/tests/test_disco.py @@ -1,96 +1,118 @@ -import unittest -from xml.etree import cElementTree as ET -from sleekxmpp.xmlstream.matcher.stanzapath import StanzaPath -from . import xmlcompare +from sleektest import * +import sleekxmpp.plugins.xep_0030 as xep_0030 -import sleekxmpp.plugins.xep_0030 as sd -def stanzaPlugin(stanza, plugin): - stanza.plugin_attrib_map[plugin.plugin_attrib] = plugin - stanza.plugin_tag_map["{%s}%s" % (plugin.namespace, plugin.name)] = plugin - -class testdisco(unittest.TestCase): +class TestDisco(SleekTest): def setUp(self): - self.sd = sd - stanzaPlugin(self.sd.Iq, self.sd.DiscoInfo) - stanzaPlugin(self.sd.Iq, self.sd.DiscoItems) - - def try3Methods(self, xmlstring, iq): - iq2 = self.sd.Iq(None, self.sd.ET.fromstring(xmlstring)) - values = iq2.getValues() - iq3 = self.sd.Iq() - iq3.setValues(values) - self.failUnless(xmlstring == str(iq) == str(iq2) == str(iq3), str(iq)+"3 methods for creating stanza don't match") + self.stanzaPlugin(Iq, xep_0030.DiscoInfo) + self.stanzaPlugin(Iq, xep_0030.DiscoItems) def testCreateInfoQueryNoNode(self): """Testing disco#info query with no node.""" - iq = self.sd.Iq() + iq = self.Iq() iq['id'] = "0" iq['disco_info']['node'] = '' - xmlstring = """""" - self.try3Methods(xmlstring, iq) + + self.checkIq(iq, """ + + + + """) def testCreateInfoQueryWithNode(self): """Testing disco#info query with a node.""" - iq = self.sd.Iq() + iq = self.Iq() iq['id'] = "0" iq['disco_info']['node'] = 'foo' - xmlstring = """""" - self.try3Methods(xmlstring, iq) + + self.checkIq(iq, """ + + + + """) def testCreateInfoQueryNoNode(self): """Testing disco#items query with no node.""" - iq = self.sd.Iq() + iq = self.Iq() iq['id'] = "0" iq['disco_items']['node'] = '' - xmlstring = """""" - self.try3Methods(xmlstring, iq) + + self.checkIq(iq, """ + + + + """) def testCreateItemsQueryWithNode(self): """Testing disco#items query with a node.""" - iq = self.sd.Iq() + iq = self.Iq() iq['id'] = "0" iq['disco_items']['node'] = 'foo' - xmlstring = """""" - self.try3Methods(xmlstring, iq) + + self.checkIq(iq, """ + + + + """) def testInfoIdentities(self): """Testing adding identities to disco#info.""" - iq = self.sd.Iq() + iq = self.Iq() iq['id'] = "0" iq['disco_info']['node'] = 'foo' iq['disco_info'].addIdentity('conference', 'text', 'Chatroom') - xmlstring = """""" - self.try3Methods(xmlstring, iq) + + self.checkIq(iq, """ + + + + + + """) def testInfoFeatures(self): """Testing adding features to disco#info.""" - iq = self.sd.Iq() + iq = self.Iq() iq['id'] = "0" iq['disco_info']['node'] = 'foo' iq['disco_info'].addFeature('foo') iq['disco_info'].addFeature('bar') - xmlstring = """""" - self.try3Methods(xmlstring, iq) + + self.checkIq(iq, """ + + + + + + + """) def testItems(self): """Testing adding features to disco#info.""" - iq = self.sd.Iq() + iq = self.Iq() iq['id'] = "0" iq['disco_items']['node'] = 'foo' iq['disco_items'].addItem('user@localhost') iq['disco_items'].addItem('user@localhost', 'foo') iq['disco_items'].addItem('user@localhost', 'bar', 'Testing') - xmlstring = """""" - self.try3Methods(xmlstring, iq) + + self.checkIq(iq, """ + + + + + + + + """) def testAddRemoveIdentities(self): """Test adding and removing identities to disco#info stanza""" ids = [('automation', 'commands', 'AdHoc'), ('conference', 'text', 'ChatRoom')] - info = self.sd.DiscoInfo() + info = xep_0030.DiscoInfo() info.addIdentity(*ids[0]) self.failUnless(info.getIdentities() == [ids[0]]) @@ -110,7 +132,7 @@ class testdisco(unittest.TestCase): """Test adding and removing features to disco#info stanza""" features = ['foo', 'bar', 'baz'] - info = self.sd.DiscoInfo() + info = xep_0030.DiscoInfo() info.addFeature(features[0]) self.failUnless(info.getFeatures() == [features[0]]) @@ -132,7 +154,7 @@ class testdisco(unittest.TestCase): ('user@localhost', 'foo', None), ('user@localhost', 'bar', 'Test')] - info = self.sd.DiscoItems() + info = xep_0030.DiscoItems() self.failUnless(True, ""+str(items[0])) info.addItem(*(items[0])) @@ -151,5 +173,4 @@ class testdisco(unittest.TestCase): self.failUnless(info.getItems() == []) - -suite = unittest.TestLoader().loadTestsFromTestCase(testdisco) +suite = unittest.TestLoader().loadTestsFromTestCase(TestDisco) -- cgit v1.2.3 From b1c997be1d7d7d456cad06ef436c01527e04df5d Mon Sep 17 00:00:00 2001 From: Lance Stout Date: Sun, 11 Jul 2010 22:01:51 -0400 Subject: Reworked the Gmail notification plugin to use stanza objects and expose more information. --- tests/test_gmail.py | 88 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 88 insertions(+) create mode 100644 tests/test_gmail.py (limited to 'tests') diff --git a/tests/test_gmail.py b/tests/test_gmail.py new file mode 100644 index 00000000..199b76ae --- /dev/null +++ b/tests/test_gmail.py @@ -0,0 +1,88 @@ +from sleektest import * +import sleekxmpp.plugins.gmail_notify as gmail + + +class TestGmail(SleekTest): + + def setUp(self): + self.stanzaPlugin(Iq, gmail.GmailQuery) + self.stanzaPlugin(Iq, gmail.MailBox) + self.stanzaPlugin(Iq, gmail.NewMail) + + def testCreateQuery(self): + """Testing querying Gmail for emails.""" + + iq = self.Iq() + iq['type'] = 'get' + iq['gmail']['search'] = 'is:starred' + iq['gmail']['newer-than-time'] = '1140638252542' + iq['gmail']['newer-than-tid'] = '11134623426430234' + + self.checkIq(iq, """ + + + + """) + + def testMailBox(self): + """Testing reading from Gmail mailbox result""" + + # Use the example from Google's documentation at + # http://code.google.com/apis/talk/jep_extensions/gmail.html#notifications + xml = ET.fromstring(""" + + + + + + + + + act1scene3 + Put thy rapier up. + Ay, ay, a scratch, a scratch; marry, 'tis enough. + + + + """) + + iq = self.Iq(xml=xml) + mailbox = iq['mailbox'] + self.failUnless(mailbox['result-time'] == '1118012394209', "result-time doesn't match") + self.failUnless(mailbox['url'] == 'http://mail.google.com/mail', "url doesn't match") + self.failUnless(mailbox['matched'] == '95', "total-matched incorrect") + self.failUnless(mailbox['estimate'] == False, "total-estimate incorrect") + self.failUnless(len(mailbox['threads']) == 1, "could not extract message threads") + + thread = mailbox['threads'][0] + self.failUnless(thread['tid'] == '1172320964060972012', "thread tid doesn't match") + self.failUnless(thread['participation'] == '1', "thread participation incorrect") + self.failUnless(thread['messages'] == '28', "thread message count incorrect") + self.failUnless(thread['date'] == '1118012394209', "thread date doesn't match") + self.failUnless(thread['url'] == 'http://mail.google.com/mail?view=cv', "thread url doesn't match") + self.failUnless(thread['labels'] == 'act1scene3', "thread labels incorrect") + self.failUnless(thread['subject'] == 'Put thy rapier up.', "thread subject doesn't match") + self.failUnless(thread['snippet'] == "Ay, ay, a scratch, a scratch; marry, 'tis enough.", "snippet doesn't match") + self.failUnless(len(thread['senders']) == 3, "could not extract senders") + + sender1 = thread['senders'][0] + self.failUnless(sender1['name'] == 'Me', "sender name doesn't match") + self.failUnless(sender1['address'] == 'romeo@gmail.com', "sender address doesn't match") + self.failUnless(sender1['originator'] == True, "sender originator incorrect") + self.failUnless(sender1['unread'] == False, "sender unread incorrectly True") + + sender2 = thread['senders'][2] + self.failUnless(sender2['unread'] == True, "sender unread incorrectly False") + +suite = unittest.TestLoader().loadTestsFromTestCase(TestGmail) -- cgit v1.2.3 From 48f0843ace5a8d383abe493b999e7bd4699598d7 Mon Sep 17 00:00:00 2001 From: Lance Stout Date: Wed, 14 Jul 2010 11:59:58 -0400 Subject: Added initial stanza object version of the xep_0004 plugin. Items/reported elements still need to be unit tested --- tests/test_forms.py | 90 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 90 insertions(+) create mode 100644 tests/test_forms.py (limited to 'tests') diff --git a/tests/test_forms.py b/tests/test_forms.py new file mode 100644 index 00000000..981d8870 --- /dev/null +++ b/tests/test_forms.py @@ -0,0 +1,90 @@ +from sleektest import * +import sleekxmpp.plugins.alt_0004 as xep_0004 + + +class TestDataForms(SleekTest): + + def setUp(self): + self.stanzaPlugin(Message, xep_0004.Form) + self.stanzaPlugin(xep_0004.Form, xep_0004.FormField) + self.stanzaPlugin(xep_0004.FormField, xep_0004.FieldOption) + + def testMultipleInstructions(self): + """Testing using multiple instructions elements in a data form.""" + msg = self.Message() + msg['form']['instructions'] = "Instructions\nSecond batch" + + self.checkMessage(msg, """ + + + Instructions + Second batch + + + """, use_values=False) + + def testAddField(self): + """Testing adding fields to a data form.""" + + msg = self.Message() + form = msg['form'] + form.addField('f1', + ftype='text-single', + label='Text', + desc='A text field', + required=True, + value='Some text!') + + self.checkMessage(msg, """ + + + + A text field + + Some text! + + + + """, use_values=False) + + form['fields'] = {'f1': {'type': 'text-single', + 'label': 'Username', + 'required': True}, + 'f2': {'type': 'text-private', + 'label': 'Password', + 'required': True}, + 'f3': {'type': 'text-multi', + 'label': 'Message', + 'value': 'Enter message.\nA long one even.'}, + 'f4': {'type': 'list-single', + 'label': 'Message Type', + 'options': [{'label': 'Cool!', + 'value': 'cool'}, + {'label': 'Urgh!', + 'value': 'urgh'}]}} + self.checkMessage(msg, """ + + + + + + + + + + Enter message. + A long one even. + + + + + + + + """, use_values=False) + +suite = unittest.TestLoader().loadTestsFromTestCase(TestDataForms) -- cgit v1.2.3 From 35212c7991312b26e813afde3bf0bbe002058c11 Mon Sep 17 00:00:00 2001 From: Lance Stout Date: Wed, 14 Jul 2010 15:24:37 -0400 Subject: Updated SleekTest to be able to simulate and test interactions with an XML stream. --- tests/sleektest.py | 150 +++++++++++++++++++++++++++++++++++++++++++++++++-- tests/test_stream.py | 34 ++++++++++++ 2 files changed, 179 insertions(+), 5 deletions(-) create mode 100644 tests/test_stream.py (limited to 'tests') diff --git a/tests/sleektest.py b/tests/sleektest.py index eed52ec2..eef3b900 100644 --- a/tests/sleektest.py +++ b/tests/sleektest.py @@ -7,11 +7,80 @@ """ import unittest +import socket +try: + import queue +except ImportError: + import Queue as queue from xml.etree import cElementTree as ET +from sleekxmpp import ClientXMPP from sleekxmpp import Message, Iq from sleekxmpp.stanza.presence import Presence from sleekxmpp.xmlstream.matcher.stanzapath import StanzaPath +class TestSocket(object): + + def __init__(self, *args, **kwargs): + self.socket = socket.socket(*args, **kwargs) + self.recv_queue = queue.Queue() + self.send_queue = queue.Queue() + + def __getattr__(self, name): + """Pass requests through to actual socket""" + # Override a few methods to prevent actual socket connections + overrides = {'connect': lambda *args: None, + 'close': lambda *args: None, + 'shutdown': lambda *args: None} + return overrides.get(name, getattr(self.socket, name)) + + # ------------------------------------------------------------------ + # Testing Interface + + def nextSent(self, timeout=None): + """Get the next stanza that has been 'sent'""" + args = {'block': False} + if timeout is not None: + args = {'block': True, 'timeout': timeout} + try: + return self.send_queue.get(**args) + except: + return None + + def recvData(self, data): + """Add data to the receiving queue""" + self.recv_queue.put(data) + + # ------------------------------------------------------------------ + # Socket Interface + + def recv(self, *args, **kwargs): + return self.read(block=True) + + def send(self, data): + self.send_queue.put(data) + + # ------------------------------------------------------------------ + # File Socket + + def makefile(self, mode='r', bufsize=-1): + """File socket version to use with ElementTree""" + return self + + def read(self, size=4096, block=True, timeout=None): + """Implement the file socket interface""" + if timeout is not None: + block = True + try: + return self.recv_queue.get(block, timeout) + except: + return None + +class TestStream(object): + """Dummy class to pass a stream object to created stanzas""" + + def __init__(self): + self.default_ns = 'jabber:client' + class SleekTest(unittest.TestCase): """ @@ -27,6 +96,9 @@ class SleekTest(unittest.TestCase): stanza.plugin_attrib_map[plugin.plugin_attrib] = plugin stanza.plugin_tag_map[tag] = plugin + # ------------------------------------------------------------------ + # Shortcut methods for creating stanza objects + def Message(self, *args, **kwargs): """Create a message stanza.""" return Message(None, *args, **kwargs) @@ -39,6 +111,9 @@ class SleekTest(unittest.TestCase): """Create a presence stanza.""" return Presence(None, *args, **kwargs) + # ------------------------------------------------------------------ + # Methods for comparing stanza objects to XML strings + def checkMessage(self, msg, xml_string, use_values=True): """ Create and compare several message stanza objects to a @@ -48,10 +123,12 @@ class SleekTest(unittest.TestCase): setValues() will not be used. """ + self.fix_namespaces(msg.xml, 'jabber:client') debug = "Given Stanza:\n%s\n" % ET.tostring(msg.xml) xml = ET.fromstring(xml_string) - xml.tag = '{jabber:client}message' + self.fix_namespaces(xml, 'jabber:client') + debug += "XML String:\n%s\n" % ET.tostring(xml) msg2 = self.Message(xml) @@ -69,8 +146,7 @@ class SleekTest(unittest.TestCase): debug += "Second Constructed Stanza:\n%s\n" % ET.tostring(msg3.xml) debug = "Three methods for creating stanza do not match:\n" + debug - self.failUnless(self.compare([xml, msg.xml, - msg2.xml, msg3.xml]), + self.failUnless(self.compare([xml, msg.xml, msg2.xml, msg3.xml]), debug) else: debug = "Two methods for creating stanza do not match:\n" + debug @@ -84,10 +160,12 @@ class SleekTest(unittest.TestCase): If use_values is False, the test using getValues() and setValues() will not be used. """ + + self.fix_namespaces(iq.xml, 'jabber:client') debug = "Given Stanza:\n%s\n" % ET.tostring(iq.xml) xml = ET.fromstring(xml_string) - xml.tag = '{jabber:client}iq' + self.fix_namespaces(xml, 'jabber:client') debug += "XML String:\n%s\n" % ET.tostring(xml) iq2 = self.Iq(xml) @@ -116,6 +194,69 @@ class SleekTest(unittest.TestCase): """ pass + # ------------------------------------------------------------------ + # Methods for simulating stanza streams. + + def streamStart(self, mode='client', skip=True): + if mode == 'client': + self.xmpp = ClientXMPP('tester@localhost', 'test') + self.xmpp.setSocket(TestSocket()) + + self.xmpp.state.set('reconnect', False) + self.xmpp.state.set('is client', True) + self.xmpp.state.set('connected', True) + + # Must have the stream header ready for xmpp.process() to work + self.xmpp.socket.recvData(self.xmpp.stream_header) + + self.xmpp.connectTCP = lambda a, b, c, d: True + self.xmpp.startTLS = lambda: True + self.xmpp.process(threaded=True) + if skip: + # Clear startup stanzas + self.xmpp.socket.nextSent(timeout=1) + + def streamRecv(self, data): + data = str(data) + self.xmpp.socket.recvData(data) + + def streamSendMessage(self, data, use_values=True, timeout=.5): + if isinstance(data, str): + data = self.Message(xml=ET.fromstring(data)) + sent = self.xmpp.socket.nextSent(timeout=1) + self.checkMessage(data, sent, use_values) + + def streamSendIq(self, data, use_values=True, timeout=.5): + if isinstance(data, str): + data = self.Iq(xml=ET.fromstring(data)) + sent = self.xmpp.socket.nextSent(timeout) + self.checkIq(data, sent, use_values) + + def streamSendPresence(self, data, use_values=True, timeout=.5): + if isinstance(data, str): + data = self.Presence(xml=ET.fromstring(data)) + sent = self.xmpp.socket.nextSent(timeout) + self.checkPresence(data, sent, use_values) + + def streamClose(self): + if self.xmpp is not None: + self.xmpp.disconnect() + self.xmpp.socket.recvData(self.xmpp.stream_footer) + + # ------------------------------------------------------------------ + # XML Comparison and Cleanup + + def fix_namespaces(self, xml, ns): + """ + Assign a namespace to an element and any children that + don't have a namespace. + """ + if xml.tag.startswith('{'): + return + xml.tag = '{%s}%s' % (ns, xml.tag) + for child in xml.getchildren(): + self.fix_namespaces(child, ns) + def compare(self, xml1, xml2=None): """ Compare XML objects. @@ -137,7 +278,6 @@ class SleekTest(unittest.TestCase): # Step 1: Check tags if xml1.tag != xml2.tag: - print xml1.tag, xml2.tag return False # Step 2: Check attributes diff --git a/tests/test_stream.py b/tests/test_stream.py new file mode 100644 index 00000000..eb4aaa59 --- /dev/null +++ b/tests/test_stream.py @@ -0,0 +1,34 @@ +from sleektest import * +import sleekxmpp.plugins.xep_0033 as xep_0033 + + +class TestStreamTester(SleekTest): + """ + Test that we can simulate and test a stanza stream. + """ + + def setUp(self): + self.streamStart() + + def tearDown(self): + self.streamClose() + + def testEcho(self): + def echo(msg): + msg.reply('Thanks for sending: %(body)s' % msg).send() + + self.xmpp.add_event_handler('message', echo) + + self.streamRecv(""" + + Hi! + + """) + + self.streamSendMessage(""" + + Thanks for sending: Hi! + + """) + +suite = unittest.TestLoader().loadTestsFromTestCase(TestStreamTester) -- cgit v1.2.3 From d5e42ac0e7282500583bf17f21eb2f944600ce76 Mon Sep 17 00:00:00 2001 From: Lance Stout Date: Mon, 19 Jul 2010 13:58:53 -0400 Subject: Condensed all of the stanzaPlugin functions into a single registerStanzaPlugin function. Updated plugins and tests to use new function. --- tests/sleektest.py | 10 ++-------- tests/test_addresses.py | 2 +- tests/test_chatstates.py | 10 +++++----- tests/test_disco.py | 4 ++-- tests/test_forms.py | 6 +++--- tests/test_gmail.py | 6 +++--- tests/test_messagestanzas.py | 4 ++-- 7 files changed, 18 insertions(+), 24 deletions(-) (limited to 'tests') diff --git a/tests/sleektest.py b/tests/sleektest.py index eef3b900..3c270ebd 100644 --- a/tests/sleektest.py +++ b/tests/sleektest.py @@ -17,6 +17,8 @@ from sleekxmpp import ClientXMPP from sleekxmpp import Message, Iq from sleekxmpp.stanza.presence import Presence from sleekxmpp.xmlstream.matcher.stanzapath import StanzaPath +from sleekxmpp.xmlstream.stanzabase import registerStanzaPlugin + class TestSocket(object): @@ -88,14 +90,6 @@ class SleekTest(unittest.TestCase): methods for comparing message, iq, and presence stanzas. """ - def stanzaPlugin(self, stanza, plugin): - """ - Associate a stanza object as a plugin for another stanza. - """ - tag = "{%s}%s" % (plugin.namespace, plugin.name) - stanza.plugin_attrib_map[plugin.plugin_attrib] = plugin - stanza.plugin_tag_map[tag] = plugin - # ------------------------------------------------------------------ # Shortcut methods for creating stanza objects diff --git a/tests/test_addresses.py b/tests/test_addresses.py index 2718bb19..63d11003 100644 --- a/tests/test_addresses.py +++ b/tests/test_addresses.py @@ -5,7 +5,7 @@ import sleekxmpp.plugins.xep_0033 as xep_0033 class TestAddresses(SleekTest): def setUp(self): - self.stanzaPlugin(Message, xep_0033.Addresses) + registerStanzaPlugin(Message, xep_0033.Addresses) def testAddAddress(self): """Testing adding extended stanza address.""" diff --git a/tests/test_chatstates.py b/tests/test_chatstates.py index 1e585be4..bcacb9e5 100644 --- a/tests/test_chatstates.py +++ b/tests/test_chatstates.py @@ -4,11 +4,11 @@ import sleekxmpp.plugins.xep_0085 as xep_0085 class TestChatStates(SleekTest): def setUp(self): - self.stanzaPlugin(Message, xep_0085.Active) - self.stanzaPlugin(Message, xep_0085.Composing) - self.stanzaPlugin(Message, xep_0085.Gone) - self.stanzaPlugin(Message, xep_0085.Inactive) - self.stanzaPlugin(Message, xep_0085.Paused) + registerStanzaPlugin(Message, xep_0085.Active) + registerStanzaPlugin(Message, xep_0085.Composing) + registerStanzaPlugin(Message, xep_0085.Gone) + registerStanzaPlugin(Message, xep_0085.Inactive) + registerStanzaPlugin(Message, xep_0085.Paused) def testCreateChatState(self): """Testing creating chat states.""" diff --git a/tests/test_disco.py b/tests/test_disco.py index 6daad13e..96a12e2a 100644 --- a/tests/test_disco.py +++ b/tests/test_disco.py @@ -5,8 +5,8 @@ import sleekxmpp.plugins.xep_0030 as xep_0030 class TestDisco(SleekTest): def setUp(self): - self.stanzaPlugin(Iq, xep_0030.DiscoInfo) - self.stanzaPlugin(Iq, xep_0030.DiscoItems) + registerStanzaPlugin(Iq, xep_0030.DiscoInfo) + registerStanzaPlugin(Iq, xep_0030.DiscoItems) def testCreateInfoQueryNoNode(self): """Testing disco#info query with no node.""" diff --git a/tests/test_forms.py b/tests/test_forms.py index 981d8870..16160249 100644 --- a/tests/test_forms.py +++ b/tests/test_forms.py @@ -5,9 +5,9 @@ import sleekxmpp.plugins.alt_0004 as xep_0004 class TestDataForms(SleekTest): def setUp(self): - self.stanzaPlugin(Message, xep_0004.Form) - self.stanzaPlugin(xep_0004.Form, xep_0004.FormField) - self.stanzaPlugin(xep_0004.FormField, xep_0004.FieldOption) + registerStanzaPlugin(Message, xep_0004.Form) + registerStanzaPlugin(xep_0004.Form, xep_0004.FormField) + registerStanzaPlugin(xep_0004.FormField, xep_0004.FieldOption) def testMultipleInstructions(self): """Testing using multiple instructions elements in a data form.""" diff --git a/tests/test_gmail.py b/tests/test_gmail.py index 199b76ae..b2e70d21 100644 --- a/tests/test_gmail.py +++ b/tests/test_gmail.py @@ -5,9 +5,9 @@ import sleekxmpp.plugins.gmail_notify as gmail class TestGmail(SleekTest): def setUp(self): - self.stanzaPlugin(Iq, gmail.GmailQuery) - self.stanzaPlugin(Iq, gmail.MailBox) - self.stanzaPlugin(Iq, gmail.NewMail) + registerStanzaPlugin(Iq, gmail.GmailQuery) + registerStanzaPlugin(Iq, gmail.MailBox) + registerStanzaPlugin(Iq, gmail.NewMail) def testCreateQuery(self): """Testing querying Gmail for emails.""" diff --git a/tests/test_messagestanzas.py b/tests/test_messagestanzas.py index 08488ce3..026a5782 100644 --- a/tests/test_messagestanzas.py +++ b/tests/test_messagestanzas.py @@ -5,9 +5,9 @@ class testmessagestanzas(unittest.TestCase): def setUp(self): import sleekxmpp.stanza.message as m - from sleekxmpp.basexmpp import stanzaPlugin + from sleekxmpp.basexmpp import registerStanzaPlugin from sleekxmpp.stanza.htmlim import HTMLIM - stanzaPlugin(m.Message, HTMLIM) + registerStanzaPlugin(m.Message, HTMLIM) self.m = m def testGroupchatReplyRegression(self): -- cgit v1.2.3 From f74baf1c23af79c6e732fffc7691cba97ee79715 Mon Sep 17 00:00:00 2001 From: Nathan Fritz Date: Mon, 19 Jul 2010 16:25:01 -0700 Subject: updated sleektest to use new stanza get/set values api --- tests/sleektest.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'tests') diff --git a/tests/sleektest.py b/tests/sleektest.py index 3c270ebd..d7a9d0a8 100644 --- a/tests/sleektest.py +++ b/tests/sleektest.py @@ -134,9 +134,9 @@ class SleekTest(unittest.TestCase): if xml.attrib.get('type', None) is None: xml.attrib['type'] = 'normal' - values = msg2.getValues() + values = msg2.getStanzaValues() msg3 = self.Message() - msg3.setValues(values) + msg3.setStanzaValues(values) debug += "Second Constructed Stanza:\n%s\n" % ET.tostring(msg3.xml) debug = "Three methods for creating stanza do not match:\n" + debug -- cgit v1.2.3 From 85ee30539d750740cd88c0ec85247815e7eea8bb Mon Sep 17 00:00:00 2001 From: Nathan Fritz Date: Mon, 19 Jul 2010 16:26:25 -0700 Subject: more set/get Values changes --- tests/sleektest.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'tests') diff --git a/tests/sleektest.py b/tests/sleektest.py index d7a9d0a8..d5696d0b 100644 --- a/tests/sleektest.py +++ b/tests/sleektest.py @@ -166,9 +166,9 @@ class SleekTest(unittest.TestCase): debug += "Constructed Stanza:\n%s\n" % ET.tostring(iq2.xml) if use_values: - values = iq.getValues() + values = iq.getStanzaValues() iq3 = self.Iq() - iq3.setValues(values) + iq3.setStanzaValues(values) debug += "Second Constructed Stanza:\n%s\n" % ET.tostring(iq3.xml) debug = "Three methods for creating stanza do not match:\n" + debug -- cgit v1.2.3 From 14f1c3ba512b17942e1925cc4e610d3558356ea7 Mon Sep 17 00:00:00 2001 From: Lance Stout Date: Mon, 19 Jul 2010 23:58:33 -0400 Subject: Updated SleekTest to implement the checkPresence method. Also, removed unnecessary TestStream class and shortened timeout during stream connection. --- tests/sleektest.py | 37 +++++++++++++++++++++++++++++-------- 1 file changed, 29 insertions(+), 8 deletions(-) (limited to 'tests') diff --git a/tests/sleektest.py b/tests/sleektest.py index d5696d0b..9f4198ec 100644 --- a/tests/sleektest.py +++ b/tests/sleektest.py @@ -77,12 +77,6 @@ class TestSocket(object): except: return None -class TestStream(object): - """Dummy class to pass a stream object to created stanzas""" - - def __init__(self): - self.default_ns = 'jabber:client' - class SleekTest(unittest.TestCase): """ @@ -186,7 +180,34 @@ class SleekTest(unittest.TestCase): If use_values is False, the test using getValues() and setValues() will not be used. """ - pass + self.fix_namespaces(pres.xml, 'jabber:client') + debug = "Given Stanza:\n%s\n" % ET.tostring(pres.xml) + + xml = ET.fromstring(xml_string) + self.fix_namespaces(xml, 'jabber:client') + debug += "XML String:\n%s\n" % ET.tostring(xml) + + pres2 = self.Presence(xml) + debug += "Constructed Stanza:\n%s\n" % ET.tostring(pres2.xml) + + # Ugly, but 'priority' has a default value and need to make + # sure it is set + pres['priority'] = pres['priority'] + pres2['priority'] = pres2['priority'] + + if use_values: + values = pres.getStanzaValues() + pres3 = self.Presence() + pres3.setStanzaValues(values) + + debug += "Second Constructed Stanza:\n%s\n" % ET.tostring(pres3.xml) + debug = "Three methods for creating stanza do not match:\n" + debug + self.failUnless(self.compare([xml, pres.xml, pres2.xml, pres3.xml]), + debug) + else: + debug = "Two methods for creating stanza do not match:\n" + debug + self.failUnless(self.compare([xml, pres.xml, pres2.xml]), debug) + # ------------------------------------------------------------------ # Methods for simulating stanza streams. @@ -208,7 +229,7 @@ class SleekTest(unittest.TestCase): self.xmpp.process(threaded=True) if skip: # Clear startup stanzas - self.xmpp.socket.nextSent(timeout=1) + self.xmpp.socket.nextSent(timeout=0.1) def streamRecv(self, data): data = str(data) -- cgit v1.2.3 From bb927c7e6ad75b190ab3aeea7fd71d8cd2118eed Mon Sep 17 00:00:00 2001 From: Lance Stout Date: Tue, 20 Jul 2010 00:04:34 -0400 Subject: Updated presence stanza to include a 'show' interface. Presence stanza tests updated accordingly. --- tests/test_presencestanzas.py | 52 ++++++++++++++++++++++++++++++------------- 1 file changed, 37 insertions(+), 15 deletions(-) (limited to 'tests') diff --git a/tests/test_presencestanzas.py b/tests/test_presencestanzas.py index 23eb911e..02799c8f 100644 --- a/tests/test_presencestanzas.py +++ b/tests/test_presencestanzas.py @@ -1,31 +1,53 @@ -import unittest +import sleekxmpp +from sleektest import * +from sleekxmpp.stanza.presence import Presence -class testpresencestanzas(unittest.TestCase): - - def setUp(self): - import sleekxmpp.stanza.presence as p - self.p = p +class TestPresenceStanzas(SleekTest): - def testPresenceShowRegression(self): - "Regression check presence['type'] = 'dnd' show value working" - p = self.p.Presence() + def testPresenceShowRegression(self): + """Regression check presence['type'] = 'dnd' show value working""" + p = self.Presence() p['type'] = 'dnd' - self.failUnless(str(p) == "dnd") - + self.checkPresence(p, """ + dnd + """) + + def testPresenceType(self): + """Test manipulating presence['type']""" + p = self.Presence() + p['type'] = 'available' + self.checkPresence(p, """ + + """) + self.failUnless(p['type'] == 'available', "Incorrect presence['type'] for type 'available'") + + for showtype in ['away', 'chat', 'dnd', 'xa']: + p['type'] = showtype + self.checkPresence(p, """ + %s + """ % showtype) + self.failUnless(p['type'] == showtype, "Incorrect presence['type'] for type '%s'" % showtype) + + p['type'] = None + self.checkPresence(p, """ + + """) + def testPresenceUnsolicitedOffline(self): - "Unsolicted offline presence does not spawn changed_status or update roster" - p = self.p.Presence() + """Unsolicted offline presence does not spawn changed_status or update roster""" + p = self.Presence() p['type'] = 'unavailable' p['from'] = 'bill@chadmore.com/gmail15af' - import sleekxmpp + c = sleekxmpp.ClientXMPP('crap@wherever', 'password') happened = [] def handlechangedpresence(event): happened.append(True) c.add_event_handler("changed_status", handlechangedpresence) c._handlePresence(p) + self.failUnless(happened == [], "changed_status event triggered for superfulous unavailable presence") self.failUnless(c.roster == {}, "Roster updated for superfulous unavailable presence") -suite = unittest.TestLoader().loadTestsFromTestCase(testpresencestanzas) +suite = unittest.TestLoader().loadTestsFromTestCase(TestPresenceStanzas) -- cgit v1.2.3 From f505e229d6af009ba926292e3947346614df89f9 Mon Sep 17 00:00:00 2001 From: Lance Stout Date: Tue, 20 Jul 2010 01:55:44 -0400 Subject: Updated message stanza tests. --- tests/test_messagestanzas.py | 37 +++++++++++++++++++------------------ 1 file changed, 19 insertions(+), 18 deletions(-) (limited to 'tests') diff --git a/tests/test_messagestanzas.py b/tests/test_messagestanzas.py index 026a5782..c83b59a7 100644 --- a/tests/test_messagestanzas.py +++ b/tests/test_messagestanzas.py @@ -1,18 +1,15 @@ -import unittest -from xml.etree import cElementTree as ET +from sleektest import * +from sleekxmpp.stanza.message import Message +from sleekxmpp.stanza.htmlim import HTMLIM -class testmessagestanzas(unittest.TestCase): +class TestMessageStanzas(SleekTest): def setUp(self): - import sleekxmpp.stanza.message as m - from sleekxmpp.basexmpp import registerStanzaPlugin - from sleekxmpp.stanza.htmlim import HTMLIM - registerStanzaPlugin(m.Message, HTMLIM) - self.m = m - + registerStanzaPlugin(Message, HTMLIM) + def testGroupchatReplyRegression(self): "Regression groupchat reply should be to barejid" - msg = self.m.Message() + msg = self.Message() msg['to'] = 'me@myserver.tld' msg['from'] = 'room@someservice.someserver.tld/somenick' msg['type'] = 'groupchat' @@ -22,23 +19,27 @@ class testmessagestanzas(unittest.TestCase): def testAttribProperty(self): "Test attrib property returning self" - msg = self.m.Message() + msg = self.Message() msg.attrib.attrib.attrib['to'] = 'usr@server.tld' self.failUnless(str(msg['to']) == 'usr@server.tld') def testHTMLPlugin(self): "Test message/html/html stanza" - msgtxt = """this is the plaintext message

This is the htmlim message

""" - msg = self.m.Message() + msg = self.Message() msg['to'] = "fritzy@netflint.net/sleekxmpp" msg['body'] = "this is the plaintext message" msg['type'] = 'chat' p = ET.Element('{http://www.w3.org/1999/xhtml}p') p.text = "This is the htmlim message" msg['html']['html'] = p - msg2 = self.m.Message() - values = msg.getValues() - msg2.setValues(values) - self.failUnless(msgtxt == str(msg) == str(msg2)) + self.checkMessage(msg, """ + + this is the plaintext message + + +

This is the htmlim message

+ + +
""") -suite = unittest.TestLoader().loadTestsFromTestCase(testmessagestanzas) +suite = unittest.TestLoader().loadTestsFromTestCase(TestMessageStanzas) -- cgit v1.2.3 From 690eaf8d3c3856c6242612da22e6c6d323f193ed Mon Sep 17 00:00:00 2001 From: Lance Stout Date: Tue, 20 Jul 2010 11:19:49 -0400 Subject: Updated license notices to use the correct MIT format. Also corrected references to nonexistant license.txt to LICENSE. --- tests/sleektest.py | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) (limited to 'tests') diff --git a/tests/sleektest.py b/tests/sleektest.py index 9f4198ec..f89966ec 100644 --- a/tests/sleektest.py +++ b/tests/sleektest.py @@ -3,7 +3,7 @@ Copyright (C) 2010 Nathanael C. Fritz, Lance J.T. Stout This file is part of SleekXMPP. - See the file license.txt for copying permission. + See the file LICENSE for copying permission. """ import unittest @@ -127,6 +127,11 @@ class SleekTest(unittest.TestCase): msg['type'] = msg['type'] if xml.attrib.get('type', None) is None: xml.attrib['type'] = 'normal' + msg2['type'] = msg2['type'] + debug += ">>>>Given Stanza:\n%s\n" % ET.tostring(msg.xml) + debug += "XML String:\n%s\n" % ET.tostring(xml) + debug += ">>>>Constructed Stanza:\n%s\n" % ET.tostring(msg2.xml) + values = msg2.getStanzaValues() msg3 = self.Message() -- cgit v1.2.3 From de24e9ed458cea4bccb9962b69e5fb4271841b3d Mon Sep 17 00:00:00 2001 From: Lance Stout Date: Tue, 20 Jul 2010 12:16:57 -0400 Subject: Lots of XEP-0004 bug fixes. Forms have default type of 'form' setFields now uses a list of tuples instead of a dictionary because ordering is important. getFields defaults to returning a list of tuples, but the use_dict parameter can change that --- tests/test_forms.py | 71 ++++++++++++++++++++++++++++++++++++----------------- 1 file changed, 48 insertions(+), 23 deletions(-) (limited to 'tests') diff --git a/tests/test_forms.py b/tests/test_forms.py index 16160249..7d37506d 100644 --- a/tests/test_forms.py +++ b/tests/test_forms.py @@ -1,5 +1,5 @@ from sleektest import * -import sleekxmpp.plugins.alt_0004 as xep_0004 +import sleekxmpp.plugins.xep_0004 as xep_0004 class TestDataForms(SleekTest): @@ -16,19 +16,19 @@ class TestDataForms(SleekTest): self.checkMessage(msg, """ - + Instructions Second batch - """, use_values=False) + """) def testAddField(self): """Testing adding fields to a data form.""" msg = self.Message() form = msg['form'] - form.addField('f1', + form.addField(var='f1', ftype='text-single', label='Text', desc='A text field', @@ -37,7 +37,7 @@ class TestDataForms(SleekTest): self.checkMessage(msg, """ - + A text field @@ -45,26 +45,26 @@ class TestDataForms(SleekTest): - """, use_values=False) + """) - form['fields'] = {'f1': {'type': 'text-single', - 'label': 'Username', - 'required': True}, - 'f2': {'type': 'text-private', - 'label': 'Password', - 'required': True}, - 'f3': {'type': 'text-multi', - 'label': 'Message', - 'value': 'Enter message.\nA long one even.'}, - 'f4': {'type': 'list-single', - 'label': 'Message Type', - 'options': [{'label': 'Cool!', - 'value': 'cool'}, - {'label': 'Urgh!', - 'value': 'urgh'}]}} + form['fields'] = [('f1', {'type': 'text-single', + 'label': 'Username', + 'required': True}), + ('f2', {'type': 'text-private', + 'label': 'Password', + 'required': True}), + ('f3', {'type': 'text-multi', + 'label': 'Message', + 'value': 'Enter message.\nA long one even.'}), + ('f4', {'type': 'list-single', + 'label': 'Message Type', + 'options': [{'label': 'Cool!', + 'value': 'cool'}, + {'label': 'Urgh!', + 'value': 'urgh'}]})] self.checkMessage(msg, """ - + @@ -85,6 +85,31 @@ class TestDataForms(SleekTest): - """, use_values=False) + """) + + def testSetValues(self): + """Testing setting form values""" + + msg = self.Message() + form = msg['form'] + form.setFields([ + ('foo', {'type': 'text-single'}), + ('bar', {'type': 'list-multi'})]) + + form.setValues({'foo': 'Foo!', + 'bar': ['a', 'b']}) + + self.checkMessage(msg, """ + + + + Foo! + + + a + b + + + """) suite = unittest.TestLoader().loadTestsFromTestCase(TestDataForms) -- cgit v1.2.3 From 7ad014368709873ed8ab760acc62264278f7723f Mon Sep 17 00:00:00 2001 From: Lance Stout Date: Tue, 20 Jul 2010 12:18:38 -0400 Subject: Updated pubsub stanzas to use xep_0004 stanza objects, and updated tests to match. --- tests/test_pubsubstanzas.py | 802 +++++++++++++++++++++++++++----------------- 1 file changed, 499 insertions(+), 303 deletions(-) (limited to 'tests') diff --git a/tests/test_pubsubstanzas.py b/tests/test_pubsubstanzas.py index 089ee180..794fa03a 100644 --- a/tests/test_pubsubstanzas.py +++ b/tests/test_pubsubstanzas.py @@ -1,315 +1,511 @@ -import unittest -from xml.etree import cElementTree as ET -from sleekxmpp.xmlstream.matcher.stanzapath import StanzaPath -from . import xmlcompare +from sleektest import * +import sleekxmpp.plugins.xep_0004 as xep_0004 +import sleekxmpp.plugins.stanza_pubsub as pubsub -class testpubsubstanzas(unittest.TestCase): - def setUp(self): - import sleekxmpp.plugins.stanza_pubsub as ps - self.ps = ps +class TestPubsubStanzas(SleekTest): - def testAffiliations(self): - "Testing iq/pubsub/affiliations/affiliation stanzas" - iq = self.ps.Iq() - aff1 = self.ps.Affiliation() - aff1['node'] = 'testnode' - aff1['affiliation'] = 'owner' - aff2 = self.ps.Affiliation() - aff2['node'] = 'testnode2' - aff2['affiliation'] = 'publisher' - iq['pubsub']['affiliations'].append(aff1) - iq['pubsub']['affiliations'].append(aff2) - xmlstring = """""" - iq2 = self.ps.Iq(None, self.ps.ET.fromstring(xmlstring)) - iq3 = self.ps.Iq() - values = iq2.getValues() - iq3.setValues(values) - self.failUnless(xmlstring == str(iq) == str(iq2) == str(iq3), "3 methods for creating stanza don't match") - self.failUnless(iq.match('iq@id=0/pubsub/affiliations/affiliation@node=testnode2@affiliation=publisher'), 'Match path failed') + def testAffiliations(self): + "Testing iq/pubsub/affiliations/affiliation stanzas" + iq = self.Iq() + aff1 = pubsub.Affiliation() + aff1['node'] = 'testnode' + aff1['affiliation'] = 'owner' + aff2 = pubsub.Affiliation() + aff2['node'] = 'testnode2' + aff2['affiliation'] = 'publisher' + iq['pubsub']['affiliations'].append(aff1) + iq['pubsub']['affiliations'].append(aff2) + self.checkIq(iq, """ + + + + + + + + """) - def testSubscriptions(self): - "Testing iq/pubsub/subscriptions/subscription stanzas" - iq = self.ps.Iq() - sub1 = self.ps.Subscription() - sub1['node'] = 'testnode' - sub1['jid'] = 'steve@myserver.tld/someresource' - sub2 = self.ps.Subscription() - sub2['node'] = 'testnode2' - sub2['jid'] = 'boogers@bork.top/bill' - sub2['subscription'] = 'subscribed' - iq['pubsub']['subscriptions'].append(sub1) - iq['pubsub']['subscriptions'].append(sub2) - xmlstring = """""" - iq2 = self.ps.Iq(None, self.ps.ET.fromstring(xmlstring)) - iq3 = self.ps.Iq() - values = iq2.getValues() - iq3.setValues(values) - self.failUnless(xmlstring == str(iq) == str(iq2) == str(iq3)) - - def testOptionalSettings(self): - "Testing iq/pubsub/subscription/subscribe-options stanzas" - iq = self.ps.Iq() - iq['pubsub']['subscription']['suboptions']['required'] = True - iq['pubsub']['subscription']['node'] = 'testnode alsdkjfas' - iq['pubsub']['subscription']['jid'] = "fritzy@netflint.net/sleekxmpp" - iq['pubsub']['subscription']['subscription'] = 'unconfigured' - xmlstring = """""" - iq2 = self.ps.Iq(None, self.ps.ET.fromstring(xmlstring)) - iq3 = self.ps.Iq() - values = iq2.getValues() - iq3.setValues(values) - self.failUnless(xmlstring == str(iq) == str(iq2) == str(iq3)) - - def testItems(self): - "Testing iq/pubsub/items stanzas" - iq = self.ps.Iq() - iq['pubsub']['items'] - payload = ET.fromstring("""""") - payload2 = ET.fromstring("""""") - item = self.ps.Item() - item['id'] = 'asdf' - item['payload'] = payload - item2 = self.ps.Item() - item2['id'] = 'asdf2' - item2['payload'] = payload2 - iq['pubsub']['items'].append(item) - iq['pubsub']['items'].append(item2) - xmlstring = """""" - iq2 = self.ps.Iq(None, self.ps.ET.fromstring(xmlstring)) - iq3 = self.ps.Iq() - values = iq2.getValues() - iq3.setValues(values) - self.failUnless(xmlstring == str(iq) == str(iq2) == str(iq3)) - - def testCreate(self): - "Testing iq/pubsub/create&configure stanzas" - from sleekxmpp.plugins import xep_0004 - iq = self.ps.Iq() - iq['pubsub']['create']['node'] = 'mynode' - form = xep_0004.Form() - form.addField('pubsub#title', ftype='text-single', value='This thing is awesome') - iq['pubsub']['configure']['config'] = form - xmlstring = """This thing is awesome""" - iq2 = self.ps.Iq(None, self.ps.ET.fromstring(xmlstring)) - iq3 = self.ps.Iq() - values = iq2.getValues() - iq3.setValues(values) - self.failUnless(xmlstring == str(iq) == str(iq2) == str(iq3)) - - def testState(self): - "Testing iq/psstate stanzas" - from sleekxmpp.plugins import xep_0004 - iq = self.ps.Iq() - iq['psstate']['node']= 'mynode' - iq['psstate']['item']= 'myitem' - pl = ET.Element('{http://andyet.net/protocol/pubsubqueue}claimed') - iq['psstate']['payload'] = pl - xmlstring = """""" - iq2 = self.ps.Iq(None, self.ps.ET.fromstring(xmlstring)) - iq3 = self.ps.Iq() - values = iq2.getValues() - iq3.setValues(values) - self.failUnless(xmlstring == str(iq) == str(iq2) == str(iq3)) - - def testDefault(self): - "Testing iq/pubsub_owner/default stanzas" - from sleekxmpp.plugins import xep_0004 - iq = self.ps.Iq() - iq['pubsub_owner']['default'] - iq['pubsub_owner']['default']['node'] = 'mynode' - iq['pubsub_owner']['default']['type'] = 'leaf' - form = xep_0004.Form() - form.addField('pubsub#title', ftype='text-single', value='This thing is awesome') - iq['pubsub_owner']['default']['config'] = form - xmlstring = """This thing is awesome""" - iq2 = self.ps.Iq(None, self.ps.ET.fromstring(xmlstring)) - iq3 = self.ps.Iq() - values = iq2.getValues() - iq3.setValues(values) - self.failUnless(xmlstring == str(iq) == str(iq2) == str(iq3)) - - def testSubscribe(self): - "Testing iq/pubsub/subscribe stanzas" - from sleekxmpp.plugins import xep_0004 - iq = self.ps.Iq() - iq['pubsub']['subscribe']['options'] - iq['pubsub']['subscribe']['node'] = 'cheese' - iq['pubsub']['subscribe']['jid'] = 'fritzy@netflint.net/sleekxmpp' - iq['pubsub']['subscribe']['options']['node'] = 'cheese' - iq['pubsub']['subscribe']['options']['jid'] = 'fritzy@netflint.net/sleekxmpp' - form = xep_0004.Form() - form.addField('pubsub#title', ftype='text-single', value='This thing is awesome') - iq['pubsub']['subscribe']['options']['options'] = form - xmlstring = """This thing is awesome""" - iq2 = self.ps.Iq(None, self.ps.ET.fromstring(xmlstring)) - iq3 = self.ps.Iq() - values = iq2.getValues() - iq3.setValues(values) - self.failUnless(xmlstring == str(iq) == str(iq2) == str(iq3)) - - def testPublish(self): - "Testing iq/pubsub/publish stanzas" - iq = self.ps.Iq() - iq['pubsub']['publish']['node'] = 'thingers' - payload = ET.fromstring("""""") - payload2 = ET.fromstring("""""") - item = self.ps.Item() - item['id'] = 'asdf' - item['payload'] = payload - item2 = self.ps.Item() - item2['id'] = 'asdf2' - item2['payload'] = payload2 - iq['pubsub']['publish'].append(item) - iq['pubsub']['publish'].append(item2) - xmlstring = """""" - iq2 = self.ps.Iq(None, self.ps.ET.fromstring(xmlstring)) - iq3 = self.ps.Iq() - values = iq2.getValues() - iq3.setValues(values) - self.failUnless(xmlstring == str(iq) == str(iq2) == str(iq3)) + def testSubscriptions(self): + "Testing iq/pubsub/subscriptions/subscription stanzas" + iq = self.Iq() + sub1 = pubsub.Subscription() + sub1['node'] = 'testnode' + sub1['jid'] = 'steve@myserver.tld/someresource' + sub2 = pubsub.Subscription() + sub2['node'] = 'testnode2' + sub2['jid'] = 'boogers@bork.top/bill' + sub2['subscription'] = 'subscribed' + iq['pubsub']['subscriptions'].append(sub1) + iq['pubsub']['subscriptions'].append(sub2) + self.checkIq(iq, """ + + + + + + + + """) - def testDelete(self): - "Testing iq/pubsub_owner/delete stanzas" - iq = self.ps.Iq() - iq['pubsub_owner']['delete']['node'] = 'thingers' - xmlstring = """""" - iq2 = self.ps.Iq(None, self.ps.ET.fromstring(xmlstring)) - iq3 = self.ps.Iq() - iq3.setValues(iq2.getValues()) - self.failUnless(xmlstring == str(iq) == str(iq2) == str(iq3)) - - def testCreateConfigGet(self): - """Testing getting config from full create""" - xml = """http://jabber.org/protocol/pubsub#node_configleaf111101openpublishersnever""" - iq = self.ps.Iq(None, self.ps.ET.fromstring(xml)) - config = iq['pubsub']['configure']['config'] - self.failUnless(config.getValues() != {}) + def testOptionalSettings(self): + "Testing iq/pubsub/subscription/subscribe-options stanzas" + iq = self.Iq() + iq['pubsub']['subscription']['suboptions']['required'] = True + iq['pubsub']['subscription']['node'] = 'testnode alsdkjfas' + iq['pubsub']['subscription']['jid'] = "fritzy@netflint.net/sleekxmpp" + iq['pubsub']['subscription']['subscription'] = 'unconfigured' + self.checkIq(iq, """ + + + + + + + + + """) - def testItemEvent(self): - """Testing message/pubsub_event/items/item""" - msg = self.ps.Message() - item = self.ps.EventItem() - pl = ET.Element('{http://netflint.net/protocol/test}test', {'failed':'3', 'passed':'24'}) - item['payload'] = pl - item['id'] = 'abc123' - msg['pubsub_event']['items'].append(item) - msg['pubsub_event']['items']['node'] = 'cheese' - msg['type'] = 'normal' - xmlstring = """""" - msg2 = self.ps.Message(None, self.ps.ET.fromstring(xmlstring)) - msg3 = self.ps.Message() - msg3.setValues(msg2.getValues()) - self.failUnless(xmlstring == str(msg) == str(msg2) == str(msg3)) + def testItems(self): + "Testing iq/pubsub/items stanzas" + iq = self.Iq() + iq['pubsub']['items'] + payload = ET.fromstring(""" + + + + """) + payload2 = ET.fromstring(""" + + + + """) + item = pubsub.Item() + item['id'] = 'asdf' + item['payload'] = payload + item2 = pubsub.Item() + item2['id'] = 'asdf2' + item2['payload'] = payload2 + iq['pubsub']['items'].append(item) + iq['pubsub']['items'].append(item2) + self.checkIq(iq, """ + + + + + + + + + + + + + + + + + + """) - def testItemsEvent(self): - """Testing multiple message/pubsub_event/items/item""" - msg = self.ps.Message() - item = self.ps.EventItem() - item2 = self.ps.EventItem() - pl = ET.Element('{http://netflint.net/protocol/test}test', {'failed':'3', 'passed':'24'}) - pl2 = ET.Element('{http://netflint.net/protocol/test-other}test', {'total':'27', 'failed':'3'}) - item2['payload'] = pl2 - item['payload'] = pl - item['id'] = 'abc123' - item2['id'] = '123abc' - msg['pubsub_event']['items'].append(item) - msg['pubsub_event']['items'].append(item2) - msg['pubsub_event']['items']['node'] = 'cheese' - msg['type'] = 'normal' - xmlstring = """""" - msg2 = self.ps.Message(None, self.ps.ET.fromstring(xmlstring)) - msg3 = self.ps.Message() - msg3.setValues(msg2.getValues()) - self.failUnless(xmlstring == str(msg) == str(msg2) == str(msg3)) + def testCreate(self): + "Testing iq/pubsub/create&configure stanzas" + iq = self.Iq() + iq['pubsub']['create']['node'] = 'mynode' + iq['pubsub']['configure']['form'].addField('pubsub#title', + ftype='text-single', + value='This thing is awesome') + self.checkIq(iq, """ + + + + + + + This thing is awesome + + + + + """) - def testItemsEvent(self): - """Testing message/pubsub_event/items/item & retract mix""" - msg = self.ps.Message() - item = self.ps.EventItem() - item2 = self.ps.EventItem() - pl = ET.Element('{http://netflint.net/protocol/test}test', {'failed':'3', 'passed':'24'}) - pl2 = ET.Element('{http://netflint.net/protocol/test-other}test', {'total':'27', 'failed':'3'}) - item2['payload'] = pl2 - retract = self.ps.EventRetract() - retract['id'] = 'aabbcc' - item['payload'] = pl - item['id'] = 'abc123' - item2['id'] = '123abc' - msg['pubsub_event']['items'].append(item) - msg['pubsub_event']['items'].append(retract) - msg['pubsub_event']['items'].append(item2) - msg['pubsub_event']['items']['node'] = 'cheese' - msg['type'] = 'normal' - xmlstring = """""" - msg2 = self.ps.Message(None, self.ps.ET.fromstring(xmlstring)) - msg3 = self.ps.Message() - msg3.setValues(msg2.getValues()) - self.failUnless(xmlstring == str(msg) == str(msg2) == str(msg3)) - - def testCollectionAssociate(self): - """Testing message/pubsub_event/collection/associate""" - msg = self.ps.Message() - msg['pubsub_event']['collection']['associate']['node'] = 'cheese' - msg['pubsub_event']['collection']['node'] = 'cheeseburger' - msg['type'] = 'headline' - xmlstring = """""" - msg2 = self.ps.Message(None, self.ps.ET.fromstring(xmlstring)) - msg3 = self.ps.Message() - msg3.setValues(msg2.getValues()) - self.failUnless(xmlstring == str(msg) == str(msg2) == str(msg3)) + def testState(self): + "Testing iq/psstate stanzas" + iq = self.Iq() + iq['psstate']['node']= 'mynode' + iq['psstate']['item']= 'myitem' + pl = ET.Element('{http://andyet.net/protocol/pubsubqueue}claimed') + iq['psstate']['payload'] = pl + self.checkIq(iq, """ + + + + + """) - def testCollectionDisassociate(self): - """Testing message/pubsub_event/collection/disassociate""" - msg = self.ps.Message() - msg['pubsub_event']['collection']['disassociate']['node'] = 'cheese' - msg['pubsub_event']['collection']['node'] = 'cheeseburger' - msg['type'] = 'headline' - xmlstring = """""" - msg2 = self.ps.Message(None, self.ps.ET.fromstring(xmlstring)) - msg3 = self.ps.Message() - msg3.setValues(msg2.getValues()) - self.failUnless(xmlstring == str(msg) == str(msg2) == str(msg3)) + def testDefault(self): + "Testing iq/pubsub_owner/default stanzas" + iq = self.Iq() + iq['pubsub_owner']['default'] + iq['pubsub_owner']['default']['node'] = 'mynode' + iq['pubsub_owner']['default']['type'] = 'leaf' + iq['pubsub_owner']['default']['form'].addField('pubsub#title', + ftype='text-single', + value='This thing is awesome') + self.checkIq(iq, """ + + + + + + This thing is awesome + + + + + """, use_values=False) - def testEventConfiguration(self): - """Testing message/pubsub_event/configuration/config""" - msg = self.ps.Message() - from sleekxmpp.plugins import xep_0004 - form = xep_0004.Form() - form.addField('pubsub#title', ftype='text-single', value='This thing is awesome') - msg['pubsub_event']['configuration']['node'] = 'cheese' - msg['pubsub_event']['configuration']['config'] = form - msg['type'] = 'headline' - xmlstring = """This thing is awesome""" - msg2 = self.ps.Message(None, self.ps.ET.fromstring(xmlstring)) - msg3 = self.ps.Message() - msg3.setValues(msg2.getValues()) - self.failUnless(xmlstring == str(msg) == str(msg2) == str(msg3)) - - def testEventPurge(self): - """Testing message/pubsub_event/purge""" - msg = self.ps.Message() - msg['pubsub_event']['purge']['node'] = 'pickles' - msg['type'] = 'headline' - xmlstring = """""" - msg2 = self.ps.Message(None, self.ps.ET.fromstring(xmlstring)) - msg3 = self.ps.Message() - msg3.setValues(msg2.getValues()) - self.failUnless(xmlstring == str(msg) == str(msg2) == str(msg3)) + def testSubscribe(self): + "Testing iq/pubsub/subscribe stanzas" + iq = self.Iq() + iq['pubsub']['subscribe']['options'] + iq['pubsub']['subscribe']['node'] = 'cheese' + iq['pubsub']['subscribe']['jid'] = 'fritzy@netflint.net/sleekxmpp' + iq['pubsub']['subscribe']['options']['node'] = 'cheese' + iq['pubsub']['subscribe']['options']['jid'] = 'fritzy@netflint.net/sleekxmpp' + form = xep_0004.Form() + form.addField('pubsub#title', ftype='text-single', value='This thing is awesome') + iq['pubsub']['subscribe']['options']['options'] = form + self.checkIq(iq, """ + + + + + + + This thing is awesome + + + + + + """, use_values=False) + + def testPublish(self): + "Testing iq/pubsub/publish stanzas" + iq = self.Iq() + iq['pubsub']['publish']['node'] = 'thingers' + payload = ET.fromstring(""" + + + + """) + payload2 = ET.fromstring(""" + + + + """) + item = pubsub.Item() + item['id'] = 'asdf' + item['payload'] = payload + item2 = pubsub.Item() + item2['id'] = 'asdf2' + item2['payload'] = payload2 + iq['pubsub']['publish'].append(item) + iq['pubsub']['publish'].append(item2) - def testEventSubscription(self): - """Testing message/pubsub_event/subscription""" - msg = self.ps.Message() - msg['pubsub_event']['subscription']['node'] = 'pickles' - msg['pubsub_event']['subscription']['jid'] = 'fritzy@netflint.net/test' - msg['pubsub_event']['subscription']['subid'] = 'aabb1122' - msg['pubsub_event']['subscription']['subscription'] = 'subscribed' - msg['pubsub_event']['subscription']['expiry'] = 'presence' - msg['type'] = 'headline' - xmlstring = """""" - msg2 = self.ps.Message(None, self.ps.ET.fromstring(xmlstring)) - msg3 = self.ps.Message() - msg3.setValues(msg2.getValues()) - self.failUnless(xmlcompare.comparemany([xmlstring, str(msg), str(msg2), str(msg3)])) + self.checkIq(iq, """ + + + + + + + + + + + + + + + + + + """) + + def testDelete(self): + "Testing iq/pubsub_owner/delete stanzas" + iq = self.Iq() + iq['pubsub_owner']['delete']['node'] = 'thingers' + self.checkIq(iq, """ + + + + + """) + + def testCreateConfigGet(self): + """Testing getting config from full create""" + iq = self.Iq() + iq['to'] = 'pubsub.asdf' + iq['from'] = 'fritzy@asdf/87292ede-524d-4117-9076-d934ed3db8e7' + iq['type'] = 'set' + iq['id'] = 'E' + + pub = iq['pubsub'] + pub['create']['node'] = 'testnode2' + pub['configure']['form']['type'] = 'submit' + pub['configure']['form'].setFields([ + ('FORM_TYPE', {'type': 'hidden', + 'value': 'http://jabber.org/protocol/pubsub#node_config'}), + ('pubsub#node_type', {'type': 'list-single', + 'label': 'Select the node type', + 'value': 'leaf'}), + ('pubsub#title', {'type': 'text-single', + 'label': 'A friendly name for the node'}), + ('pubsub#deliver_notifications', {'type': 'boolean', + 'label': 'Deliver event notifications', + 'value': True}), + ('pubsub#deliver_payloads', {'type': 'boolean', + 'label': 'Deliver payloads with event notifications', + 'value': True}), + ('pubsub#notify_config', {'type': 'boolean', + 'label': 'Notify subscribers when the node configuration changes'}), + ('pubsub#notify_delete', {'type': 'boolean', + 'label': 'Notify subscribers when the node is deleted'}), + ('pubsub#notify_retract', {'type': 'boolean', + 'label': 'Notify subscribers when items are removed from the node', + 'value': True}), + ('pubsub#notify_sub', {'type': 'boolean', + 'label': 'Notify owners about new subscribers and unsubscribes'}), + ('pubsub#persist_items', {'type': 'boolean', + 'label': 'Persist items in storage'}), + ('pubsub#max_items', {'type': 'text-single', + 'label': 'Max # of items to persist', + 'value': '10'}), + ('pubsub#subscribe', {'type': 'boolean', + 'label': 'Whether to allow subscriptions', + 'value': True}), + ('pubsub#access_model', {'type': 'list-single', + 'label': 'Specify the subscriber model', + 'value': 'open'}), + ('pubsub#publish_model', {'type': 'list-single', + 'label': 'Specify the publisher model', + 'value': 'publishers'}), + ('pubsub#send_last_published_item', {'type': 'list-single', + 'label': 'Send last published item', + 'value': 'never'}), + ('pubsub#presence_based_delivery', {'type': 'boolean', + 'label': 'Deliver notification only to available users'}), + ]) + + self.checkIq(iq, """ + + + + + + + http://jabber.org/protocol/pubsub#node_config + + + leaf + + + + 1 + + + 1 + + + + + 1 + + + + + 10 + + + 1 + + + open + + + publishers + + + never + + + + + + """) + + def testItemEvent(self): + """Testing message/pubsub_event/items/item""" + msg = self.Message() + item = pubsub.EventItem() + pl = ET.Element('{http://netflint.net/protocol/test}test', {'failed':'3', 'passed':'24'}) + item['payload'] = pl + item['id'] = 'abc123' + msg['pubsub_event']['items'].append(item) + msg['pubsub_event']['items']['node'] = 'cheese' + msg['type'] = 'normal' + self.checkMessage(msg, """ + + + + + + + + + """) + + def testItemsEvent(self): + """Testing multiple message/pubsub_event/items/item""" + msg = self.Message() + item = pubsub.EventItem() + item2 = pubsub.EventItem() + pl = ET.Element('{http://netflint.net/protocol/test}test', {'failed':'3', 'passed':'24'}) + pl2 = ET.Element('{http://netflint.net/protocol/test-other}test', {'total':'27', 'failed':'3'}) + item2['payload'] = pl2 + item['payload'] = pl + item['id'] = 'abc123' + item2['id'] = '123abc' + msg['pubsub_event']['items'].append(item) + msg['pubsub_event']['items'].append(item2) + msg['pubsub_event']['items']['node'] = 'cheese' + msg['type'] = 'normal' + self.checkMessage(msg, """ + + + + + + + + + + + + """) + + def testItemsEvent(self): + """Testing message/pubsub_event/items/item & retract mix""" + msg = self.Message() + item = pubsub.EventItem() + item2 = pubsub.EventItem() + pl = ET.Element('{http://netflint.net/protocol/test}test', {'failed':'3', 'passed':'24'}) + pl2 = ET.Element('{http://netflint.net/protocol/test-other}test', {'total':'27', 'failed':'3'}) + item2['payload'] = pl2 + retract = pubsub.EventRetract() + retract['id'] = 'aabbcc' + item['payload'] = pl + item['id'] = 'abc123' + item2['id'] = '123abc' + msg['pubsub_event']['items'].append(item) + msg['pubsub_event']['items'].append(retract) + msg['pubsub_event']['items'].append(item2) + msg['pubsub_event']['items']['node'] = 'cheese' + msg['type'] = 'normal' + self.checkMessage(msg, """ + + + + + + + + + + + + """) + + def testCollectionAssociate(self): + """Testing message/pubsub_event/collection/associate""" + msg = self.Message() + msg['pubsub_event']['collection']['associate']['node'] = 'cheese' + msg['pubsub_event']['collection']['node'] = 'cheeseburger' + msg['type'] = 'headline' + self.checkMessage(msg, """ + + + + + + + """) + + def testCollectionDisassociate(self): + """Testing message/pubsub_event/collection/disassociate""" + msg = self.Message() + msg['pubsub_event']['collection']['disassociate']['node'] = 'cheese' + msg['pubsub_event']['collection']['node'] = 'cheeseburger' + msg['type'] = 'headline' + self.checkMessage(msg, """ + + + + + + + """) + + def testEventConfiguration(self): + """Testing message/pubsub_event/configuration/config""" + msg = self.Message() + msg['pubsub_event']['configuration']['node'] = 'cheese' + msg['pubsub_event']['configuration']['form'].addField('pubsub#title', + ftype='text-single', + value='This thing is awesome') + msg['type'] = 'headline' + self.checkMessage(msg, """ + + + + + + This thing is awesome + + + + + """) + + def testEventPurge(self): + """Testing message/pubsub_event/purge""" + msg = self.Message() + msg['pubsub_event']['purge']['node'] = 'pickles' + msg['type'] = 'headline' + self.checkMessage(msg, """ + + + + + """) + + def testEventSubscription(self): + """Testing message/pubsub_event/subscription""" + msg = self.Message() + msg['pubsub_event']['subscription']['node'] = 'pickles' + msg['pubsub_event']['subscription']['jid'] = 'fritzy@netflint.net/test' + msg['pubsub_event']['subscription']['subid'] = 'aabb1122' + msg['pubsub_event']['subscription']['subscription'] = 'subscribed' + msg['pubsub_event']['subscription']['expiry'] = 'presence' + msg['type'] = 'headline' + self.checkMessage(msg, """ + + + + + """) -suite = unittest.TestLoader().loadTestsFromTestCase(testpubsubstanzas) +suite = unittest.TestLoader().loadTestsFromTestCase(TestPubsubStanzas) -- cgit v1.2.3 From 5c9b47afbdb79229d66378f9b9e1a601a3d58327 Mon Sep 17 00:00:00 2001 From: Lance Stout Date: Tue, 20 Jul 2010 12:22:25 -0400 Subject: Update test_events to use SleekTest to make everything consistent. --- tests/test_events.py | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) (limited to 'tests') diff --git a/tests/test_events.py b/tests/test_events.py index 11821dbb..8f391e1d 100644 --- a/tests/test_events.py +++ b/tests/test_events.py @@ -1,14 +1,11 @@ -import unittest +import sleekxmpp +from sleektest import * -class testevents(unittest.TestCase): - def setUp(self): - import sleekxmpp.stanza.presence as p - self.p = p +class TestEvents(SleekTest): def testEventHappening(self): "Test handler working" - import sleekxmpp c = sleekxmpp.ClientXMPP('crap@wherever', 'password') happened = [] def handletestevent(event): @@ -20,7 +17,6 @@ class testevents(unittest.TestCase): def testDelEvent(self): "Test handler working, then deleted and not triggered" - import sleekxmpp c = sleekxmpp.ClientXMPP('crap@wherever', 'password') happened = [] def handletestevent(event): @@ -32,4 +28,4 @@ class testevents(unittest.TestCase): self.failUnless(happened == [True], "event did not get triggered the correct number of times") -suite = unittest.TestLoader().loadTestsFromTestCase(testevents) +suite = unittest.TestLoader().loadTestsFromTestCase(TestEvents) -- cgit v1.2.3 From 2cb82afc2cd35051a89c5d843f13bbf0132e2003 Mon Sep 17 00:00:00 2001 From: Nathan Fritz Date: Mon, 26 Jul 2010 18:13:09 -0700 Subject: updated and moved jid class -- jids now have setters --- tests/test_jid.py | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) create mode 100644 tests/test_jid.py (limited to 'tests') diff --git a/tests/test_jid.py b/tests/test_jid.py new file mode 100644 index 00000000..8b4c9761 --- /dev/null +++ b/tests/test_jid.py @@ -0,0 +1,26 @@ +from sleektest import * +from sleekxmpp.xmlstream.jid import JID + +class TestJIDClass(SleekTest): + def testJIDfromfull(self): + j = JID('user@someserver/some/resource') + self.assertEqual(j.user, 'user', "User does not match") + self.assertEqual(j.domain, 'someserver', "Domain does not match") + self.assertEqual(j.resource, 'some/resource', "Resource does not match") + self.assertEqual(j.bare, 'user@someserver', "Bare does not match") + self.assertEqual(j.full, 'user@someserver/some/resource', "Full does not match") + self.assertEqual(str(j), 'user@someserver/some/resource', "String does not match") + + def testJIDchange(self): + j = JID('user1@someserver1/some1/resource1') + j.user = 'user' + j.domain = 'someserver' + j.resource = 'some/resource' + self.assertEqual(j.user, 'user', "User does not match") + self.assertEqual(j.domain, 'someserver', "Domain does not match") + self.assertEqual(j.resource, 'some/resource', "Resource does not match") + self.assertEqual(j.bare, 'user@someserver', "Bare does not match") + self.assertEqual(j.full, 'user@someserver/some/resource', "Full does not match") + self.assertEqual(str(j), 'user@someserver/some/resource', "String does not match") + +suite = unittest.TestLoader().loadTestsFromTestCase(TestJIDClass) -- cgit v1.2.3 From aad185fe29f0dd92388875fa2b64120057de2ea5 Mon Sep 17 00:00:00 2001 From: Lance Stout Date: Mon, 26 Jul 2010 21:38:23 -0400 Subject: Update test to reflect change in reply() method that removes the from attribute. --- tests/test_stream.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'tests') diff --git a/tests/test_stream.py b/tests/test_stream.py index eb4aaa59..c2f2667e 100644 --- a/tests/test_stream.py +++ b/tests/test_stream.py @@ -26,7 +26,7 @@ class TestStreamTester(SleekTest): """) self.streamSendMessage(""" - + Thanks for sending: Hi! """) -- cgit v1.2.3 From a96a046e27289d733eabe0cb1b902e679da5d4ca Mon Sep 17 00:00:00 2001 From: Lance Stout Date: Thu, 29 Jul 2010 23:15:49 -0400 Subject: Remove extra debugging lines and speed up stream testing in SleekTest. --- tests/sleektest.py | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) (limited to 'tests') diff --git a/tests/sleektest.py b/tests/sleektest.py index f89966ec..71ff105d 100644 --- a/tests/sleektest.py +++ b/tests/sleektest.py @@ -128,10 +128,7 @@ class SleekTest(unittest.TestCase): if xml.attrib.get('type', None) is None: xml.attrib['type'] = 'normal' msg2['type'] = msg2['type'] - debug += ">>>>Given Stanza:\n%s\n" % ET.tostring(msg.xml) debug += "XML String:\n%s\n" % ET.tostring(xml) - debug += ">>>>Constructed Stanza:\n%s\n" % ET.tostring(msg2.xml) - values = msg2.getStanzaValues() msg3 = self.Message() @@ -234,25 +231,25 @@ class SleekTest(unittest.TestCase): self.xmpp.process(threaded=True) if skip: # Clear startup stanzas - self.xmpp.socket.nextSent(timeout=0.1) + self.xmpp.socket.nextSent(timeout=0.01) def streamRecv(self, data): data = str(data) self.xmpp.socket.recvData(data) - def streamSendMessage(self, data, use_values=True, timeout=.5): + def streamSendMessage(self, data, use_values=True, timeout=.1): if isinstance(data, str): data = self.Message(xml=ET.fromstring(data)) - sent = self.xmpp.socket.nextSent(timeout=1) + sent = self.xmpp.socket.nextSent(timeout) self.checkMessage(data, sent, use_values) - def streamSendIq(self, data, use_values=True, timeout=.5): + def streamSendIq(self, data, use_values=True, timeout=.1): if isinstance(data, str): data = self.Iq(xml=ET.fromstring(data)) sent = self.xmpp.socket.nextSent(timeout) self.checkIq(data, sent, use_values) - def streamSendPresence(self, data, use_values=True, timeout=.5): + def streamSendPresence(self, data, use_values=True, timeout=.1): if isinstance(data, str): data = self.Presence(xml=ET.fromstring(data)) sent = self.xmpp.socket.nextSent(timeout) -- cgit v1.2.3 From 1da3e5b35eb59909d4d6903b1c0190a7aad98a30 Mon Sep 17 00:00:00 2001 From: Lance Stout Date: Thu, 29 Jul 2010 23:55:13 -0400 Subject: Added unit tests for error stanzas. Corrected error in deleting conditions. --- tests/test_errorstanzas.py | 56 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 56 insertions(+) create mode 100644 tests/test_errorstanzas.py (limited to 'tests') diff --git a/tests/test_errorstanzas.py b/tests/test_errorstanzas.py new file mode 100644 index 00000000..788d6c12 --- /dev/null +++ b/tests/test_errorstanzas.py @@ -0,0 +1,56 @@ +from sleektest import * + +class TestErrorStanzas(SleekTest): + + def testSetup(self): + """Test setting initial values in error stanza.""" + msg = self.Message() + msg.enable('error') + self.checkMessage(msg, """ + + + + + + """) + + def testCondition(self): + """Test modifying the error condition.""" + msg = self.Message() + msg['error']['condition'] = 'item-not-found' + + self.checkMessage(msg, """ + + + + + + """) + + self.failUnless(msg['error']['condition'] == 'item-not-found', "Error condition doesn't match.") + + del msg['error']['condition'] + + self.checkMessage(msg, """ + + + + """) + + def testDelCondition(self): + """Test that deleting error conditions doesn't remove extra elements.""" + msg = self.Message() + msg['error']['text'] = 'Error!' + msg['error']['condition'] = 'internal-server-error' + + del msg['error']['condition'] + + self.checkMessage(msg, """ + + + Error! + + + """) + +suite = unittest.TestLoader().loadTestsFromTestCase(TestErrorStanzas) -- cgit v1.2.3 From cbed8029bad691f8353854dc264f83303a196a09 Mon Sep 17 00:00:00 2001 From: Lance Stout Date: Thu, 29 Jul 2010 23:58:25 -0400 Subject: Updated, cleaned, and documented Iq stanza class. Also added unit tests. --- tests/test_iqstanzas.py | 93 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 93 insertions(+) create mode 100644 tests/test_iqstanzas.py (limited to 'tests') diff --git a/tests/test_iqstanzas.py b/tests/test_iqstanzas.py new file mode 100644 index 00000000..9ae59297 --- /dev/null +++ b/tests/test_iqstanzas.py @@ -0,0 +1,93 @@ +from sleektest import * +from sleekxmpp.xmlstream.stanzabase import ET + + +class TestIqStanzas(SleekTest): + + def setUp(self): + """Start XML stream for testing.""" + self.streamStart() + + def tearDown(self): + """Shutdown the XML stream after testing.""" + self.streamClose() + + def testSetup(self): + """Test initializing default Iq values.""" + iq = self.Iq() + self.checkIq(iq, """ + + """) + + def testPayload(self): + """Test setting Iq stanza payload.""" + iq = self.Iq() + iq.setPayload(ET.Element('{test}tester')) + self.checkIq(iq, """ + + + + """, use_values=False) + + + def testUnhandled(self): + """Test behavior for Iq.unhandled.""" + self.streamRecv(""" + + + + """) + + iq = self.Iq() + iq['id'] = 'test' + iq['error']['condition'] = 'feature-not-implemented' + iq['error']['text'] = 'No handlers registered for this request.' + + self.streamSendIq(iq, """ + + + + + No handlers registered for this request. + + + + """) + + def testQuery(self): + """Test modifying query element of Iq stanzas.""" + iq = self.Iq() + + iq['query'] = 'query_ns' + self.checkIq(iq, """ + + + + """) + + iq['query'] = 'query_ns2' + self.checkIq(iq, """ + + + + """) + + self.failUnless(iq['query'] == 'query_ns2', "Query namespace doesn't match") + + del iq['query'] + self.checkIq(iq, """ + + """) + + def testReply(self): + """Test setting proper result type in Iq replies.""" + iq = self.Iq() + iq['to'] = 'user@localhost' + iq['type'] = 'get' + iq.reply() + + self.checkIq(iq, """ + + """) + +suite = unittest.TestLoader().loadTestsFromTestCase(TestIqStanzas) -- cgit v1.2.3 From 939ae298c2856f095526a9e0f52216e9dc4e7db1 Mon Sep 17 00:00:00 2001 From: Lance Stout Date: Tue, 3 Aug 2010 12:19:45 -0400 Subject: Updated message stanzas and tests with documentation and PEP8 style. --- tests/test_messagestanzas.py | 73 ++++++++++++++++++++++---------------------- 1 file changed, 37 insertions(+), 36 deletions(-) (limited to 'tests') diff --git a/tests/test_messagestanzas.py b/tests/test_messagestanzas.py index c83b59a7..f55211db 100644 --- a/tests/test_messagestanzas.py +++ b/tests/test_messagestanzas.py @@ -2,44 +2,45 @@ from sleektest import * from sleekxmpp.stanza.message import Message from sleekxmpp.stanza.htmlim import HTMLIM + class TestMessageStanzas(SleekTest): - def setUp(self): - registerStanzaPlugin(Message, HTMLIM) - - def testGroupchatReplyRegression(self): - "Regression groupchat reply should be to barejid" - msg = self.Message() - msg['to'] = 'me@myserver.tld' - msg['from'] = 'room@someservice.someserver.tld/somenick' - msg['type'] = 'groupchat' - msg['body'] = "this is a message" - msg.reply() - self.failUnless(str(msg['to']) == 'room@someservice.someserver.tld') + def setUp(self): + registerStanzaPlugin(Message, HTMLIM) + + def testGroupchatReplyRegression(self): + "Regression groupchat reply should be to barejid" + msg = self.Message() + msg['to'] = 'me@myserver.tld' + msg['from'] = 'room@someservice.someserver.tld/somenick' + msg['type'] = 'groupchat' + msg['body'] = "this is a message" + msg.reply() + self.failUnless(str(msg['to']) == 'room@someservice.someserver.tld') + + def testAttribProperty(self): + "Test attrib property returning self" + msg = self.Message() + msg.attrib.attrib.attrib['to'] = 'usr@server.tld' + self.failUnless(str(msg['to']) == 'usr@server.tld') - def testAttribProperty(self): - "Test attrib property returning self" - msg = self.Message() - msg.attrib.attrib.attrib['to'] = 'usr@server.tld' - self.failUnless(str(msg['to']) == 'usr@server.tld') - - def testHTMLPlugin(self): - "Test message/html/html stanza" - msg = self.Message() - msg['to'] = "fritzy@netflint.net/sleekxmpp" - msg['body'] = "this is the plaintext message" - msg['type'] = 'chat' - p = ET.Element('{http://www.w3.org/1999/xhtml}p') - p.text = "This is the htmlim message" - msg['html']['html'] = p - self.checkMessage(msg, """ - - this is the plaintext message - - -

This is the htmlim message

- - -
""") + def testHTMLPlugin(self): + "Test message/html/html stanza" + msg = self.Message() + msg['to'] = "fritzy@netflint.net/sleekxmpp" + msg['body'] = "this is the plaintext message" + msg['type'] = 'chat' + p = ET.Element('{http://www.w3.org/1999/xhtml}p') + p.text = "This is the htmlim message" + msg['html']['html'] = p + self.checkMessage(msg, """ + + this is the plaintext message + + +

This is the htmlim message

+ + +
""") suite = unittest.TestLoader().loadTestsFromTestCase(TestMessageStanzas) -- cgit v1.2.3 From 41ab2b84604849d0e650ecd833554b3488733785 Mon Sep 17 00:00:00 2001 From: Lance Stout Date: Tue, 3 Aug 2010 17:30:34 -0400 Subject: Updated presence stanza with documentation and PEP8 style. --- tests/test_presencestanzas.py | 96 ++++++++++++++++++++++--------------------- 1 file changed, 50 insertions(+), 46 deletions(-) (limited to 'tests') diff --git a/tests/test_presencestanzas.py b/tests/test_presencestanzas.py index 02799c8f..2cab3af7 100644 --- a/tests/test_presencestanzas.py +++ b/tests/test_presencestanzas.py @@ -2,52 +2,56 @@ import sleekxmpp from sleektest import * from sleekxmpp.stanza.presence import Presence + class TestPresenceStanzas(SleekTest): - - def testPresenceShowRegression(self): - """Regression check presence['type'] = 'dnd' show value working""" - p = self.Presence() - p['type'] = 'dnd' - self.checkPresence(p, """ - dnd - """) - - def testPresenceType(self): - """Test manipulating presence['type']""" - p = self.Presence() - p['type'] = 'available' - self.checkPresence(p, """ - - """) - self.failUnless(p['type'] == 'available', "Incorrect presence['type'] for type 'available'") - - for showtype in ['away', 'chat', 'dnd', 'xa']: - p['type'] = showtype - self.checkPresence(p, """ - %s - """ % showtype) - self.failUnless(p['type'] == showtype, "Incorrect presence['type'] for type '%s'" % showtype) - - p['type'] = None - self.checkPresence(p, """ - - """) - - def testPresenceUnsolicitedOffline(self): - """Unsolicted offline presence does not spawn changed_status or update roster""" - p = self.Presence() - p['type'] = 'unavailable' - p['from'] = 'bill@chadmore.com/gmail15af' - - c = sleekxmpp.ClientXMPP('crap@wherever', 'password') - happened = [] - def handlechangedpresence(event): - happened.append(True) - c.add_event_handler("changed_status", handlechangedpresence) - c._handlePresence(p) - - self.failUnless(happened == [], "changed_status event triggered for superfulous unavailable presence") - self.failUnless(c.roster == {}, "Roster updated for superfulous unavailable presence") - + + def testPresenceShowRegression(self): + """Regression check presence['type'] = 'dnd' show value working""" + p = self.Presence() + p['type'] = 'dnd' + self.checkPresence(p, "dnd") + + def testPresenceType(self): + """Test manipulating presence['type']""" + p = self.Presence() + p['type'] = 'available' + self.checkPresence(p, "") + self.failUnless(p['type'] == 'available', + "Incorrect presence['type'] for type 'available'") + + for showtype in ['away', 'chat', 'dnd', 'xa']: + p['type'] = showtype + self.checkPresence(p, """ + %s + """ % showtype) + self.failUnless(p['type'] == showtype, + "Incorrect presence['type'] for type '%s'" % showtype) + + p['type'] = None + self.checkPresence(p, "") + + def testPresenceUnsolicitedOffline(self): + """ + Unsolicted offline presence does not spawn changed_status + or update the roster. + """ + p = self.Presence() + p['type'] = 'unavailable' + p['from'] = 'bill@chadmore.com/gmail15af' + + c = sleekxmpp.ClientXMPP('crap@wherever', 'password') + happened = [] + + def handlechangedpresence(event): + happened.append(True) + + c.add_event_handler("changed_status", handlechangedpresence) + c._handlePresence(p) + + self.failUnless(happened == [], + "changed_status event triggered for extra unavailable presence") + self.failUnless(c.roster == {}, + "Roster updated for superfulous unavailable presence") + suite = unittest.TestLoader().loadTestsFromTestCase(TestPresenceStanzas) -- cgit v1.2.3 From 183a3f1b87a8f5a6c4e174dec6de513a0bb5cb83 Mon Sep 17 00:00:00 2001 From: Lance Stout Date: Tue, 3 Aug 2010 17:58:18 -0400 Subject: Updated XHTML-IM stanza with documentation and PEP8 style. --- tests/test_messagestanzas.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'tests') diff --git a/tests/test_messagestanzas.py b/tests/test_messagestanzas.py index f55211db..5e2a667a 100644 --- a/tests/test_messagestanzas.py +++ b/tests/test_messagestanzas.py @@ -32,7 +32,7 @@ class TestMessageStanzas(SleekTest): msg['type'] = 'chat' p = ET.Element('{http://www.w3.org/1999/xhtml}p') p.text = "This is the htmlim message" - msg['html']['html'] = p + msg['html']['body'] = p self.checkMessage(msg, """ this is the plaintext message -- cgit v1.2.3 From 956fdf69709af8f59b92c0fe5e77490f2c670648 Mon Sep 17 00:00:00 2001 From: Lance Stout Date: Tue, 3 Aug 2010 18:31:22 -0400 Subject: Fix whitespace issues, and make some debugging statements clearer. --- tests/sleektest.py | 51 ++++++++++++++++++++++++++------------------------- 1 file changed, 26 insertions(+), 25 deletions(-) (limited to 'tests') diff --git a/tests/sleektest.py b/tests/sleektest.py index 71ff105d..cea8df66 100644 --- a/tests/sleektest.py +++ b/tests/sleektest.py @@ -21,7 +21,7 @@ from sleekxmpp.xmlstream.stanzabase import registerStanzaPlugin class TestSocket(object): - + def __init__(self, *args, **kwargs): self.socket = socket.socket(*args, **kwargs) self.recv_queue = queue.Queue() @@ -104,10 +104,10 @@ class SleekTest(unittest.TestCase): def checkMessage(self, msg, xml_string, use_values=True): """ - Create and compare several message stanza objects to a - correct XML string. + Create and compare several message stanza objects to a + correct XML string. - If use_values is False, the test using getValues() and + If use_values is False, the test using getValues() and setValues() will not be used. """ @@ -118,10 +118,10 @@ class SleekTest(unittest.TestCase): self.fix_namespaces(xml, 'jabber:client') debug += "XML String:\n%s\n" % ET.tostring(xml) - + msg2 = self.Message(xml) debug += "Constructed Stanza:\n%s\n" % ET.tostring(msg2.xml) - + if use_values: # Ugly, but need to make sure the type attribute is set. msg['type'] = msg['type'] @@ -133,10 +133,10 @@ class SleekTest(unittest.TestCase): values = msg2.getStanzaValues() msg3 = self.Message() msg3.setStanzaValues(values) - + debug += "Second Constructed Stanza:\n%s\n" % ET.tostring(msg3.xml) debug = "Three methods for creating stanza do not match:\n" + debug - self.failUnless(self.compare([xml, msg.xml, msg2.xml, msg3.xml]), + self.failUnless(self.compare([xml, msg.xml, msg2.xml, msg3.xml]), debug) else: debug = "Two methods for creating stanza do not match:\n" + debug @@ -144,10 +144,10 @@ class SleekTest(unittest.TestCase): def checkIq(self, iq, xml_string, use_values=True): """ - Create and compare several iq stanza objects to a - correct XML string. + Create and compare several iq stanza objects to a + correct XML string. - If use_values is False, the test using getValues() and + If use_values is False, the test using getValues() and setValues() will not be used. """ @@ -157,10 +157,10 @@ class SleekTest(unittest.TestCase): xml = ET.fromstring(xml_string) self.fix_namespaces(xml, 'jabber:client') debug += "XML String:\n%s\n" % ET.tostring(xml) - + iq2 = self.Iq(xml) debug += "Constructed Stanza:\n%s\n" % ET.tostring(iq2.xml) - + if use_values: values = iq.getStanzaValues() iq3 = self.Iq() @@ -168,7 +168,7 @@ class SleekTest(unittest.TestCase): debug += "Second Constructed Stanza:\n%s\n" % ET.tostring(iq3.xml) debug = "Three methods for creating stanza do not match:\n" + debug - self.failUnless(self.compare([xml, iq.xml, iq2.xml, iq3.xml]), + self.failUnless(self.compare([xml, iq.xml, iq2.xml, iq3.xml]), debug) else: debug = "Two methods for creating stanza do not match:\n" + debug @@ -176,27 +176,28 @@ class SleekTest(unittest.TestCase): def checkPresence(self, pres, xml_string, use_values=True): """ - Create and compare several presence stanza objects to a - correct XML string. + Create and compare several presence stanza objects to a + correct XML string. - If use_values is False, the test using getValues() and + If use_values is False, the test using getValues() and setValues() will not be used. """ self.fix_namespaces(pres.xml, 'jabber:client') - debug = "Given Stanza:\n%s\n" % ET.tostring(pres.xml) xml = ET.fromstring(xml_string) self.fix_namespaces(xml, 'jabber:client') - debug += "XML String:\n%s\n" % ET.tostring(xml) - + pres2 = self.Presence(xml) - debug += "Constructed Stanza:\n%s\n" % ET.tostring(pres2.xml) # Ugly, but 'priority' has a default value and need to make # sure it is set pres['priority'] = pres['priority'] pres2['priority'] = pres2['priority'] + debug = "Given Stanza:\n%s\n" % ET.tostring(pres.xml) + debug += "XML String:\n%s\n" % ET.tostring(xml) + debug += "Constructed Stanza:\n%s\n" % ET.tostring(pres2.xml) + if use_values: values = pres.getStanzaValues() pres3 = self.Presence() @@ -204,7 +205,7 @@ class SleekTest(unittest.TestCase): debug += "Second Constructed Stanza:\n%s\n" % ET.tostring(pres3.xml) debug = "Three methods for creating stanza do not match:\n" + debug - self.failUnless(self.compare([xml, pres.xml, pres2.xml, pres3.xml]), + self.failUnless(self.compare([xml, pres.xml, pres2.xml, pres3.xml]), debug) else: debug = "Two methods for creating stanza do not match:\n" + debug @@ -229,7 +230,7 @@ class SleekTest(unittest.TestCase): self.xmpp.connectTCP = lambda a, b, c, d: True self.xmpp.startTLS = lambda: True self.xmpp.process(threaded=True) - if skip: + if skip: # Clear startup stanzas self.xmpp.socket.nextSent(timeout=0.01) @@ -242,7 +243,7 @@ class SleekTest(unittest.TestCase): data = self.Message(xml=ET.fromstring(data)) sent = self.xmpp.socket.nextSent(timeout) self.checkMessage(data, sent, use_values) - + def streamSendIq(self, data, use_values=True, timeout=.1): if isinstance(data, str): data = self.Iq(xml=ET.fromstring(data)) @@ -265,7 +266,7 @@ class SleekTest(unittest.TestCase): def fix_namespaces(self, xml, ns): """ - Assign a namespace to an element and any children that + Assign a namespace to an element and any children that don't have a namespace. """ if xml.tag.startswith('{'): -- cgit v1.2.3 From fec69be7318d9ad2a8e4ac128ac57f1969a6b852 Mon Sep 17 00:00:00 2001 From: Lance Stout Date: Tue, 3 Aug 2010 18:32:53 -0400 Subject: Update nick stanza with documentation and PEP8 style. --- tests/test_messagestanzas.py | 13 ++++++++++++- tests/test_presencestanzas.py | 10 ++++++++++ 2 files changed, 22 insertions(+), 1 deletion(-) (limited to 'tests') diff --git a/tests/test_messagestanzas.py b/tests/test_messagestanzas.py index 5e2a667a..9b7b0a3f 100644 --- a/tests/test_messagestanzas.py +++ b/tests/test_messagestanzas.py @@ -25,7 +25,7 @@ class TestMessageStanzas(SleekTest): self.failUnless(str(msg['to']) == 'usr@server.tld') def testHTMLPlugin(self): - "Test message/html/html stanza" + "Test message/html/body stanza" msg = self.Message() msg['to'] = "fritzy@netflint.net/sleekxmpp" msg['body'] = "this is the plaintext message" @@ -43,4 +43,15 @@ class TestMessageStanzas(SleekTest): """) + def testNickPlugin(self): + "Test message/nick/nick stanza." + msg = self.Message() + msg['nick']['nick'] = 'A nickname!' + self.checkMessage(msg, """ + + A nickname! + + """) + + suite = unittest.TestLoader().loadTestsFromTestCase(TestMessageStanzas) diff --git a/tests/test_presencestanzas.py b/tests/test_presencestanzas.py index 2cab3af7..6c11263f 100644 --- a/tests/test_presencestanzas.py +++ b/tests/test_presencestanzas.py @@ -53,5 +53,15 @@ class TestPresenceStanzas(SleekTest): self.failUnless(c.roster == {}, "Roster updated for superfulous unavailable presence") + def testNickPlugin(self): + """Test presence/nick/nick stanza.""" + p = self.Presence() + p['nick']['nick'] = 'A nickname!' + self.checkPresence(p, """ + + A nickname! + + """) + suite = unittest.TestLoader().loadTestsFromTestCase(TestPresenceStanzas) -- cgit v1.2.3 From 58f77d898f82ab108fa17d562a32c68d3ea35306 Mon Sep 17 00:00:00 2001 From: Lance Stout Date: Thu, 5 Aug 2010 20:23:07 -0400 Subject: Updated tests to use a relative import for SleekTest to please Python3. Fixed some tabs/spaces issues. --- tests/test_addresses.py | 203 +++++++++++++++---------------- tests/test_chatstates.py | 76 ++++++------ tests/test_disco.py | 98 +++++++-------- tests/test_errorstanzas.py | 8 +- tests/test_events.py | 2 +- tests/test_forms.py | 20 +-- tests/test_gmail.py | 2 +- tests/test_iqstanzas.py | 22 ++-- tests/test_jid.py | 2 +- tests/test_messagestanzas.py | 2 +- tests/test_presencestanzas.py | 2 +- tests/test_pubsubstanzas.py | 274 +++++++++++++++++++++--------------------- tests/test_stream.py | 2 +- 13 files changed, 357 insertions(+), 356 deletions(-) (limited to 'tests') diff --git a/tests/test_addresses.py b/tests/test_addresses.py index 63d11003..450e1362 100644 --- a/tests/test_addresses.py +++ b/tests/test_addresses.py @@ -1,110 +1,111 @@ -from sleektest import * +from . sleektest import * import sleekxmpp.plugins.xep_0033 as xep_0033 class TestAddresses(SleekTest): - def setUp(self): - registerStanzaPlugin(Message, xep_0033.Addresses) - - def testAddAddress(self): - """Testing adding extended stanza address.""" - msg = self.Message() - msg['addresses'].addAddress(atype='to', jid='to@header1.org') - self.checkMessage(msg, """ - - -
- - - """) - - msg = self.Message() - msg['addresses'].addAddress(atype='replyto', - jid='replyto@header1.org', - desc='Reply address') - self.checkMessage(msg, """ - - -
- - - """) - - def testAddAddresses(self): - """Testing adding multiple extended stanza addresses.""" - - xmlstring = """ - - -
-
-
- - - """ - - msg = self.Message() - msg['addresses'].setAddresses([{'type':'replyto', - 'jid':'replyto@header1.org', - 'desc':'Reply address'}, - {'type':'cc', - 'jid':'cc@header2.org'}, - {'type':'bcc', - 'jid':'bcc@header2.org'}]) - self.checkMessage(msg, xmlstring) - - msg = self.Message() - msg['addresses']['replyto'] = [{'jid':'replyto@header1.org', + def setUp(self): + registerStanzaPlugin(Message, xep_0033.Addresses) + + def testAddAddress(self): + """Testing adding extended stanza address.""" + msg = self.Message() + msg['addresses'].addAddress(atype='to', jid='to@header1.org') + self.checkMessage(msg, """ + + +
+ + + """) + + msg = self.Message() + msg['addresses'].addAddress(atype='replyto', + jid='replyto@header1.org', + desc='Reply address') + self.checkMessage(msg, """ + + +
+ + + """) + + def testAddAddresses(self): + """Testing adding multiple extended stanza addresses.""" + + xmlstring = """ + + +
+
+
+ + + """ + + msg = self.Message() + msg['addresses'].setAddresses([ + {'type':'replyto', + 'jid':'replyto@header1.org', + 'desc':'Reply address'}, + {'type':'cc', + 'jid':'cc@header2.org'}, + {'type':'bcc', + 'jid':'bcc@header2.org'}]) + self.checkMessage(msg, xmlstring) + + msg = self.Message() + msg['addresses']['replyto'] = [{'jid':'replyto@header1.org', 'desc':'Reply address'}] - msg['addresses']['cc'] = [{'jid':'cc@header2.org'}] - msg['addresses']['bcc'] = [{'jid':'bcc@header2.org'}] - self.checkMessage(msg, xmlstring) - - def testAddURI(self): - """Testing adding URI attribute to extended stanza address.""" - - msg = self.Message() - addr = msg['addresses'].addAddress(atype='to', - jid='to@header1.org', - node='foo') - self.checkMessage(msg, """ - - -
- - - """) - - addr['uri'] = 'mailto:to@header2.org' - self.checkMessage(msg, """ - - -
- - - """) - - def testDelivered(self): - """Testing delivered attribute of extended stanza addresses.""" - - xmlstring = """ - - -
- - - """ - - msg = self.Message() - addr = msg['addresses'].addAddress(jid='to@header1.org', atype='to') - self.checkMessage(msg, xmlstring % '') - - addr['delivered'] = True - self.checkMessage(msg, xmlstring % 'delivered="true"') - - addr['delivered'] = False - self.checkMessage(msg, xmlstring % '') + msg['addresses']['cc'] = [{'jid':'cc@header2.org'}] + msg['addresses']['bcc'] = [{'jid':'bcc@header2.org'}] + self.checkMessage(msg, xmlstring) + + def testAddURI(self): + """Testing adding URI attribute to extended stanza address.""" + + msg = self.Message() + addr = msg['addresses'].addAddress(atype='to', + jid='to@header1.org', + node='foo') + self.checkMessage(msg, """ + + +
+ + + """) + + addr['uri'] = 'mailto:to@header2.org' + self.checkMessage(msg, """ + + +
+ + + """) + + def testDelivered(self): + """Testing delivered attribute of extended stanza addresses.""" + + xmlstring = """ + + +
+ + + """ + + msg = self.Message() + addr = msg['addresses'].addAddress(jid='to@header1.org', atype='to') + self.checkMessage(msg, xmlstring % '') + + addr['delivered'] = True + self.checkMessage(msg, xmlstring % 'delivered="true"') + + addr['delivered'] = False + self.checkMessage(msg, xmlstring % '') suite = unittest.TestLoader().loadTestsFromTestCase(TestAddresses) diff --git a/tests/test_chatstates.py b/tests/test_chatstates.py index bcacb9e5..74359df9 100644 --- a/tests/test_chatstates.py +++ b/tests/test_chatstates.py @@ -1,44 +1,44 @@ -from sleektest import * +from . sleektest import * import sleekxmpp.plugins.xep_0085 as xep_0085 class TestChatStates(SleekTest): - def setUp(self): - registerStanzaPlugin(Message, xep_0085.Active) - registerStanzaPlugin(Message, xep_0085.Composing) - registerStanzaPlugin(Message, xep_0085.Gone) - registerStanzaPlugin(Message, xep_0085.Inactive) - registerStanzaPlugin(Message, xep_0085.Paused) - - def testCreateChatState(self): - """Testing creating chat states.""" - - xmlstring = """ - - <%s xmlns="http://jabber.org/protocol/chatstates" /> - - """ - - msg = self.Message() - msg['chat_state'].active() - self.checkMessage(msg, xmlstring % 'active', - use_values=False) - - msg['chat_state'].composing() - self.checkMessage(msg, xmlstring % 'composing', - use_values=False) - - - msg['chat_state'].gone() - self.checkMessage(msg, xmlstring % 'gone', - use_values=False) - - msg['chat_state'].inactive() - self.checkMessage(msg, xmlstring % 'inactive', - use_values=False) - - msg['chat_state'].paused() - self.checkMessage(msg, xmlstring % 'paused', - use_values=False) + def setUp(self): + registerStanzaPlugin(Message, xep_0085.Active) + registerStanzaPlugin(Message, xep_0085.Composing) + registerStanzaPlugin(Message, xep_0085.Gone) + registerStanzaPlugin(Message, xep_0085.Inactive) + registerStanzaPlugin(Message, xep_0085.Paused) + + def testCreateChatState(self): + """Testing creating chat states.""" + + xmlstring = """ + + <%s xmlns="http://jabber.org/protocol/chatstates" /> + + """ + + msg = self.Message() + msg['chat_state'].active() + self.checkMessage(msg, xmlstring % 'active', + use_values=False) + + msg['chat_state'].composing() + self.checkMessage(msg, xmlstring % 'composing', + use_values=False) + + + msg['chat_state'].gone() + self.checkMessage(msg, xmlstring % 'gone', + use_values=False) + + msg['chat_state'].inactive() + self.checkMessage(msg, xmlstring % 'inactive', + use_values=False) + + msg['chat_state'].paused() + self.checkMessage(msg, xmlstring % 'paused', + use_values=False) suite = unittest.TestLoader().loadTestsFromTestCase(TestChatStates) diff --git a/tests/test_disco.py b/tests/test_disco.py index 96a12e2a..2cc50ee0 100644 --- a/tests/test_disco.py +++ b/tests/test_disco.py @@ -1,4 +1,4 @@ -from sleektest import * +from . sleektest import * import sleekxmpp.plugins.xep_0030 as xep_0030 @@ -7,7 +7,7 @@ class TestDisco(SleekTest): def setUp(self): registerStanzaPlugin(Iq, xep_0030.DiscoInfo) registerStanzaPlugin(Iq, xep_0030.DiscoItems) - + def testCreateInfoQueryNoNode(self): """Testing disco#info query with no node.""" iq = self.Iq() @@ -61,7 +61,7 @@ class TestDisco(SleekTest): iq = self.Iq() iq['id'] = "0" iq['disco_info']['node'] = 'foo' - iq['disco_info'].addIdentity('conference', 'text', 'Chatroom') + iq['disco_info'].addIdentity('conference', 'text', 'Chatroom') self.checkIq(iq, """ @@ -76,8 +76,8 @@ class TestDisco(SleekTest): iq = self.Iq() iq['id'] = "0" iq['disco_info']['node'] = 'foo' - iq['disco_info'].addFeature('foo') - iq['disco_info'].addFeature('bar') + iq['disco_info'].addFeature('foo') + iq['disco_info'].addFeature('bar') self.checkIq(iq, """ @@ -93,9 +93,9 @@ class TestDisco(SleekTest): iq = self.Iq() iq['id'] = "0" iq['disco_items']['node'] = 'foo' - iq['disco_items'].addItem('user@localhost') - iq['disco_items'].addItem('user@localhost', 'foo') - iq['disco_items'].addItem('user@localhost', 'bar', 'Testing') + iq['disco_items'].addItem('user@localhost') + iq['disco_items'].addItem('user@localhost', 'foo') + iq['disco_items'].addItem('user@localhost', 'bar', 'Testing') self.checkIq(iq, """ @@ -109,68 +109,68 @@ class TestDisco(SleekTest): def testAddRemoveIdentities(self): """Test adding and removing identities to disco#info stanza""" - ids = [('automation', 'commands', 'AdHoc'), - ('conference', 'text', 'ChatRoom')] + ids = [('automation', 'commands', 'AdHoc'), + ('conference', 'text', 'ChatRoom')] - info = xep_0030.DiscoInfo() - info.addIdentity(*ids[0]) - self.failUnless(info.getIdentities() == [ids[0]]) + info = xep_0030.DiscoInfo() + info.addIdentity(*ids[0]) + self.failUnless(info.getIdentities() == [ids[0]]) - info.delIdentity('automation', 'commands') - self.failUnless(info.getIdentities() == []) + info.delIdentity('automation', 'commands') + self.failUnless(info.getIdentities() == []) - info.setIdentities(ids) - self.failUnless(info.getIdentities() == ids) + info.setIdentities(ids) + self.failUnless(info.getIdentities() == ids) - info.delIdentity('automation', 'commands') - self.failUnless(info.getIdentities() == [ids[1]]) + info.delIdentity('automation', 'commands') + self.failUnless(info.getIdentities() == [ids[1]]) - info.delIdentities() - self.failUnless(info.getIdentities() == []) + info.delIdentities() + self.failUnless(info.getIdentities() == []) def testAddRemoveFeatures(self): """Test adding and removing features to disco#info stanza""" - features = ['foo', 'bar', 'baz'] + features = ['foo', 'bar', 'baz'] - info = xep_0030.DiscoInfo() - info.addFeature(features[0]) - self.failUnless(info.getFeatures() == [features[0]]) + info = xep_0030.DiscoInfo() + info.addFeature(features[0]) + self.failUnless(info.getFeatures() == [features[0]]) - info.delFeature('foo') - self.failUnless(info.getFeatures() == []) + info.delFeature('foo') + self.failUnless(info.getFeatures() == []) - info.setFeatures(features) - self.failUnless(info.getFeatures() == features) + info.setFeatures(features) + self.failUnless(info.getFeatures() == features) - info.delFeature('bar') - self.failUnless(info.getFeatures() == ['foo', 'baz']) + info.delFeature('bar') + self.failUnless(info.getFeatures() == ['foo', 'baz']) - info.delFeatures() - self.failUnless(info.getFeatures() == []) + info.delFeatures() + self.failUnless(info.getFeatures() == []) def testAddRemoveItems(self): """Test adding and removing items to disco#items stanza""" - items = [('user@localhost', None, None), - ('user@localhost', 'foo', None), - ('user@localhost', 'bar', 'Test')] + items = [('user@localhost', None, None), + ('user@localhost', 'foo', None), + ('user@localhost', 'bar', 'Test')] + + info = xep_0030.DiscoItems() + self.failUnless(True, ""+str(items[0])) - info = xep_0030.DiscoItems() - self.failUnless(True, ""+str(items[0])) + info.addItem(*(items[0])) + self.failUnless(info.getItems() == [items[0]], info.getItems()) - info.addItem(*(items[0])) - self.failUnless(info.getItems() == [items[0]], info.getItems()) + info.delItem('user@localhost') + self.failUnless(info.getItems() == []) - info.delItem('user@localhost') - self.failUnless(info.getItems() == []) + info.setItems(items) + self.failUnless(info.getItems() == items) - info.setItems(items) - self.failUnless(info.getItems() == items) + info.delItem('user@localhost', 'foo') + self.failUnless(info.getItems() == [items[0], items[2]]) - info.delItem('user@localhost', 'foo') - self.failUnless(info.getItems() == [items[0], items[2]]) + info.delItems() + self.failUnless(info.getItems() == []) - info.delItems() - self.failUnless(info.getItems() == []) - suite = unittest.TestLoader().loadTestsFromTestCase(TestDisco) diff --git a/tests/test_errorstanzas.py b/tests/test_errorstanzas.py index 788d6c12..d6fafc59 100644 --- a/tests/test_errorstanzas.py +++ b/tests/test_errorstanzas.py @@ -1,7 +1,7 @@ -from sleektest import * +from . sleektest import * class TestErrorStanzas(SleekTest): - + def testSetup(self): """Test setting initial values in error stanza.""" msg = self.Message() @@ -16,7 +16,7 @@ class TestErrorStanzas(SleekTest): def testCondition(self): """Test modifying the error condition.""" - msg = self.Message() + msg = self.Message() msg['error']['condition'] = 'item-not-found' self.checkMessage(msg, """ @@ -42,7 +42,7 @@ class TestErrorStanzas(SleekTest): msg = self.Message() msg['error']['text'] = 'Error!' msg['error']['condition'] = 'internal-server-error' - + del msg['error']['condition'] self.checkMessage(msg, """ diff --git a/tests/test_events.py b/tests/test_events.py index 8f391e1d..bbc5832e 100644 --- a/tests/test_events.py +++ b/tests/test_events.py @@ -1,5 +1,5 @@ import sleekxmpp -from sleektest import * +from . sleektest import * class TestEvents(SleekTest): diff --git a/tests/test_forms.py b/tests/test_forms.py index 7d37506d..d5710633 100644 --- a/tests/test_forms.py +++ b/tests/test_forms.py @@ -1,4 +1,4 @@ -from sleektest import * +from . sleektest import * import sleekxmpp.plugins.xep_0004 as xep_0004 @@ -28,11 +28,11 @@ class TestDataForms(SleekTest): msg = self.Message() form = msg['form'] - form.addField(var='f1', - ftype='text-single', + form.addField(var='f1', + ftype='text-single', label='Text', - desc='A text field', - required=True, + desc='A text field', + required=True, value='Some text!') self.checkMessage(msg, """ @@ -47,8 +47,8 @@ class TestDataForms(SleekTest): """) - form['fields'] = [('f1', {'type': 'text-single', - 'label': 'Username', + form['fields'] = [('f1', {'type': 'text-single', + 'label': 'Username', 'required': True}), ('f2', {'type': 'text-private', 'label': 'Password', @@ -58,7 +58,7 @@ class TestDataForms(SleekTest): 'value': 'Enter message.\nA long one even.'}), ('f4', {'type': 'list-single', 'label': 'Message Type', - 'options': [{'label': 'Cool!', + 'options': [{'label': 'Cool!', 'value': 'cool'}, {'label': 'Urgh!', 'value': 'urgh'}]})] @@ -89,13 +89,13 @@ class TestDataForms(SleekTest): def testSetValues(self): """Testing setting form values""" - + msg = self.Message() form = msg['form'] form.setFields([ ('foo', {'type': 'text-single'}), ('bar', {'type': 'list-multi'})]) - + form.setValues({'foo': 'Foo!', 'bar': ['a', 'b']}) diff --git a/tests/test_gmail.py b/tests/test_gmail.py index b2e70d21..dd256e27 100644 --- a/tests/test_gmail.py +++ b/tests/test_gmail.py @@ -1,4 +1,4 @@ -from sleektest import * +from . sleektest import * import sleekxmpp.plugins.gmail_notify as gmail diff --git a/tests/test_iqstanzas.py b/tests/test_iqstanzas.py index 9ae59297..98a01a26 100644 --- a/tests/test_iqstanzas.py +++ b/tests/test_iqstanzas.py @@ -1,4 +1,4 @@ -from sleektest import * +from . sleektest import * from sleekxmpp.xmlstream.stanzabase import ET @@ -18,7 +18,7 @@ class TestIqStanzas(SleekTest): self.checkIq(iq, """ """) - + def testPayload(self): """Test setting Iq stanza payload.""" iq = self.Iq() @@ -38,10 +38,10 @@ class TestIqStanzas(SleekTest): """) - iq = self.Iq() + iq = self.Iq() iq['id'] = 'test' - iq['error']['condition'] = 'feature-not-implemented' - iq['error']['text'] = 'No handlers registered for this request.' + iq['error']['condition'] = 'feature-not-implemented' + iq['error']['text'] = 'No handlers registered for this request.' self.streamSendIq(iq, """ @@ -72,21 +72,21 @@ class TestIqStanzas(SleekTest): """) - self.failUnless(iq['query'] == 'query_ns2', "Query namespace doesn't match") + self.failUnless(iq['query'] == 'query_ns2', "Query namespace doesn't match") - del iq['query'] - self.checkIq(iq, """ + del iq['query'] + self.checkIq(iq, """ """) def testReply(self): """Test setting proper result type in Iq replies.""" iq = self.Iq() - iq['to'] = 'user@localhost' - iq['type'] = 'get' + iq['to'] = 'user@localhost' + iq['type'] = 'get' iq.reply() - self.checkIq(iq, """ + self.checkIq(iq, """ """) diff --git a/tests/test_jid.py b/tests/test_jid.py index 8b4c9761..cddac424 100644 --- a/tests/test_jid.py +++ b/tests/test_jid.py @@ -1,4 +1,4 @@ -from sleektest import * +from . sleektest import * from sleekxmpp.xmlstream.jid import JID class TestJIDClass(SleekTest): diff --git a/tests/test_messagestanzas.py b/tests/test_messagestanzas.py index 9b7b0a3f..2a1567da 100644 --- a/tests/test_messagestanzas.py +++ b/tests/test_messagestanzas.py @@ -1,4 +1,4 @@ -from sleektest import * +from . sleektest import * from sleekxmpp.stanza.message import Message from sleekxmpp.stanza.htmlim import HTMLIM diff --git a/tests/test_presencestanzas.py b/tests/test_presencestanzas.py index 6c11263f..d6a5a388 100644 --- a/tests/test_presencestanzas.py +++ b/tests/test_presencestanzas.py @@ -1,5 +1,5 @@ import sleekxmpp -from sleektest import * +from . sleektest import * from sleekxmpp.stanza.presence import Presence diff --git a/tests/test_pubsubstanzas.py b/tests/test_pubsubstanzas.py index 794fa03a..cddfd12b 100644 --- a/tests/test_pubsubstanzas.py +++ b/tests/test_pubsubstanzas.py @@ -1,4 +1,4 @@ -from sleektest import * +from . sleektest import * import sleekxmpp.plugins.xep_0004 as xep_0004 import sleekxmpp.plugins.stanza_pubsub as pubsub @@ -25,7 +25,7 @@ class TestPubsubStanzas(SleekTest): """) - + def testSubscriptions(self): "Testing iq/pubsub/subscriptions/subscription stanzas" iq = self.Iq() @@ -38,7 +38,7 @@ class TestPubsubStanzas(SleekTest): sub2['subscription'] = 'subscribed' iq['pubsub']['subscriptions'].append(sub1) iq['pubsub']['subscriptions'].append(sub2) - self.checkIq(iq, """ + self.checkIq(iq, """ @@ -55,7 +55,7 @@ class TestPubsubStanzas(SleekTest): iq['pubsub']['subscription']['node'] = 'testnode alsdkjfas' iq['pubsub']['subscription']['jid'] = "fritzy@netflint.net/sleekxmpp" iq['pubsub']['subscription']['subscription'] = 'unconfigured' - self.checkIq(iq, """ + self.checkIq(iq, """ @@ -88,7 +88,7 @@ class TestPubsubStanzas(SleekTest): item2['payload'] = payload2 iq['pubsub']['items'].append(item) iq['pubsub']['items'].append(item2) - self.checkIq(iq, """ + self.checkIq(iq, """ @@ -112,8 +112,8 @@ class TestPubsubStanzas(SleekTest): "Testing iq/pubsub/create&configure stanzas" iq = self.Iq() iq['pubsub']['create']['node'] = 'mynode' - iq['pubsub']['configure']['form'].addField('pubsub#title', - ftype='text-single', + iq['pubsub']['configure']['form'].addField('pubsub#title', + ftype='text-single', value='This thing is awesome') self.checkIq(iq, """ @@ -131,12 +131,12 @@ class TestPubsubStanzas(SleekTest): def testState(self): "Testing iq/psstate stanzas" - iq = self.Iq() - iq['psstate']['node']= 'mynode' + iq = self.Iq() + iq['psstate']['node']= 'mynode' iq['psstate']['item']= 'myitem' pl = ET.Element('{http://andyet.net/protocol/pubsubqueue}claimed') iq['psstate']['payload'] = pl - self.checkIq(iq, """ + self.checkIq(iq, """ @@ -144,16 +144,16 @@ class TestPubsubStanzas(SleekTest): """) def testDefault(self): - "Testing iq/pubsub_owner/default stanzas" - iq = self.Iq() - iq['pubsub_owner']['default'] - iq['pubsub_owner']['default']['node'] = 'mynode' - iq['pubsub_owner']['default']['type'] = 'leaf' - iq['pubsub_owner']['default']['form'].addField('pubsub#title', - ftype='text-single', + "Testing iq/pubsub_owner/default stanzas" + iq = self.Iq() + iq['pubsub_owner']['default'] + iq['pubsub_owner']['default']['node'] = 'mynode' + iq['pubsub_owner']['default']['type'] = 'leaf' + iq['pubsub_owner']['default']['form'].addField('pubsub#title', + ftype='text-single', value='This thing is awesome') self.checkIq(iq, """ - + @@ -166,54 +166,54 @@ class TestPubsubStanzas(SleekTest): """, use_values=False) def testSubscribe(self): - "Testing iq/pubsub/subscribe stanzas" - iq = self.Iq() - iq['pubsub']['subscribe']['options'] - iq['pubsub']['subscribe']['node'] = 'cheese' - iq['pubsub']['subscribe']['jid'] = 'fritzy@netflint.net/sleekxmpp' - iq['pubsub']['subscribe']['options']['node'] = 'cheese' - iq['pubsub']['subscribe']['options']['jid'] = 'fritzy@netflint.net/sleekxmpp' - form = xep_0004.Form() - form.addField('pubsub#title', ftype='text-single', value='This thing is awesome') - iq['pubsub']['subscribe']['options']['options'] = form + "testing iq/pubsub/subscribe stanzas" + iq = self.Iq() + iq['pubsub']['subscribe']['options'] + iq['pubsub']['subscribe']['node'] = 'cheese' + iq['pubsub']['subscribe']['jid'] = 'fritzy@netflint.net/sleekxmpp' + iq['pubsub']['subscribe']['options']['node'] = 'cheese' + iq['pubsub']['subscribe']['options']['jid'] = 'fritzy@netflint.net/sleekxmpp' + form = xep_0004.Form() + form.addField('pubsub#title', ftype='text-single', value='this thing is awesome') + iq['pubsub']['subscribe']['options']['options'] = form self.checkIq(iq, """ - - - - - - - This thing is awesome - - - - - - """, use_values=False) + + + + + + + this thing is awesome + + + + + + """, use_values=False) def testPublish(self): - "Testing iq/pubsub/publish stanzas" - iq = self.Iq() - iq['pubsub']['publish']['node'] = 'thingers' - payload = ET.fromstring(""" + "Testing iq/pubsub/publish stanzas" + iq = self.Iq() + iq['pubsub']['publish']['node'] = 'thingers' + payload = ET.fromstring(""" """) - payload2 = ET.fromstring(""" + payload2 = ET.fromstring(""" """) - item = pubsub.Item() - item['id'] = 'asdf' - item['payload'] = payload - item2 = pubsub.Item() - item2['id'] = 'asdf2' - item2['payload'] = payload2 - iq['pubsub']['publish'].append(item) - iq['pubsub']['publish'].append(item2) - + item = pubsub.Item() + item['id'] = 'asdf' + item['payload'] = payload + item2 = pubsub.Item() + item2['id'] = 'asdf2' + item2['payload'] = payload2 + iq['pubsub']['publish'].append(item) + iq['pubsub']['publish'].append(item2) + self.checkIq(iq, """ @@ -235,19 +235,19 @@ class TestPubsubStanzas(SleekTest): """) def testDelete(self): - "Testing iq/pubsub_owner/delete stanzas" - iq = self.Iq() - iq['pubsub_owner']['delete']['node'] = 'thingers' + "Testing iq/pubsub_owner/delete stanzas" + iq = self.Iq() + iq['pubsub_owner']['delete']['node'] = 'thingers' self.checkIq(iq, """ - + """) def testCreateConfigGet(self): - """Testing getting config from full create""" - iq = self.Iq() + """Testing getting config from full create""" + iq = self.Iq() iq['to'] = 'pubsub.asdf' iq['from'] = 'fritzy@asdf/87292ede-524d-4117-9076-d934ed3db8e7' iq['type'] = 'set' @@ -348,16 +348,16 @@ class TestPubsubStanzas(SleekTest): """) def testItemEvent(self): - """Testing message/pubsub_event/items/item""" - msg = self.Message() - item = pubsub.EventItem() - pl = ET.Element('{http://netflint.net/protocol/test}test', {'failed':'3', 'passed':'24'}) - item['payload'] = pl - item['id'] = 'abc123' - msg['pubsub_event']['items'].append(item) - msg['pubsub_event']['items']['node'] = 'cheese' - msg['type'] = 'normal' - self.checkMessage(msg, """ + """Testing message/pubsub_event/items/item""" + msg = self.Message() + item = pubsub.EventItem() + pl = ET.Element('{http://netflint.net/protocol/test}test', {'failed':'3', 'passed':'24'}) + item['payload'] = pl + item['id'] = 'abc123' + msg['pubsub_event']['items'].append(item) + msg['pubsub_event']['items']['node'] = 'cheese' + msg['type'] = 'normal' + self.checkMessage(msg, """ @@ -369,21 +369,21 @@ class TestPubsubStanzas(SleekTest): """) def testItemsEvent(self): - """Testing multiple message/pubsub_event/items/item""" - msg = self.Message() - item = pubsub.EventItem() - item2 = pubsub.EventItem() - pl = ET.Element('{http://netflint.net/protocol/test}test', {'failed':'3', 'passed':'24'}) - pl2 = ET.Element('{http://netflint.net/protocol/test-other}test', {'total':'27', 'failed':'3'}) - item2['payload'] = pl2 - item['payload'] = pl - item['id'] = 'abc123' - item2['id'] = '123abc' - msg['pubsub_event']['items'].append(item) - msg['pubsub_event']['items'].append(item2) - msg['pubsub_event']['items']['node'] = 'cheese' - msg['type'] = 'normal' - self.checkMessage(msg, """ + """Testing multiple message/pubsub_event/items/item""" + msg = self.Message() + item = pubsub.EventItem() + item2 = pubsub.EventItem() + pl = ET.Element('{http://netflint.net/protocol/test}test', {'failed':'3', 'passed':'24'}) + pl2 = ET.Element('{http://netflint.net/protocol/test-other}test', {'total':'27', 'failed':'3'}) + item2['payload'] = pl2 + item['payload'] = pl + item['id'] = 'abc123' + item2['id'] = '123abc' + msg['pubsub_event']['items'].append(item) + msg['pubsub_event']['items'].append(item2) + msg['pubsub_event']['items']['node'] = 'cheese' + msg['type'] = 'normal' + self.checkMessage(msg, """ @@ -398,24 +398,24 @@ class TestPubsubStanzas(SleekTest): """) def testItemsEvent(self): - """Testing message/pubsub_event/items/item & retract mix""" - msg = self.Message() - item = pubsub.EventItem() - item2 = pubsub.EventItem() - pl = ET.Element('{http://netflint.net/protocol/test}test', {'failed':'3', 'passed':'24'}) - pl2 = ET.Element('{http://netflint.net/protocol/test-other}test', {'total':'27', 'failed':'3'}) - item2['payload'] = pl2 - retract = pubsub.EventRetract() - retract['id'] = 'aabbcc' - item['payload'] = pl - item['id'] = 'abc123' - item2['id'] = '123abc' - msg['pubsub_event']['items'].append(item) - msg['pubsub_event']['items'].append(retract) - msg['pubsub_event']['items'].append(item2) - msg['pubsub_event']['items']['node'] = 'cheese' - msg['type'] = 'normal' - self.checkMessage(msg, """ + """Testing message/pubsub_event/items/item & retract mix""" + msg = self.Message() + item = pubsub.EventItem() + item2 = pubsub.EventItem() + pl = ET.Element('{http://netflint.net/protocol/test}test', {'failed':'3', 'passed':'24'}) + pl2 = ET.Element('{http://netflint.net/protocol/test-other}test', {'total':'27', 'failed':'3'}) + item2['payload'] = pl2 + retract = pubsub.EventRetract() + retract['id'] = 'aabbcc' + item['payload'] = pl + item['id'] = 'abc123' + item2['id'] = '123abc' + msg['pubsub_event']['items'].append(item) + msg['pubsub_event']['items'].append(retract) + msg['pubsub_event']['items'].append(item2) + msg['pubsub_event']['items']['node'] = 'cheese' + msg['type'] = 'normal' + self.checkMessage(msg, """ @@ -430,12 +430,12 @@ class TestPubsubStanzas(SleekTest): """) def testCollectionAssociate(self): - """Testing message/pubsub_event/collection/associate""" - msg = self.Message() - msg['pubsub_event']['collection']['associate']['node'] = 'cheese' - msg['pubsub_event']['collection']['node'] = 'cheeseburger' - msg['type'] = 'headline' - self.checkMessage(msg, """ + """Testing message/pubsub_event/collection/associate""" + msg = self.Message() + msg['pubsub_event']['collection']['associate']['node'] = 'cheese' + msg['pubsub_event']['collection']['node'] = 'cheeseburger' + msg['type'] = 'headline' + self.checkMessage(msg, """ @@ -445,12 +445,12 @@ class TestPubsubStanzas(SleekTest): """) def testCollectionDisassociate(self): - """Testing message/pubsub_event/collection/disassociate""" - msg = self.Message() - msg['pubsub_event']['collection']['disassociate']['node'] = 'cheese' - msg['pubsub_event']['collection']['node'] = 'cheeseburger' - msg['type'] = 'headline' - self.checkMessage(msg, """ + """Testing message/pubsub_event/collection/disassociate""" + msg = self.Message() + msg['pubsub_event']['collection']['disassociate']['node'] = 'cheese' + msg['pubsub_event']['collection']['node'] = 'cheeseburger' + msg['type'] = 'headline' + self.checkMessage(msg, """ @@ -460,15 +460,15 @@ class TestPubsubStanzas(SleekTest): """) def testEventConfiguration(self): - """Testing message/pubsub_event/configuration/config""" - msg = self.Message() - msg['pubsub_event']['configuration']['node'] = 'cheese' - msg['pubsub_event']['configuration']['form'].addField('pubsub#title', - ftype='text-single', + """Testing message/pubsub_event/configuration/config""" + msg = self.Message() + msg['pubsub_event']['configuration']['node'] = 'cheese' + msg['pubsub_event']['configuration']['form'].addField('pubsub#title', + ftype='text-single', value='This thing is awesome') - msg['type'] = 'headline' + msg['type'] = 'headline' self.checkMessage(msg, """ - + @@ -481,11 +481,11 @@ class TestPubsubStanzas(SleekTest): """) def testEventPurge(self): - """Testing message/pubsub_event/purge""" - msg = self.Message() - msg['pubsub_event']['purge']['node'] = 'pickles' - msg['type'] = 'headline' - self.checkMessage(msg, """ + """Testing message/pubsub_event/purge""" + msg = self.Message() + msg['pubsub_event']['purge']['node'] = 'pickles' + msg['type'] = 'headline' + self.checkMessage(msg, """ @@ -493,15 +493,15 @@ class TestPubsubStanzas(SleekTest): """) def testEventSubscription(self): - """Testing message/pubsub_event/subscription""" - msg = self.Message() - msg['pubsub_event']['subscription']['node'] = 'pickles' - msg['pubsub_event']['subscription']['jid'] = 'fritzy@netflint.net/test' - msg['pubsub_event']['subscription']['subid'] = 'aabb1122' - msg['pubsub_event']['subscription']['subscription'] = 'subscribed' - msg['pubsub_event']['subscription']['expiry'] = 'presence' - msg['type'] = 'headline' - self.checkMessage(msg, """ + """Testing message/pubsub_event/subscription""" + msg = self.Message() + msg['pubsub_event']['subscription']['node'] = 'pickles' + msg['pubsub_event']['subscription']['jid'] = 'fritzy@netflint.net/test' + msg['pubsub_event']['subscription']['subid'] = 'aabb1122' + msg['pubsub_event']['subscription']['subscription'] = 'subscribed' + msg['pubsub_event']['subscription']['expiry'] = 'presence' + msg['type'] = 'headline' + self.checkMessage(msg, """ diff --git a/tests/test_stream.py b/tests/test_stream.py index c2f2667e..6e240747 100644 --- a/tests/test_stream.py +++ b/tests/test_stream.py @@ -1,4 +1,4 @@ -from sleektest import * +from . sleektest import * import sleekxmpp.plugins.xep_0033 as xep_0033 -- cgit v1.2.3 From 0d0c044a688490eb295ddd305247f406eefc0855 Mon Sep 17 00:00:00 2001 From: Lance Stout Date: Thu, 5 Aug 2010 20:57:55 -0400 Subject: Add unit tests for the tostring function. --- tests/test_tostring.py | 104 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 104 insertions(+) create mode 100644 tests/test_tostring.py (limited to 'tests') diff --git a/tests/test_tostring.py b/tests/test_tostring.py new file mode 100644 index 00000000..2999949a --- /dev/null +++ b/tests/test_tostring.py @@ -0,0 +1,104 @@ +from . sleektest import * +from sleekxmpp.stanza import Message +from sleekxmpp.xmlstream.stanzabase import ET +from sleekxmpp.xmlstream.tostring import tostring, xml_escape + + +class TestToString(SleekTest): + + """ + Test the implementation of sleekxmpp.xmlstream.tostring + """ + + def tryTostring(self, original='', expected=None, message='', **kwargs): + """ + Compare the result of calling tostring against an + expected result. + """ + if not expected: + expected=original + if isinstance(original, str): + xml = ET.fromstring(original) + else: + xml=original + result = tostring(xml, **kwargs) + self.failUnless(result == expected, "%s: %s" % (message, result)) + + def testXMLEscape(self): + """Test escaping XML special characters.""" + original = """'Hi & welcome!'""" + escaped = xml_escape(original) + desired = """<foo bar="baz">'Hi""" + desired += """ & welcome!'</foo>""" + + self.failUnless(escaped == desired, + "XML escaping did not work: %s." % escaped) + + def testEmptyElement(self): + """Test converting an empty element to a string.""" + self.tryTostring( + original='', + message="Empty element not serialized correctly") + + def testEmptyElementWrapped(self): + """Test converting an empty element inside another element.""" + self.tryTostring( + original='', + message="Wrapped empty element not serialized correctly") + + def testEmptyElementWrappedText(self): + """ + Test converting an empty element wrapped with text + inside another element. + """ + self.tryTostring( + original='Some text. More text.', + message="Text wrapped empty element serialized incorrectly") + + def testMultipleChildren(self): + """Test converting multiple child elements to a Unicode string.""" + self.tryTostring( + original='', + message="Multiple child elements not serialized correctly") + + def testXMLNS(self): + """ + Test using xmlns tostring parameter, which will prevent adding + an xmlns attribute to the serialized element if the element's + namespace is the same. + """ + self.tryTostring( + original='', + expected='', + message="The xmlns parameter was not used properly.", + xmlns='foo') + + def testStanzaNs(self): + """ + Test using the stanza_ns tostring parameter, which will prevent + adding an xmlns attribute to the serialized element if the + element's namespace is the same. + """ + self.tryTostring( + original='', + expected='', + message="The stanza_ns parameter was not used properly.", + stanza_ns='foo') + + def testStanzaStr(self): + """ + Test that stanza objects are serialized properly. + """ + utf8_message = '\xe0\xb2\xa0_\xe0\xb2\xa0' + if not hasattr(utf8_message, 'decode'): + # Python 3 + utf8_message = bytes(utf8_message, encoding='utf-8') + msg = Message() + msg['body'] = utf8_message.decode('utf-8') + expected = '\xe0\xb2\xa0_\xe0\xb2\xa0' + result = msg.__str__() + self.failUnless(result == expected, + "Stanza Unicode handling is incorrect: %s" % result) + + +suite = unittest.TestLoader().loadTestsFromTestCase(TestToString) -- cgit v1.2.3 From 48ba7292bcbc5207f08766ed3a855e16e2bf11d7 Mon Sep 17 00:00:00 2001 From: Lance Stout Date: Fri, 6 Aug 2010 12:04:52 -0400 Subject: Updated SleekTest to use the new tostring function instead of ET.tostring --- tests/sleektest.py | 27 ++++++++++++++------------- 1 file changed, 14 insertions(+), 13 deletions(-) (limited to 'tests') diff --git a/tests/sleektest.py b/tests/sleektest.py index cea8df66..a7116544 100644 --- a/tests/sleektest.py +++ b/tests/sleektest.py @@ -18,6 +18,7 @@ from sleekxmpp import Message, Iq from sleekxmpp.stanza.presence import Presence from sleekxmpp.xmlstream.matcher.stanzapath import StanzaPath from sleekxmpp.xmlstream.stanzabase import registerStanzaPlugin +from sleekxmpp.xmlstream.tostring import tostring class TestSocket(object): @@ -112,15 +113,15 @@ class SleekTest(unittest.TestCase): """ self.fix_namespaces(msg.xml, 'jabber:client') - debug = "Given Stanza:\n%s\n" % ET.tostring(msg.xml) + debug = "Given Stanza:\n%s\n" % tostring(msg.xml) xml = ET.fromstring(xml_string) self.fix_namespaces(xml, 'jabber:client') - debug += "XML String:\n%s\n" % ET.tostring(xml) + debug += "XML String:\n%s\n" % tostring(xml) msg2 = self.Message(xml) - debug += "Constructed Stanza:\n%s\n" % ET.tostring(msg2.xml) + debug += "Constructed Stanza:\n%s\n" % tostring(msg2.xml) if use_values: # Ugly, but need to make sure the type attribute is set. @@ -128,13 +129,13 @@ class SleekTest(unittest.TestCase): if xml.attrib.get('type', None) is None: xml.attrib['type'] = 'normal' msg2['type'] = msg2['type'] - debug += "XML String:\n%s\n" % ET.tostring(xml) + debug += "XML String:\n%s\n" % tostring(xml) values = msg2.getStanzaValues() msg3 = self.Message() msg3.setStanzaValues(values) - debug += "Second Constructed Stanza:\n%s\n" % ET.tostring(msg3.xml) + debug += "Second Constructed Stanza:\n%s\n" % tostring(msg3.xml) debug = "Three methods for creating stanza do not match:\n" + debug self.failUnless(self.compare([xml, msg.xml, msg2.xml, msg3.xml]), debug) @@ -152,21 +153,21 @@ class SleekTest(unittest.TestCase): """ self.fix_namespaces(iq.xml, 'jabber:client') - debug = "Given Stanza:\n%s\n" % ET.tostring(iq.xml) + debug = "Given Stanza:\n%s\n" % tostring(iq.xml) xml = ET.fromstring(xml_string) self.fix_namespaces(xml, 'jabber:client') - debug += "XML String:\n%s\n" % ET.tostring(xml) + debug += "XML String:\n%s\n" % tostring(xml) iq2 = self.Iq(xml) - debug += "Constructed Stanza:\n%s\n" % ET.tostring(iq2.xml) + debug += "Constructed Stanza:\n%s\n" % tostring(iq2.xml) if use_values: values = iq.getStanzaValues() iq3 = self.Iq() iq3.setStanzaValues(values) - debug += "Second Constructed Stanza:\n%s\n" % ET.tostring(iq3.xml) + debug += "Second Constructed Stanza:\n%s\n" % tostring(iq3.xml) debug = "Three methods for creating stanza do not match:\n" + debug self.failUnless(self.compare([xml, iq.xml, iq2.xml, iq3.xml]), debug) @@ -194,16 +195,16 @@ class SleekTest(unittest.TestCase): pres['priority'] = pres['priority'] pres2['priority'] = pres2['priority'] - debug = "Given Stanza:\n%s\n" % ET.tostring(pres.xml) - debug += "XML String:\n%s\n" % ET.tostring(xml) - debug += "Constructed Stanza:\n%s\n" % ET.tostring(pres2.xml) + debug = "Given Stanza:\n%s\n" % tostring(pres.xml) + debug += "XML String:\n%s\n" % tostring(xml) + debug += "Constructed Stanza:\n%s\n" % tostring(pres2.xml) if use_values: values = pres.getStanzaValues() pres3 = self.Presence() pres3.setStanzaValues(values) - debug += "Second Constructed Stanza:\n%s\n" % ET.tostring(pres3.xml) + debug += "Second Constructed Stanza:\n%s\n" % tostring(pres3.xml) debug = "Three methods for creating stanza do not match:\n" + debug self.failUnless(self.compare([xml, pres.xml, pres2.xml, pres3.xml]), debug) -- cgit v1.2.3 From 7a5ef2849218e122b04e244aeedd67844a0690b2 Mon Sep 17 00:00:00 2001 From: Lance Stout Date: Wed, 11 Aug 2010 18:41:57 -0400 Subject: Updated SleekTest.streamClose to check that the stream was actually started before closing it. Updated tests for Iq stanzas to not start a stream for every test; tests now run a lot faster. The call to streamClose must still be in the tearDown method to ensure it is called in the case of an error. --- tests/sleektest.py | 2 +- tests/test_iqstanzas.py | 5 +---- 2 files changed, 2 insertions(+), 5 deletions(-) (limited to 'tests') diff --git a/tests/sleektest.py b/tests/sleektest.py index a7116544..0adab2b2 100644 --- a/tests/sleektest.py +++ b/tests/sleektest.py @@ -258,7 +258,7 @@ class SleekTest(unittest.TestCase): self.checkPresence(data, sent, use_values) def streamClose(self): - if self.xmpp is not None: + if hasattr(self, 'xmpp') and self.xmpp is not None: self.xmpp.disconnect() self.xmpp.socket.recvData(self.xmpp.stream_footer) diff --git a/tests/test_iqstanzas.py b/tests/test_iqstanzas.py index 98a01a26..2dabc5e9 100644 --- a/tests/test_iqstanzas.py +++ b/tests/test_iqstanzas.py @@ -4,10 +4,6 @@ from sleekxmpp.xmlstream.stanzabase import ET class TestIqStanzas(SleekTest): - def setUp(self): - """Start XML stream for testing.""" - self.streamStart() - def tearDown(self): """Shutdown the XML stream after testing.""" self.streamClose() @@ -32,6 +28,7 @@ class TestIqStanzas(SleekTest): def testUnhandled(self): """Test behavior for Iq.unhandled.""" + self.streamStart() self.streamRecv(""" -- cgit v1.2.3 From b40a48979636ccb4055294427292b2decf095fea Mon Sep 17 00:00:00 2001 From: Lance Stout Date: Wed, 11 Aug 2010 23:32:14 -0400 Subject: Updated roster stanza with docs and PEP8 style. --- tests/test_roster.py | 84 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 84 insertions(+) create mode 100644 tests/test_roster.py (limited to 'tests') diff --git a/tests/test_roster.py b/tests/test_roster.py new file mode 100644 index 00000000..6f9fa3d6 --- /dev/null +++ b/tests/test_roster.py @@ -0,0 +1,84 @@ +from . sleektest import * +from sleekxmpp.stanza.roster import Roster + + +class TestRosterStanzas(SleekTest): + + def testAddItems(self): + """Test adding items to a roster stanza.""" + iq = self.Iq() + iq['roster'].setItems({ + 'user@example.com': { + 'name': 'User', + 'subscription': 'both', + 'groups': ['Friends', 'Coworkers']}, + 'otheruser@example.com': { + 'name': 'Other User', + 'subscription': 'both', + 'groups': []}}) + self.checkIq(iq, """ + + + + Friends + Coworkers + + + + + """) + + def testGetItems(self): + """Test retrieving items from a roster stanza.""" + xml_string = """ + + + + Friends + Coworkers + + + + + """ + iq = self.Iq(ET.fromstring(xml_string)) + expected = { + 'user@example.com': { + 'name': 'User', + 'subscription': 'both', + 'groups': ['Friends', 'Coworkers']}, + 'otheruser@example.com': { + 'name': 'Other User', + 'subscription': 'both', + 'groups': []}} + debug = "Roster items don't match after retrieval." + debug += "\nReturned: %s" % str(iq['roster']['items']) + debug += "\nExpected: %s" % str(expected) + self.failUnless(iq['roster']['items'] == expected, debug) + + def testDelItems(self): + """Test clearing items from a roster stanza.""" + xml_string = """ + + + + Friends + Coworkers + + + + + """ + iq = self.Iq(ET.fromstring(xml_string)) + del iq['roster']['items'] + self.checkIq(iq, """ + + + + """) + + +suite = unittest.TestLoader().loadTestsFromTestCase(TestRosterStanzas) -- cgit v1.2.3 From 22134c302b68f37ded406ea335aca4c9bdab3090 Mon Sep 17 00:00:00 2001 From: Lance Stout Date: Thu, 12 Aug 2010 01:25:42 -0400 Subject: Updated SleekTest with docs and PEP8 style. --- tests/sleektest.py | 293 ++++++++++++++++++++++++++++++++++++++++++++--------- 1 file changed, 245 insertions(+), 48 deletions(-) (limited to 'tests') diff --git a/tests/sleektest.py b/tests/sleektest.py index 0adab2b2..c7c72410 100644 --- a/tests/sleektest.py +++ b/tests/sleektest.py @@ -9,38 +9,73 @@ import unittest import socket try: - import queue + import queue except ImportError: - import Queue as queue -from xml.etree import cElementTree as ET + import Queue as queue + from sleekxmpp import ClientXMPP -from sleekxmpp import Message, Iq -from sleekxmpp.stanza.presence import Presence -from sleekxmpp.xmlstream.matcher.stanzapath import StanzaPath -from sleekxmpp.xmlstream.stanzabase import registerStanzaPlugin +from sleekxmpp.stanza import Message, Iq, Presence +from sleekxmpp.xmlstream.stanzabase import registerStanzaPlugin, ET from sleekxmpp.xmlstream.tostring import tostring class TestSocket(object): + """ + A dummy socket that reads and writes to queues instead + of an actual networking socket. + + Methods: + nextSent -- Return the next sent stanza. + recvData -- Make a stanza available to read next. + recv -- Read the next stanza from the socket. + send -- Write a stanza to the socket. + makefile -- Dummy call, returns self. + read -- Read the next stanza from the socket. + """ + def __init__(self, *args, **kwargs): + """ + Create a new test socket. + + Arguments: + Same as arguments for socket.socket + """ self.socket = socket.socket(*args, **kwargs) self.recv_queue = queue.Queue() self.send_queue = queue.Queue() def __getattr__(self, name): - """Pass requests through to actual socket""" - # Override a few methods to prevent actual socket connections - overrides = {'connect': lambda *args: None, - 'close': lambda *args: None, - 'shutdown': lambda *args: None} + """ + Return attribute values of internal, dummy socket. + + Some attributes and methods are disabled to prevent the + socket from connecting to the network. + + Arguments: + name -- Name of the attribute requested. + """ + + def dummy(*args): + """Method to do nothing and prevent actual socket connections.""" + return None + + overrides = {'connect': dummy, + 'close': dummy, + 'shutdown': dummy} + return overrides.get(name, getattr(self.socket, name)) # ------------------------------------------------------------------ # Testing Interface def nextSent(self, timeout=None): - """Get the next stanza that has been 'sent'""" + """ + Get the next stanza that has been 'sent'. + + Arguments: + timeout -- Optional timeout for waiting for a new value. + """ args = {'block': False} if timeout is not None: args = {'block': True, 'timeout': timeout} @@ -50,27 +85,58 @@ class TestSocket(object): return None def recvData(self, data): - """Add data to the receiving queue""" + """ + Add data to the receiving queue. + + Arguments: + data -- String data to 'write' to the socket to be received + by the XMPP client. + """ self.recv_queue.put(data) # ------------------------------------------------------------------ # Socket Interface def recv(self, *args, **kwargs): + """ + Read a value from the received queue. + + Arguments: + Placeholders. Same as for socket.Socket.recv. + """ return self.read(block=True) def send(self, data): + """ + Send data by placing it in the send queue. + + Arguments: + data -- String value to write. + """ self.send_queue.put(data) # ------------------------------------------------------------------ # File Socket - def makefile(self, mode='r', bufsize=-1): - """File socket version to use with ElementTree""" + def makefile(self, *args, **kwargs): + """ + File socket version to use with ElementTree. + + Arguments: + Placeholders, same as socket.Socket.makefile() + """ return self - def read(self, size=4096, block=True, timeout=None): - """Implement the file socket interface""" + def read(self, block=True, timeout=None, **kwargs): + """ + Implement the file socket interface. + + Arguments: + block -- Indicate if the read should block until a + value is ready. + timeout -- Time in seconds a block should last before + returning None. + """ if timeout is not None: block = True try: @@ -80,24 +146,65 @@ class TestSocket(object): class SleekTest(unittest.TestCase): + """ A SleekXMPP specific TestCase class that provides methods for comparing message, iq, and presence stanzas. + + Methods: + Message -- Create a Message stanza object. + Iq -- Create an Iq stanza object. + Presence -- Create a Presence stanza object. + checkMessage -- Compare a Message stanza against an XML string. + checkIq -- Compare an Iq stanza against an XML string. + checkPresence -- Compare a Presence stanza against an XML string. + streamStart -- Initialize a dummy XMPP client. + streamRecv -- Queue data for XMPP client to receive. + streamSendMessage -- Check that the XMPP client sent the given + Message stanza. + streamSendIq -- Check that the XMPP client sent the given + Iq stanza. + streamSendPresence -- Check taht the XMPP client sent the given + Presence stanza. + streamClose -- Disconnect the XMPP client. + fix_namespaces -- Add top-level namespace to an XML object. + compare -- Compare XML objects against each other. """ # ------------------------------------------------------------------ # Shortcut methods for creating stanza objects def Message(self, *args, **kwargs): - """Create a message stanza.""" + """ + Create a Message stanza. + + Uses same arguments as StanzaBase.__init__ + + Arguments: + xml -- An XML object to use for the Message's values. + """ return Message(None, *args, **kwargs) def Iq(self, *args, **kwargs): - """Create an iq stanza.""" + """ + Create an Iq stanza. + + Uses same arguments as StanzaBase.__init__ + + Arguments: + xml -- An XML object to use for the Iq's values. + """ return Iq(None, *args, **kwargs) def Presence(self, *args, **kwargs): - """Create a presence stanza.""" + """ + Create a Presence stanza. + + Uses same arguments as StanzaBase.__init__ + + Arguments: + xml -- An XML object to use for the Iq's values. + """ return Presence(None, *args, **kwargs) # ------------------------------------------------------------------ @@ -108,8 +215,15 @@ class SleekTest(unittest.TestCase): Create and compare several message stanza objects to a correct XML string. - If use_values is False, the test using getValues() and - setValues() will not be used. + If use_values is False, the test using getStanzaValues() and + setStanzaValues() will not be used. + + Arguments: + msg -- The Message stanza object to check. + xml_string -- The XML contents to compare against. + use_values -- Indicates if the test using getStanzaValues + and setStanzaValues should be used. Defaults + to True. """ self.fix_namespaces(msg.xml, 'jabber:client') @@ -137,19 +251,26 @@ class SleekTest(unittest.TestCase): debug += "Second Constructed Stanza:\n%s\n" % tostring(msg3.xml) debug = "Three methods for creating stanza do not match:\n" + debug - self.failUnless(self.compare([xml, msg.xml, msg2.xml, msg3.xml]), + self.failUnless(self.compare(xml, msg.xml, msg2.xml, msg3.xml), debug) else: debug = "Two methods for creating stanza do not match:\n" + debug - self.failUnless(self.compare([xml, msg.xml, msg2.xml]), debug) + self.failUnless(self.compare(xml, msg.xml, msg2.xml), debug) def checkIq(self, iq, xml_string, use_values=True): """ Create and compare several iq stanza objects to a correct XML string. - If use_values is False, the test using getValues() and - setValues() will not be used. + If use_values is False, the test using getStanzaValues() and + setStanzaValues() will not be used. + + Arguments: + iq -- The Iq stanza object to check. + xml_string -- The XML contents to compare against. + use_values -- Indicates if the test using getStanzaValues + and setStanzaValues should be used. Defaults + to True. """ self.fix_namespaces(iq.xml, 'jabber:client') @@ -169,20 +290,28 @@ class SleekTest(unittest.TestCase): debug += "Second Constructed Stanza:\n%s\n" % tostring(iq3.xml) debug = "Three methods for creating stanza do not match:\n" + debug - self.failUnless(self.compare([xml, iq.xml, iq2.xml, iq3.xml]), + self.failUnless(self.compare(xml, iq.xml, iq2.xml, iq3.xml), debug) else: debug = "Two methods for creating stanza do not match:\n" + debug - self.failUnless(self.compare([xml, iq.xml, iq2.xml]), debug) + self.failUnless(self.compare(xml, iq.xml, iq2.xml), debug) def checkPresence(self, pres, xml_string, use_values=True): """ Create and compare several presence stanza objects to a correct XML string. - If use_values is False, the test using getValues() and - setValues() will not be used. + If use_values is False, the test using getStanzaValues() and + setStanzaValues() will not be used. + + Arguments: + iq -- The Iq stanza object to check. + xml_string -- The XML contents to compare against. + use_values -- Indicates if the test using getStanzaValues + and setStanzaValues should be used. Defaults + to True. """ + self.fix_namespaces(pres.xml, 'jabber:client') xml = ET.fromstring(xml_string) @@ -206,17 +335,26 @@ class SleekTest(unittest.TestCase): debug += "Second Constructed Stanza:\n%s\n" % tostring(pres3.xml) debug = "Three methods for creating stanza do not match:\n" + debug - self.failUnless(self.compare([xml, pres.xml, pres2.xml, pres3.xml]), + self.failUnless(self.compare(xml, pres.xml, pres2.xml, pres3.xml), debug) else: debug = "Two methods for creating stanza do not match:\n" + debug - self.failUnless(self.compare([xml, pres.xml, pres2.xml]), debug) - + self.failUnless(self.compare(xml, pres.xml, pres2.xml), debug) # ------------------------------------------------------------------ # Methods for simulating stanza streams. def streamStart(self, mode='client', skip=True): + """ + Initialize an XMPP client or component using a dummy XML stream. + + Arguments: + mode -- Either 'client' or 'component'. Defaults to 'client'. + skip -- Indicates if the first item in the sent queue (the + stream header) should be removed. Tests that wish + to test initializing the stream should set this to + False. Otherwise, the default of True should be used. + """ if mode == 'client': self.xmpp = ClientXMPP('tester@localhost', 'test') self.xmpp.setSocket(TestSocket()) @@ -236,28 +374,82 @@ class SleekTest(unittest.TestCase): self.xmpp.socket.nextSent(timeout=0.01) def streamRecv(self, data): + """ + Pass data to the dummy XMPP client as if it came from an XMPP server. + + Arguments: + data -- String stanza XML to be received and processed by the + XMPP client or component. + """ data = str(data) self.xmpp.socket.recvData(data) def streamSendMessage(self, data, use_values=True, timeout=.1): + """ + Check that the XMPP client sent the given stanza XML. + + Extracts the next sent stanza and compares it with the given + XML using checkMessage. + + Arguments: + data -- The XML string of the expected Message stanza, + or an equivalent stanza object. + use_values -- Modifies the type of tests used by checkMessage. + timeout -- Time in seconds to wait for a stanza before + failing the check. + """ if isinstance(data, str): data = self.Message(xml=ET.fromstring(data)) sent = self.xmpp.socket.nextSent(timeout) self.checkMessage(data, sent, use_values) def streamSendIq(self, data, use_values=True, timeout=.1): + """ + Check that the XMPP client sent the given stanza XML. + + Extracts the next sent stanza and compares it with the given + XML using checkIq. + + Arguments: + data -- The XML string of the expected Iq stanza, + or an equivalent stanza object. + use_values -- Modifies the type of tests used by checkIq. + timeout -- Time in seconds to wait for a stanza before + failing the check. + """ if isinstance(data, str): data = self.Iq(xml=ET.fromstring(data)) sent = self.xmpp.socket.nextSent(timeout) self.checkIq(data, sent, use_values) def streamSendPresence(self, data, use_values=True, timeout=.1): + """ + Check that the XMPP client sent the given stanza XML. + + Extracts the next sent stanza and compares it with the given + XML using checkPresence. + + Arguments: + data -- The XML string of the expected Presence stanza, + or an equivalent stanza object. + use_values -- Modifies the type of tests used by checkPresence. + timeout -- Time in seconds to wait for a stanza before + failing the check. + """ if isinstance(data, str): data = self.Presence(xml=ET.fromstring(data)) sent = self.xmpp.socket.nextSent(timeout) self.checkPresence(data, sent, use_values) def streamClose(self): + """ + Disconnect the dummy XMPP client. + + Can be safely called even if streamStart has not been called. + + Must be placed in the tearDown method of a test class to ensure + that the XMPP client is disconnected after an error. + """ if hasattr(self, 'xmpp') and self.xmpp is not None: self.xmpp.disconnect() self.xmpp.socket.recvData(self.xmpp.stream_footer) @@ -269,6 +461,10 @@ class SleekTest(unittest.TestCase): """ Assign a namespace to an element and any children that don't have a namespace. + + Arguments: + xml -- The XML object to fix. + ns -- The namespace to add to the XML object. """ if xml.tag.startswith('{'): return @@ -276,36 +472,37 @@ class SleekTest(unittest.TestCase): for child in xml.getchildren(): self.fix_namespaces(child, ns) - def compare(self, xml1, xml2=None): + def compare(self, xml, *other): """ Compare XML objects. - If given a list of XML objects, then - all of the elements in the list will be - compared. + Arguments: + xml -- The XML object to compare against. + *other -- The list of XML objects to compare. """ + if not other: + return False # Compare multiple objects - if type(xml1) is list: - xmls = xml1 - xml1 = xmls[0] - for xml in xmls[1:]: - xml2 = xml - if not self.compare(xml1, xml2): + if len(other) > 1: + for xml2 in other: + if not self.compare(xml, xml2): return False return True + other = other[0] + # Step 1: Check tags - if xml1.tag != xml2.tag: + if xml.tag != other.tag: return False # Step 2: Check attributes - if xml1.attrib != xml2.attrib: + if xml.attrib != other.attrib: return False # Step 3: Recursively check children - for child in xml1: - child2s = xml2.findall("%s" % child.tag) + for child in xml: + child2s = other.findall("%s" % child.tag) if child2s is None: return False for child2 in child2s: -- cgit v1.2.3 From 5da7bd1866b6ea2c58055a3aac7d0ed273ed40c6 Mon Sep 17 00:00:00 2001 From: Lance Stout Date: Thu, 12 Aug 2010 01:26:01 -0400 Subject: Removed unused xmlcompare.py. --- tests/xmlcompare.py | 28 ---------------------------- 1 file changed, 28 deletions(-) delete mode 100644 tests/xmlcompare.py (limited to 'tests') diff --git a/tests/xmlcompare.py b/tests/xmlcompare.py deleted file mode 100644 index d97af971..00000000 --- a/tests/xmlcompare.py +++ /dev/null @@ -1,28 +0,0 @@ -from xml.etree import cElementTree as ET - -def comparemany(xmls): - xml1 = xmls[0] - if type(xml1) == type(''): - xml1 = ET.fromstring(xml1) - for xml in xmls[1:]: - xml2 = xml - if type(xml2) == type(''): - xml2 = ET.fromstring(xml2) - if not compare(xml1, xml2): return False - return True - -def compare(xml1, xml2): - if xml1.tag != xml2.tag: - return False - if xml1.attrib != xml2.attrib: - return False - for child in xml1: - child2s = xml2.findall("%s" % child.tag) - if child2s is None: - return False - found = False - for child2 in child2s: - found = compare(child, child2) - if found: break - if not found: return False - return True -- cgit v1.2.3 From c721fb412618662d33fa73fb9f9e1f0c4f045fef Mon Sep 17 00:00:00 2001 From: Lance Stout Date: Fri, 13 Aug 2010 12:23:34 -0400 Subject: Added a generic checkStanza method to SleekTest. Updated the other check methods to use it. --- tests/sleektest.py | 168 +++++++++++++++++++++++++++-------------------------- 1 file changed, 86 insertions(+), 82 deletions(-) (limited to 'tests') diff --git a/tests/sleektest.py b/tests/sleektest.py index c7c72410..801253d3 100644 --- a/tests/sleektest.py +++ b/tests/sleektest.py @@ -13,6 +13,7 @@ try: except ImportError: import Queue as queue +import sleekxmpp from sleekxmpp import ClientXMPP from sleekxmpp.stanza import Message, Iq, Presence from sleekxmpp.xmlstream.stanzabase import registerStanzaPlugin, ET @@ -210,6 +211,84 @@ class SleekTest(unittest.TestCase): # ------------------------------------------------------------------ # Methods for comparing stanza objects to XML strings + def checkStanza(self, stanza_class, stanza, xml_string, + defaults=None, use_values=True): + """ + Create and compare several stanza objects to a correct XML string. + + If use_values is False, test using getStanzaValues() and + setStanzaValues() will not be used. + + Some stanzas provide default values for some interfaces, but + these defaults can be problematic for testing since they can easily + be forgotten when supplying the XML string. A list of interfaces that + use defaults may be provided and the generated stanzas will use the + default values for those interfaces if needed. + + However, correcting the supplied XML is not possible for interfaces + that add or remove XML elements. Only interfaces that map to XML + attributes may be set using the defaults parameter. The supplied XML + must take into account any extra elements that are included by default. + + Arguments: + stanza_class -- The class of the stanza being tested. + stanza -- The stanza object to test. + xml_string -- A string version of the correct XML expected. + defaults -- A list of stanza interfaces that have default + values. These interfaces will be set to their + defaults for the given and generated stanzas to + prevent unexpected test failures. + use_values -- Indicates if testing using getStanzaValues() and + setStanzaValues() should be used. Defaults to + True. + """ + xml = ET.fromstring(xml_string) + + # Ensure that top level namespaces are used, even if they + # were not provided. + self.fix_namespaces(stanza.xml, 'jabber:client') + self.fix_namespaces(xml, 'jabber:client') + + stanza2 = stanza_class(xml=xml) + + if use_values: + # Using getStanzaValues() and setStanzaValues() will add + # XML for any interface that has a default value. We need + # to set those defaults on the existing stanzas and XML + # so that they will compare correctly. + default_stanza = stanza_class() + if defaults is None: + defaults = [] + for interface in defaults: + stanza[interface] = stanza[interface] + stanza2[interface] = stanza2[interface] + # Can really only automatically add defaults for top + # level attribute values. Anything else must be accounted + # for in the provided XML string. + if interface not in xml.attrib: + if interface in default_stanza.xml.attrib: + value = default_stanza.xml.attrib[interface] + xml.attrib[interface] = value + + values = stanza2.getStanzaValues() + stanza3 = stanza_class() + stanza3.setStanzaValues(values) + + debug = "Three methods for creating stanzas do not match.\n" + debug += "Given XML:\n%s\n" % tostring(xml) + debug += "Given stanza:\n%s\n" % tostring(stanza.xml) + debug += "Generated stanza:\n%s\n" % tostring(stanza2.xml) + debug += "Second generated stanza:\n%s\n" % tostring(stanza3.xml) + result = self.compare(xml, stanza.xml, stanza2.xml, stanza3.xml) + else: + debug = "Two methods for creating stanzas do not match.\n" + debug += "Given XML:\n%s\n" % tostring(xml) + debug += "Given stanza:\n%s\n" % tostring(stanza.xml) + debug += "Generated stanza:\n%s\n" % tostring(stanza2.xml) + result = self.compare(xml, stanza.xml, stanza2.xml) + + self.failUnless(result, debug) + def checkMessage(self, msg, xml_string, use_values=True): """ Create and compare several message stanza objects to a @@ -226,36 +305,9 @@ class SleekTest(unittest.TestCase): to True. """ - self.fix_namespaces(msg.xml, 'jabber:client') - debug = "Given Stanza:\n%s\n" % tostring(msg.xml) - - xml = ET.fromstring(xml_string) - self.fix_namespaces(xml, 'jabber:client') - - debug += "XML String:\n%s\n" % tostring(xml) - - msg2 = self.Message(xml) - debug += "Constructed Stanza:\n%s\n" % tostring(msg2.xml) - - if use_values: - # Ugly, but need to make sure the type attribute is set. - msg['type'] = msg['type'] - if xml.attrib.get('type', None) is None: - xml.attrib['type'] = 'normal' - msg2['type'] = msg2['type'] - debug += "XML String:\n%s\n" % tostring(xml) - - values = msg2.getStanzaValues() - msg3 = self.Message() - msg3.setStanzaValues(values) - - debug += "Second Constructed Stanza:\n%s\n" % tostring(msg3.xml) - debug = "Three methods for creating stanza do not match:\n" + debug - self.failUnless(self.compare(xml, msg.xml, msg2.xml, msg3.xml), - debug) - else: - debug = "Two methods for creating stanza do not match:\n" + debug - self.failUnless(self.compare(xml, msg.xml, msg2.xml), debug) + return self.checkStanza(Message, msg, xml_string, + defaults=['type'], + use_values = use_values) def checkIq(self, iq, xml_string, use_values=True): """ @@ -272,29 +324,7 @@ class SleekTest(unittest.TestCase): and setStanzaValues should be used. Defaults to True. """ - - self.fix_namespaces(iq.xml, 'jabber:client') - debug = "Given Stanza:\n%s\n" % tostring(iq.xml) - - xml = ET.fromstring(xml_string) - self.fix_namespaces(xml, 'jabber:client') - debug += "XML String:\n%s\n" % tostring(xml) - - iq2 = self.Iq(xml) - debug += "Constructed Stanza:\n%s\n" % tostring(iq2.xml) - - if use_values: - values = iq.getStanzaValues() - iq3 = self.Iq() - iq3.setStanzaValues(values) - - debug += "Second Constructed Stanza:\n%s\n" % tostring(iq3.xml) - debug = "Three methods for creating stanza do not match:\n" + debug - self.failUnless(self.compare(xml, iq.xml, iq2.xml, iq3.xml), - debug) - else: - debug = "Two methods for creating stanza do not match:\n" + debug - self.failUnless(self.compare(xml, iq.xml, iq2.xml), debug) + return self.checkStanza(Iq, iq, xml_string, use_values=use_values) def checkPresence(self, pres, xml_string, use_values=True): """ @@ -311,35 +341,9 @@ class SleekTest(unittest.TestCase): and setStanzaValues should be used. Defaults to True. """ - - self.fix_namespaces(pres.xml, 'jabber:client') - - xml = ET.fromstring(xml_string) - self.fix_namespaces(xml, 'jabber:client') - - pres2 = self.Presence(xml) - - # Ugly, but 'priority' has a default value and need to make - # sure it is set - pres['priority'] = pres['priority'] - pres2['priority'] = pres2['priority'] - - debug = "Given Stanza:\n%s\n" % tostring(pres.xml) - debug += "XML String:\n%s\n" % tostring(xml) - debug += "Constructed Stanza:\n%s\n" % tostring(pres2.xml) - - if use_values: - values = pres.getStanzaValues() - pres3 = self.Presence() - pres3.setStanzaValues(values) - - debug += "Second Constructed Stanza:\n%s\n" % tostring(pres3.xml) - debug = "Three methods for creating stanza do not match:\n" + debug - self.failUnless(self.compare(xml, pres.xml, pres2.xml, pres3.xml), - debug) - else: - debug = "Two methods for creating stanza do not match:\n" + debug - self.failUnless(self.compare(xml, pres.xml, pres2.xml), debug) + return self.checkStanza(Presence, pres, xml_string, + defaults=['priority'], + use_values=use_values) # ------------------------------------------------------------------ # Methods for simulating stanza streams. -- cgit v1.2.3 From c20fab0f6c28bcbfbe54db687be056a9b5088ad4 Mon Sep 17 00:00:00 2001 From: Lance Stout Date: Fri, 13 Aug 2010 12:24:47 -0400 Subject: Updated ElementBase.setup, and added unit tests. --- tests/test_elementbase.py | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) create mode 100644 tests/test_elementbase.py (limited to 'tests') diff --git a/tests/test_elementbase.py b/tests/test_elementbase.py new file mode 100644 index 00000000..1b018b44 --- /dev/null +++ b/tests/test_elementbase.py @@ -0,0 +1,23 @@ +from . sleektest import * +from sleekxmpp.xmlstream.stanzabase import ElementBase + +class TestElementBase(SleekTest): + + def testExtendedName(self): + """Test element names of the form tag1/tag2/tag3.""" + + class TestStanza(ElementBase): + name = "foo/bar/baz" + namespace = "test" + + stanza = TestStanza() + self.checkStanza(TestStanza, stanza, """ + + + + + + """) + + +suite = unittest.TestLoader().loadTestsFromTestCase(TestElementBase) -- cgit v1.2.3 From fe49b8c377b8491ec5fd5bc74d44834bd384f6a8 Mon Sep 17 00:00:00 2001 From: Lance Stout Date: Fri, 13 Aug 2010 20:05:24 -0400 Subject: Updated getStanzaValues and setStanzaValues with docs and unit tests. --- tests/test_elementbase.py | 90 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 90 insertions(+) (limited to 'tests') diff --git a/tests/test_elementbase.py b/tests/test_elementbase.py index 1b018b44..99c397a5 100644 --- a/tests/test_elementbase.py +++ b/tests/test_elementbase.py @@ -19,5 +19,95 @@ class TestElementBase(SleekTest): """) + def testGetStanzaValues(self): + """Test getStanzaValues using plugins and substanzas.""" + + class TestStanzaPlugin(ElementBase): + name = "foo2" + namespace = "foo" + interfaces = set(('bar', 'baz')) + plugin_attrib = "foo2" + + class TestSubStanza(ElementBase): + name = "subfoo" + namespace = "foo" + interfaces = set(('bar', 'baz')) + + class TestStanza(ElementBase): + name = "foo" + namespace = "foo" + interfaces = set(('bar', 'baz')) + subitem = set((TestSubStanza,)) + + registerStanzaPlugin(TestStanza, TestStanzaPlugin) + + stanza = TestStanza() + stanza['bar'] = 'a' + stanza['foo2']['baz'] = 'b' + substanza = TestSubStanza() + substanza['bar'] = 'c' + stanza.append(substanza) + + values = stanza.getStanzaValues() + expected = {'bar': 'a', + 'baz': '', + 'foo2': {'bar': '', + 'baz': 'b'}, + 'substanzas': [{'__childtag__': '{foo}subfoo', + 'bar': 'c', + 'baz': ''}]} + self.failUnless(values == expected, + "Unexpected stanza values:\n%s\n%s" % (str(expected), str(values))) + + + def testSetStanzaValues(self): + """Test using setStanzaValues with substanzas and plugins.""" + + class TestStanzaPlugin(ElementBase): + name = "pluginfoo" + namespace = "foo" + interfaces = set(('bar', 'baz')) + plugin_attrib = "plugin_foo" + + class TestStanzaPlugin2(ElementBase): + name = "pluginfoo2" + namespace = "foo" + interfaces = set(('bar', 'baz')) + plugin_attrib = "plugin_foo2" + + class TestSubStanza(ElementBase): + name = "subfoo" + namespace = "foo" + interfaces = set(('bar', 'baz')) + + class TestStanza(ElementBase): + name = "foo" + namespace = "foo" + interfaces = set(('bar', 'baz')) + subitem = set((TestSubStanza,)) + + registerStanzaPlugin(TestStanza, TestStanzaPlugin) + registerStanzaPlugin(TestStanza, TestStanzaPlugin2) + + stanza = TestStanza() + values = {'bar': 'a', + 'baz': '', + 'plugin_foo': {'bar': '', + 'baz': 'b'}, + 'plugin_foo2': {'bar': 'd', + 'baz': 'e'}, + 'substanzas': [{'__childtag__': '{foo}subfoo', + 'bar': 'c', + 'baz': ''}]} + stanza.setStanzaValues(values) + + self.checkStanza(TestStanza, stanza, """ + + + + + + """) + suite = unittest.TestLoader().loadTestsFromTestCase(TestElementBase) -- cgit v1.2.3 From 2f6f4fc16d81fd01bc5a4569e0a1bc4ede4a3af8 Mon Sep 17 00:00:00 2001 From: Lance Stout Date: Fri, 13 Aug 2010 21:33:11 -0400 Subject: Updated ElementBase.__getitem__ with docs and unit tests. --- tests/test_elementbase.py | 41 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 41 insertions(+) (limited to 'tests') diff --git a/tests/test_elementbase.py b/tests/test_elementbase.py index 99c397a5..d6fd457c 100644 --- a/tests/test_elementbase.py +++ b/tests/test_elementbase.py @@ -109,5 +109,46 @@ class TestElementBase(SleekTest): """) + def testGetItem(self): + """Test accessing stanza interfaces.""" + + class TestStanza(ElementBase): + name = "foo" + namespace = "foo" + interfaces = set(('bar', 'baz')) + sub_interfaces = set(('baz',)) + + class TestStanzaPlugin(ElementBase): + name = "foobar" + namespace = "foo" + plugin_attrib = "foobar" + interfaces = set(('fizz',)) + + TestStanza.subitem = (TestStanza,) + registerStanzaPlugin(TestStanza, TestStanzaPlugin) + + stanza = TestStanza() + substanza = TestStanza() + stanza.append(substanza) + stanza.setStanzaValues({'bar': 'a', + 'baz': 'b', + 'foobar': {'fizz': 'c'}}) + + # Test non-plugin interfaces + expected = {'substanzas': [substanza], + 'bar': 'a', + 'baz': 'b', + 'meh': ''} + for interface, value in expected.items(): + result = stanza[interface] + self.failUnless(result == value, + "Incorrect stanza interface access result: %s" % result) + + # Test plugin interfaces + self.failUnless(isinstance(stanza['foobar'], TestStanzaPlugin), + "Incorrect plugin object result.") + self.failUnless(stanza['foobar']['fizz'] == 'c', + "Incorrect plugin subvalue result.") + suite = unittest.TestLoader().loadTestsFromTestCase(TestElementBase) -- cgit v1.2.3 From e4240dd593207a5912de996c42451b3946f113b2 Mon Sep 17 00:00:00 2001 From: Lance Stout Date: Thu, 19 Aug 2010 14:21:58 -0400 Subject: Updated ElementBase.__setitem__ and added unit tests. --- tests/test_elementbase.py | 41 ++++++++++++++++++++++++++++++++++++++++- 1 file changed, 40 insertions(+), 1 deletion(-) (limited to 'tests') diff --git a/tests/test_elementbase.py b/tests/test_elementbase.py index d6fd457c..95502f54 100644 --- a/tests/test_elementbase.py +++ b/tests/test_elementbase.py @@ -115,9 +115,12 @@ class TestElementBase(SleekTest): class TestStanza(ElementBase): name = "foo" namespace = "foo" - interfaces = set(('bar', 'baz')) + interfaces = set(('bar', 'baz', 'qux')) sub_interfaces = set(('baz',)) + def getQux(self): + return 'qux' + class TestStanzaPlugin(ElementBase): name = "foobar" namespace = "foo" @@ -132,12 +135,14 @@ class TestElementBase(SleekTest): stanza.append(substanza) stanza.setStanzaValues({'bar': 'a', 'baz': 'b', + 'qux': 42, 'foobar': {'fizz': 'c'}}) # Test non-plugin interfaces expected = {'substanzas': [substanza], 'bar': 'a', 'baz': 'b', + 'qux': 'qux', 'meh': ''} for interface, value in expected.items(): result = stanza[interface] @@ -150,5 +155,39 @@ class TestElementBase(SleekTest): self.failUnless(stanza['foobar']['fizz'] == 'c', "Incorrect plugin subvalue result.") + def testSetItem(self): + """Test assigning to stanza interfaces.""" + + class TestStanza(ElementBase): + name = "foo" + namespace = "foo" + interfaces = set(('bar', 'baz', 'qux')) + sub_interfaces = set(('baz',)) + + def setQux(self, value): + pass + + class TestStanzaPlugin(ElementBase): + name = "foobar" + namespace = "foo" + plugin_attrib = "foobar" + interfaces = set(('foobar',)) + + registerStanzaPlugin(TestStanza, TestStanzaPlugin) + + stanza = TestStanza() + + stanza['bar'] = 'attribute!' + stanza['baz'] = 'element!' + stanza['qux'] = 'overridden' + stanza['foobar'] = 'plugin' + + self.checkStanza(TestStanza, stanza, """ + + element! + + + """) + suite = unittest.TestLoader().loadTestsFromTestCase(TestElementBase) -- cgit v1.2.3