2009-01-11 14:49:03 +01:00
|
|
|
'''
|
|
|
|
Tests for capabilities and the capabilities cache
|
|
|
|
'''
|
2008-06-12 05:56:47 +02:00
|
|
|
import unittest
|
|
|
|
|
2018-11-10 18:23:40 +01:00
|
|
|
from unittest.mock import MagicMock, Mock
|
2018-01-26 23:15:08 +01:00
|
|
|
from nbxmpp import NS_MUC, NS_PING, NS_XHTML_IM, Iq
|
2017-08-12 02:39:55 +02:00
|
|
|
from gajim.common import caps_cache as caps
|
2018-07-22 12:18:24 +02:00
|
|
|
from gajim.common.modules.discovery import Discovery
|
2008-06-12 05:56:47 +02:00
|
|
|
|
2018-11-21 19:58:57 +01:00
|
|
|
EXAMPLES = [
|
|
|
|
'''<iq>
|
2018-01-26 23:15:08 +01:00
|
|
|
<query xmlns='http://jabber.org/protocol/disco#info' node='http://psi-im.org#q07IKJEyjvHSyhy//CH0CxmKi8w='>
|
|
|
|
<identity xml:lang='en' category='client' name='Psi 0.11' type='pc'/>
|
|
|
|
<identity xml:lang='el' category='client' name='Ψ 0.11' type='pc'/>
|
|
|
|
<feature var='http://jabber.org/protocol/caps'/>
|
|
|
|
<feature var='http://jabber.org/protocol/disco#info'/>
|
|
|
|
<feature var='http://jabber.org/protocol/disco#items'/>
|
|
|
|
<feature var='http://jabber.org/protocol/muc'/>
|
|
|
|
<x xmlns='jabber:x:data' type='result'>
|
|
|
|
<field var='FORM_TYPE' type='hidden'>
|
|
|
|
<value>urn:xmpp:dataforms:softwareinfo</value>
|
|
|
|
</field>
|
|
|
|
<field var='ip_version'>
|
|
|
|
<value>ipv4</value>
|
|
|
|
<value>ipv6</value>
|
|
|
|
</field>
|
|
|
|
<field var='os'>
|
|
|
|
<value>Mac</value>
|
|
|
|
</field>
|
|
|
|
<field var='os_version'>
|
|
|
|
<value>10.5.1</value>
|
|
|
|
</field>
|
|
|
|
<field var='software'>
|
|
|
|
<value>Psi</value>
|
|
|
|
</field>
|
|
|
|
<field var='software_version'>
|
|
|
|
<value>0.11</value>
|
|
|
|
</field>
|
|
|
|
</x>
|
|
|
|
</query>
|
2018-11-21 19:58:57 +01:00
|
|
|
</iq>
|
|
|
|
''',
|
|
|
|
|
|
|
|
'''<iq>
|
|
|
|
<query node="http://bombusmod.net.ru/caps#tbBQGBMv8g8U7kW55TEZZRnMCJ4=" xmlns="http://jabber.org/protocol/disco#info">
|
|
|
|
<identity category="client" name="BombusMod" type="mobile"/>
|
|
|
|
<feature var="http://jabber.org/protocol/chatstates"/>
|
|
|
|
<feature var="http://jabber.org/protocol/disco#info"/>
|
|
|
|
<feature var="http://jabber.org/protocol/disco#items"/>
|
|
|
|
<feature var="http://jabber.org/protocol/rosterx"/>
|
|
|
|
<feature var="jabber:iq:last"/>
|
|
|
|
<feature var="jabber:iq:privacy"/>
|
|
|
|
<feature var="jabber:iq:roster"/>
|
|
|
|
<feature var="jabber:iq:time"/>
|
|
|
|
<feature var="jabber:iq:version"/>
|
|
|
|
<feature var="jabber:x:oob"/>
|
|
|
|
<feature var="urn:xmpp:ping"/>
|
|
|
|
<feature var="urn:xmpp:receipts"/>
|
|
|
|
<feature var="urn:xmpp:time"/>
|
|
|
|
</query>
|
|
|
|
</iq>
|
|
|
|
''',
|
|
|
|
|
|
|
|
'''<iq>
|
|
|
|
<query node="http://jappix.org/#qRsaGbKTz8EwAOakYO00InkZUxM=" xmlns="http://jabber.org/protocol/disco#info">
|
|
|
|
<identity category="client" name="Jappix" type="web"/>
|
|
|
|
<feature var="http://jabber.org/protocol/activity"/>
|
|
|
|
<feature var="http://jabber.org/protocol/activity+notify"/>
|
|
|
|
<feature var="http://jabber.org/protocol/caps"/>
|
|
|
|
<feature var="http://jabber.org/protocol/chatstates"/>
|
|
|
|
<feature var="http://jabber.org/protocol/commands"/>
|
|
|
|
<feature var="http://jabber.org/protocol/disco#info"/>
|
|
|
|
<feature var="http://jabber.org/protocol/disco#items"/>
|
|
|
|
<feature var="http://jabber.org/protocol/geoloc"/>
|
|
|
|
<feature var="http://jabber.org/protocol/geoloc+notify"/>
|
|
|
|
<feature var="http://jabber.org/protocol/http-auth"/>
|
|
|
|
<feature var="http://jabber.org/protocol/httpbind"/>
|
|
|
|
<feature var="http://jabber.org/protocol/mood"/>
|
|
|
|
<feature var="http://jabber.org/protocol/mood+notify"/>
|
|
|
|
<feature var="http://jabber.org/protocol/muc"/>
|
|
|
|
<feature var="http://jabber.org/protocol/muc#admin"/>
|
|
|
|
<feature var="http://jabber.org/protocol/muc#owner"/>
|
|
|
|
<feature var="http://jabber.org/protocol/muc#roomconfig"/>
|
|
|
|
<feature var="http://jabber.org/protocol/muc#user"/>
|
|
|
|
<feature var="http://jabber.org/protocol/nick"/>
|
|
|
|
<feature var="http://jabber.org/protocol/pubsub#retrieve-items"/>
|
|
|
|
<feature var="http://jabber.org/protocol/rosterx"/>
|
|
|
|
<feature var="http://jabber.org/protocol/tune"/>
|
|
|
|
<feature var="http://jabber.org/protocol/tune+notify"/>
|
|
|
|
<feature var="http://jabber.org/protocol/xhtml-im"/>
|
|
|
|
<feature var="ipv6"/>
|
|
|
|
<feature var="jabber:iq:last"/>
|
|
|
|
<feature var="jabber:iq:oob"/>
|
|
|
|
<feature var="jabber:iq:privacy"/>
|
|
|
|
<feature var="jabber:iq:private"/>
|
|
|
|
<feature var="jabber:iq:register"/>
|
|
|
|
<feature var="jabber:iq:roster"/>
|
|
|
|
<feature var="jabber:iq:search"/>
|
|
|
|
<feature var="jabber:iq:version"/>
|
|
|
|
<feature var="jabber:x:data"/>
|
|
|
|
<feature var="jabber:x:oob"/>
|
|
|
|
<feature var="urn:ietf:params:xml:ns:vcard-4.0"/>
|
|
|
|
<feature var="urn:ietf:rfc:3264"/>
|
|
|
|
<feature var="urn:xmpp:avatar:data"/>
|
|
|
|
<feature var="urn:xmpp:avatar:metadata"/>
|
|
|
|
<feature var="urn:xmpp:delay"/>
|
|
|
|
<feature var="urn:xmpp:extdisco:1"/>
|
|
|
|
<feature var="urn:xmpp:inbox"/>
|
|
|
|
<feature var="urn:xmpp:inbox+notify"/>
|
|
|
|
<feature var="urn:xmpp:jingle:1"/>
|
|
|
|
<feature var="urn:xmpp:jingle:apps:rtp:1"/>
|
|
|
|
<feature var="urn:xmpp:jingle:apps:rtp:audio"/>
|
|
|
|
<feature var="urn:xmpp:jingle:apps:rtp:rtcp-fb:0"/>
|
|
|
|
<feature var="urn:xmpp:jingle:apps:rtp:rtp-hdrext:0"/>
|
|
|
|
<feature var="urn:xmpp:jingle:apps:rtp:video"/>
|
|
|
|
<feature var="urn:xmpp:jingle:apps:rtp:zrtp:1"/>
|
|
|
|
<feature var="urn:xmpp:jingle:transports:ice-udp:1"/>
|
|
|
|
<feature var="urn:xmpp:mam:0"/>
|
|
|
|
<feature var="urn:xmpp:microblog:0"/>
|
|
|
|
<feature var="urn:xmpp:microblog:0+notify"/>
|
|
|
|
<feature var="urn:xmpp:ping"/>
|
|
|
|
<feature var="urn:xmpp:receipts"/>
|
|
|
|
<feature var="urn:xmpp:time"/>
|
|
|
|
<feature var="urn:xmpp:tmp:jingle:apps:dtls:0"/>
|
|
|
|
<feature var="vcard-temp"/>
|
|
|
|
</query>
|
|
|
|
</iq>''',
|
|
|
|
]
|
2018-01-26 23:15:08 +01:00
|
|
|
|
2009-12-10 18:31:00 +01:00
|
|
|
|
|
|
|
class CommonCapsTest(unittest.TestCase):
|
|
|
|
|
2010-02-08 15:08:40 +01:00
|
|
|
def setUp(self):
|
|
|
|
self.caps_method = 'sha-1'
|
|
|
|
self.caps_hash = 'm3P2WeXPMGVH2tZPe7yITnfY0Dw='
|
|
|
|
self.client_caps = (self.caps_method, self.caps_hash)
|
2009-12-10 18:31:00 +01:00
|
|
|
|
2010-02-08 15:08:40 +01:00
|
|
|
self.node = "http://gajim.org"
|
|
|
|
self.identity = {'category': 'client', 'type': 'pc', 'name':'Gajim'}
|
2008-06-12 05:56:47 +02:00
|
|
|
|
2010-02-08 15:08:40 +01:00
|
|
|
self.identities = [self.identity]
|
|
|
|
self.features = [NS_MUC, NS_XHTML_IM] # NS_MUC not supported!
|
2009-12-10 18:31:00 +01:00
|
|
|
|
2010-02-08 15:08:40 +01:00
|
|
|
# Simulate a filled db
|
|
|
|
db_caps_cache = [
|
|
|
|
(self.caps_method, self.caps_hash, self.identities, self.features),
|
|
|
|
('old', self.node + '#' + self.caps_hash, self.identities, self.features)]
|
2018-11-10 18:23:40 +01:00
|
|
|
self.logger = Mock()
|
|
|
|
self.logger.iter_caps_data = Mock(return_value=db_caps_cache)
|
2009-12-10 18:31:00 +01:00
|
|
|
|
2010-02-08 15:08:40 +01:00
|
|
|
self.cc = caps.CapsCache(self.logger)
|
|
|
|
caps.capscache = self.cc
|
2009-12-10 18:31:00 +01:00
|
|
|
|
|
|
|
|
2009-10-25 22:32:18 +01:00
|
|
|
class TestCapsCache(CommonCapsTest):
|
2009-12-10 18:31:00 +01:00
|
|
|
|
2010-02-08 15:08:40 +01:00
|
|
|
def test_set_retrieve(self):
|
|
|
|
''' Test basic set / retrieve cycle '''
|
2008-06-12 05:56:47 +02:00
|
|
|
|
2010-02-08 15:08:40 +01:00
|
|
|
self.cc[self.client_caps].identities = self.identities
|
|
|
|
self.cc[self.client_caps].features = self.features
|
2008-06-12 05:56:47 +02:00
|
|
|
|
2017-09-10 12:21:10 +02:00
|
|
|
self.assertTrue(NS_MUC in self.cc[self.client_caps].features)
|
|
|
|
self.assertTrue(NS_PING not in self.cc[self.client_caps].features)
|
2008-08-27 09:49:11 +02:00
|
|
|
|
2010-02-08 15:08:40 +01:00
|
|
|
identities = self.cc[self.client_caps].identities
|
2009-10-25 21:17:32 +01:00
|
|
|
|
2010-02-08 15:08:40 +01:00
|
|
|
self.assertEqual(1, len(identities))
|
2009-10-25 21:17:32 +01:00
|
|
|
|
2010-02-08 15:08:40 +01:00
|
|
|
identity = identities[0]
|
|
|
|
self.assertEqual('client', identity['category'])
|
|
|
|
self.assertEqual('pc', identity['type'])
|
2009-12-10 18:31:00 +01:00
|
|
|
|
2010-02-08 15:08:40 +01:00
|
|
|
def test_set_and_store(self):
|
|
|
|
''' Test client_caps update gets logged into db '''
|
2009-12-10 18:31:00 +01:00
|
|
|
|
2010-02-08 15:08:40 +01:00
|
|
|
item = self.cc[self.client_caps]
|
|
|
|
item.set_and_store(self.identities, self.features)
|
2009-12-10 18:31:00 +01:00
|
|
|
|
2018-11-10 18:23:40 +01:00
|
|
|
self.logger.add_caps_entry.assert_called_once_with(self.caps_method,
|
|
|
|
self.caps_hash,
|
|
|
|
self.identities,
|
|
|
|
self.features)
|
2009-12-10 18:31:00 +01:00
|
|
|
|
2010-02-08 15:08:40 +01:00
|
|
|
def test_initialize_from_db(self):
|
|
|
|
''' Read cashed dummy data from db '''
|
|
|
|
self.assertEqual(self.cc[self.client_caps].status, caps.NEW)
|
|
|
|
self.cc.initialize_from_db()
|
|
|
|
self.assertEqual(self.cc[self.client_caps].status, caps.CACHED)
|
2009-10-25 21:17:32 +01:00
|
|
|
|
2010-02-08 15:08:40 +01:00
|
|
|
def test_preload_triggering_query(self):
|
|
|
|
''' Make sure that preload issues a disco '''
|
2018-07-22 12:18:24 +02:00
|
|
|
connection = MagicMock()
|
2010-02-08 15:08:40 +01:00
|
|
|
client_caps = caps.ClientCaps(self.caps_hash, self.node, self.caps_method)
|
2009-12-10 18:31:00 +01:00
|
|
|
|
2018-07-22 12:18:24 +02:00
|
|
|
self.cc.query_client_of_jid_if_unknown(
|
|
|
|
connection, "test@gajim.org", client_caps)
|
2009-12-10 18:31:00 +01:00
|
|
|
|
2018-07-22 12:18:24 +02:00
|
|
|
self.assertEqual(1, connection.get_module('Discovery').disco_contact.call_count)
|
2009-12-10 18:31:00 +01:00
|
|
|
|
2010-02-08 15:08:40 +01:00
|
|
|
def test_no_preload_query_if_cashed(self):
|
|
|
|
''' Preload must not send a query if the data is already cached '''
|
2018-07-22 12:18:24 +02:00
|
|
|
connection = MagicMock()
|
2010-02-08 15:08:40 +01:00
|
|
|
client_caps = caps.ClientCaps(self.caps_hash, self.node, self.caps_method)
|
2009-10-27 20:31:09 +01:00
|
|
|
|
2010-02-08 15:08:40 +01:00
|
|
|
self.cc.initialize_from_db()
|
2018-07-22 12:18:24 +02:00
|
|
|
self.cc.query_client_of_jid_if_unknown(
|
|
|
|
connection, "test@gajim.org", client_caps)
|
2009-12-10 18:31:00 +01:00
|
|
|
|
2018-07-22 12:18:24 +02:00
|
|
|
self.assertEqual(0, connection.get_module('Discovery').disco_contact.call_count)
|
2009-12-10 18:31:00 +01:00
|
|
|
|
2010-02-08 15:08:40 +01:00
|
|
|
def test_hash(self):
|
|
|
|
'''tests the hash computation'''
|
2018-11-21 19:58:57 +01:00
|
|
|
for example in EXAMPLES:
|
|
|
|
stanza = Iq(node=example)
|
|
|
|
identities, features, data, node = Discovery.parse_info_response(stanza)
|
|
|
|
computed_hash = caps.compute_caps_hash(identities, features, data)
|
|
|
|
hash_ = node.split('#')[1]
|
|
|
|
self.assertEqual(hash_, computed_hash)
|
2008-08-27 09:49:11 +02:00
|
|
|
|
2009-10-25 21:17:32 +01:00
|
|
|
|
2009-10-26 19:20:16 +01:00
|
|
|
class TestClientCaps(CommonCapsTest):
|
2009-12-10 18:31:00 +01:00
|
|
|
|
2010-02-08 15:08:40 +01:00
|
|
|
def setUp(self):
|
|
|
|
CommonCapsTest.setUp(self)
|
|
|
|
self.client_caps = caps.ClientCaps(self.caps_hash, self.node, self.caps_method)
|
2009-12-10 18:31:00 +01:00
|
|
|
|
2010-02-08 15:08:40 +01:00
|
|
|
def test_query_by_get_discover_strategy(self):
|
|
|
|
''' Client must be queried if the data is unkown '''
|
2018-07-22 12:18:24 +02:00
|
|
|
connection = MagicMock()
|
2010-02-08 15:08:40 +01:00
|
|
|
discover = self.client_caps.get_discover_strategy()
|
|
|
|
discover(connection, "test@gajim.org")
|
2018-07-22 12:18:24 +02:00
|
|
|
connection.get_module('Discovery').disco_contact.assert_called_once_with(
|
|
|
|
'test@gajim.org', 'http://gajim.org#m3P2WeXPMGVH2tZPe7yITnfY0Dw=')
|
2009-12-10 18:31:00 +01:00
|
|
|
|
2010-02-08 15:08:40 +01:00
|
|
|
def test_client_supports(self):
|
|
|
|
self.assertTrue(caps.client_supports(self.client_caps, NS_PING),
|
|
|
|
msg="Assume supported, if we don't have caps")
|
2009-12-10 18:31:00 +01:00
|
|
|
|
2010-02-08 15:08:40 +01:00
|
|
|
self.assertFalse(caps.client_supports(self.client_caps, NS_XHTML_IM),
|
|
|
|
msg="Must not assume blacklisted feature is supported on default")
|
2009-12-10 18:31:00 +01:00
|
|
|
|
2010-02-08 15:08:40 +01:00
|
|
|
self.cc.initialize_from_db()
|
2009-12-10 18:31:00 +01:00
|
|
|
|
2010-02-08 15:08:40 +01:00
|
|
|
self.assertFalse(caps.client_supports(self.client_caps, NS_PING),
|
|
|
|
msg="Must return false on unsupported feature")
|
2009-12-10 18:31:00 +01:00
|
|
|
|
2010-02-08 15:08:40 +01:00
|
|
|
self.assertTrue(caps.client_supports(self.client_caps, NS_XHTML_IM),
|
|
|
|
msg="Must return True on supported feature")
|
2009-12-10 18:31:00 +01:00
|
|
|
|
2010-02-08 15:08:40 +01:00
|
|
|
self.assertTrue(caps.client_supports(self.client_caps, NS_MUC),
|
|
|
|
msg="Must return True on supported feature")
|
2009-10-26 19:20:16 +01:00
|
|
|
|
2009-12-10 18:31:00 +01:00
|
|
|
|
|
|
|
class TestOldClientCaps(TestClientCaps):
|
2009-10-25 22:32:18 +01:00
|
|
|
|
2010-02-08 15:08:40 +01:00
|
|
|
def setUp(self):
|
|
|
|
TestClientCaps.setUp(self)
|
|
|
|
self.client_caps = caps.OldClientCaps(self.caps_hash, self.node)
|
2009-12-10 18:31:00 +01:00
|
|
|
|
2010-02-08 15:08:40 +01:00
|
|
|
def test_query_by_get_discover_strategy(self):
|
|
|
|
''' Client must be queried if the data is unknown '''
|
2018-07-22 12:18:24 +02:00
|
|
|
connection = MagicMock()
|
2010-02-08 15:08:40 +01:00
|
|
|
discover = self.client_caps.get_discover_strategy()
|
|
|
|
discover(connection, "test@gajim.org")
|
2009-12-10 18:31:00 +01:00
|
|
|
|
2018-07-22 12:18:24 +02:00
|
|
|
connection.get_module('Discovery').disco_contact.assert_called_once_with('test@gajim.org')
|
2009-10-25 22:32:18 +01:00
|
|
|
|
2008-06-12 05:56:47 +02:00
|
|
|
if __name__ == '__main__':
|
2010-02-08 15:08:40 +01:00
|
|
|
unittest.main()
|