diff --git a/src/common/caps.py b/src/common/caps.py index c092399a4..9ef228e33 100644 --- a/src/common/caps.py +++ b/src/common/caps.py @@ -62,7 +62,7 @@ class AbstractEntityCapabilities(object): self._discover(connection, jid) q.queried = 1 - def supports_feature(self, feature): + def contains_feature(self, feature): ''' Returns true if these capabilities contain the given feature ''' features = self._lookup_in_cache().features @@ -116,10 +116,13 @@ class NullEntityCapabilities(AbstractEntityCapabilities): Assumes everything is supported. ''' + def __init__(self): + pass + def query_client_of_jid_if_unknown(self, connection, jid): pass - def supports_feature(self, feature): + def contains_feature(self, feature): return True diff --git a/src/common/contacts.py b/src/common/contacts.py index 73afb8c70..c3b605725 100644 --- a/src/common/contacts.py +++ b/src/common/contacts.py @@ -30,7 +30,7 @@ import common.gajim -class Contact: +class Contact(object): '''Information concerning each contact''' def __init__(self, jid='', name='', groups=[], show='', status='', sub='', ask='', resource='', priority=0, keyID='', caps_node=None, @@ -135,6 +135,33 @@ class Contact: return False + def _set_supported_caps(self, value): + ''' + Set an EntityCapabilities object + ''' + self._caps = value + + def _get_supported_caps(self): + ''' + Returns a function which delegates to the EntityCapabilites support checker + + This allows easy checks like: + if contact.supports(NS_COOL_FEATURE): ... + ''' + def test(feature): + if self.show == 'offline': + # Unfortunately, if all resources are offline, the contact + # includes the last resource that was online. Check for its + # show, so we can be sure it's existant. Otherwise, we still + # return caps for a contact that has no resources left. + return False + else: + return self._caps.contains_feature(feature) + return test + + supports = property(_get_supported_caps, _set_supported_caps) + + class GC_Contact: '''Information concerning each groupchat contact''' def __init__(self, room_jid='', name='', show='', status='', role='', diff --git a/test/test_caps.py b/test/test_caps.py index f9b0b03fd..3c5dfaa19 100644 --- a/test/test_caps.py +++ b/test/test_caps.py @@ -118,35 +118,35 @@ class TestEntityCapabilities(CommonCapsTest): def setUp(self): CommonCapsTest.setUp(self) - self.entity = EntityCapabilities(self.cc, self.caps_hash, self.node, + self.caps = EntityCapabilities(self.cc, self.caps_hash, self.node, self.caps_method) def test_no_query_client_of_jid(self): ''' Client must not be queried if the data is already cached ''' connection = Mock() self.cc.initialize_from_db() - self.entity.query_client_of_jid_if_unknown(connection, "test@gajim.org") + self.caps.query_client_of_jid_if_unknown(connection, "test@gajim.org") self.assertEqual(0, len(connection.mockGetAllCalls())) def test_query_client_of_jid_if_unknown(self): ''' Client must be queried if the data is unkown ''' connection = Mock() - self.entity.query_client_of_jid_if_unknown(connection, "test@gajim.org") + self.caps.query_client_of_jid_if_unknown(connection, "test@gajim.org") connection.mockCheckCall(0, "discoverInfo", 'test@gajim.org', 'http://gajim.org#RNzJvJnTWqczirzu+YF4V8am9ro=') def test_is_supported(self): - self.assertTrue(self.entity.supports_feature(self.chatstates), + self.assertTrue(self.caps.contains_feature(self.chatstates), msg="Assume everything is supported, if we don't have caps") self.cc.initialize_from_db() - self.assertFalse(self.entity.supports_feature(self.chatstates), + self.assertFalse(self.caps.contains_feature(self.chatstates), msg="Must return false on unsupported feature") - self.assertTrue(self.entity.supports_feature(self.muc), + self.assertTrue(self.caps.contains_feature(self.muc), msg="Must return True on supported feature") @@ -154,20 +154,20 @@ class TestOldEntityCapabilities(TestEntityCapabilities): def setUp(self): TestEntityCapabilities.setUp(self) - self.entity = OldEntityCapabilities(self.cc, self.caps_hash, self.node) + self.caps = OldEntityCapabilities(self.cc, self.caps_hash, self.node) def test_no_query_client_of_jid(self): ''' Client must not be queried if the data is already cached ''' connection = Mock() self.cc.initialize_from_db() - self.entity.query_client_of_jid_if_unknown(connection, "test@gajim.org") + self.caps.query_client_of_jid_if_unknown(connection, "test@gajim.org") self.assertEqual(0, len(connection.mockGetAllCalls())) def test_query_client_of_jid_if_unknown(self): ''' Client must be queried if the data is unkown ''' connection = Mock() - self.entity.query_client_of_jid_if_unknown(connection, "test@gajim.org") + self.caps.query_client_of_jid_if_unknown(connection, "test@gajim.org") connection.mockCheckCall(0, "discoverInfo", "test@gajim.org") diff --git a/test/test_contacts.py b/test/test_contacts.py new file mode 100644 index 000000000..ae25889da --- /dev/null +++ b/test/test_contacts.py @@ -0,0 +1,46 @@ +''' +Test for Contact, GC_Contact and Contacts +''' +import unittest + +import lib +lib.setup_env() + +from common.contacts import Contact +from common.caps import NullEntityCapabilities + +from mock import Mock + +class TestContact(unittest.TestCase): + + + + def test_supports(self): + ''' Test the Entity Capabilities part of the contact instance ''' + + NS_MUC = 'http://jabber.org/protocol/muc' + + # Test with mocks to get basic set/get property behaviour checked + all_supported_mock_entity_caps = Mock( + returnValues={"contains_feature": True}) + nothing_supported_mock_entity_caps = Mock( + returnValues={"contains_feature": False}) + + contact = Contact() + + contact.supports = all_supported_mock_entity_caps + self.assertTrue(contact.supports(NS_MUC)) + + contact.supports = nothing_supported_mock_entity_caps + self.assertFalse(contact.supports(NS_MUC)) + + # Test with EntityCapabilites to detect API changes + contact.supports = NullEntityCapabilities() + self.assertTrue(contact.supports(NS_MUC), + msg="Default behaviour is to support everything on unknown caps") + + + + +if __name__ == "__main__": + unittest.main() \ No newline at end of file