mirror of
https://github.com/correl/SleekXMPP.git
synced 2025-03-17 17:00:12 -09: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.boundjid = JID("")
|
||||||
|
|
||||||
self.plugin = {}
|
self.plugin = {}
|
||||||
|
self.plugin_config = {}
|
||||||
|
self.plugin_whitelist = []
|
||||||
self.roster = {}
|
self.roster = {}
|
||||||
self.is_component = False
|
self.is_component = False
|
||||||
self.auto_authorize = True
|
self.auto_authorize = True
|
||||||
|
|
|
@ -71,11 +71,12 @@ class DiscoInfo(ElementBase):
|
||||||
for idXML in idsXML:
|
for idXML in idsXML:
|
||||||
self.xml.remove(idXML)
|
self.xml.remove(idXML)
|
||||||
|
|
||||||
def addIdentity(self, category, id_type, name=''):
|
def addIdentity(self, category, itype, name=''):
|
||||||
idXML = ET.Element('{%s}identity' % self.namespace,
|
idXML = ET.Element('{%s}identity' % self.namespace)
|
||||||
{'category': category,
|
idXML.attrib['category'] = category
|
||||||
'type': id_type,
|
idXML.attrib['type'] = itype
|
||||||
'name': name})
|
if name:
|
||||||
|
idXML.attrib['name'] = name
|
||||||
self.xml.append(idXML)
|
self.xml.append(idXML)
|
||||||
|
|
||||||
def delIdentity(self, category, id_type, name=''):
|
def delIdentity(self, category, id_type, name=''):
|
||||||
|
@ -214,7 +215,10 @@ class xep_0030(base.base_plugin):
|
||||||
self.xmpp.add_event_handler('disco_items_request', self.handle_disco_items)
|
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.xmpp.add_event_handler('disco_info_request', self.handle_disco_info)
|
||||||
|
|
||||||
self.nodes = {'main': DiscoNode('main')}
|
self.nodes = {}
|
||||||
|
|
||||||
|
self.add_node('')
|
||||||
|
self.add_feature('http://jabber.org/protocol/disco#info', node='')
|
||||||
|
|
||||||
def add_node(self, node):
|
def add_node(self, node):
|
||||||
if node not in self.nodes:
|
if node not in self.nodes:
|
||||||
|
@ -258,14 +262,30 @@ class xep_0030(base.base_plugin):
|
||||||
return
|
return
|
||||||
|
|
||||||
node_name = iq['disco_info']['node']
|
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)
|
log.debug("Using default handler for disco#info on node '%s'." % node_name)
|
||||||
|
|
||||||
if node_name in self.nodes:
|
if node_name in self.nodes:
|
||||||
node = self.nodes[node_name]
|
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:
|
else:
|
||||||
log.debug("Node %s requested, but does not exist." % node_name)
|
log.debug("Node %s requested, but does not exist." % node_name)
|
||||||
iq.reply().error().setPayload(iq['disco_info'].xml)
|
iq.reply().error().setPayload(iq['disco_info'].xml)
|
||||||
|
@ -287,10 +307,7 @@ class xep_0030(base.base_plugin):
|
||||||
return
|
return
|
||||||
|
|
||||||
node_name = iq['disco_items']['node']
|
node_name = iq['disco_items']['node']
|
||||||
if not node_name:
|
log.debug("Using default handler for disco#items on node: '%s'." % node_name)
|
||||||
node_name = 'main'
|
|
||||||
|
|
||||||
log.debug("Using default handler for disco#items on node '%s'." % node_name)
|
|
||||||
|
|
||||||
if node_name in self.nodes:
|
if node_name in self.nodes:
|
||||||
node = self.nodes[node_name]
|
node = self.nodes[node_name]
|
||||||
|
@ -321,17 +338,17 @@ class xep_0030(base.base_plugin):
|
||||||
iq['disco_items']['node'] = node
|
iq['disco_items']['node'] = node
|
||||||
return iq.send()
|
return iq.send()
|
||||||
|
|
||||||
def add_feature(self, feature, node='main'):
|
def add_feature(self, feature, node=''):
|
||||||
self.add_node(node)
|
self.add_node(node)
|
||||||
self.nodes[node].addFeature(feature)
|
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.add_node(node)
|
||||||
self.nodes[node].addIdentity(category=category,
|
self.nodes[node].addIdentity(category=category,
|
||||||
id_type=itype,
|
id_type=itype,
|
||||||
name=name)
|
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(node)
|
||||||
self.add_node(subnode)
|
self.add_node(subnode)
|
||||||
if jid is None:
|
if jid is None:
|
||||||
|
|
|
@ -257,7 +257,7 @@ class SleekTest(unittest.TestCase):
|
||||||
def stream_start(self, mode='client', skip=True, header=None,
|
def stream_start(self, mode='client', skip=True, header=None,
|
||||||
socket='mock', jid='tester@localhost',
|
socket='mock', jid='tester@localhost',
|
||||||
password='test', server='localhost',
|
password='test', server='localhost',
|
||||||
port=5222):
|
port=5222, plugins=None):
|
||||||
"""
|
"""
|
||||||
Initialize an XMPP client or component using a dummy XML stream.
|
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'.
|
server -- The name of the XMPP server. Defaults to 'localhost'.
|
||||||
port -- The port to use when connecting to the server.
|
port -- The port to use when connecting to the server.
|
||||||
Defaults to 5222.
|
Defaults to 5222.
|
||||||
|
plugins -- List of plugins to register. By default, all plugins
|
||||||
|
are loaded.
|
||||||
"""
|
"""
|
||||||
if mode == 'client':
|
if mode == 'client':
|
||||||
self.xmpp = ClientXMPP(jid, password)
|
self.xmpp = ClientXMPP(jid, password)
|
||||||
|
@ -312,7 +314,11 @@ class SleekTest(unittest.TestCase):
|
||||||
else:
|
else:
|
||||||
raise ValueError("Unknown socket type.")
|
raise ValueError("Unknown socket type.")
|
||||||
|
|
||||||
|
if plugins is None:
|
||||||
self.xmpp.register_plugins()
|
self.xmpp.register_plugins()
|
||||||
|
else:
|
||||||
|
for plugin in plugins:
|
||||||
|
self.xmpp.register_plugin(plugin)
|
||||||
self.xmpp.process(threaded=True)
|
self.xmpp.process(threaded=True)
|
||||||
if skip:
|
if skip:
|
||||||
if socket != 'live':
|
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…
Add table
Reference in a new issue