Adding stream tests for XEP-0030.

Fixed some errors when responding to disco requests.
This commit is contained in:
Lance Stout 2010-11-18 15:50:45 -05:00
parent 291b118aca
commit ab25301953
4 changed files with 127 additions and 19 deletions

View file

@ -110,6 +110,8 @@ class BaseXMPP(XMLStream):
self.boundjid = JID("")
self.plugin = {}
self.plugin_config = {}
self.plugin_whitelist = []
self.roster = {}
self.is_component = False
self.auto_authorize = True

View file

@ -71,11 +71,12 @@ class DiscoInfo(ElementBase):
for idXML in idsXML:
self.xml.remove(idXML)
def addIdentity(self, category, id_type, name=''):
idXML = ET.Element('{%s}identity' % self.namespace,
{'category': category,
'type': id_type,
'name': name})
def addIdentity(self, category, itype, name=''):
idXML = ET.Element('{%s}identity' % self.namespace)
idXML.attrib['category'] = category
idXML.attrib['type'] = itype
if name:
idXML.attrib['name'] = name
self.xml.append(idXML)
def delIdentity(self, category, id_type, name=''):
@ -213,8 +214,11 @@ class xep_0030(base.base_plugin):
self.xmpp.add_event_handler('disco_items_request', self.handle_disco_items)
self.xmpp.add_event_handler('disco_info_request', self.handle_disco_info)
self.nodes = {}
self.nodes = {'main': DiscoNode('main')}
self.add_node('')
self.add_feature('http://jabber.org/protocol/disco#info', node='')
def add_node(self, node):
if node not in self.nodes:
@ -258,14 +262,30 @@ class xep_0030(base.base_plugin):
return
node_name = iq['disco_info']['node']
if not node_name:
node_name = 'main'
log.debug("Using default handler for disco#info on node '%s'." % node_name)
if node_name in self.nodes:
node = self.nodes[node_name]
iq.reply().setPayload(node.info.xml).send()
iq.reply()
iq['disco_info']['node'] = node_name
identities = node.info['identities']
if identities:
iq['disco_info']['identities'] = identities
else:
if self.xmpp.is_component:
iq['disco_info'].addIdentity(
category='component',
itype='generic')
else:
iq['disco_info'].addIdentity(
category='client',
itype='bot')
log.info("No identity found for node '%'," + \
"using default, generic identity")
iq['disco_info']['features'] = node.info['features']
iq.send()
else:
log.debug("Node %s requested, but does not exist." % node_name)
iq.reply().error().setPayload(iq['disco_info'].xml)
@ -287,10 +307,7 @@ class xep_0030(base.base_plugin):
return
node_name = iq['disco_items']['node']
if not node_name:
node_name = 'main'
log.debug("Using default handler for disco#items on node '%s'." % node_name)
log.debug("Using default handler for disco#items on node: '%s'." % node_name)
if node_name in self.nodes:
node = self.nodes[node_name]
@ -321,17 +338,17 @@ class xep_0030(base.base_plugin):
iq['disco_items']['node'] = node
return iq.send()
def add_feature(self, feature, node='main'):
def add_feature(self, feature, node=''):
self.add_node(node)
self.nodes[node].addFeature(feature)
def add_identity(self, category='', itype='', name='', node='main'):
def add_identity(self, category='', itype='', name='', node=''):
self.add_node(node)
self.nodes[node].addIdentity(category=category,
id_type=itype,
name=name)
def add_item(self, jid=None, name='', node='main', subnode=''):
def add_item(self, jid=None, name='', node='', subnode=''):
self.add_node(node)
self.add_node(subnode)
if jid is None:

View file

@ -257,7 +257,7 @@ class SleekTest(unittest.TestCase):
def stream_start(self, mode='client', skip=True, header=None,
socket='mock', jid='tester@localhost',
password='test', server='localhost',
port=5222):
port=5222, plugins=None):
"""
Initialize an XMPP client or component using a dummy XML stream.
@ -277,6 +277,8 @@ class SleekTest(unittest.TestCase):
server -- The name of the XMPP server. Defaults to 'localhost'.
port -- The port to use when connecting to the server.
Defaults to 5222.
plugins -- List of plugins to register. By default, all plugins
are loaded.
"""
if mode == 'client':
self.xmpp = ClientXMPP(jid, password)
@ -312,7 +314,11 @@ class SleekTest(unittest.TestCase):
else:
raise ValueError("Unknown socket type.")
self.xmpp.register_plugins()
if plugins is None:
self.xmpp.register_plugins()
else:
for plugin in plugins:
self.xmpp.register_plugin(plugin)
self.xmpp.process(threaded=True)
if skip:
if socket != 'live':

View file

@ -0,0 +1,83 @@
import time
from sleekxmpp.test import *
class TestStreamDisco(SleekTest):
"""
Test using the XEP-0030 plugin.
"""
def tearDown(self):
self.stream_close()
def testInfoEmptyNode(self):
"""
Info queries to a node MUST have at least one identity
and feature, namely http://jabber.org/protocol/disco#info.
Since the XEP-0030 plugin is loaded, a disco response should
be generated and not an error result.
"""
self.stream_start(plugins=['xep_0030'])
self.recv("""
<iq type="get" id="test">
<query xmlns="http://jabber.org/protocol/disco#info" />
</iq>
""")
self.send("""
<iq type="result" id="test">
<query xmlns="http://jabber.org/protocol/disco#info">
<identity category="client" type="bot" />
<feature var="http://jabber.org/protocol/disco#info" />
</query>
</iq>""")
def testInfoEmptyNodeComponent(self):
"""
Test requesting an empty node using a Component.
"""
self.stream_start(mode='component',
plugins=['xep_0030'])
self.recv("""
<iq type="get" id="test">
<query xmlns="http://jabber.org/protocol/disco#info" />
</iq>
""")
self.send("""
<iq type="result" id="test">
<query xmlns="http://jabber.org/protocol/disco#info">
<identity category="component" type="generic" />
<feature var="http://jabber.org/protocol/disco#info" />
</query>
</iq>""")
def testInfoIncludeNode(self):
"""
Results for info queries directed to a particular node MUST
include the node in the query response.
"""
self.stream_start(plugins=['xep_0030'])
self.xmpp['xep_0030'].add_node('testing')
self.recv("""
<iq type="get" id="test">
<query xmlns="http://jabber.org/protocol/disco#info"
node="testing" />
</iq>
""")
self.send("""
<iq type="result" id="test">
<query xmlns="http://jabber.org/protocol/disco#info"
node="testing">
</query>
</iq>""",
method='mask')
suite = unittest.TestLoader().loadTestsFromTestCase(TestStreamDisco)