~ubuntu-branches/ubuntu/natty/telepathy-haze/natty

« back to all changes in this revision

Viewing changes to tests/twisted/roster/groups.py

  • Committer: Bazaar Package Importer
  • Author(s): Jonny Lamb
  • Date: 2010-07-19 12:33:29 UTC
  • mfrom: (1.1.10 upstream)
  • Revision ID: james.westby@ubuntu.com-20100719123329-lz52qtzku66jpw17
Tags: 0.3.6-1
New upstream release.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
"""
 
2
Test adding to, and removing from, groups
 
3
"""
 
4
 
 
5
import dbus
 
6
 
 
7
from twisted.words.protocols.jabber.client import IQ
 
8
from twisted.words.xish import domish, xpath
 
9
 
 
10
from servicetest import (EventPattern, wrap_channel, assertLength,
 
11
        assertEquals, call_async, sync_dbus, assertContains)
 
12
from hazetest import acknowledge_iq, exec_test, sync_stream
 
13
import constants as cs
 
14
import ns
 
15
 
 
16
def test(q, bus, conn, stream):
 
17
    conn.Connect()
 
18
    q.expect('dbus-signal', signal='StatusChanged',
 
19
            args=[cs.CONN_STATUS_CONNECTED, cs.CSR_REQUESTED])
 
20
 
 
21
    call_async(q, conn.Requests, 'EnsureChannel',{
 
22
        cs.CHANNEL_TYPE: cs.CHANNEL_TYPE_CONTACT_LIST,
 
23
        cs.TARGET_HANDLE_TYPE: cs.HT_LIST,
 
24
        cs.TARGET_ID: 'subscribe',
 
25
        })
 
26
    e = q.expect('dbus-return', method='EnsureChannel')
 
27
    subscribe = wrap_channel(bus.get_object(conn.bus_name, e.value[1]),
 
28
            cs.CHANNEL_TYPE_CONTACT_LIST)
 
29
 
 
30
    romeo, juliet, duncan = conn.RequestHandles(cs.HT_CONTACT,
 
31
            ['romeo@montague.lit', 'juliet@capulet.lit',
 
32
                'duncan@scotland.lit'])
 
33
 
 
34
    # receive some roster pushes for the "initial" state
 
35
    iq = IQ(stream, 'set')
 
36
    iq['id'] = 'roster-push'
 
37
    query = iq.addElement(('jabber:iq:roster', 'query'))
 
38
    item = query.addElement('item')
 
39
    item['jid'] = 'juliet@capulet.lit'
 
40
    item['subscription'] = 'both'
 
41
    group = item.addElement('group', content='Still alive')
 
42
    group = item.addElement('group', content='Capulets')
 
43
    stream.send(iq)
 
44
 
 
45
    iq = IQ(stream, 'set')
 
46
    iq['id'] = 'roster-push'
 
47
    query = iq.addElement(('jabber:iq:roster', 'query'))
 
48
    item = query.addElement('item')
 
49
    item['jid'] = 'romeo@montague.lit'
 
50
    item['subscription'] = 'both'
 
51
    group = item.addElement('group', content='Still alive')
 
52
    stream.send(iq)
 
53
 
 
54
    iq = IQ(stream, 'set')
 
55
    iq['id'] = 'roster-push'
 
56
    query = iq.addElement(('jabber:iq:roster', 'query'))
 
57
    item = query.addElement('item')
 
58
    item['jid'] = 'duncan@scotland.lit'
 
59
    item['subscription'] = 'both'
 
60
    stream.send(iq)
 
61
 
 
62
    sync_dbus(bus, q, conn)
 
63
    sync_stream(q, stream)
 
64
 
 
65
    call_async(q, conn.Requests, 'EnsureChannel',{
 
66
        cs.CHANNEL_TYPE: cs.CHANNEL_TYPE_CONTACT_LIST,
 
67
        cs.TARGET_HANDLE_TYPE: cs.HT_GROUP,
 
68
        cs.TARGET_ID: 'Still alive',
 
69
        })
 
70
    e = q.expect('dbus-return', method='EnsureChannel')
 
