mirror of
https://github.com/correl/SleekXMPP.git
synced 2024-12-25 19:25:41 +00:00
Adding stream tests for XEP-0030.
Fixed some errors when responding to disco requests.
This commit is contained in:
parent
291b118aca
commit
ab25301953
4 changed files with 127 additions and 19 deletions
|
@ -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
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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':
|
||||
|
|
83
tests/test_stream_xep_0030.py
Normal file
83
tests/test_stream_xep_0030.py
Normal 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)
|
Loading…
Reference in a new issue