diff options
author | Simon McVittie <simon.mcvittie@collabora.co.uk> | 2010-07-01 13:00:41 +0100 |
---|---|---|
committer | Simon McVittie <simon.mcvittie@collabora.co.uk> | 2010-07-01 13:00:41 +0100 |
commit | 7f234add16a76d62c42c7616e11b3492017f2253 (patch) | |
tree | 4b8c6cd21f2162669e9c28a0ddda877c8c869d63 | |
parent | c78714159040a1f817a7ba5a3a840575be0ad247 (diff) | |
download | telepathy-haze-7f234add16a76d62c42c7616e11b3492017f2253.tar.gz |
Test adding to, and removing from, groups, including fd.o #21294
-rw-r--r-- | tests/twisted/Makefile.am | 1 | ||||
-rw-r--r-- | tests/twisted/roster/groups.py | 209 |
2 files changed, 210 insertions, 0 deletions
diff --git a/tests/twisted/Makefile.am b/tests/twisted/Makefile.am index 9e7b780..7beaca7 100644 --- a/tests/twisted/Makefile.am +++ b/tests/twisted/Makefile.am @@ -5,6 +5,7 @@ TWISTED_TESTS = \ connect/twice-to-same-account.py \ presence/presence.py \ roster/initial-roster.py \ + roster/groups.py \ roster/publish.py \ roster/removed-from-rp-subscribe.py \ roster/subscribe.py \ diff --git a/tests/twisted/roster/groups.py b/tests/twisted/roster/groups.py new file mode 100644 index 0000000..4702f2e --- /dev/null +++ b/tests/twisted/roster/groups.py @@ -0,0 +1,209 @@ +""" +Test adding to, and removing from, groups +""" + +import dbus + +from twisted.words.protocols.jabber.client import IQ +from twisted.words.xish import domish, xpath + +from servicetest import (EventPattern, wrap_channel, assertLength, + assertEquals, call_async, sync_dbus, assertContains) +from hazetest import acknowledge_iq, exec_test, sync_stream +import constants as cs +import ns + +def test(q, bus, conn, stream): + conn.Connect() + q.expect('dbus-signal', signal='StatusChanged', + args=[cs.CONN_STATUS_CONNECTED, cs.CSR_REQUESTED]) + + call_async(q, conn.Requests, 'EnsureChannel',{ + cs.CHANNEL_TYPE: cs.CHANNEL_TYPE_CONTACT_LIST, + cs.TARGET_HANDLE_TYPE: cs.HT_LIST, + cs.TARGET_ID: 'subscribe', + }) + e = q.expect('dbus-return', method='EnsureChannel') + subscribe = wrap_channel(bus.get_object(conn.bus_name, e.value[1]), + cs.CHANNEL_TYPE_CONTACT_LIST) + + romeo, juliet, duncan = conn.RequestHandles(cs.HT_CONTACT, + ['romeo@montague.lit', 'juliet@capulet.lit', + 'duncan@scotland.lit']) + + # receive some roster pushes for the "initial" state + iq = IQ(stream, 'set') + iq['id'] = 'roster-push' + query = iq.addElement(('jabber:iq:roster', 'query')) + item = query.addElement('item') + item['jid'] = 'juliet@capulet.lit' + item['subscription'] = 'both' + group = item.addElement('group', content='Still alive') + group = item.addElement('group', content='Capulets') + stream.send(iq) + + iq = IQ(stream, 'set') + iq['id'] = 'roster-push' + query = iq.addElement(('jabber:iq:roster', 'query')) + item = query.addElement('item') + item['jid'] = 'romeo@montague.lit' + item['subscription'] = 'both' + group = item.addElement('group', content='Still alive') + stream.send(iq) + + iq = IQ(stream, 'set') + iq['id'] = 'roster-push' + query = iq.addElement(('jabber:iq:roster', 'query')) + item = query.addElement('item') + item['jid'] = 'duncan@scotland.lit' + item['subscription'] = 'both' + stream.send(iq) + + sync_dbus(bus, q, conn) + sync_stream(q, stream) + + call_async(q, conn.Requests, 'EnsureChannel',{ + cs.CHANNEL_TYPE: cs.CHANNEL_TYPE_CONTACT_LIST, + cs.TARGET_HANDLE_TYPE: cs.HT_GROUP, + cs.TARGET_ID: 'Still alive', + }) + e = q.expect('dbus-return', method='EnsureChannel') + still_alive = wrap_channel(bus.get_object(conn.bus_name, e.value[1]), + cs.CHANNEL_TYPE_CONTACT_LIST) + + call_async(q, conn.Requests, 'EnsureChannel',{ + cs.CHANNEL_TYPE: cs.CHANNEL_TYPE_CONTACT_LIST, + cs.TARGET_HANDLE_TYPE: cs.HT_GROUP, + cs.TARGET_ID: 'Capulets', + }) + e = q.expect('dbus-return', method='EnsureChannel') + capulets = wrap_channel(bus.get_object(conn.bus_name, e.value[1]), + cs.CHANNEL_TYPE_CONTACT_LIST) + + # the XMPP prpl puts people into some sort of group, probably called + # Buddies + channels = conn.Properties.Get(cs.CONN_IFACE_REQUESTS, 'Channels') + default_group = None + default_props = None + + for path, props in channels: + if props.get(cs.CHANNEL_TYPE) != cs.CHANNEL_TYPE_CONTACT_LIST: + continue + + if props.get(cs.TARGET_HANDLE_TYPE) != cs.HT_GROUP: + continue + + if props.get(cs.TARGET_ID) in ('Capulets', 'Still alive'): + continue + + if default_group is not None: + raise AssertionError('Two unexplained groups: %s, %s' % + (path, default_group.object_path)) + + default_group = wrap_channel(bus.get_object(conn.bus_name, path), + cs.CHANNEL_TYPE_CONTACT_LIST) + default_group_name = props.get(cs.TARGET_ID) + + assertEquals(set([romeo, juliet]), set(still_alive.Group.GetMembers())) + assertEquals(set([juliet]), set(capulets.Group.GetMembers())) + assertEquals(set([duncan]), set(default_group.Group.GetMembers())) + + # We can't remove Duncan from the default group, because it's his only + # group + call_async(q, default_group.Group, 'RemoveMembers', [duncan], '') + q.expect('dbus-error', method='RemoveMembers', + name=cs.NOT_AVAILABLE) + + # Make a new group and add Duncan to it + call_async(q, conn.Requests, 'CreateChannel',{ + cs.CHANNEL_TYPE: cs.CHANNEL_TYPE_CONTACT_LIST, + cs.TARGET_HANDLE_TYPE: cs.HT_GROUP, + cs.TARGET_ID: 'Scots', + }) + e = q.expect('dbus-return', method='CreateChannel') + scots = wrap_channel(bus.get_object(conn.bus_name, e.value[0]), + cs.CHANNEL_TYPE_CONTACT_LIST) + assertEquals(set(), set(scots.Group.GetMembers())) + + call_async(q, scots.Group, 'AddMembers', [duncan], '') + iq, _, _ = q.expect_many( + EventPattern('stream-iq', iq_type='set', query_name='query', + query_ns=ns.ROSTER), + EventPattern('dbus-signal', signal='MembersChanged', + path=scots.object_path, + args=['', [duncan], [], [], [], 0, cs.GC_REASON_NONE]), + EventPattern('dbus-return', method='AddMembers'), + ) + assertEquals('duncan@scotland.lit', iq.stanza.query.item['jid']) + groups = set([str(x) for x in xpath.queryForNodes('/iq/query/item/group', + iq.stanza)]) + assertLength(2, groups) + assertContains(default_group_name, groups) + assertContains('Scots', groups) + + # Now we can remove him from the default group. Much rejoicing. + call_async(q, default_group.Group, 'RemoveMembers', [duncan], '') + iq, _, _ = q.expect_many( + EventPattern('stream-iq', iq_type='set', query_name='query', + query_ns=ns.ROSTER), + EventPattern('dbus-signal', signal='MembersChanged', + path=default_group.object_path, + args=['', [], [duncan], [], [], 0, cs.GC_REASON_NONE]), + EventPattern('dbus-return', method='RemoveMembers'), + ) + assertEquals('duncan@scotland.lit', iq.stanza.query.item['jid']) + groups = set([str(x) for x in xpath.queryForNodes('/iq/query/item/group', + iq.stanza)]) + assertLength(1, groups) + assertContains('Scots', groups) + + # Romeo dies. If he drops off the roster as a result, that would be + # fd.o #21294. However, to fix that bug, Haze now puts him in the + # default group. + call_async(q, still_alive.Group, 'RemoveMembers', [romeo], '') + iq1, iq2, _, _, _ = q.expect_many( + EventPattern('stream-iq', iq_type='set', query_name='query', + query_ns=ns.ROSTER), + EventPattern('stream-iq', iq_type='set', query_name='query', + query_ns=ns.ROSTER), + EventPattern('dbus-signal', signal='MembersChanged', + path=still_alive.object_path, + args=['', [], [romeo], [], [], 0, cs.GC_REASON_NONE]), + EventPattern('dbus-signal', signal='MembersChanged', + path=default_group.object_path, + args=['', [romeo], [], [], [], 0, cs.GC_REASON_NONE]), + EventPattern('dbus-return', method='RemoveMembers'), + ) + + assertEquals('romeo@montague.lit', iq1.stanza.query.item['jid']) + groups = set([str(x) for x in xpath.queryForNodes('/iq/query/item/group', + iq1.stanza)]) + assertLength(2, groups) + assertContains('Still alive', groups) + assertContains(default_group_name, groups) + + assertEquals('romeo@montague.lit', iq2.stanza.query.item['jid']) + groups = set([str(x) for x in xpath.queryForNodes('/iq/query/item/group', + iq2.stanza)]) + assertLength(1, groups) + assertContains(default_group_name, groups) + + # Juliet dies. She's in another group already, so the workaround for + # fd.o #21294 is not active. + call_async(q, still_alive.Group, 'RemoveMembers', [juliet], '') + iq, _, _ = q.expect_many( + EventPattern('stream-iq', iq_type='set', query_name='query', + query_ns=ns.ROSTER), + EventPattern('dbus-signal', signal='MembersChanged', + path=still_alive.object_path, + args=['', [], [juliet], [], [], 0, cs.GC_REASON_NONE]), + EventPattern('dbus-return', method='RemoveMembers'), + ) + assertEquals('juliet@capulet.lit', iq.stanza.query.item['jid']) + groups = set([str(x) for x in xpath.queryForNodes('/iq/query/item/group', + iq.stanza)]) + assertLength(1, groups) + assertContains('Capulets', groups) + +if __name__ == '__main__': + exec_test(test) |