71
    still_alive = wrap_channel(bus.get_object(conn.bus_name, e.value[1]),
 
72
            cs.CHANNEL_TYPE_CONTACT_LIST)
 
73
 
 
74
    call_async(q, conn.Requests, 'EnsureChannel',{
 
75
        cs.CHANNEL_TYPE: cs.CHANNEL_TYPE_CONTACT_LIST,
 
76
        cs.TARGET_HANDLE_TYPE: cs.HT_GROUP,
 
77
        cs.TARGET_ID: 'Capulets',
 
78
        })
 
79
    e = q.expect('dbus-return', method='EnsureChannel')
 
80
    capulets = wrap_channel(bus.get_object(conn.bus_name, e.value[1]),
 
81
            cs.CHANNEL_TYPE_CONTACT_LIST)
 
82
 
 
83
    # the XMPP prpl puts people into some sort of group, probably called
 
84
    # Buddies
 
85
    channels = conn.Properties.Get(cs.CONN_IFACE_REQUESTS, 'Channels')
 
86
    default_group = None
 
87
    default_props = None
 
88
 
 
89
    for path, props in channels:
 
90
        if props.get(cs.CHANNEL_TYPE) != cs.CHANNEL_TYPE_CONTACT_LIST:
 
91
            continue
 
92
 
 
93
        if props.get(cs.TARGET_HANDLE_TYPE) != cs.HT_GROUP:
 
94
            continue
 
95
 
 
96
        if props.get(cs.TARGET_ID) in ('Capulets', 'Still alive'):
 
97
            continue
 
98
 
 
99
        if default_group is not None:
 
100
            raise AssertionError('Two unexplained groups: %s, %s' %
 
101
                    (path, default_group.object_path))
 
102
 
 
103
        default_group = wrap_channel(bus.get_object(conn.bus_name, path),
 
104
                cs.CHANNEL_TYPE_CONTACT_LIST)
 
105
        default_group_name = props.get(cs.TARGET_ID)
 
106
 
 
107
    assertEquals(set([romeo, juliet]), set(still_alive.Group.GetMembers()))
 
108
    assertEquals(set([juliet]), set(capulets.Group.GetMembers()))
 
109
    assertEquals(set([duncan]), set(default_group.Group.GetMembers()))
 
110
 
 
111
    # We can't remove Duncan from the default group, because it's his only
 
112
    # group
 
113
    call_async(q, default_group.Group, 'RemoveMembers', [duncan], '')
 
114
    q.expect('dbus-error', method='RemoveMembers',
 
115
            name=cs.NOT_AVAILABLE)
 
116
 
 
117
    # Make a new group and add Duncan to it
 
118
    call_async(q, conn.Requests, 'CreateChannel',{
 
119
        cs.CHANNEL_TYPE: cs.CHANNEL_TYPE_CONTACT_LIST,
 
120
        cs.TARGET_HANDLE_TYPE: cs.HT_GROUP,
 
121
        cs.TARGET_ID: 'Scots',
 
122
        })
 
123
    e = q.expect('dbus-return', method='CreateChannel')
 
124
    scots = wrap_channel(bus.get_object(conn.bus_name, e.value[0]),
 
125
            cs.CHANNEL_TYPE_CONTACT_LIST)
 
126
    assertEquals(set(), set(scots.Group.GetMembers()))
 
127
 
 
128
    call_async(q, scots.Group, 'AddMembers', [duncan], '')
 
129
    iq, _, _ = q.expect_many(
 
130
            EventPattern('stream-iq', iq_type='set', query_name='query',
 
131
                query_ns=ns.ROSTER),
 
132
            EventPattern('dbus-signal', signal='MembersChanged',
 
133
                path=scots.object_path,
 
134
                args=['', [duncan], [], [], [], 0, cs.GC_REASON_NONE]),
 
135
            EventPattern('dbus-return', method='AddMembers'),
 
136
            )
 
137
    assertEquals('duncan@scotland.lit', iq.stanza.query.item['jid'])
 
138
    groups = set([str(x) for x in xpath.queryForNodes('/iq/query/item/group',
 
139
        iq.stanza)])
 
140
    assertLength(2, groups)
 
141
    assertContains(default_group_name, groups)
 
142
    assertContains('Scots', groups)
 
143
 
 
144
    # Now we can remove him from the default group. Much rejoicing.
 
145
    call_async(q, default_group.Group, 'RemoveMembers', [duncan], '')
 
146
    iq, _, _ = q.expect_many(
 
147
            EventPattern('stream-iq', iq_type='set', query_name='query',
 
148
                query_ns=ns.ROSTER),
 
149
            EventPattern('dbus-signal', signal='MembersChanged',
 
150
                path=default_group.object_path,
 
151
                args=['', [], [duncan], [], [], 0, cs.GC_REASON_NONE]),
 
152
            EventPattern('dbus-return', method='RemoveMembers'),
 
153
            )
 
154
    assertEquals('duncan@scotland.lit', iq.stanza.query.item['jid'])
 
155
    groups = set([str(x) for x in xpath.queryForNodes('/iq/query/item/group',
 
156
        iq.stanza)])
 
157
    assertLength(1, groups)
 
158
    assertContains('Scots', groups)
 
159
 
 
160
    # Romeo dies. If he drops off the roster as a result, that would be
 
161
    # fd.o #21294. However, to fix that bug, Haze now puts him in the
 
162
    # default group.
 
163
    call_async(q, still_alive.Group, 'RemoveMembers', [romeo], '')
 
164
    iq1, iq2, _, _, _ = q.expect_many(
 
165
            EventPattern('stream-iq', iq_type='set', query_name='query',
 
166
                query_ns=ns.ROSTER),
 
167
            EventPattern('stream-iq', iq_type='set', query_name='query',
 
168
                query_ns=ns.ROSTER),
 
169
            EventPattern('dbus-signal', signal='MembersChanged',
 
170
                path=still_alive.object_path,
 
171
                args=['', [], [romeo], [], [], 0, cs.GC_REASON_NONE]),
 
172
            EventPattern('dbus-signal', signal='MembersChanged',
 
173
                path=default_group.object_path,
 
174
                args=['', [romeo], [], [], [], 0, cs.GC_REASON_NONE]),
 
175
            EventPattern('dbus-return', method='RemoveMembers'),
 
176
            )
 
177
 
 
178
    assertEquals('romeo@montague.lit', iq1.stanza.query.item['jid'])
 
179
    groups = set([str(x) for x in xpath.queryForNodes('/iq/query/item/group',
 
180
        iq1.stanza)])
 
181
    assertLength(2, groups)
 
182
    assertContains('Still alive', groups)
 
183
    assertContains(default_group_name, groups)
 
184
 
 
185
    assertEquals('romeo@montague.lit', iq2.stanza.query.item['jid'])
 
186
    groups = set([str(x) for x in xpath.queryForNodes('/iq/query/item/group',
 
187
        iq2.stanza)])
 
188
    assertLength(1, groups)
 
189
    assertContains(default_group_name, groups)
 
190
 
 
191
    # Juliet dies. She's in another group already, so the workaround for
 
192
    # fd.o #21294 is not active.
 
193
    call_async(q, still_alive.Group, 'RemoveMembers', [juliet], '')
 
194
    iq, _, _ = q.expect_many(
 
195
            EventPattern('stream-iq', iq_type='set', query_name='query',
 
196
                query_ns=ns.ROSTER),
 
197
            EventPattern('dbus-signal', signal='MembersChanged',
 
198
                path=still_alive.object_path,
 
199
                args=['', [], [juliet], [], [], 0, cs.GC_REASON_NONE]),
 
200
            EventPattern('dbus-return', method='RemoveMembers'),
 
201
            )
 
202
    assertEquals('juliet@capulet.lit', iq.stanza.query.item['jid'])
 
203
    groups = set([str(x) for x in xpath.queryForNodes('/iq/query/item/group',
 
204
        iq.stanza)])
 
205
    assertLength(1, groups)
 
206
    assertContains('Capulets', groups)
 
207
 
 
208
if __name__ == '__main__':
 
209
    exec_test(test)